OmniAICreator/Qiita-1.07M huggingface dataset:
users_controller.rb

class UsersController < ApplicationController
  before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
  before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
  before_action :ensure_correct_user, {only: [:edit, :update]}
  
  def index
    @users = User.all
  end
  
  def show
    @user = User.find_by(id: params[:id])
  end
  
  def new
    @user = User.new
  end
  
  def create
    @user = User.new(
      name: params[:name],
      email: params[:email],
      image_name: "default_user.jpg",
      password: params[:password]
    )
    if @user.save
      session[:user_id] = @user.id
      flash[:notice] = "ユーザー登録が完了しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/new")
    end
  end
  
  def edit
    @user = User.find_by(id: params[:id])
  end
  
  def update
    @user = User.find_by(id: params[:id])
    @user.name = params[:name]
    @user.email = params[:email]
    
    if params[:image]
      @user.image_name = "#{@user.id}.jpg"
      image = params[:image]
      File.binwrite("public/user_images/#{@user.image_name}", image.read)
    end
    
    if @user.save
      flash[:notice] = "ユーザー情報を編集しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/edit")
    end
  end
  
  def login_form
  end
  
  def login
    # メールアドレスのみを用いて、ユーザーを取得するように書き換えてください
    @user = User.find_by(email: params[:email])
    # if文の条件を&&とauthenticateメソッドを用いて書き換えてください
    if @user && @user.authenticate(params[:password])
      session[:user_id] = @user.id
      flash[:notice] = "ログインしました"
      redirect_to("/posts/index")
    else
      @error_message = "メールアドレスまたはパスワードが間違っています"
      @email = params[:email]
      @password = params[:password]
      render("users/login_form")
    end
  end
  
  def logout
    session[:user_id] = nil
    flash[:notice] = "ログアウトしました"
    redirect_to("/login")
  end
  
  def likes
    @user = User.find_by(id: params[:id])
    @likes = Like.where(user_id: @user.id)
  end
  
  def ensure_correct_user
    if @current_user.id != params[:id].to_i
      flash[:notice] = "権限がありません"
      redirect_to("/posts/index")
    end
  end
  
end
curlでCookieを保存、送信する

# 概要

`curl` を使って `cookie` を保存したり、送ったりします。
例は `localhost` への接続です。
環境に合わせて `http://localhost` を書き換えてください。

# 保存
`localhost` から受け付けたCookieを `cookie.txt` として保存

```sh
curl -c cookie.txt http://localhost
```

# 送信 (ファイルから)
`localhost` に保存した `cookie.txt` を送信

```sh
curl -b cookie.txt http://localhost
```

# 送信 (任意の Key、Value)
任意の `Key` `Value` を指定して送信

```sh
curl -b "KEY=VALUE" http://localhost
```

# 保存しつつ送信もする
```sh
curl -c cookie.txt -b cookie.txt http://localhost
```

# ついでにヘッダも表示
```sh
curl -c cookie.txt -b cookie.txt -D http://localhost
```

#
BigQueryのUDFをTypeScriptで書く

# BigQueryのUDFをTypeScriptで書く

BigQueryのUDFをTypeScriptで書く方法の備忘録。
[サンプル](https://github.com/hotoku/bigquery-udf-typescript)をGitHubに置いたので、中で何をやっているかを簡単にメモしておく。
普段からJavaScriptを書く人ではないので、間違ったことも書いているかもしれない。

## ざっくり
1. WebPackによって、tsをjsにコンパイルして1ファイルにまとめる
1. そのファイルの内容をUDFの定義文字列の中に挿入する



## 各ファイルの意味（主要部だけ）
### ソースファイル
####  sql/greet.jinja.sql
```sql:sql/greet.jinja.sql
#standardSQL

create temp function greet(name string)
returns string
language js as
"""
{% include "greet.js" %}
return greet.greet(name);
""";


select greet("World");
```
UDFの定義を書いたファイル。が、本質的な部分はテンプレート化され、外部の`greet.js`というファイルから読み込むようになっている。
WebPackによって、このファイルがTypeScriptのソースから作成されるようにする。

#### src/main.ts
```ts:src/main.ts
import { Hello } from "./Hello";



export function greet(name: string): string{
    const h = new Hello(name);
    return h.greet();
}
```
`greet`という関数を`export`している。このファイルが上のSQLで参照されているファイル（`greet.js`）にコンパイルされるように、WebPackその他の設定ファイルを作る。

単体テストのコードについては省略。


### 設定ファイル
#### package.json
開発に必要なライブラリと、ビルド・テストコマンドなどを書いておくところ。`npm run XXX`とすると、このjsonの`"scripts"`から対応するコマンドを探して実行する。

#### package-lock.json
`npm install`した際に実際にダウンロードされたパッケージとバージョンの記録。開発環境を完璧に再現するために使われる。

#### tsconfig.json
tsからjsへのコンパイル時に参照される設定、だと思うが、その意味はよく分かってない。

#### webpack-config.js
複数ファイルをまとめて1つのファイルにするための設定集。大事なところは

- `mode`: `production`にしておく。`develop`としてもパッケージングはできるが、出来上がったコードにコメントなどが含まれてしまい、SQLに埋め込んだときに問題となる
- `entry`: 実行対象となる関数のソースファイルへのパス
- `path`: 出来上がるファイルのファイルの置き場所
- `filenaem`: 出来上がるファイルのファイル名
- `library`: ライブラリオブジェクトの名前
- `libraryTargt`: `var`を指定しておく。これによって、`var ... = `で始まるjsファイルが生成される（`...`には`library`の値が入る）。

#### Makefile
普段、JavaScriptを触らないので、コマンドの備忘を兼ねてMakefileが置いてある。

```makefile:Makefile
.PHONY: load prepare build test clean

load: dist/greet.sql
	cat $< | bq query

dist/%.sql: sql/%.jinja.sql build
	cp $< dist
	jinja2 $(subst sql/,dist/,$<) > $@

build:
	npm run build

test:
	npm run test

prepare:
	npm i

clean:
	rm -rf dist

```


## 動作確認
```bash
$ git clone https://github.com/hotoku/bigquery-udf-typescript.git
$ cd bigquery-udf-typescript
$ make prepare # npm installが走る
$ make test # 単体テストを実行する
$ make load # コンパイル・UDF定義への埋め込みを実行し、BigQueryにクエリを投げる
```

注意：生成されるJSコードをSQLに埋め込むためにjinja2を使っている（`pip install jinja-cli`でインストールできる）。


## 単体テストについて
chai/mochaというフレームワークを利用している。これについては、ここでは書かない。
C++によるプログラミング技法_非メンバ非フレンド形式の関数を使い結合度を下げる

# 1. はじめに
　c++学習の備忘録として、今回はC++を用いたソフトウェア設計の際に役に立ちそうな方法を紹介したいと思います。

#2. 優れたソフトウェア設計をするための指標
　優れたソフトウェアの設計をするための指標のとして、**結合度(カップリング)**と**凝集度(コヒージョン)**があります。

***・結合度***
　ソフトウェアコンポーネント間の相互連結生の強度。システム内で、あるコンポーネントが別のコンポーネントに依存する度合い

***・凝集度***
　一つのソフトウェアコンポーネント内の様々な機能間の密着性/関係性の強度

上記の二つを用いて、優れたソフトウェア設計は***結合度が低く(ルーズカップリング、疎結合)***かつ***凝集度が高い(ハイコヒージョン)***ものだと良く言われるものです(情報処理の午前問題の出題されていた)。

#3 非メンバ非フレンド形式の関数を使い結合度を下げる
 疎結合の指標である結合度を下げる方法を以下に示します。

```Sample.cpp
class SampleObject
{
public:
    SampleObject() = default;
    ~SampleObject() = default;
    int GetValue() const;
　　void DoSomething();

private:
    int m_Value;
};

void PrintValue(const SampleObject& obj);

```

関数PrintValueは、Sampleオブジェクトの***パブリックメソッド(この例ではconstメンバ関数GetValue)にしかアクセスできません。***これにより結合度が削減できます。
***仮に関数PrintValueがメンバ関数だと***、***SampleObjectのプライベートメンバ(例だとm_value)またはconstメンバ関数ではないほかのメンバ関数(例だと関数DoSomething)にアクセスできてしまいます。***
実際にこのテクニックはSTLでも頻繁に使われており、例として、***std::for_each()***や***std::unique()***などがあります。
また、SampleObjectと関数PrintValueの概念的な結び付きを強く表現する方法として、以下のように名前空間を用いた方法があります。

```UseNameSpace.cpp
class SampleObject
{
public:
    SampleObject() = default;
    ~SampleObject() = default;
    int GetValue() const;
　　void DoSomething();


private:
    int m_Value;
};
namespace SampleObjectHelper
{
    void PrintValue(const SampleObject& obj);
}
```

上記は名前空間SmapleObjectHelperを用いてSampleオブジェクトと同系統である事を示しています。

#最後に
　今回は結合度を下げる手法として、非メンバ非フレンド形式の関数を使いました。簡易的なAPIを作成する時に役立つのではないかと思います。
JavaScriptを用いて外部サイトからのランディングの判定をする

##はじめに
メディアの開発において外部サイトからの流入者のみに何かポップアップやモーダールの表示したい時などはありませんか。
今回はその判定についてまとめていきたいと思います。

##外部サイトからのランディングの判定をしよう
JavaScriptを用いて外部サイトからのランディングの判定をするには分割して考える必要があります。
主に以下3つになります。

**①1つ前に開いていたページのドメイン取得**
**②現在開いているページのドメインの取得**
**③①1つ前のページのドメインと②現在のページのドメインが一致するか判定**

※ちなみにドメインとは例えば`https://www.google.com/toppagedayo`こんなURLがあるとすると、`www.google.com`の部分のことです。

それでは1つづつ確認していきましょう。

###①1つ前に開いていたページのドメイン取得
これはとても簡単です。
`document.referrer`で取得できます。
デバックとしてChromeデベロッパー・ツールのconsoleに`document.referrer`と入力して実行すると1つ前に開いていたページのドメイン取得結果が確認できます。
<img width="548" alt="スクリーンショット 2020-06-13 9.44.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384180/d876e5d4-2fc0-5ac4-4782-24ea94566b35.png">
1つ前にgoogleのページを開いていたのでこんな感じに確認できます。

###②現在開いているページのドメインの取得
これもとても簡単です。
`location.hostname`で取得できます。
こちらも同じくChromeデベロッパー・ツーでデバックできます。
<img width="546" alt="スクリーンショット 2020-06-13 9.54.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384180/fc22a71b-c421-4538-80fe-58eef52629e4.png">
今Qiitaのトップページを開いているのですが、しっかり表示できていますね。

###③①1つ前のページのドメインと②現在のそれが一致するか判定
文字列の中に、ある文字（もしくは配列）が含まれるか確認するには`indexOf`関数を用いて確認します。
文字列が見つかればそのインデックスを、含まれなければ`-1`を返します。
つまり判定結果でインデックスが返ってくるということは**1つ前のページのドメインと現在のページのドメインが一致する場合**で、`-1`が返ってくるということは**1つ前のページのドメインと現在のページのドメインが一致しない場合**ということがわかります。

そして①から③までを考慮して実装すると下記のようになります。

```javascript:
if (document.referrer.indexOf(location.hostname) !== -1) {
    //1つ前のページのドメインと現在のページのドメインが一致する場合
}else{
    //1つ前のページのドメインと現在のページのドメインが一致しない場合
};
```

##おわりに
いかがでしたでしょうか。
業務でこの実装する際に既存のコードが無かったり検索してもきれいにまとまった無かったりしたので、まとめてみました。
PYNQ-Z1 > SystemVerilog | UART > ボタン押下時にシリアルで0x41 ("A")を送信する (Tutorialの実行) | Jupyterの応答がなくなる

```txt:動作環境
Windows 10 Pro (v1909) 
PYNQ-Z1 (Digilent) (以下、PYNQと表記)
Vivado v2019.1 (64-bit)
Analog Discovery 2 (以下、AD2と記載)
```

### 概要

- System Verilogにてシリアル送信をする実装を試した
- ボタン押下時に0x41("A")が送信される

### Tutorial

- [ACRi シリアル通信で Hello, FPGA (3)](https://www.acri.c.titech.ac.jp/wordpress/archives/733)

情報感謝です。

上記とその続きをPYNQで試した。

- serial_send.sv
- serial_fpga.sv
- serial_test.sv (Run Simulationでの確認をした)

### ピン割当

PYNQのピンは以下を割り当てした。

- CLK: H16 (LVCMOS33)
- RST: D19 (LVCMOS33) => Button 0
- TXD: Y18 (LVCMOS33) => PmodAの0ピン

### Block Design

- AXI-GPIOを追加
- 8ビット, All outputに設定
- 他はVivadoのAuto XXXを使用

![コメント 2020-06-13 100037.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/0a1369bf-069a-7f59-2cfb-7687c373e633.png)

### AD2との接続

- AD2: GND <=> PmodAのGND
- AD2: D0 <=> PmodAの0ピン

### 実行

2020_06_13_0942_UART_send.ipynb

```py
from pynq import Overlay
from pynq import PL
OL = Overlay("/home/xilinx/pynq/overlays/base/UART_send_2020_06_13.bit")
OL.download()
```

<font color=red>上記を実行するとJupyterの応答がない。この点は不明</font>

### AD2での確認

接続したAD2でUARTを読み取った。
Button0押下時に0x41 ("A")が読み取れている。

![コメント 2020-06-13 095210.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32870/ba6d0925-dc02-3d77-ed4f-16be45dda25b.png)
user.rb

class User < ApplicationRecord
  # has_secure_passwordメソッドを追加してください
  has_secure_password
  
  validates :name, {presence: true}
  validates :email, {presence: true, uniqueness: true}
  # 以下のバリデーションを削除してください
  
  
  def posts
    return Post.where(user_id: self.id)
  end
  
end
has_secure_passwordで暗号化
【Linux編】 電源投入からPC起動までの流れ

#大まかな流れ

1. BIOSがマスターブートレコードを読みに行く
2. その中にあるブートローダを起動する。（ブートローダ：OSを起動するためのプログラム）
3. ブートローダがどのブートセクタを読み込むか（どのOSを起動するか）パーティションテーブルを参照する
4. 起動するOSがパーティションを見て分かったのでブートセレクタを読み込む
5. ブートセクタが読み込まれるとOS起動のためのプログラムが起動する
6. OS起動プログラムがOSを起動する

#Linuxシステムは以下の順序で実行される

1. BIOSの起動 メモリのチェック、ハードウェア設定の読み込み、起動デバイスのチェック、起動デバイスのMBRに格納されたブートローダを実行します。 
2. ブートローダ カーネルをメモリにロードし、OSに制御を引き渡します。 Linuxで使用されるブートローダはGRUB2やGRUBがよく使われていますが、古いディレクトリビューションではLILOが利用されています。 またDVDやUSBから起動するライブメディアなどは、SYSLINUXが利用されています。 
3. カーネルとinitramfsのメモリロード まずカーネルの読み込みを行います。 その後、カーネルはinitramfsのマウントを行い、initramfsに保存されたカーネルモジュールの読み込みを行います。 カーネルモジュールの読み込みを行うことで、必要なドライバを全て読み込み、ルートファイルシステムのマウントが出来るようになります。 
4. ルートファイルシステムのマウント ルートファイルシステムの検索、エラーチェック、マウントを行います。 
5. initプロセスの起動 プロセスID1のプロセスinitが起動され、システムの初期化を行います。 その後、ランレベルに応じたサービスを起動します。
IFTTTで、CURLする (脱Smart Life)

#Smart LifeのIFTTTからの脱退

先の、5末(2020/5/26?)でもって、Smart LifeがIFTTTを脱退しました。当方の環境でも6/頭くらいから、CURLスクリプトが動かない、という事案が発生して、あたふたしました。

せっせとSmart Lifeガジェットを集めようかとしていた矢先、この仕打ちは、痛すぎます。
捨てるわけにも、新たにガジェットを買いますこともままならない我が小遣い。別の管理ツールの導入を図ります。

ちなみに、IFTTTのステータスは、あっさりしております。障害出てますって、雰囲気。この記事に騙された人は多いはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/2b1b66de-a56e-e0ec-a00e-963028613cad.png)

なんだよ、Pausedって。Technical difficultiesではなく、Budget difficultyだし。[この記事](https://qiita.com/mbamba/items/c9ec0ffa9de35823e1d0)から1年足らずで、サービス終了。

ちなみに、本稿を書いている時点では、Merossは問題なし。CURLの設定を変えずに使えてます。


#BrilliantSmartの導入
結果論で記事を書いているので、画像がなくてすみません。

簡単に言うと、いくつか、Smart Lifeクローンというか、互換のツールがあるようです。当方が探し当てたのは
- SmartThings (powered by Samsung)
- BrilliantSmart

Samsungのアカウントを持っている人は、こちらでもよいかと思いますが、当方なかったので、わざわざ作るのも、という軽い気持ちで、BrilliantSmartを導入

こちらに、登録すると、Smart Lifeのアプリから、デバイスが削除されます。
英語記事にいろいろ書かれている通り、アプリの操作は、まんまSmart Lifeなので、移行したから、UIがガラッと変わることはないです。

#IFTTTとの連携

WebhooksからのCULR操作が希望なので、頑張って、登録しなおします。やり方は、[以前](https://qiita.com/mbamba/items/c9ec0ffa9de35823e1d0)と同じ。

まず、Createにて作成モードに移ります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/3589739a-6cfd-9c7b-7e29-9861a46d7798.png)

次の画面に移るので、+Thisをクリックして、サービスの選択に移ります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/5ca5cc32-08fa-ddfb-a499-26d709d95ff0.png)

サーチボックスに、webと入れると、Webhooksが表示されるので、選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/d9587a6f-456f-c9a3-0860-4268787f6e5c.png)

webhooksでは、1つしか選べないので、それを選択して、名前を付けて上がると、+Thisの設定が完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/daee50b4-4a2b-7e0b-13cc-87aa02f3f9be.png)

続いて、+Thatをクリックして、サービスを選択します。サーチボックスに、Brillといれると、Brilliant Smartが表示されます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/fc920119-70f9-4f04-798f-e59544db3d40.png)

BrilliantSmartがIFTTTで導入しているサービスが、ずらずら表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/7643a1fe-c80c-4081-ba70-6453f7dd5c9c.png)

Turn onとTurn offがあればいいので、OKです。Turn Onを選択すると、対象とするデバイスの選択に移るので、制御したいデバイスを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/79685fdf-d20d-cd8e-8d89-fe62e1d17c86.png)


最後に、確認画面が出るので、ざっと確認してFinishで終了。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/213097/d6ee52ee-e3b8-b730-27f0-11daf55ab7f5.png)

notificationを受信するか、がデフォルトではONになっているので、いらない場合は、変更します。上の例は、Offにしています。

#CURLで制御
あとは、[元記事:IFTTTをcurlで操作](https://qiita.com/mbamba/items/c9ec0ffa9de35823e1d0)に書いてある通り、
- My Service
- webhooks
- Document
と追っていき、CurlのURLを確認します。

```
$ curl -X POST https://maker.ifttt.com/trigger/FanOn/with/key/XXXXXXXXXXXXXXXXXXXXX
Congratulations! You've fired the FanOn event
```

正しく制御されていれば、スマホアプリ側で、ステータスの変更が確認できます。

これで、無事に、Smart LifeがIFTTTを脱退しても、Curl制御が続けられます。めでたしめでたし。

[おしまい]
HyperSwitch 私のおすすめ設定

macのデフォルトで `Command`+`Tab` キーを押すことでアプリケーションを切り替えることができるが、
HyperSwitchの切り替えをそのショートカットキーで行えるようにするのがいいと思う。

HyperSwitchは、デフォルトだと `Option`+`Tab` キーで切り替えることになるが、
これを`Command`+`Tab`に変更します。

『General』タブの『Activate the window switcher for』の『all windows:』の部分を `Option`を`Command`に変更する。

![スクリーンショット 2020-06-13 9.40.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/71931/79cf3483-c886-58cd-f170-92d3469c9b80.png)


macのデフォルトのアプリケーション切り替えは使えなくなるが、HyperSwitchでの切り替えの方が私は便利なのでこの設定にしている。
CodePen : 中国語の四声変換ツールつくってみた（a1a2a3a4⇔āáǎà）

いい感じの入力ツールを見つけられなかったので、変換ツールを作ってみた。
まっとうなテキストエディタ上で編集しておいて、コピペって使う想定。

単純に文字列置換しているだけなので、母音の組み合わせによる四声のルールとかは考慮していません。

<p class="codepen" data-height="500" data-theme-id="light" data-default-tab="result" data-user="kob58im" data-slug-hash="JjGXgqM" style="height: 500px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="Chinese four tone - text converter">
  <span>See the Pen <a href="https://codepen.io/kob58im/pen/JjGXgqM">
  Chinese four tone - text converter</a> by kob58im (<a href="https://codepen.io/kob58im">@kob58im</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

このツールと直接関係ないけど、
テキストエディタで保存するときはエンコードに注意。(UTF-8(BOMなし)あたりが無難)。


# 参考
- [特定の文字列を全て置換する[Javascript]](https://qiita.com/DecoratedKnight/items/103ab57431b6c448e535)
- [正規表現を使ったマッチングに変数を使用する](https://qiita.com/ykob/items/6e4d0b07bed57881a2bd)


# 他のやり方

中文を書いてからGoogle翻訳に掛ければルビが表示されるので、そっちのほうが楽かも。時々間違った四声が出るので注意・・。
配列の要素先頭を削除する

```
function createSheetRenameIndex(){
  const TemplateSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Template');
  const IndexSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Index');
  const ThisSread = SpreadsheetApp.getActiveSpreadsheet();
  const index_range = IndexSheet.getRange(1, 1).getDataRegion().getValues();
  let sheet_index = separateArray(index_range);
  let count_number = 0;
  for(let sheet_name of sheet_index){
    let new_sheet = TemplateSheet.copyTo(ThisSread);
    new_sheet.setName(sheet_name);
    count_number ++;
  }
}
// 二次元配列の縦一列を取得 => return element[column_index]とすることで抽出が可能
function separateArray(array) {
　let index_list = array.map(function (element) {return element[0]});
  // 先頭の要素を削除する
  index_list.shift();
  return index_list;
}
```
GCP Loggingで該当のurlのみのログを取得する

GCPのLoggingにて、文字列の部分一致で検索をする方法がわからなかったので調べました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/88791/04cad442-6a00-58ae-e31d-bae7320a0ddc.png)


# 結論

```
httpRequest.requestUrl:"https://hogehoge.com/"
```

`:`でつなぐことで部分一致になる。
`=`にすると完全一致。
https://cloud.google.com/logging/docs/view/advanced-queries?hl=ja#searching_examples
CSS：Bulma：Centering menu items in Navbar（メニューを中央に配置）

# Code

Put "navbar-end" class divs continuously.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/7bcb7872-7fbb-15c8-aca9-aca584e10be9.png)


# Output

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/15972/386ba7c8-f844-37d8-1c56-a581ad787867.png)


# Remark

This code was modified with reference to Bulma's Navbar sample code.

[▶ Navbar | Bulma](https://bulma.io/documentation/components/navbar/)


Bulmaでメニューを中央に配置するコードがなかなか探してもなかったので、掲載します。
【エラー対処】Jupyter/Jupyter LabでDockerにおいてマウントがされないとき


# はじめに

[Jupyter LabをDockerで環境構築する](https://qiita.com/Esfahan/items/a3cb8e91e13b96eacc73)
の記事で、JupyterLabをDockerで環境構築しようとしていたのですが

```bash
sudo docker run  \
    --rm \
    -e TZ=Asia/Tokyo \
    -p 8888:8888 \
    --name jupyterlab \
    -v $(pwd)/code:/code \
    jupyterlab:latest \
    start.sh jupyter lab --NotebookApp.password="sha1:xxxxxxxxxxxxxxxxxxxxxxxx"
```

このあたりで、どうも環境が構築できない･･･

というのも、`-v`オプションは
`自分のディレクトリ:コンテナ側のディレクトリ`で、ディレクトリ内容を同期できるものなのですが、どうやら同期が出来ませんでした。

自分の環境がMacであることや、途中で操作ミスを行っていた可能性もあります。

今回は、その中で学んだことを、まとめていきます。

# コンテナ内を調べる

まず

```bash
 docker run --rm --name test -it jupyterlab:latest bash
```

このコマンドで、jupyterlabイメージをtestというコンテナ名で作って、bashでつないでみます。

このコンテナ内で

```bash
echo $HOME
```

とすると、/home/jovyanがホームのようです。

# -vに与えるディレクトリを変えてみる

結論から言えば、自分の場合`-v $(pwd):/home/jovyan/code`や`-v $(pwd)/code:/home/jovyan/code`とすることでうまくいきました。

そこまでに右往曲折あったのですが･･･

```bash
docker run  -v `pwd`:/home/jovyan/work/works -p 10000:8888 --name jupyter jupyter/datascience-notebook 
```

まず、以上のようにして、jupyterで普通に調べることにしました。
上記のようにすると、`pwd`=(Users/ganariya/~/The_ML)の内容

- Dockerfile
- .gitignore
- README.md

が,/home/jovyan/work/worksに展開されていました。

つまり、
/home/jovyan/work/works/Dockerfile
/home/jovyan/work/works/.gitignore


のようになっていました。

どうやら、`pwd:コンテナディレクトリ`は、ホストの`pwd`にある内容を、`/home/jovyan/work/works`内に展開しているようですね＞＜

次に

```bash
docker run  -v `pwd`/abc:/home/jovyan/work/works -p 10000:8888 --name jupyter jupyter/datascience-notebook 
```
としてみました。つまり、ホストするMac側のファイルを、`pwd`ではなく
`pwd`/abcディレクトリのものにしよう！というわけです。

このようにすると、`pwd/abc`の中身が/home/jovyan/work/worksに入っていました。

ここまでは想定通りのようです。

# なぜ問題が起こったのか？

ここまでで調べた結果から
`Jupyter`や`JupyterLab`がtreeの基準にする位置が原因で、同期がされていないんだな　という結論に至りました。

JupyterやJupyterLabは、おそらく変更はできると思うのですが
公式イメージからビルドしたコンテナを開くと

<img width="593" alt="スクリーンショット 2020-06-13 8.53.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211482/f00562c0-40fc-75e9-7d5e-c13f39454781.png">

上記のようになっており、`/home/jovyan`がtreeのものになっています。

よって、`$(pwd):/home/jovyan/work`や、`$(pwd):/home/jovyan/work/works`は、jupyterで触れたわけです。


しかし、最初の`$(pwd)/code:/code`では、問題が発生します。
ホストディレクトリの$(pwd)/codeディレクトリを、**コンテナのルートディレクトリのcodeというディレクトリ**に作成します。

しかし、datascience-notebookなどのデフォルトのイメージでは、そのコンテナのHomeが`/home/jovyan`であるため、`/code`に触ることが出来ません。

よって、マウント自体はされているのですが、**見えることのないさらに上位の階層**でマウントされていたわけです･･･＞＜


# 結論

脳死で使いたいときはJupyterに関しては

`-v $(pwd):/home/jovyan/code`

のように、`/home/jovyan`以下に置こう･･･＞＜！


# 感想

/codeでもできそう･･･！（ホームディレクトリを変えたり、JupyterLabの起動位置を変える･･･？）
iOSでFirebaseを環境ごとにプロジェクトを分ける方法

iOSの場合、開発環境と本番環境を分ける場合、Firebaseのプロジェクトを分けるのが手っ取り早く行える方法だと思います。

##対象
Firebaseを導入したいiOSエンジニア

##前提
開発と本番でTARGETが分かれている
TARGETを複数作る方法は[こちら](https://qiita.com/alt_yamamoto/items/c3b78b24d0ff5ddc93f9)から
##手順
1. Firebaseにて2つプロジェクトを作成（開発用と本番用）
2. 「GoogleService-info.plist」ファイルをダウンロードする（開発用プロジェクトと本番用プロジェクト）
3. 「GoogleService-info.plist」ファイルの名称変更
4. Xcodeプロジェクトに名称変更した「GoogleService-info.plist」ファイルを設置
5. Xcode内で、ShellScript作成
6. 開発、本番で読み込む「GoogleService-info.plist」ファイルを変える

##Firebaseにて2つプロジェクトを作成とダウンロード（開発用と本番用）
Firebaseにて2つプロジェクトを作成
（開発用と本番用）
プロジェクトの作成手順とPodsのインストール及び初期化は[こちら](https://qiita.com/kumas/items/74d74a87b04d8614259a)を参照

ダウンロード内に「GoogleService-info.plist」ファイルが２つ存在する状態になる

##名称変更
ダウンロードした「GoogleService-info.plist」ファイルのうち、

* 開発用プロジェクト
    *  GoogleService-info-develop.plist
* 本番用プロジェクト
    * GoogleService-info-Release.plist

##Xcodeプロジェクトに名称変更した「GoogleService-info.plist」ファイルを設置
ドラッグ＆ドロップで追加

* 「Copy items if needed」
* 「Create group」

上記、２つにチェックが入っていることを確認してください。

##Xcode内でShellScript作成
ShellScriptを記載できる場所は
「TARGETS」　→　「Build Phases」

左上の「＋」から、新しいScript「New Run Script Phases」を選択
<img width="1065" alt="スクリーンショット 2020-06-13 8.35.13.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/d03eef7c-9b65-069b-527d-d78b38451336.png">

追加された「Run Script」
<img width="1054" alt="スクリーンショット 2020-06-13 8.37.48.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/246668/01be0f20-e8e8-ac79-7965-f30e70f1e9b8.png">

コメントアウトされている

```
# Type a script or drag a script file from your workspace to insert its path.
```

部分に環境による「GoogleService-info.plist」ファイルの読み分けを記載します。

```
PATH_TO_GOOGLE_PLISTS="${PROJECT_DIR}/${PRODUCT_NAME}"

case "${CONFIGURATION}" in

   "Develop" )
        cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-develop.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;

   "Release" )
        cp -r "$PATH_TO_GOOGLE_PLISTS/GoogleService-Info-Release.plist" "${BUILT_PRODUCTS_DIR}/${PRODUCT_NAME}.app/GoogleService-Info.plist" ;;

    *)
;;
esac

```



以上で、環境によるFirebaseのプロジェクト分けは完了になります。
足らないこと、間違い等ありましたら、コメントもしくは、[@gurensouen](https://twitter.com/gurensouen)
にご連絡いただけますと幸いです。
MongoDB 備忘録

# MogoDB
MongoDBを自己学習してみた。学習時のコマンド等を備忘録程度に残す

# コマンド一覧

| やりたいこと| コマンド | コマンド例 | 
|------------|----------|------------|
| データベースを作成する | use データベース名 | use test |
| データベースの一覧確認 | show dbs | show dbs |
| データベースの統計情報の確認 | db.stats() | db.stats() |
| データベースの削除 | db.dropDatabase() | db.dropDatabase() |
| コレクションの作成 | db.createCollection("コレクション名") | db.createCollection('employee') |
| Capped コレクションの作成 | db.createCollection("コレクション名", { capped: true, size:<データサイズの上限>}) | db.createCollection("log", {capped:true, size: 1024000}) |
| | | db.createCollection("log_max", {capped:true, size: 1024000, max: 5000}) |
| Capped コレクションに変更する | db.runCommand({"convertToCapped": "コレクション名", size: <データサイズの上限>}) | db.runCommand({"convertToCapped": "mycol", size: 100000})|
| コレクションの一覧 | show collections | show collections |
| コレクションの削除 | db.collection.drop() | db.employee.drop |
| コレクションに1件だけ登録 | db.collection.insertOne({kye1: value1, key2: value2, ・・・}) | db.employee.insertOne({ name: "田村", age: 30}) |
| コレクションに複数件、登録する | db.collection.insertMany([{kye1: value1, key2: value2, ・・・},{kye1: value1, key2: value2, ・・・}]) | db.employee.insertMany([{name: '田村', age:30}, {name: '山田' , age: 31}, {name: '佐藤', age: 23}]) |

# 統計情報で確認するフィールド
| No. | フィールド名 | 説明 |
|-----|--------------|------|
| 1 | collections | データベースの中にあるコレクション数です |
| 2 | dataSize | 圧縮される前のデータサイズです |
| 3 | storageSize | コレクションに割り当てられたスペースの合計サイズです。データ圧縮された後のサイズが表示されます |
| 4 | indexes | インデックスの数です |
| 5 | indexSize | インデックスのデータ量の合計です |
| 6 | fileSize | ストレージに保存されるファイルのサイズです。 |

# リンク集
| No. | インデックス | リンク先 |
|-----|--------------|------|
| 1 | 各種データ型 | https://docs.mongodb.com/manual/reference/operator/query/type/ |
likes.html.erb

<!-- 指定されたコードを貼り付けてください -->
<div class="main user-show">
  <div class="container">
    <div class="user">
      <img src="<%= "/user_images/#{@user.image_name}" %>">
      <h2><%= @user.name %></h2>
      <p><%= @user.email %></p>
      <% if @user.id == @current_user.id %>
        <%= link_to("編集", "/users/#{@user.id}/edit") %>
      <% end %>
    </div>
    
    <ul class="user-tabs">
      <li><%= link_to("投稿", "/users/#{@user.id}") %></li>
      <li class="active"><%= link_to("いいね!", "/users/#{@user.id}/likes") %></li>
    </ul>
    
    <!-- 変数@likesに対してeach文を用いてください -->
    <% @likes.each do |like| %>
      <!-- 変数postを定義してください -->
      <% post = Post.find_by(id: like.post_id) %>
      
      <div class="posts-index-item">
        <div class="post-left">
          <img src="<%= "/user_images/#{post.user.image_name}" %>">
        </div>
        <div class="post-right">
          <div class="post-user-name">
            <%= link_to(post.user.name, "/users/#{post.user.id}") %>
          </div>
          <%= link_to(post.content, "/posts/#{post.id}") %>
        </div>
      </div>
    <!-- each文のendを追加してください -->
    <% end %>
  </div>
</div>
//いいね機能を実装する
【AutoLISP】ジオメトリ関数の使い方

[ジオメトリ関数リファレンス（公式ヘルプ）](https://help.autodesk.com/view/OARX/2020/JPN/?guid=GUID-8C29D7A3-9CBB-47A8-A936-87118782303B)

### 2点を結ぶ線分の角度を求める angle
```scheme
(angle '(0 0 0) '(1 1 0))
;; -> 0.785398
(angle '(5 5 0) '(1 2 0))
;; -> 3.78509
(angle '(0 0 0) '(2 5 0))
;; -> 1.19029
```

### 2点間の距離を求める distance
```scheme
(distance '(0 0 0) '(1 1 0))
;; -> 1.41421
(distance '(0 0 0) '(100 0 0))
;; -> 100.0
```

### 2本の線分の交点を求める inters
```scheme
(inters '(0 0 0) '(100 100 0) '(100 0 0) '(0 100 0))
;; -> (50.0 50.0 0.0)
(inters '(0 0 0) '(100 100 0) '(100 0 0) '(60 40 0))
;; -> nil

;; 延長線上も拾う
(inters '(0 0 0) '(100 100 0) '(100 0 0) '(60 40 0) nil)
;; -> (50.0 50.0 0.0)
```

### 指定された点にオブジェクトスナップモードを適用して取得した点を返す osnap
```scheme
;; '(0 0 0) '(100 100 0) の線分が作図されているとして
(osnap '(40 40 0) "_mid")
;; -> (50.0 50.0 0.0)
(osnap '(40 41 0) "_mid")
;; -> (50.0 50.0 0.0)
(osnap '(100 50 0) "_mid")
;; -> nil
```

### 指定点から指定角度と距離だけ離れた点を返す polar
```scheme
(polar '(0 0 0) 0 100)
;; -> (100.0 0.0 0.0)
(polar '(0 0 0) (/ pi 2) 100)
;; -> (0.0 100.0 0.0)
(polar '(0 0 0) (/ pi 4) (sqrt 2))
;; -> (1.0 1.0 0.0)
```

### 文字を囲むボックスの対角頂点の座標を返す textbox
```scheme
;; 文字を選択 ※マルチテキスト不可
(setq text (car (entsel)))
(textbox (entget text))
;; -> ((0.75 0.25 0.0) (9.93122 3.43122 0.0)) ※選択した文字による
```
users_controller.rb

class UsersController < ApplicationController
  before_action :authenticate_user, {only: [:index, :show, :edit, :update]}
  before_action :forbid_login_user, {only: [:new, :create, :login_form, :login]}
  before_action :ensure_correct_user, {only: [:edit, :update]}
  
  def index
    @users = User.all
  end
  
  def show
    @user = User.find_by(id: params[:id])
  end
  
  def new
    @user = User.new
  end
  
  def create
    @user = User.new(
      name: params[:name],
      email: params[:email],
      image_name: "default_user.jpg",
      password: params[:password]
    )
    if @user.save
      session[:user_id] = @user.id
      flash[:notice] = "ユーザー登録が完了しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/new")
    end
  end
  
  def edit
    @user = User.find_by(id: params[:id])
  end
  
  def update
    @user = User.find_by(id: params[:id])
    @user.name = params[:name]
    @user.email = params[:email]
    
    if params[:image]
      @user.image_name = "#{@user.id}.jpg"
      image = params[:image]
      File.binwrite("public/user_images/#{@user.image_name}", image.read)
    end
    
    if @user.save
      flash[:notice] = "ユーザー情報を編集しました"
      redirect_to("/users/#{@user.id}")
    else
      render("users/edit")
    end
  end
  
  def login_form
  end
  
  def login
    @user = User.find_by(email: params[:email], password: params[:password])
    if @user
      session[:user_id] = @user.id
      flash[:notice] = "ログインしました"
      redirect_to("/posts/index")
    else
      @error_message = "メールアドレスまたはパスワードが間違っています"
      @email = params[:email]
      @password = params[:password]
      render("users/login_form")
    end
  end
  
  def logout
    session[:user_id] = nil
    flash[:notice] = "ログアウトしました"
    redirect_to("/login")
  end
  
  def likes
    # 変数@userを定義してください
    @user = User.find_by(id: params[:id])
    
    # 変数@likesを定義してください
    @likes = Like.where(user_id: @user.id)
    
    
  end
  
  def ensure_correct_user
    if @current_user.id != params[:id].to_i
      flash[:notice] = "権限がありません"
      redirect_to("/posts/index")
    end
  end
  
end
//いいね機能を実装する
カスタムオブジェクトの最後に作成された添付ファイルを探すSOQL

#Query the last file created under a custom object record

https://success.salesforce.com/answers?id=9063A000000eecI

Idはどんどん値が増えていくよなイメージなのかな。

SELECT max(ContentDocumentId ) from ContentDocumentLink where LinkedEntityId  = '[Record Id]'
phpunitで三項演算子のカバレッジってどうなるんだっけ?

# phpunitで三項演算子のカバレッジってどうなるんだっけ?
わからんのでやってみよう。

## やってみる
### やった環境
```shell-session
$ php -v
PHP 7.4.6 (cli) (built: May 14 2020 10:38:36) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Xdebug v2.9.2, Copyright (c) 2002-2020, by Derick Rethans
    with Zend OPcache v7.4.6, Copyright (c), by Zend Technologies

$ ./vendor/bin/phpunit --version
PHPUnit 7.5.20 by Sebastian Bergmann and contributors.
```

### やってみた
```PHP:Target.php
<?php

class Target
{
    public static function returnExcludeZero(int $num1, int $num2): int
    {
        if (!empty($num1)) {
            return $num1;
        }

        return !empty($num2) ? $num2 : 9999;
    }
}
```
↑を作って
↓でテスト

```PHP:TargetTest.php
<?php

use PHPUnit\Framework\TestCase;

class TargetTest extends TestCase
{
    public function testReturnExcludeZero(): void
    {
        $this->assertEquals(1, Target::returnExcludeZero(1, 0));
        $this->assertEquals(2, Target::returnExcludeZero(0, 2));
        // $this->assertEquals(9999, Target::returnExcludeZero(0, 0));
    }
}
```
9999返す部分は通ってないけど…:chicken:


### やった結果
```text
PHPUnit 7.5.20 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 127 ms, Memory: 4.00 MB

OK (1 test, 2 assertions)


Code Coverage Report:   
  2020-06-12 23:19:51   
                        
 Summary:               
  Classes: 100.00% (1/1)
  Methods: 100.00% (1/1)
  Lines:   100.00% (3/3)

Target
  Methods: 100.00% ( 1/ 1)   Lines: 100.00% (  3/  3)
```
**カバレッジ100%だー！！**:rooster:
※ 行ベースのカバレッジだから当たり前の話だけども…

### phpdbgなら?
phpdbgでテストしても一緒。
ちなみに、上の単純なテストでもphpdbgで実行したら結構早くなるので、みんなphpdbg使おうよ！

```text
Time: 77 ms, Memory: 6.00 MB
```

## おまけ
* [テストコードとか突っ込んだリポジトリ](https://github.com/kotaoue/investigateCoverageOfConditionalOperator)
ユーザーIDは何桁まで？

ユーザーIDはデータベース上で何桁必要なものなのか、調べてみたもののまとめ。

### 考察

[IDの桁数についての話](http://underscore42rina.hatenablog.com/entry/2013/09/05/130302)
- PasswordではなくIDについての制限のメリット等の考察。`桁数制限いるの？、上限が必要な理由とかある？、６とか１４って数字は？` 等
- Passwordについては、[チョコっとプラスパスワード(IPA)](https://www.ipa.go.jp/chocotto/pw.html)

メールアドレスの長さについては、RFC5321 4.5.3で規定されている。255。
https://tools.ietf.org/html/rfc5321#section-4.5.3


### 参考

GmailユーザID [6～30 文字](https://support.google.com/mail/answer/9211434?hl=ja)
Facebook [5文字以上](https://ja-jp.facebook.com/help/105399436216001)
Apple ID [メールアドレス](https://support.apple.com/ja-jp/HT201356)
Microsoft [256 文字](https://docs.microsoft.com/en-us/windows-hardware/customize/desktop/unattend/microsoft-windows-shell-setup-autologon-username#:~:text=Values,-Table%201&text=Specifies%20the%20user%20account%20name,maximum%20length%20of%20256%20characters.)
[Linuxにおいて、ユーザのアカウントとパスワードの文字列長の制限はいくつでしょうか？（ポリシーをお聞きしているのではありません）](https://q.hatena.ne.jp/1116521370)
【自動化】PythonでWordの文書を読み取る

##Word文書をPythonで読み取る

契約書や報告書などオフィスでは様々な文書がありますが、主流は【Word文書】かと思います。

業務を自動化するにあたっては、Word文書の作成や読み取りを自動化したいというケースも多そうです。
実際、私も3ヶ月ごとに作成する委託契約書の作成をPythonで自動化しています。

本記事では、python-docxというライブラリを使って**PythonでWord文書を読み取る方法**を解説します。
（次回はWord文書の作成や置換についてご紹介します。）

## Word文書の読み取り

python-docxは標準ライブラリではありません。Anacondaでもデフォルトでは入っていないのでまずインストールしましょう。

```
pip install python-docx
```


インストールが終わったらライブラリをimportします。
importのときはpython-docxではなく**docx**なので注意してください。


```python:python
import docx
```

次にWord文書を読み込んでオブジェクトを作成します。
ここでは「テスト.docx」という下記のような文書を読み込みます。
![test_docx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/7dc0f43d-6326-caa2-a251-28655d94b784.png)


```python:python
document = docx.Document("テスト.docx")
```

このdocumentオブジェクトはparagraphsというリストと、tablesというリストを持ちます。

paragraphsは本文中の段落のことで、tablesは表のことです。
tablesは行をrowsのリストとして持ち、さらにrowsは列(セル)をcellsというリストとして持っています。
テキストを取得したい場合は、textという属性を参照します。

つまり、このような構造になります。
![python-docx.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/634673/2941ff9f-23f1-8712-79b0-a5ba9733f47b.png)


```python:python
for paragraph in word.paragraphs:
    print(paragraph.text)
```
```:実行結果
ここは1段落目。

ここは2段落目。

```

```python:python
for table in document.tables:
    for row in table.rows:
        for cell in row.cells:
            print(cell.text)
```

```:実行結果
ここは表の1行/1列
ここは表の1行/2列
ここは表の2行/1列
ここは表の2行/2列
```

## 注意点

残念ながら、python-docxでは**脚注**を読み取ることはできません。
※少なくとも、私はいくら調べても脚注を操作する方法がわかりませんでした。もし、何か情報をお持ちならコメントいただけると幸いです。

脚注も含めて操作したい場合には、別の方法を検討する必要がありそうです。
Python超初心者の超初心者のためのPython #関数1

環境
windows7　（Mac Book Pro 16inch欲しい）
Visual Studio Code
chrome
python ver3.8.3

この記事はプログラミング初心者かつPython初心者に向けて記述します。

##関数その1
関数‥‥それは中学校で習ったあれのことか？
それとも関鯖のように美味しいあれのことか？

そう、正解は中学校で習ったあれのようなものです。

```Python:func.py
y=f(x)

```

懐かしさで胸が熱くなります。
では、関数とはなんでしょ？
weblioによりますと、関数とは

> 関数
読み方：かんすう 
【英】function
関数とは、入力された値に対してある決まった内容の計算を行い、入力された値に応じた処理結果を返す、数式、あるいは命令の集まりのことである。

>[weblio](https://www.google.co.jp/amp/s/www.weblio.jp/content/amp/%25E9%2596%25A2%25E6%2595%25B0)

との事です。
だいぶ記憶が戻って参りました。
しかし、まだわかりにくいのでちょっと下記のように言葉を変えてみましょう。

関数
読み方：かんすう 
【英】function
関数とは、入力された`食材`に対してある決まった内容の`調理`を行い、入力された`食材`に応じた`料理`結果を返す、数式、あるいは命令の集まりのことである。

これをもっと簡単に例えて言うと、こう言えるのではないでしょうか


###1、staubに`食材`を入れる
まずはstaub(鍋)に`食材`を入れます。ジャガイモ、にんじん、肉、ルーなどなど。

###2、火をかける`調理`
鍋に火を当ててstaubの中の`食材`を`調理`します。

###3、カレーという`料理`となる
はい。美味しいカレー`料理`の出来上がりです。

つまりは、
`y=f(x)`
はこうです、

####`料理`=`調理`(`食材`)

と乱暴ですが置き換えてみましょう。
`食材`を`調理`すると`料理`になります。

さて、これを踏まえて次に行きます。

####`料理`=`調理`(`食材`)
の`料理`は変数に。`食材`は引数に。`調理`は関数に。これがPythonの関数です。
####変数=関数(引数)

続く
Node.jsで指定したディレクトリをZIP圧縮するサンプル (async/awaitを用いて書く)

`Node.js`で指定したディレクトリをZIP圧縮するためのサンプルコードとなります。
`async/await`を用いて書いてみます。

なお、圧縮処理には `archiver`というnpmライブラリを利用します。

https://github.com/archiverjs/node-archiver


下記のような状況を想定しています。
ここの`dir`を `dir.zip`にするイメージです。

```sh
dir
├── sample1.mp4
├── sample1.mov
└── sample2.mov
```

## サンプルコード

`archiver`をインストール

```sh
yarn add archiver
```

なるべくシンプルに書こうと思い、削れるところは削ってみています。
`archiver` 自体の細かな使い方は公式を参照してみてください。


```javascript
const fs = require('fs');
const path = require('path');
const archiver = require('archiver');

const zipArchive = async targetDir => {
  const zipPath = `${targetDir}.zip`;
  const output = fs.createWriteStream(path.join(__dirname, zipPath));

  const archive = archiver('zip', {
    zlib: { level: 9 }
  });

  archive.pipe(output);

  archive.glob(path.join(targetDir, '*.mp4'));
  archive.glob(path.join(targetDir, '*.mov'));

  await archive.finalize();

  return;
}

(async() => {
  await zipArchive('dir');
})();

```

## 圧縮する際のオプションについて(archiver)

```javascript
  const archive = archiver('zip', {
    zlib: { level: 9 }
  });
```

この記述はREADMEに記述されていたものをそのまま拝借していますが、ここの指定により圧縮率が異なるようです。
ためしにここのオプションをなしにしてみたところ、ZIP圧縮時の容量がやや大きくなりました。
(圧縮するデータにもよるかと思いますが、自身の場合は0.5MBほど大きくなりました)

該当するドキュメントはここあたりになるかと思います。
https://www.archiverjs.com/archiver
https://www.archiverjs.com/global.html#ZipOptions
PHPのエラー表示設定

PHPでの開発時に、ページを更新したら画面が表示されないときに使うコードです。

```
// 1でエラー表示 0で非表示
ini_set('display_errors', 1);
```


>php.net

>ini_set ( string \$varname , string \$newvalue ) : string


エラーがある場合、エラーを非表示にするとコンソールに`500 (Internal Server Error)`が返り、
該当ページは表示されません。

その為、初めのうちは画面を更新したら真っ白で何も表示されない！と焦ってしまいました。

`php.ini`を触らなくても、上記コードでエラーを確認しながら開発を進めることができます。
getContext('2d')がnullになる問題

htmlにおいて、描画をする際にgetCOntect('2d')を使う時に、
なぜかnullになる事があった。

この問題がややこしい点としては、たまに取得できるし、たまに取得できない。ような事も発生する。とにかく解決しない。


でおそらく、普通にdocument ready　や onload　の中に「書け」というアンサーが多いのだが、そもそも途中でボタンをおして取得をする行動においてnullだったので、htmlを読みに行けてないという事ではない。毎回ダメではないので記述が間違っているわけではない。


settimeoutの中にいれたらダメだったなども聞いたりもしたけど、1点、ポイントとしては、１度取得できると、保持はしてくれる。という点があった。

drawImage()みたいのをした時にnullですよー。ってなる。ので、

$(document).ready(function(){
  ここでgetContect('2d')を取得
});

で使う時まで保持しておく。

であわよくば、この時に一回fillRectとかで書くよ。って宣言すると、メモリ領域に「このキャンバスは使うよ」って宣言してくれるみたいで、問題なく動作をして必要な時によんでくるだけ

そんな問題があった。
MongoDB

# MongoDB
```
>> mongo // 起動
>> use admin  
>> db.auth('userName', 'password')
>> rs.status()    //レプリカセットとかのデータが取れる
```

# 繋ぎ方 以下参照
この記事はマジで神

https://qiita.com/chenglin/items/ecf6f67e8f80c4750204
初心者によるプログラミング学習ログ 343日目

#100日チャレンジの343日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
343日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>343日目　2.5h<br>・ポートフォリオ作成<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1271537828208365568?ref_src=twsrc%5Etfw">June 12, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
VSCode＆Java開発環境構築で詰まった点

# VSCodeでも簡単にJavaのデバッグが可能！
構築手順については下記リンク参照。
https://qiita.com/takuma-jpn/items/b49785a314fb4db85775
# デバッグ時になぜかエラー
**Failed to launch debuggee in terminal with TransportTimeoutException**
手順通りにやったのにエラー↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482410/bb855b20-f155-70ce-fe31-a683d2a35721.png)

debugの際にターミナルを利用しようとするから的なことかな、ということで検索したところ
GitHubのissueを見つけた。
Ctrl+Shift+Pからユーザー設定を開き「java debug setting console」と検索。
デフォルトで「integratedTerminal」となっているが「internalConsole」を指定すればデバッグ可能となった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482410/0e390524-e5df-ad4d-2892-49c8abb6e74e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/482410/e470cd43-bb88-1607-9498-add88505235d.png)

参考：https://github.com/microsoft/vscode-java-debug/issues/637
EC2 ドメイン名設定 Route53

# EC2にドメイン名を設定しよう！
### ElasticIPを設定
これを設定しないと, EC2のdefaultのパブリックDNS(IPv4)は変わっちゃうみたい.
どのタイミングで変わるのかは知らんけど。
### RouteS3にドメイン名を設定
お名前.com とかでとってきたオリジナルドメイン名を設定する.
設定したホストドメインに毎月0.5ドルくらいかかるらしいけど, それ以上稼げばいいだけの話.

### ElasticIPとRoute53に設定したドメインをの結びつけ
Route53の中の**Aレコード**ってやつが, みんながアクセスする時に見るドメイン名なんだってさ. 
だから, その中にElasticIPを結び付けるんだ！！！

### ネームサーバーの設定
僕はお名前.comを使ったので, そこでの作業になるんだけど, **Route53**の中にあるタイプ**NS**っていうやつの欄にある値を, お名前.comのどネームサーバー設定の所に全部いれるの！！！

### これでサーバーのドメイン名の設定は終わりだお。
# 参考
https://avinton.com/academy/route53-dns-vhost/


### WebサーバーにNginxを使っている場合
このままでは設定したドメインにアクセスしても, 失敗するお。
**Nginx**のWebサーバーを使用している時は以下を参照されたし。

```
cd /etc/nginx/conf.d/
sudo vi default.conf


ここを  server_name yor.domain.name.com;
```

# 参考
https://qiita.com/ryuchan00/items/3e172fbfd1044e093c52
ネームサーバーとは

# ネームサーバーとはなんぞや（DNSサーバー)
ネームサーバーとは、インターネット上でドメインとWebサーバーやメールサーバーを結びつけるための名前解決をするサーバーです。


インターネット上にあるサーバー（コンピューター）には、すべてIPアドレス（123.145.167.189のように数字で構成されたもの）が割り振られています。IPアドレスが判明すれば、実際にホームページやメールを運用しているサーバーにアクセスすることができます。
このIPアドレスとドメインを結び付ける役割を担っているのがネームサーバーとなります。いわば、電話番号（ドメイン）と電話機（サーバー）を結びつける電話線のようなものです。


なお、DNS（Domain Name System）サーバーと呼ばれることもあります。


# 参考URL
https://help.onamae.com/answer/8072
gdal ツールで GeoTiff ファイルの切り抜きを行ってみる。

https://www.gsi.go.jp/kankyochiri/gm_jpn.html 

このページで取得できる[日本全体の標高 GetTiff ファイル](http://www1.gsi.go.jp/geowww/globalmap-gsi/download/data/gm-japan/gm-jpn-el_u_1_1.zip)から、東京近辺を囲む一次メッシュコード : 5339 の緯度経度範囲で切り抜きを行いたい。

切り抜く方法は色々あるけど、今回は gdal ツールに含まれる gdal_translate を利用してみる。

## 地域メッシュコードから緯度経度範囲を求める

一次地域メッシュコードからコードが示す範囲の南端・西端の緯度経度を求める式は以下の通り。

```
- 南端 : 一次地域メッシュコードの先頭2桁 / 1.5
- 西端 : 一次地域メッシュコードの末尾2桁 + 100
```

東京近辺を囲む一次メッシュコード : 5339の場合、

- 南端 : 53/1.5 = 35.3333333333
- 西端 : 39 + 100 = 139.0

となる。

北端と東端については、対象メッシュコードの右上にあるメッシュコードの南端・西端と等しくなる。
5339の右上にある範囲のコードは 5440 となり、このコードから南端・西端を求めると、

- 5440 コードの南端 (5339の北端) : 54/1.5 = 36.0 
- 5440 コードの西端 (5339の東端) : 40 + 100 = 140

となる。

## gdal_translate コマンドを使ってGeoTiff から指定した緯度経度範囲でクリップ

gdal_translate コマンドの -projwin オプションを用いることで指定した GeoTiff ファイルから指定した緯度経度範囲で切り抜きを行うことができる。

```bash
$ gdal_translate -projwin  [west]  [north]  [east]  [south]    [input.tif]  [output.tif]
```
日本全体の標高情報を画像化した el.tif はこんな感じ。

![スクリーンショット 2020-06-13 2.47.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/311653f4-f5f3-5b7a-5144-548afcefd8a2.png)

この GeoTiff 画像から一次地域メッシュコード : 5339 の範囲で切り抜くには

```bash
$ gdal_translate -projwin 139.0 36.0 140.0 35.33 el.tif el_5339.tif
```

と指定する。

このコマンドによって el_5339.tif が生成される。

中身を覗いてみると、以下の画像が確認できる。

![スクリーンショット 2020-06-13 2.47.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18599/6693cb56-9654-cb46-086c-f037eb1dab8f.png)
【Amplify】graphqlでid以外を指定してupdateできるようにschemeを編集する

#解決策
player というtypeを用いroomIdが一致するデータのみ更新する例をあげる。
scheme の type と key を下記のように編集する

```javascript

type Player 
@model(subscriptions:{ onCreate:["onCreatePlayer"], onDelete:["onDeletePlayer"],onUpdate: ["onUpdatePlayer","onUpdatePlayerByRoomId(roomId:String!)"]})
@key(name: "byRoomId", fields: ["roomId", "id"], queryField: "getPlayerByRoomId")
{
  id: ID
  userId: String
  roomId: String
  userName: String
}
```
その後生成されるAPIを使ってこう叩く

```javascript
 await API.graphql(
    graphqlOperation(updatePlayer, { input: newPlayers })
 );
```

result に入れることで更新後の結果を取得することもできる。

```javascript
const result = await API.graphql(
    graphqlOperation(updatePlayer, { input: newPlayers })
 );
```
Apache Tomcat の起動が失敗した原因は環境変数のパスの最後のスラッシュ

備忘録
[参考:https://dev4app.com/archives/5398654-tomcat-not-starting.html](https://dev4app.com/archives/5398654-tomcat-not-starting.html)

環境変数のパスの最後のスラッシュが余計だった件。

本日は(昨晩は？) Apache Tomcat9.0.36の64-bit Windows zipをダウンロード。
中身のbinフォルダなどを C:\Apache\apache-tomcat-9.0.36 下に置いたので、
環境変数に 

```
CATALINA_HOME=C:\Apache\apache-tomcat-9.0.36\ 
```

のようにセットしたのでした。

環境変数を設定して、8080ポートは使っていないのを確認して、binフォルダ下のstartup.batを実行してみたところ、

```
C:\Apache\apache-tomcat-9.0.36>C:\Apache\apache-tomcat-9.0.36\bin\startup.bat
Using CATALINA_BASE:   "C:\Apache\apache-tomcat-9.0.36"
Using CATALINA_HOME:   "C:\Apache\apache-tomcat-9.0.36"
Using CATALINA_TMPDIR: "C:\Apache\apache-tomcat-9.0.36\temp"
Using JRE_HOME:        "C:\Program Files\Java\jdk-14.0.1"
Using CLASSPATH:       "C:\Apache\apache-tomcat-9.0.36\bin\bootstrap.jar;C:\Apache\apache-tomcat-9.0.36\bin\tomcat-juli.jar"
```

とは表示されるのにどういうわけかtomcatが起動しない。

catalina.bat runを実行して何が起きているのか確認したところ

```
java.util.logging.ErrorManager: 4: Unable to create [C:\Apache\apache-tomcat-9.0.36" -Dcatalina.home=C:\Apache\apache-tomcat-9.0.36"\logs]
java.util.logging.ErrorManager: 4: Unable to create [C:\Apache\apache-tomcat-9.0.36" -Dcatalina.home=C:\Apache\apache-tomcat-9.0.36"\logs]
java.util.logging.ErrorManager: 4: Unable to create [C:\Apache\apache-tomcat-9.0.36" -Dcatalina.home=C:\Apache\apache-tomcat-9.0.36"\logs]
java.util.logging.ErrorManager: 4: Unable to create [C:\Apache\apache-tomcat-9.0.36" -Dcatalina.home=C:\Apache\apache-tomcat-9.0.36"\logs]
13-Jun-2020 02:40:25.098 驥榊､ｧ [main] org.apache.catalina.startup.Bootstrap.initClassLoaders Class loader creation threw exception
        java.lang.IllegalArgumentException: The double quote ["] character can only be used to quote paths. It must not appear in a path. This loader path is not valid: ["C:\Apache\apache-tomcat-9.0.36" -Dcatalina.home=C:\Apache\apache-tomcat-9.0.36"/lib","C:\Apache\apache-tomcat-9.0.36" -Dcatalina.home=C:\Apache\apache-tomcat-9.0.36"/lib/*.jar","C:\Apache\apache-tomcat-9.0.36/lib","C:\Apache\apache-tomcat-9.0.36/lib/*.jar"]
```

というメッセージが。。。よく見てみると

```
C:\Apache\apache-tomcat-9.0.36" -Dcatalina.home=C:\Apache\apache-tomcat-9.0.36"\logs
```

と書いてある。そんなところに「"」があったのですね。CATALINA_HOMEを定義したときの最後のバックスラッシュが悪さをしていたのです。

```
CATALINA_HOME=C:\Apache\apache-tomcat-9.0.36
```
と定義しなおしたところ無事tomcatは起動しました。
【Apex】Database.query(String) を使ってはいけない

# はじめに
動的 SOQL である`Database.query(String)` は公式のドキュメントに普通のやり方のように書かれているためか、未だにそこそこな頻度で見かけることがあるので啓発の意味を込めて書きます。SELECT するフィールドを動的に生成する必要があるなどの特別な事情がない限り使わないでください。

# 結論

**インライン SOQL を使ってください**

```groovy
List<Account> accounts = Database.query('SELECT Id FROM Account'); // Bad
List<Account> accounts = [SELECT Id FROM Account]; // Good
``` 

# 理由
## 1. セキュリティリスクを考慮する必要がある
[公式](https://developer.salesforce.com/docs/atlas.ja-jp.apexcode.meta/apexcode/apex_dynamic_soql.htm)でも言及されてますが文字列でクエリを渡しているため、画面などからのインプットを素通しすると SOQL インジェクションのリスクがあります。`escapeSingleQuotes`を使えば問題ないですが、いちいちメソッドを呼ぶ必要があるので忘れがちです。インライン SOQL であれば

```java
[SELECT Id FROM Account WHERE Id = :inputId]
```

のようにバインドで変数を呼ぶだけでいいので考慮することがより少ないです。

## 2. エディタの補助機能を活かせない
VSCode などのエディタを使うと文字列としか認識されていないため、オブジェクトの項目名がサジェストされない上に、項目名が間違っていたとしても警告が出ないため実行しないとエラーに気付けません。これらは効率と品質面に悪い影響しか与えません。

## 3. 項目の使用場所に引っ掛からない
オブジェクトの項目のページから、その項目がどの Apex クラスで使われているかを確認できますが、文字列としか認識されていないためこの機能に引っかかりません。これによって項目の影響調査がしづらくなり保守性が下がってしまいます。また、通常どこかで項目が使用されていれば項目削除はできませんが、動的 SOQL でやっていたがために項目削除ができて障害が起きる...というようなリスクも出てきます。

---

ということで動的 SOQL はインライン SOQL に比べるとほとんどデメリットしかないので使うのはできる限り控えましょうという話でした。
Nuxt.jsで動的に生成されるパスをリロードしたときにエラーが出る問題を解決する

#解決策

`nuxt.config` に `router` の `mode` で `hash` を指定する

```
export default {
  mode: 'universal',
  router: {
    mode: 'hash' // 追記
  },
  /*
  ** Headers of the page
  */
  head: {
```


実際にhash で指定したサイト
https://blog.higuuu-searvice.com/#/
言葉が足りなかったな、すまん（追記

前回の記事では割とわけのわからんことを書いたと反省。
まあやりたかったことはこうだ。Linux環境において、

1.プロセスAとプロセスBで少量のデータを一方通行に送りたい
2.割とタイムクリティカルな制約でやりたい
3.通信経路をread()でブロッキング監視したい

最後の3はCPUを無駄食いさせないためだ。そしてこの仕様を満たすために使おうとしたのがFIFO、名前つきパイプだった。

プロセス間通信のやり方はいろいろあるが、

・ドメインソケットは便利だがオーバーヘッドが気になる。
・共有メモリは高速だがCPUの無駄食い対策がしにくい。
・read()でブロッキングしてOSにディスパッチを任せたい。

ということでFIFOを使ってみた。結果、大外れであった。

まずfdのopen()が曲者で、**FIFOに対する使用** の場合

・~~write側だけをopen()するとSIGPIPEを発生する~~（無視もできる）
　※SIGPIPEは改めて調べる
・ブロッキングopen()するとread()がブロッキングしない
　※openモードで挙動が違う
・ノンブロッキングでopen()するとread()でブロッキングできない
・FIFOの両端が閉じるとその瞬間に抱えているデータが消える

とまあどこまでも扱いにくい代物であった。

やむを得ず
open()でブロッキングして
データが到着したらread()して
close()で最初に戻る

という実装をテストしてみたが、open()/close()の遅延がでかい。
最初のタイムクリティカルな制約を満たせなくなってしまった。

そうじゃない。やりたいことは違うんだ。

1.通信経路をブロッキング指定でopen()するが即時復帰して
2.通信経路をread()したらデータ到着までブロッキングして
3.あとは2をループ中で繰り返せばオーバーヘッドが最小
4.ループが終わったら通信経路をclose()

これを満たすAPIを探していたのだ。そしてついに見つけた。
POSIXメッセージキューがそれだった。
こいつはSystemVメッセージキューを拡張したものだ。

・一度キューを作ればプロセスが落ちてもカーネル寿命で存在する
・両端が閉じてもデータを失うことがない
・read端とwrite端のどちらを先にオープンしてもよい
・mq_open()しても即時復帰する
・mq_receive()を呼ぶとブロッキングモードならデータを待つ
・相手側プロセスがmq_send()すれば起床してデータが取れる
・しかも動作が思ったより高速である
・メッセージに優先度をつけたりシグナルを送ったりできる
　（使わないけど）

とまあ、いいことずくめのようだが少々のクセはある。
「メッセージ」の「キュー」なので、データはパケット扱いだ。
パイプのようなバイトストリームではない。
それと、キュー作成時のパラメータをいくつか指定するのだが

・ブロッキングかノンブロッキングか
・１メッセージのサイズ
・キューが保持可能なメッセージ数
・あとなんか１つ（忘れた）

を指定する必要がある。

・データがキューに渋滞しない程度のメッセージ数
・最大公約数的なメッセージサイズ
・キューのブロッキング動作は作成時に決定

という設計が必要だ。加えて落とし穴が１つあって、

・mq_receive()のバッファサイズはメッセージサイズ以上

という制約がある。
メッセージサイズより小さいバッファを指定するとエラーを返す。

これさえ押さえておけば、割と簡単に使うことができる。
ただしプロセスが落ちてもカーネルバッファにキューのデータが残ることには注意が必要である。プロセス落ちからの再起動があるならキューの残存データは考慮しておこう。

まあ細かいこと言いだせば、シグナル通知とかforkしてパイプとかメモリマップトファイルとかあるにはあるのだが、赤の他人ならぬ他プロセスとのデータ交換を考えるなら、FIFOかキューかドメインソケットから選ぶことになるだろう。共有メモリは排他制御とCPU浪費対策が面倒だ。

API仕様の表面からは見えにくい罠にはまってしまった。