OmniAICreator/Qiita-1.07M huggingface dataset:
【Mac】CentOSインストール用のUSBメモリを作成する

#用意するもの

USBメモリ（８GB）

#isoイメージのダウンロード

Macで理化学研究所のftpサーバにあるISOイメージをダウンロードする（最小構成で約1GB）

```
http://ftp.riken.jp/Linux/centos/7.7.1908/isos/x86_64/
```

# USBメモリの認識確認

/dev/disk2として認識されている事がわかります

```
$ diskutil list
/dev/disk0 (internal):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      GUID_partition_scheme                         251.0 GB   disk0
   1:                        EFI EFI                     314.6 MB   disk0s1
   2:                 Apple_APFS Container disk1         250.7 GB   disk0s2
 
/dev/disk1 (synthesized):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:      APFS Container Scheme -                      +250.7 GB   disk1
                                 Physical Store disk0s2
   1:                APFS Volume Macintosh HD            134.6 GB   disk1s1
   2:                APFS Volume Preboot                 43.5 MB    disk1s2
   3:                APFS Volume Recovery                510.4 MB   disk1s3
   4:                APFS Volume VM                      4.3 GB     disk1s4
 
/dev/disk2 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:     FDisk_partition_scheme                        *7.9 GB     disk2
   1:                       0xEF                         8.9 MB     disk2s2
```

#USBメモリを初期化してフォーマットする

```
$ diskutil eraseDisk MS-DOS UNTITLED /dev/disk2
Started erase on disk2
Unmounting disk
Creating the partition map
Waiting for partitions to activate
Formatting disk2s2 as MS-DOS (FAT) with name UNTITLED
512 bytes per physical sector
/dev/rdisk2s2: 14990720 sectors in 1873840 FAT32 clusters (4096 bytes/cluster)
bps=512 spc=8 res=32 nft=2 mid=0xf8 spt=32 hds=255 hid=411648 drv=0x80 bsec=15020032 bspf=14640 rdcl=2 infs=1 bkbs=6
Mounting disk
Finished erase on disk2
```

#USBメモリをアンマウントする
isoイメージを焼くにあたりddコマンドを実行するが、マウントしていると実行出来ないのでアンマウントする。

```
$ diskutil unmountDisk /dev/disk2
Unmount of all volumes on disk2 was successful
```

#ddコマンドでイメージをUSBメモリに焼く

指定するデバイスがrdiskになっている事に注意

**参考ページ： https://www.junk-works.science/disk-and-rdisk/**

```
$ sudo dd if=CentOS-7-x86_64-Minimal-1908.iso of=/dev/rdisk2 bs=1m
942+0 records in
942+0 records out
987758592 bytes transferred in 94.048308 secs (10502673 bytes/sec)
```

これをサーバに接続してUSBメモリからブートするとインストールウィザードが走る
「���s」Rパッケージ開発時の文字化け解決方法のひとつ

---
Rパッケージ開発時に良く出くわす困った現象．
エラーや警告文(日本語)が文字化けして読めない．
例）Build Test時
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34549/fe659f21-a222-f7b1-7e11-74407aa9285c.png)

---
システム上で扱われる言語を英語にすれば突破できるのでは？？
結果）���sと文字化けしていた箇所を読むことができた．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34549/e3020a06-26ca-0f9c-c0a3-e0ebe28f54dd.png)


---
#方法1：
Sys.setenv(LANG = "en")



#方法2：
LANGUAGE=en
と書いた「.Renviron」ファイルをRパッケージプロジェクトフォルダの直下に配置する．
プロジェクトを開くときに，自動的にシステム言語が英語扱いになる．
方法1を毎回コンソールで実行する必要が無くなるので効率的．
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/34549/ae61fdcc-f851-8465-3289-f8926c00270b.png)
null安全とLINQ

##前書
流石にLINQまでフロー解析はしてくれないらしい

##直面した場面
```C#

public static int? ToIntOrNull(int num)
{
    return num % 2 == 0 ? (int?)null : num;
}

//
public static IEnumerable<int> TestFunc1()
{
    //kは非nullが確定しているが警告が出る
    //CS8629	Null 許容値型は Null になる場合があります。
    return Enumerable.Range(0, 10)
        .Select((i) => ToIntOrNull(i))
        .Where((j) => j != null)
        .Select((k) => (int)k);
}
public static IEnumerable<int> TestFunc2()
{
    //!演算子をつければ警告は出ない
    return Enumerable.Range(0, 10)
        .Select((i) => ToIntOrNull(i))
        .Where((j) => j != null)
        .Select((k) => (int)k!);
}

```

##追記
コメントを頂いたのでそのまま転記
OfType<T>()を使えばすっきり綺麗に書けるそうです

```C#
public static IEnumerable<int> TestFunc3()
{
    return Enumerable.Range(0, 10)
        .Select((i) => ToIntOrNull(i))
        .OfType<int>();
// 1,3,5,7,9
}
```
@Stateの値によって処理を制御する方法いくつか

# はじめに

`@State` で定義した値に変化が生じた際、それに応じて処理を挟み込むいくつかの方法です。

# 準備

デモ用に、文字列の末尾が3の倍数だったらアホになるExtensionを生やします。

```swift
extension String {
    var needsAho: Bool {
        self.last
            .flatMap { Int("\($0)") }
            .flatMap { $0 % 3 == 0 } ?? false
    }
}
```

# 1. Computed Propertyを使う

- 一番シンプルな方法で、値に変化があると即時に反映されます

```swift
import SwiftUI

struct ContentView: View {
    @State private var inputText: String = ""
    private var displayText: String {
        inputText.needsAho ? "🤪" : ""
    }

    var body: some View {
        VStack {
            TextField("title", text: $inputText)
            Text(displayText)
        }.padding()
    }
}
```

<img alt="sample1.gif" width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41486/b9bb4bb3-5935-d875-38ce-eb73ba916576.gif"/>


# 2. Publishedを使う

- 1.の方法では、例えば「1秒間の間に連続されて入力された場合、まとめて1回だけ処理を行いたい」といった場合などに対応できません
- `ObservableObject` に `Published` プロパティを生やすことで、Publisherとして扱うことができるようになるので、Combineオペレーターを使えるようになります

```swift
import Combine
import SwiftUI

class ViewModel: ObservableObject {
    @Published var inputText: String = ""
    @Published var displayText: String = ""
    private var cancellables: Set<AnyCancellable> = []

    init() {
        $inputText
            .debounce(for: 1.0, scheduler: DispatchQueue.main)
            .map { $0.needsAho ? "🤪" : "" }
            .receive(on: DispatchQueue.main)
            .assign(to: \.displayText, on: self)
            .store(in: &self.cancellables)
    }
    
    deinit {
        self.cancellables.forEach { $0.cancel() }
    }
}

struct ContentView: View {
    @ObservedObject private var viewModel = ViewModel()

    var body: some View {
        VStack {
            TextField("title", text: $viewModel.inputText)
            Text(viewModel.displayText)
        }.padding()
    }
}
```

<img alt="sample2.gif" width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41486/9fed69e4-29b6-49da-1722-dc74519e33e6.gif"/>


# 3. CurrentValueSubjectを使う

- 2の方法では、いちいち `ObservableObject` を作らなくてはなりません
- `CurrentValueSubject` を `@State` プロパティで持っておけば、Viewだけで同様の挙動を実現できます

```swift
import Combine
import SwiftUI

struct ContentView: View {
    @State private var inputTextSubject: CurrentValueSubject<String, Never> = .init("")
    @State private var displayText: String = ""
    @State private var cancellables: Set<AnyCancellable> = []

    var body: some View {
        VStack {
            TextField("title", text: $inputTextSubject.value)
            Text(displayText)
        }
        .padding()
        .onAppear {
            self.inputTextSubject
                .debounce(for: 1.0, scheduler: DispatchQueue.main)
                .map { $0.needsAho ? "🤪" : "" }
                .receive(on: DispatchQueue.main)
                .assign(to: \.displayText, on: self)
                .store(in: &self.cancellables)
        }
        .onDisappear {
            self.cancellables.forEach { $0.cancel() }
        }
    }
}
```

<img alt="sample3.gif" width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41486/34dc287d-fa3b-242d-5b79-8962d03a1a96.gif"/>
apacheを使ってみる2(apacheの文字化けの修正)

##この前の続き
[apacheを使ってみる](https://qiita.com/jajaja/items/d914e8a34658bdbbfa83)の続き

##本題
[Macに入ってるApacheでローカルWebサーバを起動する]
(https://qiita.com/takenobi/items/83068ab79ed95cbc84c8)
を参考に`Desktop/page/index.html`を作りVScodeを用いてindex.htmlを編集し、`Sites/index.html`を`sudo cp -rf Desktop/page /Users/ユーザ名/Sites`と更新しようとしたら次のエラーが
(index.htmlファイルのみをコピーするならこう。
`cp -rf Desktop/page/index.html /Users/[ユーザ名]/Sites `)

`
cp: /Sites: Read-only file system
cp: Desktop/page: unable to copy extended attributes to /Sites: Read-only file system
cp: /Sites/index.html: No such file or directory
`
Sitesが読み取り専用になっているらしい。
パーミッションを755に変更して再度実行。

無事にコピーはできたが文字化けの問題が続く

![スクリーンショット 2020-03-25 16.19.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402798/eb95e505-b854-fa6f-333a-6541c99d2a3b.png)

文字コードが原因だと考えた。
[Webブラウザが文字コードを判定する基準は？]
(https://www.atmarkit.co.jp/ait/articles/0412/25/news006.html)
によると、HTTPのContent-Typeの情報のcharsetパラメータがないことが原因であることが多いらしく、実際自分もそこだった。
HTTPヘッダの確認
（chromeだと、[Google Chrome でHTTPヘッダー情報を確認する方法]
(https://smakoma.com/http-header-chrome.html)に記載されてる方法で確認できる。
または、[curlコマンドでHTTPヘッダを扱うレシピ]
(https://qiita.com/youcune/items/45271a32dccb7498033f)に記載されている方法でターミナルでも確認できる。）

[.htaccessによる文字化け対策]
(http://www.koikikukan.com/archives/2004/11/23-142537.php)を参考に、.htaccess　にAddTypeで宣言をかく、`AddType "text/html;charset=UTF-8" html`と今回は書いた。
httpd.confファイルに書いてもいいんだけど、httpd.confはapache全体の設定で.htaccessは各ディレクトリごとの設定(あってる?)だから、全般の設定をいじらない方が良いと考え.htaccessにしました。

そしたら無事に文字化けが直った。



![スクリーンショット 2020-03-25 16.22.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402798/f32d5c82-a57f-7cfd-d23f-c7fe53e1c219.png)


####メモ
・apacheは表示内容を自動で更新しないため、更新するためには`sudo apachectl restart`
を打つ
・パーミッションの設定は`chmod`コマンドで行い、大体のパーミッションの問題は`chmod 755 [ディレクトリorファイル名]`で解決しそう
・`.so`は共有ファイル、`.conf`はunix系で慣例的に使われる設定ファイルのこと
・エラーログは`httpd.conf`ファイルで`ErrorLog`で検索すると位置が書いてある。
自分の場合は`/private/var/log/apache2/error_log`だった。

##感想
文字化け以外にもいろいろハマった、、、
こういう完全に初めてやるようなことは本を読んでからやろうと考えました。


##参照
・[Macに入ってるApacheでローカルWebサーバを起動する]
(https://qiita.com/takenobi/items/83068ab79ed95cbc84c8)
・[パーミッションについて]
(http://web.tku.ac.jp/~densan/local/permission/permission.htm)
・[so[拡張子]とは]
(https://wa3.i-3-i.info/word13856.html)
・[confファイルとは]
(https://wa3.i-3-i.info/word11392.html)
・[Webブラウザが文字コードを判定する基準は？]
(https://www.atmarkit.co.jp/ait/articles/0412/25/news006.html)
・[MIMEタイプの追加(AddType)]
(https://www.adminweb.jp/apache/docroot/index4.html)
・[Google Chrome でHTTPヘッダー情報を確認する方法]
(https://smakoma.com/http-header-chrome.html)
・[Apache Web サーバーの設定メモ]
(http://www.nminoru.jp/~nminoru/unix/apache.html)
・[curlコマンドでHTTPヘッダを扱うレシピ]
(https://qiita.com/youcune/items/45271a32dccb7498033f)
・[.htaccessとは？設定できることや書き方と設定場所について]
(https://digital-marketing.jp/creative/what-is-htaccess/)
・[【touch】Linuxで新規ファイル作成をするコマンド]
(https://uxmilk.jp/8395)
・[.htaccessによる文字化け対策]
(http://www.koikikukan.com/archives/2004/11/23-142537.php)
ESP-ADFを使って、計算した音声信号を外部I2S-DACへ出力する方法（１）

# はじめに

　先日、[ESP-IDF(ESP32) v4 で外部I2S DACを使って正弦波を鳴らす](https://qiita.com/moppii/items/e109324d21429f12e2bd)という投稿をしました。この記事では、[ESP-IDF(IoT Development Framework)](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/)を使ってESP32に外部接続したI2S-DACから正弦波を出力しました。しかし、より実用的に使う（例えばPCM音源を再生したり、合成等の信号処理をしたりする）ためには、要素機能毎にタスクを分割し、マルチタスクで同時実行したり、各タスク間で信号を受け渡したりする必要があります。  

　通常、こういった機能は自前で実装するものかもしれませんが、ESP32の開発元であるEspressif社の提供している[ESP-ADF(Audio Development Framework)](https://docs.espressif.com/projects/esp-adf/en/latest/)というライブラリに、まさにこれらの機能が実装されていることが分かりましたので、これを活用することにしました。このESP-ADFは専用ボード（[ESP32-LyraT](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/get-started-esp32-lyrat.html)など）での使用を想定しているようですが、単体のESP32でも使用可能ですので、本投稿では前回同様にESP32と外部I2S-DACとスピーカを使用して、簡単な正弦波を出力してみます。  

　[公式サンプル](https://github.com/espressif/esp-adf/tree/master/examples)との違いは、出力する信号波形を自分で(sin関数を使って)計算している点です。公式のサンプルにはmp3やwavファイルを読み取って再生するものがありますが、信号波形を直接触ることはほぼしておらず、ドキュメントにもあまりその方法の説明がありません。そこで今回は、信号波形の生データを自分で生成してI2S出力に渡す処理を、分かりやすく説明できるようなプログラムを作成しました。

　今回の投稿では、まず動作させるまでを説明します。プログラムやライブラリ仕様の説明は、後日投稿します。



# 準備するもの
- PC(筆者はMac)
- ESP32開発ボード(NodeMCU, ESP-WROOM-32等)
- MAX98357A I2S DACモジュール(Adafruit製や類似品)
- スピーカユニット（使用するDACに適したもの。0.5～3W程度の小さいもの）



# 環境構築
## ESP-ADFの導入
　公式サイト（[Get Started](https://docs.espressif.com/projects/esp-adf/en/latest/get-started/index.html)）の説明通りにESP-IDFとESP-ADFを導入します。なお[先日の投稿](https://qiita.com/moppii/items/e109324d21429f12e2bd)とはESP-IDFのバージョンが異なるため、注意が必要です（前回はv4でしたが、今回はv3.3.1を使います）。私はesp_v3とesp_v4の2つ似フォルダを分けて両立させています（環境変数も切り替えています）が、よく分からなければ既存のespフォルダを削除または退避して、改めて再導入すればOKです。  

　新規導入する場合の手順は、以下のようになります。（macの場合）  

```bash
# 事前に https://dl.espressif.com/dl/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz を~/Downloadsへダウンロードしておく。
mkdir -p ~/esp
cd ~/esp
tar -xzf ~/Downloads/xtensa-esp32-elf-osx-1.22.0-80-g6c4433a-5.2.0.tar.gz
git clone -b v3.3.1 --recursive https://github.com/espressif/esp-idf.git
git clone --recursive https://github.com/espressif/esp-adf.git

# pipでパッケージをインストールする。（pipが無ければ別途インストール必要）
# また、環境変数$IDF_PATHを設定する必要あり。
python -m pip install --user -r $IDF_PATH/requirements.txt
```



## Githubからプログラムを入手（git clonoe）
　今回もgithubに一式を用意しましたので、git cloneでダウンロードするだけでOKです。  

```bash
cd ~/esp
git clone https://github.com/moppii-hub/ESPADF_geneSig.git
```



## 回路の製作
　[先日の投稿](https://qiita.com/moppii/items/e109324d21429f12e2bd)の回路と同じです。再掲します。  

![Wiring](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603551/20ed0e84-7233-4fa5-71ab-d0998ecd68af.png)



# とりあえず動作させる
　まず、`make menuconfig`を実行し、シリアルポートの設定をします。  

```bash
cd ~/esp/ESPADF_geneSig/
make menuconfig
```

　設定方法は[公式の説明](https://docs.espressif.com/projects/esp-idf/en/v3.3.1/get-started/index.html#configure)の通りですが、menuconfigの画面が出たら`Serial flasher config` > `Default serial port` と選び、ポート名を入力し、save, exitします。なおポート名は、以下の方法で調べることができます。私の環境(mac)では、`/dev/tty.SLAB_USBtoUART`です。  

```bash
ls /dev/tty.*
```  

　ポートの設定が完了したら、ESP32をPCへ接続し、プログラムを書き込みます。  

```bash
make flash
```

　プログラムの書き込みが終わり、スピーカから正弦波が鳴れば成功です。  


# さいごに
　簡単ですが、今回はここまでとします。次回は、今回動作させたプログラムの説明と、ESP-ADFライブラリの使用方法の説明をします。
AVSampleBufferDisplayLayerを透過する

特殊なケースですが、透過情報を持ったSampleBufferを`AVSampleBufferDisplayLayer`にenqueueしても、背景が透過されないことがあります。

これは`AVSampleBufferDisplayLayer`が透過できない訳ではなく、enqueueしたCMSampleBufferに透過情報があるかどうかのフラグが有効になっていないため起こる問題です。

次のようにSampleBufferに含まれるimageBufferに対して`kCVImageBufferAlphaChannelIsOpaque`フラグを落とせば透過が有効になります。

```swift
imageBuffer.attachments.merge([kCVImageBufferAlphaChannelIsOpaque as String : false], mode: .shouldPropagate)
```
Goodby/CSV 大量にデータをインポートすると、マルチバイト文字列が欠落する場合がある

自分用の備忘録

### 何が問題か

私が教えてほしいです。

大量に(400行ぐらい)データをインポートすると、1～数行、
日本語文字列が一文字(3バイト分)だけ欠落するという事象が発生した

原因は不明。誰か教えて

### 直し方

これを

```
$config->setFromCharset("UTF-8");
```

こうすれば直った

```
$config->setFromCharset(NULL);
```

### ソースコード

```
    /**
     * Import Csv By Goodby\CSV Parser
     * このメソッドはCSVの読み込みのみを担当し、加工はコントローラー側に任せる想定
     *
     * @param  string $filePath
     * @return array
     * @link https://github.com/goodby/csv
     * @link https://nori-life.com/laravel-csv-import-goodbycsv/
     */
    public function import($filePath)
    {
        // variable definition
        $rows = array();

        // goodby csv configuration
        $config = new LexerConfig();
        $config->setDelimiter(","); // e.g. [",", "\t"]
        $config->setEnclosure('"'); // e.g. ["'", '"']
        $config->setEscape("\\");

        // UTF-8にすると、大量にデータを読み込んだ際に、マルチバイト文字列が欠落する場合がある模様
        //$config->setFromCharset("UTF-8"); // e.g. [NULL, "UTF-8", "SJIS-win", "EUC-JP"]
        $config->setFromCharset(NULL); // e.g. [NULL, "UTF-8", "SJIS-win", "EUC-JP"]

        $config->setToCharset("UTF-8"); // e.g. [NULL, "UTF-8", "SJIS-win", "EUC-JP"]
        $config->setIgnoreHeaderLine(TRUE);

        // format csv
        $interpreter = new Interpreter();
        $interpreter->addObserver(function(array $row) use (&$rows){
            $rows[] = $row;
        });

        // parse csv
        $lexer = new Lexer($config);
        $lexer->parse($filePath, $interpreter); // parsed csv data into $rows here.

        return $rows;
    }
```
対象のリポジトリが大きすぎてgit cloneできない時の対処法

備忘録として。

# エラー内容: packet_write_wait: Broken pipe

リモートリポジトリのサイズがクライアント側の受け入れ容量を超えてしまい、`git clone`時に以下のエラーが出る。

```bash
$ git clone ssh://~ sample

Cloning into 'sample'...
remote: Counting objects: 1556, done.
packet_write_wait: Connection to ~ port ~: Broken pipe
fatal: the remote end hung up unexpectedly
fatal: early EOF
fatal: index-pack faile
```

# 解決

gitクライアント側でバッファの容量をとりあえず20MBまで増やしてあげる。

```bash
$ git config --global http.postBuffer 20M
```
Wordpress ページによって読み込むcssを変える

#はじめに
wordpressでページごとに読み込むcssを変えたい！と思う事があるかもしれません。

実はphpの条件分岐を使えば、簡単にできるのです。:cop:
**今回は固定ページごとに**、読み込むcssを変える方法を紹介

#スラッグ（Slug）を確認
まずは固定ページのスラッグ（Slug）を確認

<img width="486" alt="スクリーンショット 2020-03-25 18.55.29.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167220/d066420e-92d2-dd12-c568-83f0644a5f94.jpeg">

`固定ページ一覧＞クイック編集`から確認できるかと（無理だったら目的のページの編集画面まで行こう）

#header.phpで条件分岐

```php:header.php
<head>
.省略
.
.
 <?php if(is_page('movie100')) { ?>
        <link href="<?php echo get_template_directory_uri(); ?>/css/movie100.css" rel="stylesheet ">
        <?php }?>

</head>
```

これでスラッグが`movie100`の固定ページでは、`movie100.css`が読み込まれます。

##もっと複数の条件分岐をしたい場合

```php
<?php if(is_page(array('movie100', 'manga100'))) : ?>
         <link href="<?php echo get_template_directory_uri(); ?>/css/movie100.css" rel="stylesheet ">
        <?php else: ?>
        <link href="<?php echo get_template_directory_uri(); ?>/css/style.css" rel="stylesheet ">
        <?php endif; ?>
```

これでスラッグが`movie100`と`manga100`の固定ページの場合は`movie100.css`が読み込まれ、それ以外のページでは`style.css`が読み込まれる。
AWS CLIで現在作業中のアカウント情報を確認する方法


AWS CLIで現在作業中のアカウント情報を確認する方法を備忘録的に書いていきます。

## JSON形式で情報取得する

`GetCallerIdentity`というものがあるらしく、これを使うことでJSON形式で情報を取得することができます。

```
$ aws sts get-caller-identity

{
    "Account": "123456789012",
    "UserId": "AIDAXXXXXXXXXXXXXXXXX",
    "Arn": "arn:aws:iam::123456789012:user/user_name"
}
```

## 特定の情報だけを取得する

特定の情報だけを取得したい場合は`query`オプションなどを使って取得することができます。（`output`オプションを使ってるのはダブルコーテーションを省くためです）

```
$ aws sts get-caller-identity --query 'Account' --output text
```

## ユーザー名だけを取得する
ユーザー名だけを取得したい場合は、色々な方法があると思いますが`awk`コマンドを使って下記のように書くことができると思います。


```
$ aws sts get-caller-identity --query 'Arn' | awk '{ print substr($1, index($1, "/")) }' | awk '{ sub("/", ""); sub("\"", ""); print }'
```
field_with_errorsによるレイアウト崩れを防ぐ

# 実装したいこと
新規会員登録機能バリデーションを設定し、入力項目にエラーがある場合はエラーメッセージとともに、入力ページに戻るように設定してします。
この時下の写真のようにレイアウト崩れが発生しますので、この事例について修正します。

###初回入力時
<img width="615" alt="スクリーンショット 2020-03-25 18.29.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527013/719970d1-9f76-7f80-d75b-14636116e5a7.png">

###再入力時（レイアウト崩れ）<img width="615" alt="スクリーンショット 2020-03-25 18.29.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527013/498c7444-5d6c-7f32-00f1-901d6d34cc37.png">

#レイアウト崩れの原因
この事象の原因は、エラーが発生している時Railsが自動的に`field_with_errors`クラスを持つdivタグで、labelタグやinputタグを囲むことによって発生します。横並びになっている２つのinputタグそれぞれをdivダグで囲むため、改行されて表示されています。

```new.html.haml
.contents-field
  = f.label :お名前（全角）
  %span.contents-field__require 必須
  %br
  = f.text_field :family_name, class:"contents-field__input half", placeholder:"例）山田"
  = f.text_field :first_name, class:"contents-field__input half", placeholder:"例）太郎"
.contents-field
  = f.label :お名前カナ（全角）
  %span.contents-field__require 必須
  %br
  = f.text_field :family_name_kana, class:"contents-field__input half", placeholder:"例）ヤマダ"
  = f.text_field :first_name_kana, class:"contents-field__input half", placeholder:"例）タロウ"
```

<img width="383" alt="スクリーンショット 2020-03-25 18.30.26.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/527013/713d828a-67ee-fdb6-2e94-8f536e9e5dc5.png">

#解決方法
上記の事象に対する解決方法は２つが考えられます。

- 自動で読み込まれる`field_with_errors`タグを読み込まないように設定する。
- `field_with_errors`に対してCSSをあてる

今回は`field_with_errors`タグを読み込まないようにする方法で、以下のように`applicaton.rb`を編集します。

```applicaton.rb
module FreemarketSample65d
  class Application < Rails::Application
    #以下を追加
    config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag }
  end
end

```
herokuでのArgumentErrorの解決

#  herokuでのArgumentErrorやErrno::ECONNREFUSED: Connection refused – connect(2) for action mailerの解決

メモ用に残しておく

ArgumentError in Users::Registrations#createというerrorが発生

こんな感じにconfig/environments/development.rbに書いてあった文をproduction.rbに移してサーバーを再起動するだけだった。

```production.rb
config.action_mailer.default_url_options = { protocol: 'https', host: 'https://〇〇〇〇.com' }
config.action_mailer.raise_delivery_errors = true
config.action_mailer.smtp_settings = {
  port:                  　XXX,
  address:               'smtp.gmail.com',
  domain:                'smtp.gmail.com',
  user_name:             'XXXXXXX@gmail.com',
  password:              ‘XXXXXXX’,
  authentication:        'login',
  enable_starttls_auto:  true
}
```
MacBook Air 11' Early 2015にArchLinuxをインストールする際にハマった事メモ(2020年3月)

走り書きのメモです。
久々にArchLinux環境をリフレッシュしようとしたら、かなり手間取りました。

# 新しめのカーネルが内臓ストレージ(nvme0n1)を認識しない
この症状はいつぞやから起動しないなと認識はしていたので、途中からltsカーネルをインストールして使っていました。
技術的背景等は調べていませんが、[こちらのスレッド](https://www.reddit.com/r/archlinux/comments/dupyg6/macbook_linux_doesnt_see_macbook_disk_at_install/)によると、nvmeをLinux Kernel 5.1.5からサポートしなくなったとされています。
ただ自分が確かめた範囲では、少なくとも自分の機体に関してはもっと前の4.19でも認識しませんでした。
色々な世代のインストールイメージを入手して試した限りでは、2019.05.02(Kernelは4.16.12-1)で認識できました。
ただしこのUSBでは別の問題があります。詳細は次の見出しで。

# archlinux-keyringが更新できない

こちらに関してはpacmanで用いられるパッケージの圧縮形式の変更が影響しています。
https://www.archlinux.jp/news/required-update-to-recent-libarchive/
要約すると、

- 新しいpacman5.2は.zst圧縮に対応する
- 今後はこちらの圧縮方式に変更していく
- libarchiveを3.3.3-1以降に更新するように

という話です。

これが何故問題化するかというと、前述の2019.05.02のインストールイメージでは

- libarchiveのバージョンは問題ない
- pacmanはこの5.2より前のバージョン(5.2のリリースは2019.10.22)で、.zstパッケージを取り扱えない
- archlinux-keyringパッケージは既に.zst圧縮になっている

archlinux-keyringはパッケージ署名の情報等が含まれているので、インストール時にここに無い署名が含まれているとエラーが出て更新しろと言われるのですが、アップデートができません。
その他のパッケージにも.zst圧縮の物が既に含まれており、ストレージを認識していてもpacstrapを完了できません。

# 解決について
問題を整理すると

- インストールUSBと本体にインストールするKernelが4.16以下である必要がある(確認した限り)
- pacmanが5.2以上である必要があり、libarchiveも3.3.3-1以上にする必要がある

上記の問題を同時に解決できるインストールUSBは存在しないので、[archiso](https://wiki.archlinux.jp/index.php/Archiso)を使用するか、[isoをリマスタリング](https://wiki.archlinux.jp/index.php/%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB_ISO_%E3%81%AE%E3%83%AA%E3%83%9E%E3%82%B9%E3%82%BF%E3%83%AA%E3%83%B3%E3%82%B0)してカスタムインストールUSBを作成して解決する事になると思います。
その為、別にArchLinuxが動作している環境(VMでも可)が必須になります。

使用するカーネルは、[linux-lts414](https://aur.archlinux.org/packages/linux-lts414/)がお勧めです。このMacBookでも問題なく動作する上に、サポートがとても長い(~2024年1月)ので当分安泰です。
ただしこのカーネルはAURのものなので、こちらについても別のArchLinux環境でビルドした上で、プライベートリポジトリを設定してarchisoの構築時に使用させるようなどしてください。
もしくはビルド済みパッケージを提供しているリポジトリを追加してください。(未発見)
AURパッケージの為、カーネルのセキュリティアップデートにもビルドが必要になります。

またオプションですが、ついでにbroadcom-wl-dkmsパッケージを含めておくと、インストール時にも無線LANを使用できるようになります。
インストール手順に関しては、基本的に[ArchWikiのMacBookの記事](https://wiki.archlinux.jp/index.php/MacBook)の内容に従ってください。ブートローダーは、筆者はsystemd-bootを採用しています。

#おわりに
もう5年前の機種ですし、あまりこういった使い方をする方はいないかもしれませんが、役立てば幸いです。
warning: already initialized constant Rack::Utils::ParameterTypeError などのrack utils のエラーの解決例

#1.どんなエラー？

デプロイをしたときにユニコーンのバージョンがローカルとずれてしまい、ユニコーンをダウングレードしたときにでたエラーで、連動して動けなくなってしまったgemを表示したものでした

<img width="1256" alt="スクリーンショット 2020-03-25 14.58.37.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/4da62be8-937c-377a-6ee5-bdd12c981d1d.png">
<img width="1260" alt="スクリーンショット 2020-03-25 14.58.52.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/d8ed99c6-2cfb-7a53-1aa9-f7ca03ba00d4.png">
<img width="1159" alt="スクリーンショット 2020-03-25 14.58.58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/555157/0b2d9f54-6159-272e-4e49-f1e25b83c651.png">


#2.解決方法
unicornの指定のバージョンを新しいものに変え（筆者はそのまま本番環境が新しいものになっていたためそのまま）、`RAILS_SERV_STATIC_FILE=1 bundle exec unicorn_rails -c config/unicorn.rb -E production -D`とすることで、おそらくこのエラーは解消しました。

もう少し深掘りすると`bundle exec`をつけることで初期設定で`bundle install`で更新されないgemが更新されるため、このエラー文は解決できたと思われます。

また、`bundle update -default`すれば直るという記事がいくつか見受けられるのですが、筆者はこれでなかなか苦労したのでupdateコマンドは慎重に行われた方が良いと思います

#3.注意事項
筆者の場合はこのエラーを解決してもその他のエラーが残り、cssが当たらず引き続き試行錯誤を行なっているため、根本的な解決になっているかは不明なのであくまで参考程度にしていただければと思います。
もしかするとこの方法は、「動いていた頃のデータを使う」というその場しのぎの方法かもしれないため、うまくいったときでも最新のものが本番環境に反映されているか再度ご確認ください。

#4.後日談（エラー解決しました）
この方法であっていました。そのほかはnginxとunicorn.rbのpathミスを修正したら直りました
小ワザ : zip(*[lists])を用いてN-gramを作成する

## この記事は・・・
``zip(*[lists])``の挙動の理解に時間がかかった為、備忘録として書きました。

## はじめに
現在、自然言語処理系のKaggleコンペに取り組んでいます。
コンペ参加者のノートブックの中に、探索的データ分析(Exploratory Data Analysis : EDA)を行う目的で N-gramのリストを作成する関数を発見しました。

```python
from wordcloud import STOPWORDS # STOPWORDSのリストを取得

def generate_ngrams(text, n_gram=1):
    token = [token for token in text.lower().split(' ') if token != '' if token not in STOPWORDS]
    ngrams = zip(*[token[i:] for i in range(n_gram)])
    return [' '.join(ngram) for ngram in ngrams]

# 試しに generate_ngrams()を使ってみる
text = "I wanna be a deep python engineer"
ngrams = generate_ngrams(text, n_gram=2)
print(ngrams)
```

```text:実行結果
['wanna deep', 'deep python', 'python engineer']
```

なるほど、引数``n_gram``を変えることで、引数``text``をトークナイズし、ストップワードは取り除いた上でリスト形式のN-gramのリストを返してくれる関数みたいですね。
なんとなくそのままスルーしそうになりましたが、``ngrams = zip(*[token[i:] for ...``の一行が気になりました。
少し考えてみましたが、直感的に理解できなかった。。。のでノートブックで色々トライして理解してみることにしました。

## 結論
``*`` 演算子をつけることで、各リストから、先頭要素から順番に、同じインデックスの要素を取り出して新しいリストを作ることができます。
[公式ドキュメント](https://docs.python.org/ja/3/library/functions.html)の``zip(*iterables)``の項目によると、
> zip() に続けて * 演算子を使うと、zip したリストを元に戻せます:

つまり、unzipを行っていることになるそうです。
また、[同様のテーマを取り上げたQiitaの記事](https://qiita.com/7of9/items/e23bdd6e8d4d7997104a)にもあるように、「行と列を変換している」とイメージすると直感的に理解しやすいかもしれません。

「N-gramを作成する」という目的で、``zip(*[lists])``を使うとするならば、中身のリストは、トークンのリストから先頭の要素を1つずつ削除したリストをn個並べるリストだと良さそうです。
上記の関数では``[token[i:] for i in range(n_gram)]``が正に目的のリストを作成しています。
綺麗なコードだなと感心しました。


## 理解のためにトライしたこと
理解のために実行したコードをだらだらと記しています。。。

``zip(*[lists])``のlists部分を正しく理解してみた。

```python
token = ["wanna", "deep", "python", "engineer"] # 関数実行で得られる tokenのリスト
n_gram = 3 # トライグラムのコーパスを作る
lists = [token[i:] for i in range(n_gram)]
print(lists)
```

```text:実行結果
[['wanna', 'deep', 'python', 'engineer'], ['deep', 'python', 'engineer'], ['python', 'engineer']]
```

分かりづらいので``zip(*[lists])``の中身のリスト部分を重複しない数字に置き換えてみた。

```python
for nums in zip(*[1,2,3,4], [5,6,7], [8,9]):
    print(nums)
```

```text:実行結果
(1, 5, 8)
(2, 6, 9)
```
3つのリストの1番目要素を取り出したリスト、2番目要素を取り出したリストが作られました。
CloudFrontのx-edge-request-idをAPI側に渡す方法

#概要
データを分析するにあたってエッジロケーションからのリクエスト単位で集計をしたく、CloudFrontのログに出力されているx-edge-request-idを使用するという事になった

x-edge-request-idはレスポンスヘッダではx-amz-cf-idとして出力されるのでてっきりOriginにもx-amz-cf-idに同じ値が格納されていると思っていた
しかし検証した結果、OriginでCloudFrontからのリクエストを受け取った際にx-amz-cf-idはあるにはあるが
ヘッダに格納されているx-amz-cf-idの値がx-edge-request-idとは異なる値になっていた

これを解消するために調査した結果を記しておく

#結論

Lambda@EdgeをOrigin Requestに設置し、リクエストを中継する
Originに渡されるx-amz-cf-idがx-edge-request-idと同じになる


#Lambda@Edgeのサンプルコード

```event.py
import json

def lambda_handler(event, context):
    # TODO implement
    print('####lambda edge start###')
    print('####event###')
    print(event)
    print('####lambda edge end###')
    print('####context###')
    print(context)
    cf_request = event['Records'][0]['cf']['request']    
    return cf_request
```

#その他
他の方法としてはOrigin RequestのLambda@Edgeで別のヘッダにrequestId（x-edge-request-idのLambda@Edgeのkey）をコピーする方法がある

なんでこんな挙動なのかは諸事情によりAWSの技術サポートに聞くことができず、知ってる人いたら教えてください
【Rails】【DB】RailsのDBをMySQL2に変更する方法

RailsのDBをMySQL2にする方法を記載します。
まずは`database.yml`を記載していきます。
#database.yml編集
```database.yml
development:
  adapter: mysql2
  encoding: utf8
  database: [アプリケーション名]_development
  pool: 5
  username: [任意のユーザ名]
  password: [任意のパスワード]
  host: localhost

test:
  adapter: mysql2
  encoding: utf8
  database: [アプリケーション名]_test
  pool: 5
  username: [任意のユーザ名]
  password: [任意のパスワード]
  host: localhost

production:
  adapter: mysql2
  encoding: utf8
  database: [アプリケーション名]_production
  pool: 5
  username: [任意のユーザ名]
  password: [任意のパスワード]
  host: localhost
```
上記のように記載していきます。
`[アプリケーション名]`、`[任意のユーザ名]`、`[任意のパスワード]`はご自身のものを記載お願いします。
`database.yml`については[こちら](https://qiita.com/ryouya3948/items/ba3012ba88d9ea8fd43d)をご参考ください。
続いてMySQL2をインストールしていきます。

#MySQL2インストール

```:Gemfile
gem 'mysql2'
:
:
```
これで`bundle install`します。
MySQLではホスト名、ユーザー名、パスワードの指定が必要になるので、設定をしてきます。

#ホスト名、ユーザー名、パスワード設定
MySQLにログインします。

```
$ mysql -u root
:
:
mysql> create user 'ユーザー名'@'localhost' identified by 'パスワード';
mysql> select User,Host from mysql.user;
```
`mysql> create user 'ユーザー名'@'localhost' identified by 'パスワード';`ではホスト名、ユーザー名、パスワードを設定しています。
`select User,Host from mysql.user;`ではユーザーの登録が成功しているか確認を行っています。

続いてユーザーにアカウント権限をつけます。

```
mysql> grant all on *.* to '[ユーザー名]'@'localhost';
```
これで`MySQL2`での設定は完了しました。
先ほどの`database.yml`に登録した`ユーザー`と`ホスト名`、`パスワード`を記載しましょう。
#データベース作成
続いてデータベースを作成して、マイグレーションしていきます。

```
$ rails db:create
$ rails db:migrate
```
`production`の場合は下記のようにデータベースを作成します。

```
rails db:create RAILS_ENV=production
```
これでRailsのDBをMySQL2に変更することができました。
AWS Amplify Consoleを使ってReactアプリのCICD環境を10分で作る

# はじめに
AWS Amplify Consoleを使うと、Reactアプリなどのフロントエンドアプリを簡単にデプロイできるCICD環境が作れます。驚くほど簡単で早いです。
「[AWS S3 + CloudFrontでReactアプリをHTTPS公開するための正しい構成](https://qiita.com/NorihitoYamamoto/items/63df7d87dfd67628d775)」や「[AWS Codepipelineを使ってReactアプリのCI環境をゼロから作る](https://qiita.com/NorihitoYamamoto/items/a463c5641bc3401a4439)」で作ってきた環境を数ステップ、10分以内で作成できます。また、リポジトリのブランチに合わせて環境を簡単に作っていくことができるのも非常に便利です。ただし、制約もあります（[Amplifyの制約](#amplifyの制約)）。

# 作成するもの
Amplifyを使って、GitHubにpushしたコードを、自動的にCloudFront+S3環境にビルドしデプロイする環境です。CloudFrontやS3はAmplifyが内部的に使います（個人のアカウントには現れません）。
![Amplify.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/603113/0cac016c-5cb3-0f26-b437-5da0120cd9a0.png)

# 事前準備
* Reactアプリ（たとえば、「[React版Reactivesearch v3を使ってゼロから最速でElasticsearchフロントアプリを作る](https://qiita.com/NorihitoYamamoto/items/be6d7a245b1e8864952c)」で作ったReactアプリ）
* GitHub環境（たとえば、「[AWS Codepipelineを使ってReactアプリのCI環境をゼロから作る](https://qiita.com/NorihitoYamamoto/items/a463c5641bc3401a4439)」の「GitHub環境の準備」まで）
* Route53での独自ドメインホストゾーン（たとえば、「[AWS S3 + CloudFrontでReactアプリをHTTPS公開するための正しい構成](https://qiita.com/NorihitoYamamoto/items/63df7d87dfd67628d775)」の「Route53登録」）

# 手順

### AWS Amplify Consoleの設定
1. AWS管理コンソールにログインし、AWS Amplifyの画面に移動
2. 「Deploy With the Amplify Console」の下の「GET STARTED」ボタンを押す（もしくは「アプリの作成」ボタンを押す）
3. 「From your existing code」でGitHubにチェックを入れ「Continue」ボタンを押す
4. GitHubの認証を行う
5. GitHubリポジトリ、ブランチを選択し、「次へ」ボタンを押す
6. 「ビルド設定の追加」で「アプリの名前」を任意で付け、「ビルドの設定」で「Edit」ボタンを押し、Reactivesearchのインストール定義を入れて「Save」ボタンを押し（下「[ビルドの設定でのamplify.yml内容](#ビルドの設定でのamplify.yml内容)」参照）、「次へ」ボタンを押す
7. 内容を確認し「保存してデプロイ」ボタンを押す
8. 初回の環境構築、ビルド、デプロイが走るので検証がOKになるまで待つ
9. 環境にアクセスし動作しているか確認する（https://master.xxxxx.amplifyapp.com/ のようなURL）
10. また、「検証」をクリックすると検証タブで、さまざまなデバイスでどう見えるかについても確認可能

### ビルドの設定でのamplify.yml内容例
Reactivesearchモジュールを含めてビルドします。

```yaml:amplify.yml

version: 0.1
frontend:
  phases:
    install:
      commands:
        - npm install @appbaseio/reactivesearch
    preBuild:
      commands:
        - npm ci
    build:
      commands:
        - npm run build
  artifacts:
    baseDirectory: build
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*
```

### 独自URLの設定
1. AWS管理コンソールのAWS Amplifyの画面に移動
2. 左ペインを開き、該当アプリのリンクをクリックする
3. 左ペインの「アプリの設定」にある「ドメイン管理」をクリックする
4. 「カスタムドメインの追加」ボタンを押す
5. 「ドメイン」欄でRoute53に登録されているドメイン名がリストされるので該当のドメインを選び、「ドメインの検索」ボタンを押す
6. ドメインのルートを使いたくない場合は「Exclude root」ボタンを押してルートをグレーアウトし、サブドメイン名に独自URLとして付けたい名前を入れ（ここではcityrank）、「保存」ボタンを押す
7. Route53設定やサーバ証明書設定が自動で行われ、独自URLでアプリが公開される

これだけです。

# Amplifyの制約
Amplifyのアプリ公開環境は、Amplifyが内部的に用意します。マニュアル上はCloudFront + S3環境を使っているように読めますが（[QuickStart](https://aws-amplify.github.io/docs/cli-toolchain/quickstart#continuous-deployment-and-hosting)）、自分のアカウントのCloudFrontやS3ではないため、CloudFrontやS3への追加の設定ができません。
そのため、現時点では、たとえば、CloudFrontにAWS WAFの機能を付けられません。また、CloudFrontが持っているモニタリングツールで監視することもできません。公開環境へのアクセスログは、CloudFront相当のものが取得できますが、管理コンソールから確認およびダウンロードできるものの、AWS CLIではダウンロードできません。
CICD環境としても、ブランチごとの設定などはできますが、CodePipelineで設定できるような細かいパイプラインの設定はできません。基本的にはブランチごとにGitHubのWeb HookなどをトリガーにCodebuildでビルドしてデプロイするのみとなります。
【Python3.7】Mecabの導入方法

Mecabの動作テストのために、Windows・Python3.7の環境で試してみました。
# 導入方法
## Mecabのインストール
公式のexeは32Bit版しか無いので、有志の野良ビルドを利用します。
[ダウンロードはこちら](https://github.com/ikegami-yukino/mecab/releases/tag/v0.996)

ダウンロードしたexeを実行し、インストールを行います。

インストールした場所にあるbinフォルダ内をCMDで開きます。
mecabコマンドを起動して、何か文章を打ち、出力が得られれば、動作しています。
※ UTF-8で出力されているため、現在は文字化けしていますが、正常にインストールされている事が確認できれば問題ありません。

```sh:実行結果
C:\Program Files\MeCab\bin>mecab
東京は今日も暑いです。
東京は今日も暑い        險伜捷,荳闊ｬ,*,*,*,*,*
ﾅ       蜷崎ｩ・蝗ｺ譛牙錐隧・邨・ｹ・*,*,*,*
ｷ       險伜捷,荳闊ｬ,*,*,*,*,*
B       蜷崎ｩ・蝗ｺ譛牙錐隧・邨・ｹ・*,*,*,*
EOS
```

## Pythonのための利用設定
下記2つのモジュールを取得する
`pip install ipykernel`
`pip install mecab-python-windows`
## Pythonで試してみる。
Pythonで実行してみましょう。
```py:MeCab実行
import MeCab

tagger = MeCab.Tagger("-Ochasen")
result = tagger.parse("東京は今日も暑いです。")
print(result)
```

```sh:実行結果
>>> print(result)
東京    トウキョウ      東京    名詞-固有名詞-地域-一般
は      ハ      は      助詞-係助詞
今日    キョウ  今日    名詞-副詞可能
も      モ      も      助詞-係助詞
暑い    アツイ  暑い    形容詞-自立     形容詞・アウオ段        基本形
です    デス    です    助動詞  特殊・デス      基本形
。      。      。      記号-句点
EOS
```
見事、出力されました。

## 出力フォーマットの指定について

-Oyomi (ヨミ付与)
-Ochasen (ChaSen互換)
-Odump (全情報を出力)


# 参考URL
http://taku910.github.io/mecab/
[memo] BigQueryのScheduleとCloud FunctionsでGCSにテーブル情報を送信

# TODO

BigQueryにて設定したスケジュールが実行完了後にGCSにテーブル情報をCSVに変換してファイルを送信するようにする

* Pub/SubをトリガーにしたCloud Functionsの送信処理の実装
* BigQueryでスケジュールの設定

## Pub/SubをトリガーにしたCloud Functionsの送信処理の実装
### Pub/Subの設定
<img width="200" alt="PUBSUB.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102903/ae360df7-2292-9ea2-cc53-bd9ca1a0c594.png">

1. Cloud FunctionsのトリガーとなるTopic IDを入力

例： 「example-1」を設定

### Cloud Functionsの設定
<img width="200" alt="FUNK1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102903/11dcbc7d-84c2-81c5-db8f-ba30df3eb916.png">

トリガーが発火した際に
GCSにBQのテーブルを参照して
CSVを送信するようにするスクリプトを配置

1. トリガーは「Cloud Pub/Sub」で設定する
上記で、「example-1」を選択
2. 言語は好みで、今回はPythonでインラインの実装

`REQUIREMENTS.TXT` では必要なモジュールなどを記載
`MAIN.PY` で実際に動作するものを記載

実装内容は「BQ上で昨日のテーブルの情報をGCSに送るようにする」といった内容

* REQUIREMENTS.TXT


```
# pip でインストールされるもの
google-cloud-bigquery
```
* MAIN.PY

```python
from google.cloud import bigquery
from datetime import date, timedelta
def export_table(event, context):
    client = bigquery.Client()
    yesterday = date.today() - timedelta(days=1)
    project = "project_name"
    dataset_id = "data_set_name"
    table_id = "table_name_yyyymmdd_" + yesterday.strftime('%Y%m%d')
    destination_uri = "gs://{}/{}".format("dir_name", yesterday.strftime('%Y%m%d')+".csv")
    dataset_ref = client.dataset(dataset_id, project=project)
    table_ref = dataset_ref.table(table_id)
    extract_job = client.extract_table(
    table_ref,
    destination_uri,
    location="US",
    )
    extract_job.result()
```

最後に「export_table」を実行関数として入力


## BigQueryでスケジュールの設定

BigQueryの機能の一つとして提供されている「スケジュール」があるので、利用する

<img width="200" alt="BQ1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102903/2585851e-7f48-968f-6e4e-e4f30c326e61.png">

有効なクエリを記載し、そのスケジュールの新規作成から入る

<img width="200" alt="BQ2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102903/dd82f6e4-4969-8436-d761-7899fea1ff91.png">

下の方にあるPub/Subの入力で「example-1」を設定することによって、
テーブルが生成されたタイミングでトリガーが発火するようになる。

以上で、BigQueryにて設定したスケジュールが実行完了後にGCSにテーブル情報をCSVに変換してファイルを送信するようになる


# あとがき
Rundeckのオンプレのサーバをクラウドに移行した際に
サービスアカウントが切り替わっており、GSの実行権限が付与されてなかった。
内容自体は「BQ内で完結するテーブル生成」と「GCSにそのテーブルデータを送信」といった
結構小規模な機能の利用だったので、GCPで完結するようにした。

大した内容では無いので、ココで実装したメモを残します。
エミュレータをつくりたい

# はじめに
x86 CPUエミュレータを作ろうとしています。
エミュレータ作成を通し、
CPUの動き、機械語やアセンブリ言語など、低レイヤーの知識をつけることを目的としています。
今回はまともなプログラムは動かせません。
"Hello, World"もできません。

# 参考書籍
[自作エミュレータで学ぶx86アーキテクチャ](https://book.mynavi.jp/ec/products/detail/id=41347)

# 前提知識
## レジスタ
レジスタは、CPUに組み込まれている作業領域です。
汎用レジスタと特殊レジスタがあります。

(ESP、EBPを汎用レジスタって言う本があったり、
特殊レジスタって言う本があったり結局どっちなの？という気持ちになる。)
### 汎用レジスタ
x86環境下では汎用レジスタは以下の８つがあります。
1. EAX
2. ECX
3. EDX
4. EBX
5. ESP
6. EBP
7. ESI
8. EDI

アセンブリ言語で、なにかデータを指定する箇所では、
汎用レジスタは大体指定することができます。

演算結果を、EAXやEDXに暗黙的に入れられることもあります。
例えば、`div ecx`とすると、
`EAX ÷ ECX`の商がEAXに、余がEDXに入ります。

### 特殊レジスタ
EIPとEFLAGSがあります。
EIPには次に実行するアセンブリ命令のアドレスが入っています。
EFLAGSは条件判定に使うようなフラグが入っています。

## アセンブリ言語
機械語と一対一で対応している言語です。

# 実装
## 処理の方針
1バイトのオペコードを読み込み、その値によって処理を振り分けていきます。

## mov命令
mov命令のオペコードは`0xB8` から `0xBF`までです。
オペコード自身に、レジスタの指定が含まれています。
4バイトの値を、指定したレジスタにコピーします。

## short jump命令
short jump命令のオペコードは`0xEB`です。
1バイトの符号付き整数を取り、eipに加算します。
つまり、-127から+128の範囲内を飛ぶことができます。
S3 + CloudFront で ホスティングしたページのCORS設定方法

# 概要
クロスドメイントラッキング用サイトを作成するためにS3+CloudFrontでペライチのページをホスティングしたが、CORS設定をしていないので呼び出し元からjsでアクセスできない状況を打破する。

# 設定方法
## S3での設定
- ホスティングしている対象バケットを選択
- 【アクセス権限】タブを選択
- 【CORSの設定】を選択
- 【CORS構成エディター】に下記のように設定を追加

```xml

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>http://www.example1.com</AllowedOrigin>

   <AllowedMethod>GET</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>http://www.example2.com</AllowedOrigin>

   <AllowedMethod>PUT</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>

   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
 <CORSRule>
   <AllowedOrigin>*</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
 </CORSRule>
</CORSConfiguration>
```
Methodなどが同じなのであれば下記のようにまとめて記載することも可能


```xml

<CORSConfiguration>
 <CORSRule>
   <AllowedOrigin>http://www.example1.com</AllowedOrigin>
   <AllowedOrigin>http://www.example2.com</AllowedOrigin>
   <AllowedMethod>GET</AllowedMethod>
   <AllowedMethod>POST</AllowedMethod>
   <AllowedMethod>DELETE</AllowedMethod>
   <AllowedHeader>*</AllowedHeader>
 </CORSRule>
</CORSConfiguration>
```


## CloudFrontの設定
- 【Behaviors】【Edit】に移動
- 【WhitelistHeaders】で【Origin】をAddし反映させる(Access-Control-Request-Geadersはいらない)



# 補足
ちなみに

```xml
   <AllowedOrigin>*</AllowedOrigin>
```

といった記述は可能だし

```xml
   <AllowedOrigin>https://*.example.com</AllowedOrigin>
```

といったようなサブドメインにワイルドカード指定もできた。
サブドメインのワイルドカード指定できないという記事がいくつかあったので注意。


# 確認方法
```bash:
$curl -X GET -I -H "Origin: {上記で設定した接続元}" {接続先}
```

```bash:例
$curl -X GET -I -H "Origin: https://www.example.com" https://www.sample.com
```
上記のコマンドを実行し

```bash
access-control-allow-origin: https://www.example.com
access-control-allow-methods: GET, POST
access-control-allow-credentials: true
```
などの表示が確認できればてCORS設定ができている。
NestJSでscope: Scope.Requestにしたサービスがあるとテストがコケる件


## Scope.Requestを使うケース
こういうの
https://qiita.com/rdlabo/items/7c25b711fa8db99512a6

## 起きること

```typescript
@Injectable({
  scope: Scope.Request
})
class AwesomeService {...}
```

こういうサービスを使っているクラスのテストがコケる。


```bash
  ● Site Controller › list site api › should return items

    TypeError: Cannot read property 'loadCurrentUser' of undefined

      35 |   })
      36 |   public async listSites(): Promise<SiteResponseItemDTO[]> {
    > 37 |     const { Username: username } = this.cognito.loadCurrentUser();
         |     
```

DIしたはずのクラスがundefinedになっており、メソッドが見つからないというエラーが出る。

## 実動作について
`yarn start`や`sls offline`などで動かす分には問題がない。
あくまでテストだけ。

## 対応方法：Scopeをdefaultにする

要はScopeをテストの時だけDefaultにすればOKです。

### 対応1: テストコードで上書きする

`createTestingModule`する時にscopeを上書きしてやると、undefinedにならなくなります。

```typescript
      const mod = await Test.createTestingModule({
        providers: [{
          provide: LoginService,
          useClass: LoginService,
          scope: Scope.DEFAULT
        }],
      }).compile();
```

### 対応2: `module.get`を`module.resolve`にする
対応1で動かない場合、テスト対象クラスを取得する処理を`get`から`resolve`に変えると動く場合もあります。

```typescript
      const mod = await Test.createTestingModule({
        controllers: [AdminController],
        providers: [{
          provide: LoginService,
          useClass: LoginService,
          scope: Scope.DEFAULT
        }],
      }).compile();

      // Before
      const controller = mod.get<AdminController>(AdminController)

      // After
      const controller = await mod.resolve<AdminController>(AdminController)
```

### 対応3: 定義側で変える

`@Injectable`する時に環境変数で変えてしまうという手もあります。

```typescript
@Injectable({
  // @See https://github.com/nestjs/nest/issues/2049#issuecomment-559959575
  scope: process.env.NODE_ENV === 'test' ? Scope.DEFAULT : Scope.REQUEST,
})
class AwesomeService {...}
```


## そのほか
Scope.Requestの場合、`module.get`ではなく`await module.resolve`を使う必要がある。

```typescript
      const mod = await Test.createTestingModule({
        providers: [LoginService],
      }).compile();

      // Error
      // LoginService is marked as a scoped provider.
      // Request and transient-scoped providers can't be used in combination with "get()" method.
      // Please, use "resolve()" instead.
      const service = mod.get<LoginService>(LoginService);

      // うごく
      service = await mod.resolve<LoginService>(LoginService)
```


## 参考

結構遭遇している人が多いみたい。
https://github.com/nestjs/nest/issues/2049
Windows Serverの設計観点

今までずっとSolaris、Linuxの案件ばかりだったが、初めてWindows Server 2016の環境設計に携わったので、環境設計書の目次項目より抜粋し、設計観点をまとめておく。
ドキュメント体系として、前工程の基本設計書が存在し、より詳細なパラメータシートがある。

これが全ての設計項目ではなく、こう設計しておけば良いというものではないのであくまで参考として頂きたい。ベンダーによって設計方針もまちまちだと思われる。

#環境設計書　設計観点
## １　はじめに

・前提条件
・記載範囲
・パッチ適用凍結時期
　などを記載する。

今回は、VMware vSphereの仮想マシンとして導入したので、ハード周りに関する記載はない。
 
## ２　 OS基本設計
##### ２．１　コンピュータ名とドメイン・ワークグループ設計
・コンピュータ名の定義
・ドメイン名、NETBIOS名、OUの配置先

ADサーバ自体は作業対象外で別ベンダー実施であったため、ADクライアント側としての情報をここに記載。

##### ２．２　DNS設定
・DNSサーバの指定

##### ２．３　Windows Updateの設定
・WSUSによる配布
・自動アップデート無効化

##### ２．４　Windows Defenderの設定
・ウイルス対策ソフトを導入する場合は自動無効化

##### ２．５　診断とフィードバック
・Microsoft社へのフィードバックを無効化

##### ２．６　リモート管理
・リモートデスクトップ機能の有効化

##### ２．７　電源オプション
・高パフォーマンスモードにする
・スリープ状態までのタイムアウト値

##### ２．８　役割と機能 
・追加するOS標準機能一覧（SNMP等）

##### ２．９　Windowsファイアウォール設定
・無効化 

##### ２．１０　仮想メモリの設定
・ページファイルサイズ

##### ２．１１　起動と回復(システムエラー)
・メモリダンプ設定（完全メモリダンプ）

##### ２．１２　NTP設定
・時刻同期先
・時刻同期方式（ADの場合はNT5DS)

##### ２．１３　セキュリティポリシー設定
・アカウントポリシー/パスワードポリシー
・監査ポリシー

##### ２．１４　個別設定
・自動ログイン設定
・エフェメラルポートの変更設定

## ３　ユーザ設計
##### 3．1 ユーザ
・ローカルユーザ
　ユーザごとにそれぞれグループ、パスワード有効期限を一覧で記載。

・ドメインユーザ
　ユーザごとにそれぞれグループ、パスワード有効期限、配置先のOUを一覧で記載。

##### ３．２　ユーザグループ

・ローカルユーザグループ
・ドメインユーザグループ
　それぞれローカルグループ、ADセキュリティグループ、配置先のOUを一覧で記載。　

##### ３．３　ドメインユーザポリシー
・設定するセキュリティポリシーを記載

## ４　サービス一覧
・ログオンアカウント
・停止対象のサービス
・ミドルウェア導入によって起動するサービス

## ５　タスクスケジューラ設計
・システム起動時の自動実行タスク
・手動実行するタスク

## ６ レジストリ設計
・設定変更を行うレジストリキー
　※NTPの動作設定、IPv6の無効化等
 
## ７ ログ設計
７．１　対象ログ 
７．２　ログの設定 
 
## ８ ネットワーク設計
チーミング
・LBFOのモード、負荷分散モード

ネットワークアダプタ設定 
・ネットワークアダプタ名
・ネットワークのカテゴリ
・対象のネットワークセグメント

IPv6設定 
・黙って無効化

ルーティング設定 
・スタティックルート設定
　今回は設定しなかった。

## ９ ディスク設計
パーティション構成  
・容量
・ドライブ
・ファイルシステム
・フォーマット（GPT、MBR）
・種別（ベーシック）
・アロケーションユニットサイズ
・ドライブごとの主な用途

Rawディスクがある場合は詳細記載
今回はOracle ASMを利用したため容量と用途を記載。

ディスクの最適化 
・デフラグの設定（OFF）
 
## １０ 名前解決
・hostsファイルに記載するエントリ
・名前解決の優先順位

## １１　追加ソフトウェア設計
・.NET Framework
・Microsoft Visual C++ 2017 再頒布可能パッケージ (x86)

インストールパスやバージョンを記載。
JFrog Artifactoryは何者だ

[JFrog Artifactory](https://jfrog.co.jp/artifactory/)は、Artifact Repository Managerと呼ばれるツールの一種で、主要なパッケージフォーマットのほぼ全てをサポートするJFrog社のDevOpsツールです。

## Artifact Repository Manager
Artifactはよく人工物などと訳されますが、このコンテキストにおいては**ビルド済みのプログラム、成果物**といった意味になります。

また、Repositoryもよく耳にしますが厳密にどんな意味かを考えると、**特定のリソースを蓄えるデータベース/ストア**です。
特定のリソースといっても、主にソースコードや技術情報などが該当します。今回のようにArtifact Repositoryというと、**成果物が蓄えられているデータベース**という認識になります。

要するにArtifact Repository Managerは**成果物を蓄えるデータベースを管理する仕組み**という認識で問題ないでしょう。
Artifact Repository Managerという呼び名の他に、Binary Repository Managerなどと呼ばれる事もあります。

ソースコードのバージョン管理を行うなら、GitHubやBitBucketなどがありますが、これらは成果物のバージョン管理を行うためのサービスとなります。

これだけだとナンノコッチャとなりますが、身近なツールで例えるなら、

- Node.jsで開発した成果物の管理はnpmを用い、
- Pythonならpipなどがありますし、
- JavaならMaven、

その他OSのパッケージ管理でも、

- Debian系ならapt、
- centosならyum、
- お馴染みbrewなど

たくさんのパッケージマネージャがあります。
[List of software package management systems](https://en.wikipedia.org/wiki/List_of_software_package_management_systems)

これらパッケージマネージャは、それぞれ対応するレポジトリが存在し、そこからパッケージを取得します。
PythonのpipならPyPIや、Debianのdebならいくつかのdebレポジトリがあり、
これらレポジトリがArtifact Repositoryになります。

## JFrog Artifactory

では、JFrog Artifactoryとは何かという話に戻りましょう。

JFrog Artifactory(以下Artifactory)も、一言で表すと上述したような成果物のバージョン管理を行うレポジトリを簡単に作る事ができるサービスです。

公式からも謳われている特長として、ほぼ全ての主要なパッケージフォーマットをサポートしているので、Artifactory上でPython用レポジトリやCentOS向けレポジトリ、Dockerコンテナレポジトリなどを建てる事が出来ます。
[JFrog Artifactory Feature](https://jfrog.com/artifactory/features/)

Artifactoryに類似するサービスとして、

名称|開発元|リンク
---|---|---
Archiva|Apache Software Foundation|https://archiva.apache.org/
Nexus|Sonatype|https://www.sonatype.com/

が有名ですが、その中でもArtifactoryを選ぶ理由としては

- まず上にある通り対応するパッケージフォーマットの多さ
- 主要なビルドツール、CI/CDサーバーと簡単に統合し、自動化できる
- マルチクラウド・SaaS・HighAvailabilityと機能詰め詰めでビジネスの継続性を高める

などがあるでしょうが、詳しくは[公式サイト](https://jfrog.com/artifactory/features/)を参照ください。

### 料金プラン

基本的な料金プランと、各プランの比較は以下のページで確認出来ます。

- [オンプレ版](https://jfrog.com/pricing/#onprem)
- [クラウド版](https://jfrog.com/pricing/#cloud)

さらにこちらを確認すると、Artifactory-ossと書かれた無料版もあるようです。
[Open Source Artifactory](https://jfrog.com/open-source/#artifactory)

docker版は以下のコマンドで無料版のイメージを取得出来ます。

```
docker pull docker.bintray.io/jfrog/artifactory-oss:latest
```

無料版では、Maven・Gradle・Ivyのみサポートと書かれていますが、GenericとSBTも利用できるようです。
![スクリーンショット 2020-03-25 17.11.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/249725/8b9931e2-dd13-533e-07ea-05dc09bcb517.png)

---

色々と調べてみた感じ、Java開発なら無料版でも事足りると思いますが、それ以外なら有料版以外の選択肢は無いように感じます。

ただ、有料プランであれば一番安いプランでも、全てのパッケージフォーマットを利用可能になり、料金の違いは主に冗長構成に関する差異が多いように感じたので、どれだけ冗長性を確保したいかでプランを選べば良いかなぁと思います。
TypeScriptで数値の空判定を行う

# 経緯
TypeScriptで数値型のinput入力値の空判定をする必要がありました。
簡易的に再現すると下記のような感じで
valはnumberなので`''`との比較を行うことでエラーが発生しました。

```typescript

const val: number = 0;
if (val === '') { // エラーになる
  // 処理
}
```

# 解決方法
数値型の値を文字列化して別の変数に代入することで
空判定が可能になりました。

```typescript

const val: number = 0;
const valStr = String(val); // 空判定のため文字列化
if (valStr === '') { // エラーにならない
  // 処理
}
```

# 参考
JavaScript のデータ型とデータ構造
https://developer.mozilla.org/ja/docs/Web/JavaScript/Data_structures
Ruby on Railsの開発環境（仮想環境）の構築方法

# はじめに

現在のバージョン：
macOS Catalina 10.15.3

Ruby on Railsで環境構築を実施してみました。自身のPC（ローカル）に直接環境を構築すると現在のPCの設定に影響を与えてしまう可能性がある為、仮想環境を作りました。

# 仮想環境について
仮想環境とは自身のPCとは別のPCを仮想的に作ることです。（１台のPCで複数のPCを扱えるイメージ）
開発環境をローカルでやらない為自身のPCに影響を与えないメリットがある。
※仮想環境は不要になればすぐに削除が可能です。

# 仮想環境を構築
###VirtualBoxをインストール
VirtualBox（バーチャルボックス）をインストールして、仮想環境を構築。
[macOS：VirtualBox(6.0.14)ダウンロード](https://download.virtualbox.org/virtualbox/6.1.4/VirtualBox-6.1.4-136177-OSX.dmg)
ダウンロード後開くと下記の画面になります。
<img width="724" alt="スクリーンショット 2020-03-25 15.53.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607914/fca9a366-0be4-bc72-7340-75dbaf5b198b.png">
「１」をダブルクリックして、インストール実施完了後「Applications」フォルダに追加されてます。<img width="767" alt="スクリーンショット 2020-03-25 15.59.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607914/1b9f15d8-5726-b71b-fc39-53ebcc4a21f8.png">

**インストール後以下のコマンドでバージョンが表示されるか確認。**
```$ vagrant box list
centos/7 (virtualbox, 1905.1)```

### Vagrantをインストール
Vagrant（ベイグラント）をインストールして、仮想環境を管理・構築をします。Windows、Mac OS X、Linuxで動作します。

[macOS：Vagrant(64bit)ダウンロード](https://releases.hashicorp.com/vagrant/2.2.7/vagrant_2.2.7_x86_64.dmg)

**インストール後以下のコマンドでバージョンが表示されるか確認。**
```$ vagrant --version
Vagrant ２.２.４```

※macOSのバージョンによっては、以下の設定が必要になります。
アップルメニューから**「システム環境設定」→「セキュリティとプライバシー」アイコンクリック→「一般」タブクリック→「開発元を確認できないため、開けませんでした」の「このまま開く」をクリック**する。

### vagrant-vbguestプラグインをインストール
「vagrant-vbguest」は自分の環境と仮想環境のバージョンを自動で合わせてくれるVagrantのプラグインです。
Vagrant起動の準備をする際に、「vagrant-vbguest」プラグインのインストールがあると面倒な作業を肩代わりしてくれます。

**・インストール方法**
ターミナルで以下コードの入力をする。
```$ vagrant plugin install vagrant-vbguest```

参考にコマンド一覧も載せておきます。
<img width="604" alt="スクリーンショット 2020-03-25 16.33.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607914/3e6ac12c-5cdf-3679-322e-5fd80e77be63.png">


### Vagrantfileの作成
Vagrantfileの作成をしますが、その前に作業ディレクトリーの作成をします。

ターミナルでデスクトップに移動　[エラーが出た場合](https://qiita.com/tiger26/items/50c0a6906ddd26b7bfeb)
```$ cd Desktop```
フォルダをデスクトップに作成する
```$ mkdir フォルダ名 ```
任意のフォルダに移動する
```$ cd フォルダ名 ```
フォルダ内に「vagrant」という名のフォルダを作成する
```$ mkdir vagrant ```
vagrantフォルダに移動する
```$ cd vagrant ```

ここからVagrantfileを作成していきます。
Vagrantfileを作成
```$ vagrant init centos/7```
コマンド実行後、Vagrantfileを作成されております。

#Vagrant起動
Vagrantの起動コマンド
```$ vagrant up```
初回の起動は、３０分から３時間はかかります。

以下のように表示がされると完了です。
<img width="598" alt="スクリーンショット 2020-03-25 17.31.31.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/607914/b7ec212b-3635-f315-1759-7a75442a9dde.png">

完了後、以下のコマンドでシャットダウンして導入が完了です。
```$ vagrant halt```
※再度起動する際はVagrantの起動コマンド
```$ vagrant up```を実行してください。