OmniAICreator/Qiita-1.07M huggingface dataset:
Railsで日本語をurlに使いたい時の書き方備忘録

## この記事で書くこと
- `/animals/隣の猫さん` `/animals/山奥の熊さん`
のようなurlを実現させるために何をする必要があるのか。

何も対処しないと、以下のような`animals#show`にリクエストすると `URI::InvalidURIError` が発生してしまう。 :disappointed: 

```rb:animals_controller.rb
class AnimalsController < ApplicationController
  def show
    @animal = Animal.find_by(name: params[:name])
  end
end
```


## 結論

### Controller


以下のようにutf-8にエンコードしてあげれば良い.


```rb:animals_controller.rb
class AnimalsController < ApplicationController
  before_action :encode_with_utf_8, only: :show

  def show
    @animal = Animal.find_by(name: params[:name])
  end

  private

  def encode_with_utf_8
    request.url.force_encoding("utf-8")
  end
end
```

### テストはどう書くか

[Ruby 2.7.0 リファレンスマニュアル | URI.encode_www_form_component](https://docs.ruby-lang.org/ja/latest/method/URI/s/encode_www_form_component.html) を使用する。

```rb:spec/requests/animals_spec.rb
RSpec.describe 'Animals', type: :request do
  let(:animal) { create(:animal, name: '隣町の鳥さん') }

  describe 'GET /animals/:name' do
    context 'when animal exist' do
      it 'successes.' do
        url_encoded = URI.encode_www_form_component animal.name
        get "/animals/#{url_encoded}"
        expect(response).to be_success
      end
    end
  end
end
```
java 固定長文字列の中身の有無を調べる方法




```java
		String sti = "     ";
		//スペースをtrimする
		//その結果、ブランクであるかどうか
		if(sti.trim().isEmpty()) {
			System.out.println("blank");
		}else {
			System.out.println("notBlank");
		}
```
nimpyでnimからpythonを使って主成分分析をする

# 概要
Nimからsklearnをつかって主成分分析を行う手順をまとめました。
言わずとしれたsklearnを使うことで主成分分析を数行で行うことができますので、Nimから実行するためnimpyというライブラリをつかって実行してみます。実際にsklearnを使って主成分分析を行う部分はPythonで記述します。

nimpyでPythonを呼ぶ方法については以前やったのでその応用になります。
[Nimpyでnimからpythonを呼ぶ](https://qiita.com/kixixixixi/items/b9b34030959fe718ab93)

# Python側の準備
pyenv等で任意のPythonをいれる際に例のごとく（上記の記事を参考に）、`CONFIGURE_OPTS="--enable-shared"`を付与してlibpythonが生成されるようにします。
そしてpoetry等を使ってsklearnをいれます。

```toml:pyproject.toml 
[tool.poetry]
name = "nimpy_pca"
version = "0.1.0"
description = ""
authors = ["Your Name <you@example.com>"]

[tool.poetry.dependencies]
python = "^3.7"
numpy = "^1.18"
scikit-learn = "^0.22.2"

[tool.poetry.dev-dependencies]

[build-system]
requires = ["poetry>=1.0"]
build-backend = "poetry.masonry.api"
```

sklearnでのPCAの書き方がnimから呼ぶのが難しいため、pythonで処理を書きます。（nimpyではメソッドをcall仕組みなのでイニシャライザのような書き方や戻り値のない構文が使えない）
型の受け渡しを簡略化するためにJSONを使ってデータや結果のやり取りを行うようにしています。

```python:pca.py
from sklearn.decomposition import PCA
import numpy as np
import json

def pca(json_text):
    data = json.loads(json_text)
    pca = PCA(n_components=2)
    A = np.array(data)
    pca.fit(A)
    return {
        "components": pca.components_.tolist(),
        "varianceRatio": pca.explained_variance_ratio_.tolist()
    }
```

# nimpyでNimからPythonを呼ぶ
まず、poetryで入れたsklearnが読み込みできるようにlibpythonのpathを指定します。

```nim
import nimpy
import nimpy/py_lib as pyLib

pyLib.pyInitLibPath("/root/.pyenv/versions/3.7.7/lib/libpython3.7m.so")
```

また、先程つくったPythonを読み込めるようにファイルのある場所のpathを追加します。

```nim
discard pyImport("sys").path.append("/workspace/src")
```

そしてJSONデータをつかって先程のメソッドにデータを渡します。 `toJson` をつかって 戻り値の `PyObject` という型からJsonNode型に変換しています。

```nim
let pcaResult = pyImport("pca.py").callMethod("pca", json).toJson
```

あとはpcaResultにはいっている値を展開すれば完成です。

```nim
import sugar

let projectedValues = datas.map(data =>
    pcaResult["components"].getElems.map(c => c.getElems.zip(data).map(n => n[0].getFloat * n[1]).foldl(a + b))
)
```

# まとめ
`pyImport`のパスの指定の仕方やpythonファイルの名前衝突などにつまりましたが、pythonの読み込みがこちらのやり方できました。
これを応用すれば、他の統計処理や線形処理もPythonにまかせて簡単に実行することができそうです。
最適化コンパイラへのいざない (1)

### 記事一覧
1. はじめに（この記事）
2. [マルチパスコンパイラ](https://qiita.com/uint256_t/items/32fab9d3678f48b0f03d)
3. [定数に関する最適化](https://qiita.com/uint256_t/items/a0d050894927b618daa3)
4. [プログラムの構造](https://qiita.com/uint256_t/items/7d4556cb8f5997b9e95c)
5. .....

### 対象読者

- コンパイラの内部構造について興味がある方
- コンパイラに関して精通している方（批評お待ちしております）

# はじめに

ある程度コンパイラについての学習が進み，小さな自作言語などを作れるようになると，こんな疑問が浮かぶのではないでしょうか．

**「世の中のコンパイラって，こんなのだったっけ？」**

コンパイラの作り方が解説されている日本語の記事は，最近なら簡単に見つかります．ですが，それらの大半は所謂[ワンパスコンパイラ](https://ja.wikipedia.org/wiki/%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9#%E3%83%AF%E3%83%B3%E3%83%91%E3%82%B9%E3%81%A8%E3%83%9E%E3%83%AB%E3%83%81%E3%83%91%E3%82%B9)の作り方について解説しており，より高度な，具体的には ``gcc`` や ``clang`` 等の実用的コンパイラが行っている**最適化**というものについての記述が乏しいです．
（もちろん，ドラゴンブックや虎本を読めば最適化について書いてありますが，初心者が簡単に手を出せるものではないように思えます．少なくとも私はそうでした．）

次の記事以降では，簡単な最適化手法からアーキテクチャに依存するような高度なものまで，私の勉強もかねて紹介していこうと思います．一連の記事を読み終えた人が（書き終わるのが一体いつになるのかはわかりませんが...)，clangが``-O3``で生成する程度の機械語を吐き出せる自作言語処理系を作れるようになれば良いなと考えています．

# 扱う最適化手法

この一連の記事では主に，プログラムの実行時間を短くするための最適化について扱います．
使用メモリ量・電力量についての最適化は，私は詳しくないので扱う予定は今のところありません．もしかしたら，自分の勉強のために記事としてまとめるかもしれません．

# 解説の難易度

次回以降，最適化手法について紹介・解説していきますが，未だにどの程度詳しく解説すればいいのか悩んでいます．
手法の紹介とそのアルゴリズムの簡単な説明，で留めるべきか．疑似コードまでしっかり書いて，読者が動作するコードを書けるように準備をするべきか．
コメントで意見をもらえると嬉しいです．
【オンライン/オフライン】スマホ・PCで行える投票・QAサービスまとめ 2020

#はじめに
コロナの影響でオフラインイベントが続々と中止される自体が起きています。
今では"オンラインイベントをどう盛り上げるか？"と言った事に主眼をおいてイベント運営を考える事が重要になっています。

イベントでよくあるのが回答用紙を使ってアンケートや講演会で行うQAですね。
主催者は紙やペンの用意、回収後の集計処理や事前事後の準備が手間がかかって大変です。
回答者も記述式だと回答のハードルも上がると思います。

最近ではそれらをスマホやWEBで行える便利なサービスがあります。
(入力・回答・集計ができるアンケート・QA作成出来ると便利ですよね。）

ということで、某企業に務める会社員が国内で行っている主要ASPサービスを比較し、まとめて記事にしました。※あくまでWEB上の情報をまとめたものになりますのでご理解下さい。

同様なサービスを検討の方の一助になれば幸いです。

##・【2020年版】イベントを盛り上げる！アンケート作成サービス3選！

最初に気になる(1)機能(2)金額(3)利用人数について比較してみました。
まずはこちらをご覧ください。
![比較.001.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436544/1f5b1aea-5deb-a58c-5f10-f0760859e9a8.jpeg)

それではそれぞれのサービスの詳細を見ていきましょう。

## ①Live!アンケート
![スクリーンショット 2020-08-05 17.48.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436544/b6fe0542-a0a3-43fa-ec1d-25921e799c9c.png)

「Live!アンケート」はその名の通り、セミナーや講義などで参加者が登壇者への質問を簡単にスマホから出来る製品となります。

複数候補の中から投票し、その投票数に応じたパーセンテージをリアルタイムにグラフ化する「Live!投票」
あるテーマに沿った質問をタイムライン上にリアルタイム表示する「Live!Q&A」
の2種類のアンケートを使用することが出来ます。

UIが非常にシンプルで初めて使う方でもすぐに設定・利用できる仕様になっています。
サービスのローンチが2019年と他のサービスよりも遅れてされたため、機能の総量としては劣る部分もありますが、数ヶ月単位で機能リリースもしている様なので期待が持てるサービスです。

https://enquete.eventos.tokyo/

## ②Slido(スライドゥ)
![スクリーンショット 2020-08-05 17.49.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436544/24d9caa4-9ee0-5b5e-1e92-5dd481024d6a.png)

Slidoは会議や勉強会にインタラクティブにQ&Aや投票を行えるWebサービスです。 
IT系イベントでこのサービスを使って公演している人をよく見かけるのでこの手のサービスでは1番知名度が高いんじゃないでしょうか。

イベントを作成するとイベントコードが発行されるのでそれをブラウザから入力することで簡単に参加できますのでスマホからの利用も便利です。また、他のSlackやGoogleスライド連携など他連携機能も豊富です。

無料アカウントを発行して使ってみましたが、この手のサービスの先駆者なので必要な機能が充分に実装されている印象でした。また、投票結果を集計し、分析機能もついている様です。

https://www.sli.do/jp

## ③Respon(レスポン)
![スクリーンショット 2020-08-05 17.50.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/436544/1a6ffe48-b548-b3f4-cff5-f440b63a5336.png)

レスポンは主に教育機関での利用を想定し、サービスを展開しています。（もちろん企業向けのサービスも展開しています。）

授業や講義中に教員と生徒でのリアルタイムコミュニケーションを図る事に活用されており、独自でリリースしているアプリ単独でも利用することができる事や最近のアップデートでUIが大きく変わったのが特徴です。

学校向けということもあり画面のデザインやLPも可愛いデザインで幅広い年齢に受け入れられそうです。
そういった事で学生向けに利用する事が多い場合は良いサービスかもしれません。
https://respon.jp/

## まとめ
それぞれのサービスをご紹介させていただきましたが、アメリカではスタンダードとなっているこの分野ですが、日本国内では浸透していないと言った印象です。それだからこそ非常に楽しみで面白い分野だと思います。

スマホの普及率が人口の８５％を超え、ほとんどの国民が持つ今だからこそ大きく普及するサービスの１つではないでしょうか。

コロナ渦でオフラインのイベントが開催しにくい状況でも輝くサービスだと思います。
それぞれ無料版も用意されていますので、あなたも会社やプライベートでの利用を検討してみては如何でしょうか？
深層学習とかでのエラー『ImportError: DLL load failed: 指定されたモジュールが見つかりません。 』での「指定されたモジュール」を知る方法。

#目的

Pythonにおいて、

以下のエラーに出会うことはよくある。

```
ImportError: DLL load failed: 指定されたモジュールが見つかりません。
```

もう少し手前から示すと、以下のようなエラー。

```
ImportError: Traceback (most recent call last):
  File "C:\Users\XYZZZ\AppData\Local\Programs\Python\Python37\lib\site-packages\tensorflow\python\pywrap_tensorflow.py", line 64, in <module>
    from tensorflow.python._pywrap_tensorflow_internal import *
ImportError: DLL load failed: 指定されたモジュールが見つかりません。
```

**気分としては、**
指定されたモジュール
が何か、**具体的なファイル名**を知りたい場合がある。

#「指定されたモジュール」を知る方法
## Process Monitor をインストール

以下のサイトから取得できる。
https://docs.microsoft.com/ja-jp/sysinternals/downloads/procmon#introduction

##「指定されたモジュール」を知る

以下のような画面で、見つからないDLLがわかる。
(沢山の表示が出るので、適宜、フィルターをかけて下さい。python.exe等で。）
下記は、pygameで、「SDL.dll」というのを隠してみた例。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/342207/4dcac53e-4097-dcdc-46ee-fcca90cc9a07.png)

#まとめ
見つからないDLLのファイル名がわかっても、対処方法としては、pathが変になっているとか、インストールがうまくいってないとか、何か、具体的な対処方法をとる必要があるので、ファイル名がわかるだけでは解決にならないですが、全然、**原因がわからないときとかには、有効かも。。。**
**あちこちどこに探しにいっているか**とかも、わかるので、自分の認識と、実際の動きの違いがわかり、原因究明になるかも。（Windows等に詳しい方は、もっと、簡単に、調べられるのかも。。。）
コメントなどあれば、お願いします。:candy:
昔発売されていたCASIOのゲーム電卓のデジタルインベーダーをJavaScriptで作成

1980年にカシオ計算機が発売した初代[ゲーム電卓](https://ja.wikipedia.org/wiki/%E3%82%B2%E3%83%BC%E3%83%A0%E9%9B%BB%E5%8D%93)のデジタルインベーダーをJavaScriptで再現したものです。
2018年には[復刻版](https://casio.jp/dentaku/general/game/)も発売されて、ちょっと話題になっていました。

今回作成したものは[こちらからプレイできます](https://akebi.jp/gamecalc/)

スクリプト自体は数年前(2016年頃)に作成したものですが、リプレイ対応や難易度設定の追加など今回少し手直ししました。
作成した当時は表示する敵数字を決定するのに普通に`Math.random()`を使用していましたが、リプレイ機能を追加するにあたって同じ乱数列を出す必要があったので、今回`Xorshift`を使ってシード値を指定することで同じ乱数列を出せるようにしています。

~~~js:xorshift.js
class XorShift {
    constructor(seed = Math.random() * 0x7fffffff) {
        this.x = 123456789;
        this.y = 362436069;
        this.z = 521288629;
        this.w = seed;
    }

    next() {
        const t = this.x ^ (this.x << 11);
        this.x = this.y;
        this.y = this.z;
        this.z = this.w;
        this.w = (this.w ^ (this.w >>> 19)) ^ (t ^ (t >>> 8)); 
        return this.w;
    }

    random() {
        return (this.next() + 0x80000000) / 0x100000000;
    }

    rand(min, max) {
        if(min > max) [min, max] = [max, min];
        return min + Math.floor(this.random() * (1 + max - min));
    }
}

// example
console.log('SEED無指定');
const x0 = new XorShift(); // SEED無指定(Math.random()でSEED決定)
for(let i = 0; i < 10; ++i) console.log(x0.next());

console.log('SEED指定');
const x1 = new XorShift(12345678); // SEED指定
for(let i = 0; i < 10; ++i) console.log(x1.next());

// 速度と出現する値のばらつき具合確認
const arr = {};
console.time();
const x = new XorShift();
for(let i = 0; i < 1e7; ++i) {
    const r = x.rand(1, 10);
    if(arr[r] === undefined) arr[r] = 1;
    else ++arr[r];
}
console.log(arr);
console.timeEnd();
~~~

Xorshiftのおかげでリプレイについては概ね正確に再現できていますが、まだ稀になにかのタイミングでずれることがあるようで(ずれる原因は`Xorshift`とは無関係の部分です)、最後まで再現できていたらラッキー、程度に捉えてもらえると助かります。

最近のiOS、iPadOSでは、`touchstart`/`touchend`イベントの連打が最低でも0.5秒程度開けないと効かない(それより早い連打は無視される)不具合があったようでプレイに支障をきたしていたのですが、ともにバージョン13.6で元に戻ったようです。
ページネーションをAPIのレスポンスとして返す備忘録

# やり方
```php:適当なコントローラのメソッド内
/*
 * モデル化するならここをモデルメソッドにする
 * API URLに &page=* が付いていれば自動でページングされている
 */
$users = App\User::paginate(10);

//return response()->json($users, 200);
return $users; // これでいい
```


# データ部分だけ返したい
https://readouble.com/laravel/6.x/ja/pagination.html#converting-results-to-json
こんな構造になっているが、data部分だけ返したい場合。

```php:適当なコントローラのメソッド内
$users = App\User::paginate(15);
$users = $users->toArray();                   //一旦配列型に変換して
return response()->json($users['data'], 200); //data部分だけを返す
```
rails の assign_attributes で中間テーブルが保存されてしまう

- 入力フォームから値を受け取り、バリデーションを行ってから保存したい、みたいな時に一旦インスタンスの変数を更新するために `assign_attributes` を利用したら思わぬ結果になった
- rails の中間テーブルにおいては、`assign_attributes` 実行時にDBインサートが走り、コミットまでされてしまう
    - そのため、modelのバリデーションエラーで保存に失敗した際に、中間テーブルが保存されっぱなしの状態になってしまった
    - 以下のように理解していたが、これは正確ではなさそう
        - `update_attributes` はインスタンス変数の更新を行い、DBの更新まで行う
        - `assign_attributes` はインスタンス変数の更新を行うが、DBの更新は行わない
- つまり、`assign_attributes` してからバリデーションにかかったり、何らかの理由で保存されたくない時は明示的にロールバックするか、先にインサートしないという工夫が必要になる

# ユースケース
- 以下のようなユースケースを想定
    - `User` と `Group` が多対多で、中間テーブルのモデルとして `GroupUsers` が存在
    - `User` を保存する際に、同時に `GroupUsers` も保存したい
    - view から受け取ったパラメータをセットし保存を行うが、バリデーションエラーの時は保存せずエラーを返す

```groups.rb
class Group < ApplicationRecord
  has_many :group_users
  has_many :users, through: :group_users
end
```

```users.rb
class User < ApplicationRecord
  has_many :group_users
  has_many :groups, through: :group_users
  
  validates :name, presence: true
end
```

```group_users.rb
class GroupUsers < ApplicationRecord
  belongs_to :group
  belongs_to :user
end
```

- User に以下のフィールドが生えるが、そのフィールドに値をセットするとインサートが走ってしまう
    - groups
    - group_ids
    - group_users
    - group_user_ids

## 案1 transaction を張る
- `assign_attributes` から `save` までを transaction で囲んで、保存できない時はロールバックするようにする

```users_controller.rb
class UsersController < ApplicationController
  def update
    @user = Users.new

    begin
      ActiveRecord::Base.transaction do
        @user.assign_attributes(user_params)     #ここで一旦中間テーブルに保存されるが、save!でエラーならロールバックされる
        @user.save!
      end
      p "更新成功"
    rescue
      p "更新失敗"
    end
  end
end
```

## 案2 after_save を利用する
-  `after_save` は、データベースへの COMMIT の直前に実行される
    - つまり、model のバリデーションなどを実行後に、そのメソッドを呼び出してくれる
- 自動で生えるリレーション用のフィールドとは別の attribute 名で view からパラメータを送り、model のバリデーション後にそのパラメータの値を保存したい中間テーブルの attribute にセットして保存することで、バリデーション通過後に中間テーブルが保存されるようにする
    - `assign_attributes` 実行時にはリレーションを意味するフィールドには何もセットせず、`after_save` で実行するメソッドの中で、値をセットするようにする


```users.rb
class User < ApplicationRecord
  has_many :group_users
  has_many :groups, through: :group_users
  
  validates :name, presence: true
  
  after_save :save_group_user
  
  attr_accessor :g_ids
  
  # User のバリデーション実行後、コミットする直前に呼ばれる
  def save_group_user
    self.group_ids = @g_ids
  end
end
```
- model には `after_save` を定義し、実行するメソッドの中で中間テーブル用の `group_ids` をセットするようにしておく
- また view からきたパラメータをセットしておく用の attribute として `attr_accessor :g_ids` を定義しておく
- view からは `g_ids` のように適当なフィールド名でパラメータを送り、`after_save` のメソッドで `group_ids` にセットすることで中間テーブルを保存する

```users_controller.rb
class UsersController < ApplicationController
    def update
      @user = Users.new
      @user.assign_attributes(user_params)
      @user.save ? (redirect_to root_path notice: '更新成功') : (render :edit)
    end
end
```

- コントローラーでは普通に save を実行して保存すれば良い

# ちなみに
- 新規作成時など、User が id フィールドが nil の状態であれば、中間テーブル用のフィールドに値をセットしても自動でインサートが走ることはないので、あくまでも更新時に気をつければいいっぽい
CAELinux2020のリリースノートについて

原文はこちら
[New release: CAELinux 2020](https://www.caelinux.com/CMS3/index.php/articles/70-/61-caelinux-202020-released)

**詳細**

記述：Joël Cugnoni
カテゴリー：ニュース

![Screenshot_at_2020-08-11_220958.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201403/d264dabc-29c6-ab39-9e8b-704fe48f0647.png)

私たち全員が経験しているかなり複雑な時代にもかかわらず、私は新しいCAELinuxバージョンがダウンロードできると発表できて満足です。
CAELinux 2020はXubuntu 18.04をベースにしており、いつものように応力解析、熱や流体の流れのシミュレーションやその他の物理学のための多くのオープンソースのシミュレーションツールを提供するようにカスタマイズされていますが、数学的なモデリング、グラフィック、デザイン、CAD / CAM、プロトタイピングソフトウェアの全範囲が含まれており、純粋にオープンソースのツールを使用してFablabやMakerSpaceを実行するための理想的なソフトウェアとなっています。

CAELinux 2018は、主にインストーラーとLiveDVDの作成やブートに関する問題が多くありました。
原因は、ほとんどのブートコードでは適切に処理できないISOイメージのサイズが大きいことに関係していました。
また、多くのソフトウェアを搭載しているため、ISOイメージでは通常4GBの制約があるにもかかわらず、完全なCAEワークステーションを提案し続けるための解決策を見つけなければなりませんでした。
現在、4Gbの壁を越えても、有効なISOイメージを生成する方法を見つけました。
しかし、これはまた、今のCAELinuxはUSBフラッシュディスクからしか起動できなくなることを意味します。
4Gb以上のISOを起動することは簡単なことではありませんので、SourceforgeのリリースページにあるGetting Startedガイドの指示を読んでください。

## ダウンロード用：[caelinux.sourceforge.net](https://sourceforge.net/projects/caelinux/)

## 機能

* Xubuntu18.04LTS64ビット版をベースとしたLiveDVDディストリビューションとXFCE軽量デスクトップ
* USBフラッシュドライブ用のインストール可能なISOイメージとして利用可能；
* インストールなしでUSBキーから直接実行
* 最高のパフォーマンスを得るために：シンプルなUbuntuのインストーラーを使用してハードディスクへのインストールを行う必要があります
* オープンソースエンジニアリング開発のための完全なプラットフォームを提供：コンピューター支援設計・製造（CAD/CAM）とシミュレーション（CAE、FEA/CFD）、エレクトロニクス設計、科学的コンピューティング、プログラミング、数学的モデリング
* CAD/CAMと3Dプリント：Salome, Freecad, OpenSCAD, LibreCad, Pycam, Camotics, dxf2gcode & Cura
* FEA、CFD、マルチフィジックスシミュレーション：Salome-Meca 2019 / Code-Aster、SalomeCFD/Code-Saturne、HelyxOs/OpenFOAM v7、Elmer FEM、ランチャー＆CAE GUI付きCalculix
* メッシュ生成、プリポスト、可視化：Salome、Paraview、Helyx-OS、Elmer GUI、VoxelMesher
* 電子設計とプロトタイピング：KiCad、Arduino、Flatcam、PCB絶縁フライスのためのdxf2gcode / cadpy
* 科学・開発ツール:Python 3、Spyder、GNU Octave、R、wxMaxima、OpenModelica、Qt Creator、gcc、gfortran、java、g ++、perl、tcl / tk
[SQL]DELETE文でデータを削除

#DELETE文でデータを削除
テーブルのデータを削除するときはDELETE文を使います。

```
DELETE FROM テーブル名 WHERE 条件文;
```

SELECT文でuserテーブルのデータを確認。

```
mysql> select * from user;
+------+---------------+----------------------------------------------------+
| id   | name          | prefecture | address       　                    　 |                             
+------+---------------+----------------------------------------------------+
|    1 | テスト　　    　 | 東京都      | 東京都千代田区丸の内１丁目                 |                             
|    2 | テスト1         | 滋賀県      | 滋賀県彦根市金剛寺町2-16ザ金剛寺町313      |                            
|    3 | テスト2         | 大阪府      | 東京都練馬区豊玉南4-11                   |
|    4 | テスト3         | 北海道      | 北海道千歳市千代田町2-3千代田町シティ102　　 |                          
|    5 | テスト4         | 東京都      | 東京都小平市回田町2-12-17フォレスト回田町202 |                           
+------+---------------+---------------------------+------------------------+
```

データを削除していきます。
「id > 3」とすると、idが3より大きいデータが対象になります。

```
mysql> DELETE FROM meibo WHERE id > 3;
Query OK, 2 rows affected (0.19 sec)
```

データが削除されているか確認します。

```
mysql> select * from user;
+------+---------------+----------------------------------------------------+
| id   | name          | prefecture | address       　                    　 |                             
+------+---------------+----------------------------------------------------+
|    1 | テスト　　    　 | 東京都      | 東京都千代田区丸の内１丁目                 |                             
|    2 | テスト1         | 滋賀県      | 滋賀県彦根市金剛寺町2-16ザ金剛寺町313      |                            
|    3 | テスト2         | 大阪府      | 東京都練馬区豊玉南4-11                   |                          
+------+---------------+---------------------------+------------------------+
```
Vision API(トレーニング済み機械学習モデル)を使ってRubyでテキスト抽出(OCR)をためしてみた

# Vision APIとは？ 
Google Cloud の Vision API は REST API や RPC API を介して強力な事前トレーニング済み機械学習モデルを提供します。画像にラベルを割り当てることで、事前定義済みの数百万のカテゴリに画像を高速に分類できます。オブジェクトや顔を検出し、印刷テキストや手書き入力を読み取り、有用なメタデータを画像カタログに作成します。
([公式ドキュメント](https://cloud.google.com/vision?hl=ja)より引用)

# 分析にかけた画像
[アサインナビ トップページ](https://assign-navi.jp/)のキャプチャ画像（PNG形式） 

|![anavi.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/363962/84db9d19-814d-2a4c-1a5c-339869bb58c4.png)|
|:--|

# 分析結果
```
$ bundle exec rake cloud_vision:text['app/assets/images/anavi.png']
assign navi
新しい働き方
案件/人材を探す
ご利用ガイド
サービスについて
ログイン
会員登録
IT案件、外部人材との出会いを
テクノロジーで効率化
00
```
かなり高精度で、テキスト抽出できていますね (^^)

# 今回作成したコード

```ruby:lib/tasks/cloud_vision.rake
## 呼び出し方
## $ bundle exec rake cloud_vision:text[image_file] # image_fileに'ここに画像ファイルのパス'

# Google Cloud client libraryの読み込み
require "google/cloud/vision"

namespace :cloud_vision do
  desc 'Run OCR.'
  task :text, [:image_file] do |task, args|
    return unless args[:image_file]

    # クライアントをインスタンス化
    image_annotator = Google::Cloud::Vision.image_annotator

    # OCRの実行
    response = image_annotator.text_detection(
      image: args[:image_file],
      max_results: 1 # optional, defaults to 10
    )

    # OCR結果の表示 
    response.responses.each do |res|
      res.text_annotations.each do |text|
        puts text.description
      end
    end
  end
end
```

環境変数はdotenvに記載

```
#.envファイル
GOOGLE_CLOUD_PROJECT="ここにプロジェクトIDを記載"
GOOGLE_APPLICATION_CREDENTIALS="Vision APIにアクセスする認証キーjsonファイルへのパスを記載"
```
# セットアップ手順
セットアップ手順は近日中に追記させて頂きます

# 参考文献
[Using the Vision API with Ruby](https://codelabs.developers.google.com/codelabs/cloud-vision-api-ruby/index.html?index=..%2F..cloudai&hl=ja#0)

フォローや記事へのLGTMは、日々の投稿の励みになります。
温かい１クリックのほど、よろしくお願いします。 m(_ _)m
bash testコマンドと変数の展開

# testコマンド、知ってますか
シェルスクリプトで重要な役割を果たすのがtestコマンドです。

```bash:sample1.sh
if [ $# -eq 1 ]; then
  echo 'an argument is set'
fi
```

といった感じで使います。
え？どこに`test`が使われているんだって？
`[]`が`test`コマンドのシンタックスシュガーです。
`[`の直後、`]`の直前には必ず半角スペースを入れましょう（初心者がハマりがちな罠）

# オプション色々
`test`コマンドには様々なオプションがあります。

* 引数をオプションの前後に取るもの
 * `-eq`, `-ne`, `-gt`, `-ge`, `-lt`, `-le`: 数値比較（等しい、等しくない、大きい、以上、小さい、以下）
 * `=`, `!=`: 文字列比較(等しい、等しくない)
* 引数をオプションの後ろにのみ取るもの
 * `-n`, `-z`: 文字列長(0ではない、0である)
 * `-e`, `-f`, `-d`など: ファイル確認(存在する, 通常ファイルである, ディレクトリである)
 * `-v`: 変数が定義されている

```bash:sample2.sh
hoge='sample2.sh'
if [ $hoge = 'sample2.sh' ]; then
  echo "I am $hoge" # I am sample2.shと出力
end
if [ -e $hoge ]; then
  echo "$hoge exists!" # sample2.sh exists! と出力
end
```

# 変数の展開
さて、シェルには変数の展開という機能があります。
さきほどのsample2.shの中で、`echo "I am $hoge"`という命令で `I am sample2.sh`と出力していた機能です。

この機能、意識しないとハマります

```bash:sample3.sh
if [ $# -eq 1 ]; then
  $arg1 = 'yobaretayo'
fi
if [ -v $arg1 ]; then
  bundle exec ruby hoge.rb --opt $arg1
else
  bundle exec ruby hoge.rb
fi
```
```ruby:hoge.rb
#require 'optimist'

class Hoge
  def initialize
    @options = Optimist::options do
      opt :opt, 'Option', type: :string, required: false
    end
  end
  def run
    echo @options[:opt] if @options[:opt]
  end
end
```
というシェルプログラムを書きました。
hoge.rbは --optというオプションを受け取るか、引数なしで呼び出されます。
ところが、
`$ ./sample3.sh`
というコマンドを実行すると、
`Error: option '--opt' needs a parameter.`
というエラーになってしまうのです。

$arg1はsample3.shの引数がない場合には未定義なので、
`if [ -v $arg1 ];` はfalse(!=0)となり、`bundle exec ruby hoge.rb`が呼ばれるはずです。
はて・・・？

正解は
`if [ -v arg1 ];` でした。

違いがわかりますか？

`if [ -v $arg1 ];`は変数の展開が行われて `if [ -v  ];`と解釈されてしまい、true(=0)で扱われるのです。

シェルスクリプトでtestコマンドを利用する際は変数の展開を意識しないとハマるよ、というお話でした。

おわり
client_loop: send disconnect: Broken pipeの解決方法

###エラー内容
AWSでEC2にターミナルでログインしたまま、
webページを１０分くらい見ていると.....
こんなエラーが出てしまった...

````
[ec2-user@~]$ client_loop: send disconnect: Broken pipe
````
しかもちょっとだけフリーズする！！ｳｻﾞ━━━━(´Д｀)━━━━

別にこんなエラー直さなくてもいいがマジでうっとしいので
エラーを直しました( ｰ̀ωｰ́ )


###解決方法
ターミナルでssh接続する場合
ある程度の間、放置しているとタイムアウトにより、sshが切断される仕組みになっているみたい...
ホスト側とクライアント側でsshの設定を変更する必要があるらしい

````
*ホスト側
username@mbp ~ %vi /Users/{PCの名前}/.ssh/config
＊クライアント側
[root@ip-10-0-10-10 ] vi /etc/ssh/ssh_config

*vim画面（どちら側でも同じ）
Host github.com
  IdentityFile ~/.ssh/github
  User git

Host vagrant
  HostName vagrant

＊ここから下を追加する
Host *
ServerAliveInterval 60
TCPKeepAlive yes
````

用語説明
Host *
＊全てのホストを指定
ServerAliveInterval 60
＊TCPKeepAliveを送信する間隔を60秒に設定
TCPKeepAlive yes
＊接続を維持するかどうか



###最後に
これで解決できたと思います
いやーWindowsのTera termだったらこんな設定いらないのに....
まぁこれでうっとしいエラーとはおさらばです！
お疲れ様でした(´･ω･`)ﾉｵﾂ㌍♪
AngularでブラウザURLを扱う

## Location
Angularにはアプリ側からブラウザのURL情報をやりとりできる[Location](https://angular.jp/api/common/Location)というサービスが予め用意されています。

## 使用例：前ページに戻る
ボタンをクリックするとブラウザ履歴の前ページに戻る実装をします。

```some.component.ts
import { Location } from '@angular/common';

export class SomeComponent {
  constructor(
    private location: Location,
  ) { }

  cancel() {
    this.location.back();
  }
}
```

```some.component.html
<button (click)="cancel()">
  キャンセル
</button>
```

## 使用例：現在のルートパスを取得する
```some.component.ts
path: string;

this.path = this.location.path();
```

## 使用例：履歴を変えずにブラウザのURLを置き換え
こちらがわかりやすいです。
[Angularで履歴を変えずにブラウザのURLを置き換える](https://qiita.com/maechabin/items/7eefe7663a738578e86b)

## 参考
- [Angular 日本語ドキュメンテーション - Location](https://angular.jp/api/common/Location)
- [Angular 日本語ドキュメンテーション - ルーティングを使ったアプリ内ナビゲーションの追加](https://angular.jp/tutorial/toh-pt5#%E6%88%BB%E3%82%8B%E6%96%B9%E6%B3%95%E3%82%92%E6%8E%A2%E3%81%99)
【AWS】【Lambda】 外部モジュールを読み込めるようにする方法

- 普通にLambdaをアップロードしただけではAWSにデフォルトでインストールされているライブラリ（AWS SDKとか）以外は使用できないみたい
    - ```Cannot find module```と言われてしまいます
- 言語はNode.js
- AWS CDKを使っている

## 方法① LambdaのZipファイルに外部モジュールを含める
- AWSコンソールを使えば、LambdaファイルをZip圧縮したものをアップロードすることができるため、このZip内にnode_moduleディレクトリを含めて外部モジュールごとアップロードしてしまえば良いです
- ただし、AWS CDKを使用してアップロードする場合、この方法は使えません(/_;)

## 方法② 外部モジュールのZipファイルをLambda Layersへ登録する
- node_modulesディレクトリをZip圧縮して、AWSコンソールからLambda Layersにアップロードすれば良いです
- ただし、せっかくLambdaのアップロードをAWS CDKで自動化しているのに、別の手作業が発生してしまうのは悲しいです

## 方法③ AWS CDKを使ってLambda Layersに登録する
- これがやりたい

### やり方
- CDKプロジェクトフォルダ内に「layer」というフォルダを作成します
- 「layer」フォルダ内に「nodejs」というフォルダを作成します
- 「nodejs」フォルダ内で```npm init```を行い、必要なライブラリをインストールします
- stackファイルに以下を追加します

```typescript
const nodeModulesLayer = new lambda.LayerVersion(this, 'NodeModulesLayer', {
  code: lambda.AssetCode.fromAsset('layer'),
  compatibleRuntimes: [lambda.Runtime.NODEJS_10_X, lambda.Runtime.NODEJS_12_X]
});
```

- lambda呼び出しのコードにも一行追加します

```typescript
const myFunction = new lambda.Function(this, 'MyHandler', {
  functionName: 'SalesforceSample',
  runtime: lambda.Runtime.NODEJS_12_X,
  code: lambda.Code.fromAsset('lambda'),
  handler: 'salesforceSample.handler',
  layers: [nodeModulesLayer] // これ
});
```

### 問題点
- これだとコード作成時のnode_modulesと、アップロードされるnode_modulesを別々に管理する必要があるのがナンセンス
- node_modulesをnodejsフォルダ以下に自動的にコピーするような処理があると完璧なのかなあ・・・
[SQL]UPDATE文でデータを更新

#UPDATE文でデータを更新
すでに挿入済みのデータを更新するときは、UPDATE文を使います。

```
UPDATE テーブル名 SET カラム名1 = 値1, カラム名2 = 値2 WHERE 条件文; 
```

現在のテーブルデータは以下です。

```
mysql> select * from user;
+------+---------------+----------------------------------------------------+
| id   | name          | prefecture | address       　                    　 |                             
+------+---------------+----------------------------------------------------+
|    1 | テスト　　    　 | 東京都      | 東京都千代田区丸の内１丁目                 |                             
|    2 | テスト1         | 滋賀県      | 滋賀県彦根市金剛寺町2-16ザ金剛寺町313      |                            
|    3 | テスト2         | 東京都      | 東京都練馬区豊玉南4-11                   |
|    4 | テスト3         | 北海道      | 北海道千歳市千代田町2-3千代田町シティ102　　 |                          
|    5 | テスト4         | 東京都      | 東京都小平市回田町2-12-17フォレスト回田町202 |                           
+------+---------------+---------------------------+------------------------+
```

上記テーブルの「id=2」の「prefecture」を変更してみます。

```
mysql> UPDATE user SET prefecture = 大阪府 WHERE id = 2;
Query OK, 1 row affected (0.17 sec)
Rows matched: 1  Changed: 1  Warnings: 0
```

更新できているか確認してみます。

```
mysql> select * from user;
+------+---------------+----------------------------------------------------+
| id   | name          | prefecture | address       　                    　 |                             
+------+---------------+----------------------------------------------------+
|    1 | テスト　　    　 | 東京都      | 東京都千代田区丸の内１丁目                 |                             
|    2 | テスト1         | 滋賀県      | 滋賀県彦根市金剛寺町2-16ザ金剛寺町313      |                            
|    3 | テスト2         | 大阪府      | 東京都練馬区豊玉南4-11                   |
|    4 | テスト3         | 北海道      | 北海道千歳市千代田町2-3千代田町シティ102　　 |                          
|    5 | テスト4         | 東京都      | 東京都小平市回田町2-12-17フォレスト回田町202 |                           
+------+---------------+---------------------------+------------------------+
```
RHELのサブスクリプション設定

`CentOS` と違って `RHEL`(Red Hat Enterprise Linux)を使用する場合は、「サブスクリプション」の設定をする必要があります。

「サブスクリプション」の設定をする事で、`Red Hat` の公式のレポジトリからモジュールをダウンロードする事ができるようになります。

`RHEL`では「サブスクリプション」の設定をしなければ、`yum` 等のコマンドを使って追加のコンポーネントを導入する事も、アップデートをする事もできません。

# サブスクリプションの設定

### はじめに
この「サブスクリプション」の設定は、コマンドと GUI の両方からできますが、エラーが起きた時に GUIでは何が起きたかよくわからない事があるため、基本、コマンドラインでの登録をおすすめします。

### 準備
正式に `RHEL`を購入している場合、`Red Hat` の [Customer Portal](https://access.redhat.com/) の User ID/Password を持っているはずです。ます、Customer Portal の UseID/Password を手元に準備します。

### 登録

```
# サブスクリプションの登録。以下を入力すると Customer Portal の UserID /Password が聞かれます。
$ subscription-manager register

# システムを 1 つ以上の最適なサブスクリプションに自動的にアタッチする。
$ subscription-manager attach --auto
```

これだけで終了です。

ちょっと長いのですが、[こちら](https://access.redhat.com/ja/articles/3221791)に公式のKBがありました。
私が書いている方法以外にも GUIからやる方法も書かれています。


# うまく行かない場合

私の場合は、Subscription の登録が途中で HTTP 503 のエラーを受け取って失敗する事が何度かありました。
HTTP 503 なので一時的なサーバーの障害かと思ったのですが、いろいろ試していた所、下のコマンドで上手くサブスクリプションの設定する事ができました。

```
# サブスクリプション証明書(※1)のレフレッシュ
$ subscription-manager refresh

# システムを 1 つ以上の最適なサブスクリプションに自動的にアタッチする(もう一回）
$ subscription-manager attach --auto
```
※1) サブスクリプション証明書：利用可能な製品名やサブスクリプションの開始日と終了日等が記載された証明書。

# サブスクリプションの登録が完了すると…

[Customer Portal](https://cloud.redhat.com) から、以下のようにサブスクリプションの登録が完了している RHELサーバーの数が見られるようになりました。

すぐには以下の User Interface には反映される、[こちらのマニュアルの記述](https://access.redhat.com/documentation/en-us/subscription_central/2021/html/getting_started_with_the_subscriptions_service/con-how-does-subscriptionwatch-show-data_assembly-viewing-understanding-subscriptionwatch-data-ctxt/) によると24時間に一回データがアップデートされているそうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99425/fea792f2-ea6b-1fd8-5ddb-3b686cf31c98.png)

上記のキャプチャーの例だと、4台のRHELサーバーが登録されている事がわかります。
Open Policy Agentについて

### 概要
- オープンソースの汎用的なポリシーエンジン
- 略してOPAとも
- サイドカー([こちらを参照](https://qiita.com/mach555/items/f4c693967402735709c6#%E3%82%B5%E3%82%A4%E3%83%89%E3%82%AB%E3%83%BC%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3))、デーモン、ライブラリなどとして用意しアプリケーションからはAPIを介して呼び出す形式で利用する
- アプリケーションからはAPIを介してOPAに問い合わせる形にすることで、ポリシー制御を個々のアプリケーションから分離し統一的に管理することを実現する
- ポリシーをコードとして管理することを可能にする（Policy as Code）
 - 記述例  
aliceはbobの、charlieはdavidの上位権限であることを以下のように表せる

~~~json
{
  "alice": ["bob"],
  "bob": [],
  "charlie": ["david"],
  "david": []
}
~~~

### ユースケース
 - マイクロサービスでのサービス間の認可
 - KubernetesのAdmission Controlを使ったリソースのバリデーション
 - Terraformの設定ファイルのバリデーション

## 参考リンク
[注目のOpen Policy Agent、その概要とKubernetesでの活用事例](https://thinkit.co.jp/article/17511)
プロ野球選手のリアルタイム成績を返すLINE botを作った(LINE bot+heroku)

# 概要

**現役プロ野球931名（2020/8/14現在）のプロフィール&今年度成績を教えてくれるLINE bot**を作ったという話。

# 経緯

自分はプロ野球が好きです。

野球を見てると、自分や相手チームの選手の成績や出身高校が知りたくなる時がありました。
ただ、**気になった選手の情報を欲しいときにすぐに入手するのは意外に難しい**です。

* 選手名鑑の本だと、前年度成績しか載ってない…
* 速報アプリだと、調べたい選手の情報にたどり着くのに時間がかかったり、欲しい情報に対して情報過多だったりする…
* チームと背番号しかわからない選手だと、調べること自体が難しい…

そんな中、1年ほど前に[Bリーグの選手情報を返すLINE Botを作った](https://kta-basket.hatenablog.com/entry/2019/02/08/005551)　の記事を拝見しました。

* 普段から使っている**LINEが選手名鑑になる！　本を取り出さなくてもいい！**
* 出てくる情報がシンプルで、**欲しい情報が一目瞭然！**
* **選手名が分からなくても、チーム名と背番号だけで調べられる！**（これが一番うれしいかも）

こんなツールがプロ野球にもあったらいいな　と思ったのが開発経緯です！

# プロ野球選手名鑑bot

色々試行錯誤して、こんなのできました！

![image](https://user-images.githubusercontent.com/61776220/90086377-4488dc00-dd55-11ea-8f20-7f7d08a77150.gif)

使ってみたい方はこちらからご自由にどうぞ！
<a href="https://lin.ee/CqYJbKN"><img src="https://scdn.line-apps.com/n/line_add_friends/btn/ja.png" alt="友だち追加" height="36" border="0"></a>
※ちなみに、botが誰と友達かとかは自分からは一切分からないので安心してご利用ください。

## 機能


以下がシステム構成図です。

![npbmeikan](https://user-images.githubusercontent.com/61776220/90129304-5c874c80-dda3-11ea-8f72-c9756ffb93bc.png)

ざっくりいうと、以下の動作です。

1. NPBウェブサイトから1日1回、現役プロ野球全選手データを取得してDBに格納
2. LINE-botからWebhookリクエストがあったら、DBから選手データを引っ張ってLINEに表示

コードや機能詳細は、[Github (suibari/NPBmeikan_bot)](https://github.com/suibari/NPBmeikan_bot)　を参照ください！

# ふりかえり
## Keep

* Promiseクラスを使った同期処理にTryできた
* SQLを基本情報で勉強して以来使えた。手を動かすことでSQLインジェクションの攻撃原理と対策方法が理解できた
* heroku postgresで人生初のDB構築できた
* heroku schedulerを初めて使ってcronっぽいことができた
* LINE flex-messageを使って、LINE上の見た目を工夫できた
* 既存の異体字検索アルゴリズムを組み込めた

## Problem

* 機能分割的に綺麗じゃない
* コードが汚い。Don't repeat yourself の原則を守りたい。例えば、request→cheerio→Xする の処理は何度も出てきてるので、Xを引数でコールバック関数にするとか
* 野球に詳しくないと、数字を見ただけではどういう選手かは分からない。誰にでもわかりやすい情報を提供することはできていない

## Try

* 機能分割
* リファクタリング。同じ処理を関数化・クラス化してまとめる
* どういうタイプの選手なのか、成績から評価コメントを生成する？ ランダムに生成できたらすごい楽しそう

# まとめ

**LINE bot楽しい！**
特にflex messageで見せ方を変えられるのは楽しいです。今後も色々なbotに応用できるかも。

もしご意見ご質問、ここが詳しく知りたいなどありましたらぜひコメントください。
【abc174-E】二分探索実装時のインデックス問題

※注意
いつも通り，この記事は主に自分の脳内整理および次回以降自分が使いやすいように書いているので，決して読みやすいものではないと思います．特に今日は1時間後に飲み会が控えていて，爆速一発書きのためおそらくこの傾向が顕著です．ご了承ください．


#コンセプト
C++には`lower_bound`や`upper_bound`といった魔法のような二分探索の関数があるが，これは事前にソートされた配列やvectorに対して作用させることしかできないという欠点がある．

たとえば，1以上N以下の自然数入力に対して，(特に広義)単調増加(減少)となるような関数 $f(n)$ があるとする．このとき，「この関数の出力がある値以上(以下)となるような，最小の入力値を求めよ」という問題を解きたいシーンは多い．もし全ての入力に対する関数の出力を格納した配列のようなものがあれば，それは`lower_bound`が突き刺さって見事に解決である．しかしそれがない場合，この魔法で二分探索を行うことはできない．N回関数を起動して`lower_bound`用の配列を作る，というのは明らかにナンセンスで，そもそもそんな暇があったらその過程で所望の答えが見つかっているはずである．(この配列を用意した上で，このあと多数のクエリに回答する，という状況ならこの限りではない)．

こういうときは自分で二分探索のアルゴリズムを実装してそこに関数 $f(n)$ を組み込めばいいわけだが，私はにぶたんするときいつもインデックスの細かいところが不安になって仕方がないので，ここで雛形を整理していざという時に取り出せるようにしておく．


#background
これについて整理したきっかけは，[abc-174-E(Log).Difficulty: 1158](https://atcoder.jp/contests/abc174/tasks/abc174_e)．
答えについて二分探索とかいう個人的にめちゃくちゃ反直感的な解法をギリギリまで出せなかった挙句，このインデックス問題にハマって時間内に通せなかったという苦い思い出．


#結論
コードが全てを語ってくれることを期待してもう載せちゃいます．

```abc174/e4.cpp
  int left = 1;
  int right = 1000000000;

  while(left<right) {
    int mid = (left+right)/2;
    if(f(mid) < k) {
      left = mid+1;
    }
    else if(f(mid) >= k) {
      right = mid;
    }
  }

  cout<<left<<endl;
```

ネット漁るといろんなバージョンが出てくるけど，個人的にはこれかなあ．関数 $f(n)$ は入力として1〜10^9 を許し，広義単調増加であるという想定(さっきのE問題は単調減少なんだけどね)．まあこれはあくまで雛形として．適当に言いたいことを箇条書きにしておくと

- whileループの終了条件は「leftとrightの一致」に等しい．
- `left = mid+1;` と `right = mid;` ．ここがメインコンテンツだと言ってもいい．こうすると，所望の値に等しい(けどインデックスは最小じゃない)位置にmidが来たとき，きちんと探索箇所は左にスライドする．leftくんは確実に正解の位置に近づいていき，leftとrightが1差のまま固まることもない(次の瞬間mid=leftとなり，このターンの値の更新で見事にleft==rightとなる)．
- あのE問題みたいにfが単調減少のときは，if，else ifの分岐の条件内の不等号の向きを入れ替えればよい．=は動かさなくていいよ．

こんな感じかなあ．どこまでいっても飲み会前なので，もう少し頭回して自分への信頼度を上げておく必要はあるけど．とりあえず現状これで不具合は確認されておりません．


#ACコード
まあ貼らない理由もないので．abc174-EのACコードです．こうしてみると短いね．

```abc174/e4.cpp
#include <bits/stdc++.h>
using namespace std;

int cut_times(int* logs, int n, int min_length) {
  int ans = 0;
  for(int i=0; i<n; i++) {
    ans += (logs[i]-1)/min_length;
  }

  return ans;
}

int main() {
  int n,k;
  cin>>n>>k;
  int a[n];
  for(int i=0; i<n; i++) cin>>a[i];

  int left = 1;
  int right = 1000000000;

  while(left<right) {
    int mid = (left+right)/2;
    if(cut_times(a,n,mid) > k) {
      left = mid+1;
    }
    else if(cut_times(a,n,mid) <= k) {
      right = mid;
    }
  }

  cout<<left<<endl;

  return 0;
}
```


#おしまい
なんとか集合に間に合いそうでよかった．自分の理解はきちんと深まったので，今後もネットの海にこんな無責任な記事を投げるかもしれません．すみません．
Flutter で Cloud Database を利用時、ビルドエラー「D8: Cannot fit requested classes in a single dex file」が出て先に進めない

## 背景

- Flutter で FireStore の Cloud Database を利用したモバイルアプリを開発中に当事象に遭遇。

- Firestore を利用するために、cloud_firestore プラグインを `pubspec.yaml` でインストール後、ビルドするとエラーが表示され、先に進めなくなってしまいました。

```log
D8: Cannot fit requested classes in a single dex file (# methods: 83479 > 65536)
com.android.builder.dexing.DexArchiveMergerException: Error while merging dex archives:
The number of method references in a .dex file cannot exceed 64K.
```

## 原因

どうやら 64K 問題と呼ばれるものらしく、Android 界隈では有名な問題らしいですね。。。

Android アプリに関しては、ビルドシステムの都合で参照できるメソッド数が 65536 個を超えるとビルドができなくなる制約のことを指すようです。

DEX ファイルというものは Android で実行可能なメソッド群ファイルで、本エラーログではその DEX ファイルには 83479 個（ > 65536 個）のメソッドがあるといわれていました。

## 解決方法

解決方法は簡単で、Android アプリで 65536 個を超えるメソッド数でも DEX ファイルを参照できるように設定を変更すれば良いそうです。

具体的には、`multiDexEnabled true` を以下に追加すれば OK です。

```android/app/build.gradle
android {
    :
    defaultConfig {
        applicationId "com.example.xxxxxxxx"
        :
        multiDexEnabled true // これを追加
    }
    :
}
```
MySQLで複数のDBをまたいで使用する

#概要
サービスが大きくなったりしてDBが増えたときに、複数のDBをまたいで使用する場合の書き方です。

#環境
PHP 5.3.29
FuelPHP 1.7.3
MySQL 5.5.61

#本題
##方法１
まず、FuelPHPの`fuel/app/config`以下にある`db.php`に設定を書きます。書くファイルはそれぞれの環境に応じたものにします。（開発環境であれば`development/db.php`）
ここに複数の設定を書けばクエリを発行する際に各DBを指定して使用できます。

```db.php
<?php
return array{
  'db01' => array(
    'type'        => 'pdo',
    'connection'  => array(
      'dsn'        => 'mysql:host=localhost;dbname=db01',
      'username'   => '',
      'password'   => '',
    ),
  ),
  'db02' => array(
    'type'        => 'pdo',
    'connection'  => array(
      'dsn'        => 'mysql:host=localhost;dbname=db02',
      'username'   => '',
      'password'   => '',
    ),
  ),
  'db03' => array(
    'type'        => 'pdo',
    'connection'  => array(
      'dsn'        => 'mysql:host=localhost;dbname=db03',
      'username'   => '',
      'password'   => '',
    ),
  ),
);
?>
```
各パラメータは各々の環境に合わせます。

次に、モデルにクエリを発行する文を書きます。

```examplemodel.php
<?php
namespace Example;
class Model_Examplemodel extends \Model
{
  public static function get_example()
  {
    $get = \DB::select()
    ->from('tablename')
    ->execute('db01')
    return $get;
  }
}
?>
```
このように`execute()`の引数にdb.phpで定義した文字を入れればそのDBを参照してくれます。
##方法２
セレクトするテーブルの情報にDB名を加える形でも可能です。

```examplemodel.php
<?php
namespace Example;
class Model_Examplemodel extends \Model
{
  public static function get_example()
  {
    $get = \DB::select()
    ->from('db01.tablename')
    ->execute()
    return $get;
  }
}
?>
```

##joinする場合
joinする場合は、方法１をとるとすべてそのDBにあるテーブルが参照されます。
ですので、db01・db02それぞれからテーブルを参照する必要がある場合は方法２、もしくは両方を合わせて使う必要があります。

```examplemodel.php
<?php
namespace Example;
class Model_Examplemodel extends \Model
{
  public static function get_example()
  {
    $get = \DB::select()
    ->from('db01.table01')
    ->join('db02.table02')
    ->on('table01.column01', '=', 'table02.column01')
    ->execute()
    return $get;
  }
}
?>
```
カラム名が被っている場合はその点にも注意します。
#終わりに
FuelPHPを書いていて、発行されたクエリが簡単にわかる方法はないかなーと思って探しています。知っている方いましたらコメントいただけるとすごく助かります。
フォームの入力欄を動的に追加する

##はじめに
独学でプログラミングを学習中の大学3年生です。
今回が初投稿になります。

フォームの値を配列で受け取るときに入力欄を動的に追加したいことがあったので、
調べてまとめてみました。
初学者にも分かりやすいように、できるだけ簡潔なコードになるよう心がけています。


CodePen
---
以下のページで動作を確認できます。
コードも見やすいかもしれません。
https://codepen.io/yuji-207/pen/OJNMYgv


コード
---
```form.html
<form action="" method="">
    <input type="text" name="text[]" class="text"></input>
    <button type="button" class="btn-clone">clone</button>
    <button type="button" class="btn-remove">remove</button>
    <button type="submit"></button>
</form>
```

バックエンドで配列textとしてデータを受け取れます。

```stylesheet.css
input, button {
    display: block;
}

.btn-remove {
    display: none;
}
```

入力欄の削除ボタンはデフォルトで非表示にしておきます。

```script.js
$(function() {

    // button
    var btn_clone = $('.btn-clone');  // 追加ボタン
    var btn_remove = $('.btn-remove');  // 削除ボタン

    // clone
    btn_clone.click(function() {
    
        var text = $('.text').last();  // 最後尾にあるinput

        text
          .clone()  // クローン
          .val('')  // valueもクローンされるので削除する
          .insertAfter(text);  // inputを最後尾に追加
    
        if ($('.text').length >= 2) {
            $(btn_remove).show();  // inputが2つ以上あるときに削除ボタンを表示
        }

    });

    // remove
    btn_remove.click(function() {
  
        $('.text').last().remove();

        if ($('.text').length < 2) {
            btn_remove.hide();  // inputが2つ未満のときに削除ボタンを非表示
        }
    
    });
});
```

入力欄が2つ以上あるときだけ、削除ボタンを表示させます。


ハマったこと
---
初歩の初歩で少しだけハマりました。
ここでハマる人はあまりいないと思いますが、一応…

```script.js
var len = $('.text').length
```

このような入力欄の数を数える変数を1行目とかで宣言してしまうと、
（当たり前ですが）入力欄を増やしたとしても、lenは増えません。


参考
---
参考にさせていただきました。ありがとうございます。
https://qiita.com/SiskAra/items/5f4bc7ee4e598b863add
Invalid route name, already in use: 'new_user_session'のエラー解決方法

## 環境
Mac OS Catalina
Ruby 2.7.1
Rails 6.0.3.2

## 現象
ログイン機能用にdeviseを導入しrouteを設定。
その後、Rails routesを実行すると下記のエラーが出た。

``` 
Invalid route name, already in use: 'new_user_session'  (ArgumentError)
You may have defined two routes with the same name using the `:as` option, or you may be overriding a route already defined by a resource with the same naming. For the latter, you can restrict the routes created with `resources` as explained here: 
https://guides.rubyonrails.org/routing.html#restricting-the-routes-created
```

どうやら、'new_user_session'という名前のルートが既に使われているぞ！と言ってる様子。

現象発生時のルートは下記の通り。

``` ruby:routes.rb
Rails.application.routes.draw do
  devise_for :users
  # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
  
  root to: 'toppages#index'
  
  resources :users, only: [:index, :show, :edit, :update, :destroy] do
    member do
      get :followings
      get :followers
      get :likes
    end
  end
  
  devise_for :users,
    path: '',
    path_names: {
      sign_up: '',
      sign_in: 'login',
      sign_out: 'logout',
      registration: 'signup'
    },
    controllers: {
      registrations: 'users/registrations',
      sessions: 'users/sessions',
      passwords: 'users/passwords'
    }
  devise_scope :user do
    get 'signup', to: 'users/registrations#new'
    get 'login', to: 'users/sessions#new'
    get 'logout', to: 'users/sessions#destroy'
  end

  resources :posts, only: [:create, :destroy] do
    collection do
      get :search
    end
  end
  
  resources :relationships, only: [:create, :destroy]
  resources :favorites, only: [:create, :destroy]
  
end
```

## 解決方法
「２箇所定義とかしてないのにな〜」とか考えていましたが、ふと一番上に行が追加されていることに気づきましたｗ
devise_for :users の行を削除することで解決。


``` ruby:routes.rb
Rails.application.routes.draw do
  root to: 'toppages#index'
  
  resources :users, only: [:index, :show, :edit, :update, :destroy] do
    member do
      get :followings
      get :followers
      get :likes
    end
  end
  
  devise_for :users,
    path: '',
    path_names: {
      sign_up: '',
      sign_in: 'login',
      sign_out: 'logout',
      registration: 'signup'
    },
    controllers: {
      registrations: 'users/registrations',
      sessions: 'users/sessions',
      passwords: 'users/passwords'
    }
  devise_scope :user do
    get 'signup', to: 'users/registrations#new'
    get 'login', to: 'users/sessions#new'
    get 'logout', to: 'users/sessions#destroy'
  end

  resources :posts, only: [:create, :destroy] do
    collection do
      get :search
    end
  end
  
  resources :relationships, only: [:create, :destroy]
  resources :favorites, only: [:create, :destroy]
  
end
```

無事、起動することができました！

## 最後に
already in use系のエラーは、今回と同様に同じルーティングが既に設定されていると考えて良さそうですね。
（そのままですが）
今後同じエラーが出た際は、サクッと解決できそう。
Apache Spark(pyspark)でmavenリポジトリのjarを追加

Apache Sparkで追加のパッケージ([Mavenリポジトリ](https://mvnrepository.com/)にあるもの)を利用したいときに、configの設定が必要になるときがあるので自分用にメモ。

# 1. Mavenパッケージ

Mavenリポジトリ上のパッケージ情報は`groupId`、`artifactId`、`version`の3つの要素からなるらしい。(Maven coordinatesというらしい)
Sparkのconfigに渡すときはこれらを`:`でつないで、`groupId:artifactId:version`の文字列にしたものを用意する。

複数のパッケージを渡したいときはこれらを`,`でつないで、`groupId1:artifactId1:version1,groupId2:artifactId2:version2,groupId3:artifactId3:version3`
のようにする。

# 2. configの設定

設定ファイルに書いておいて常に適用されるようにしておくとか、コードの中で呼び出すなど様々な方法がある。
自分がやったことのある方法について記す。

## 2-1. コードの中でSparkSessionに渡す

例1：

```python
from pyspark.sql import SparkSession

# configメソッドを使い、"spark.jars.packages"の項目を設定する
spark = SparkSession \
    .builder \
    .config("spark.jars.packages", "graphframes:graphframes:0.8.0-spark3.0-s_2.12") \
    .getOrCreate()
```

例2(複数パッケージを指定):

```python
from pyspark.sql import SparkSession

spark = SparkSession \
    .builder \
    .config(
        "spark.jars.packages",
        "graphframes:graphframes:0.8.0-spark3.0-s_2.12,org.postgresql:postgresql:42.2.14"
    ) \
    .getOrCreate()
```
簡易的に使ってみるときや設定ファイルを汚したくないときによくやる。

Spark UI（ローカルで動かしているときは http://localhost:4040 など）の'Environment'などを確認すると、jarファイルが追加されているのが確認出来る。

## 2-2. spark-defaults.confに記入

Apache Sparkのインストール場所を`$SPARK_HOME`とすると、おそらく`$SPARK_HOME/conf/spark-defaults.conf`に以下の設定を追記すればOK
(なお、同じディレクトリ上に`spark-defaults.conf.default`みたいなテンプレートファイルがあるはず)

```conf:spark-defaults.conf
# 以下を追記
spark.jars.packages    graphframes:graphframes:0.8.0-spark3.0-s_2.12,org.postgresql:postgresql:42.2.14
```
こうしておくと、SparkSession生成時にconfigを設定しなくてもデフォルトで設定される。

## 2-3. その他

やったことがあるのは主に上記の２つだが、
Sparkはconfigの設定方法が色々あるようなので、他のやり方もある。

アプリケーションとして`spark-submit`を使って実行するような場合は[ここ](https://spark.apache.org/docs/3.0.0/submitting-applications.html)などを参考に、`spark-submit`のオプション：`--packages`を使って設定出来るはず。
あるいは、bashなどのCLIで`pyspark --packages groupId:artifactId:version`とか`spark-shell --packages groupId:artifactId:version`などとすると、configにpackage情報を渡した状態で`pyspark`や`spark-shell`のセッションを開始出来る。

Sparkは多機能でカバーできていない部分がまだ沢山あるので、他にもやりようがあるかもしれない。

# あとがき

[2-1](#2-1-コードの中でsparksessionに渡す)と[2-2](#2-2-spark-defaultsconfに記入)はjarの追加方法というより、一般的なconfigの設定方法な気がしてきた

# 参考

https://spark.apache.org/docs/3.0.0/configuration.html
docker importでイメージを作るとき、storage driverにより途中ディレクトリのパーミッションが異なる

## 環境

```
# docker version
Client:
 Version:      17.05.0-ce
 API version:  1.29
 Go version:   go1.7.5
 Git commit:   89658be
 Built:        Thu May  4 22:09:06 2017
 OS/Arch:      linux/amd64
```

## 準備

単純のため、busybox static binaryを/bin/busyboxに置く設定にします。

```
chdir /tmp
mkdir bin
wget -O bin/busybox https://www.busybox.net/downloads/binaries/1.31.0-defconfig-multiarch-musl/busybox-x86_64
chmod 755 bin/busybox
```

## テスト

```
tar -c bin/busybox | docker import /dev/stdin importtest; docker run -it --rm importtest /bin/busybox ls -l /; docker image rm importtest
```

## 結果

- `dockerd --storage-driver=overlay`

```
drw-------    2 0        0             4096 Aug 14 06:24 bin
drwxr-xr-x    5 0        0              360 Aug 14 06:24 dev
drwxr-xr-x    2 0        0             4096 Aug 14 06:24 etc
dr-xr-xr-x  559 0        0                0 Aug 14 06:24 proc
dr-xr-xr-x   13 0        0                0 Aug 14 06:24 sys
```

- `dockerd --storage-driver=overlay2`

```
drwxr-xr-x    2 0        0             4096 Aug 14 06:19 bin
drwxr-xr-x    5 0        0              360 Aug 14 06:19 dev
drwxr-xr-x    2 0        0             4096 Aug 14 06:19 etc
dr-xr-xr-x  557 0        0                0 Aug 14 06:19 proc
dr-xr-xr-x   13 0        0                0 Aug 14 06:19 sys
```

- `dockerd --storage-driver=aufs`

```
drwxr-xr-x    2 0        0             4096 Aug 14 06:31 bin
drwxr-xr-x    5 0        0              360 Aug 14 06:31 dev
drwxr-xr-x    2 0        0             4096 Aug 14 06:31 etc
dr-xr-xr-x  561 0        0                0 Aug 14 06:31 proc
dr-xr-xr-x   13 0        0                0 Aug 14 06:31 sys
```

- `dockerd --storage-driver=vfs`

```
drw-------    2 0        0             4096 Aug 14 06:08 bin
drwxr-xr-x    5 0        0              360 Aug 14 06:19 dev
drwxr-xr-x    2 0        0             4096 Aug 14 06:19 etc
dr-xr-xr-x  554 0        0                0 Aug 14 06:19 proc
dr-xr-xr-x   13 0        0                0 Aug 14 06:19 sys
```

overlayとvfsではパーミッションが非想定値になっていることがわかります。実際に、`docker run -it --rm --user $(id -u nobody) importtest /bin/busybox ls -l /bin`はPermission deniedとなり失敗します。

## 結論

usr/bin/busyboxを置いてusr/binをtarした場合も同様でした(/usr/binは755だが/usrは600になる)。動的にイメージを作る場合は特に注意しましょう(Dockerfileを使う場合は影響がないようですが…)。

https://qiita.com/cielavenir/items/05e50fa6bb493040085e で「そういえば/var/lib/dockerがVOLUME指定されているかでdocker内dockerの挙動が変わるよな〜」とか思い出せたんですが、この経験がなかったら今日の仕事は死んでた(暗黙的にvfs driverに切り替わってたのが原因だった)。きっと。
にいがた食堂　作成1日目

にいがた食堂　作成1日目　（1Hくらい）

htmlの骨格の作成と最上部（背景画像の上に「ヘッダー（ロゴとナビ）」と「コンテンツ」）のCSSの記述を行った。

〇作業内容
・最上部には、大きい背景画像の上にヘッダー及びコンテンツを配置する。
（kana本のwebcafeと同じ構造）
・classをどのようにマークアップするか悩む
・背景画像だけのための```<div class="ly_bigPhoto">```を作成。
・その配下に以下を配置
   ヘッダー→```<header class="bl_header"></header>```
   コンテンツ→```<div class="bl_photoCont"></div>```
・上記コンテンツの横幅と中央揃いをどこに記述するか悩む
・kana本では、wrapperを別に使っていたので、上記2つをwrapperで包むことに。
・cssの記述としてCSS設計ガイドに、以下のような親子逆転の記述がありとの記載（p182）があったので```<header class="bl_header">```の親に```<div class="bl_header_wrapper">```という記述にした。
・```<header class="bl_header">```では以下のように、ロゴとナビのレイアウトを書き

```
.bl_header{
  display:flex;
  justify-content: space-between;
  padding-top:20px;
}
```

```<div class="bl_header_wrapper">```では、ヘッダー自体のレイアウトを書くという役割分担ができたのでわかりやすいかなと。

```
.bl_header_wrapper{
  max-width: 1100px;
  margin:0 auto;
  padding:0 4%;
}
```

本日のまとめ↓
```
 <div class="ly_bigPhoto">

    <div class="bl_header_wrapper">
      <header class="bl_header">
        <h1><a href="#"><img src="img/logo.png" class="el_logo"></a></h1>
        <nav class="bl_nav">
          <ul class="bl_nav_inner">
            <li><a href="#">運営会社</a></li>
            <li><a href="#">お問い合わせ</a></li>
          </ul>
        </nav>
      </header>
      <!-- /.bl_header -->
    </div>
    <!-- /.bl_header_wrapper -->

    <div class="bl_photoCont_wrapper">
      <div class="bl_photoCont">
      </div>
      <!-- /.bl_photoCont -->
    </div>
    <!-- /.bl_photoConto_wrapper -->
  </div>
  <!-- /.ly_bigPhoto -->
```