OmniAICreator/Qiita-1.07M huggingface dataset:
本番環境で背景画像が表示されない場合の対処法

どうも、岩城です。

本番環境でデプロイできた！よっしゃ！

 「....え？？
　背景画像が表示されてない...
　どぉしてだよおおおお！！！！」

と、新世界の神から転落した人は少なく無いはず。

# image-urlを試してみる

```
.titlebg{
background-image:url(images/bg.png);
}
```

これを


```
.titlebg{
background-image:image-url('images/bg.png');
}
```


urlをシングルクォーテーションで囲うことを忘れないで下さいね＾＾

これで表示されると思います＾＾
【Laravel+React】ページルーティング

#困ったこと
今回サービスを開発する上でLaravelでのルーティングをするのかReactでのルーティングをするのか迷い，元から実装していたReactでの実装にした．
その時単純なreact-router-domの記述ではLaravelとの連携ができない

#解決
web.phpのルーティング記述を以下のように変更して連携させる．

```php:routes/web.php
Route::get('/{path?}', function(){
  return view('welcome');
} )->where('path','.*');
```
welcome.blade.phpには従来のReactと同じようにRenderするためのルートIDを設ける．あとapp.jsを読み込む．（こいつがWebpack的にcssとかjsとか集約するっぽい）

```html:resources/views/welcome.blade.php
<body>
  <div id="root"></div>
  <script src="{{mix('js/app.js')}}" ></script>
</body>
```
【Ruby】スレッドID(tid)を表示する

## メモ

### スレッドIDを取得するシステムコール
スレッドIDを取得するシステムコールがある(gettid)。
で、これはシステムコール番号186（64bitの場合）。

Man page of GETTID https://linuxjm.osdn.jp/html/LDP_man-pages/man2/gettid.2.html

Syscall Number for x86-64 linux (A) https://www.mztn.org/lxasm64/x86_x64_table.html

### システムコールを実行するRubyのメソッド
で、Rubyにはシステムコールを実行するメソッドがある( `Kernel#syscall` )ので、これで上記のシステムコール番号を指定する。

Kernel.#syscall (Ruby 2.7.0 リファレンスマニュアル) https://docs.ruby-lang.org/ja/latest/method/Kernel/m/syscall.html


## サンプル

```ruby:irb
puts syscall(186)
```

これでOK。

ちなみに、マルチスレッドで実行するとちゃんと別々のIDが表示される

```ruby:test-thread.rb
puts syscall(186)

t = Thread.new do
  puts syscall(186)
  sleep 5
end

t.join
```

OSレベルで上記のふるまいを確かめる場合は上記を実行している途中で以下を実行すれば確認できる（下記コマンドの場合は `LWP` を見る）。同じ番号が表示されるはず。[^1]

```sh
% ps -eLf | grep -e test-thread.rb -e PID
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
kure     15785  9657 15785  2    2 23:17 pts/1    00:00:00 ruby test-thread.rb
kure     15785  9657 15813  0    2 23:17 pts/1    00:00:00 ruby test-thread.rb
```

***

ちなみに、簡単に取得するためのExtensionを以下で見つけたりした。多分似たようなことをやってるもよう。

tomlobato/ruby-get_tid: Get the Thread ID (tid/lwp/spid) in Ruby/Linux https://github.com/tomlobato/ruby-get_tid


[^1]: ちなみに[psのmanページ](https://linuxjm.osdn.jp/html/procps/man1/ps.1.html)の記述によるとlwp, spid, tid は別名で同じものを指しているらしい。（厳密には分からない）
M5StickVのMaixPyファームウェアをソースからビルドして書き込む

MaixPyに "kmodel v4 supportが追加された" とあったのでソースからファームウェア？をビルドして焼いてみた

- [MaixPyのm5stickV用ソースコード](https://github.com/sipeed/MaixPy/tree/master/projects/maixpy_m5stickv)

---

公式の[Build from source](https://github.com/sipeed/MaixPy/blob/master/build.md)の手順そのままでいけた

1. 手順通りにmaixpy.binをビルドする
2. kflashでM5StickVに焼く
3. 本体にログインするとターミナルに `MicroPython v0.5.0-22-g7ac6b09bf on 2020-03-07; Sipeed_M1 with kendryte-k210`
と出ており、MaixPyが新しくなった模様


## 追記

ビルドの設定次第でheap memoryに差異が出るらしい。

https://github.com/sipeed/MaixPy/issues/180
- sipeedが配布しているPre compliedバイナリの場合、v0.4.0_47とv0.4.0_92で900KBぐらい違う
- sys heap memoryによってロードできるモデルのサイズが違ってくる？
- 自分でビルドする際に `python3 project.py menuconfig` でビルドオプションを変える (不要な機能を削る) ことでheap memoryを大きくすることができるらしい

### 1. 今回ビルドしたもの

MicroPythonのバージョンは `v0.5.0-22`

```
...
MicroPython v0.5.0-22-g7ac6b09bf on 2020-03-07; Sipeed_M1 with kendryte-k210
Type "help()" for more information.
>>>
>>> kpu.memtest()
###free gc heap memory : 378 KB
###free sys heap memory: 1512 KB
>>> 
```


### 2. `M5StickV_Firmware_1022_beta.kfpkg`

公式で配布されているファームウェア
MiroPythonのバージョンは `v0.4.0-52` 

```
...
MicroPython v0.4.0-52-g3b8c18b84-dirty on 2019-10-21; M5Stick-V with Kendryte K210
Type "help()" for more information.
>>> 
>>> kpu.memtest()
###free gc heap memory : 400 KB
###free sys heap memory: 1768 KB
```

あまり変わらないような、、

上の [Github issue](https://github.com/sipeed/MaixPy/issues/180) によると sipeedが配布してる `maixpy_v0.4.0_47_g39bb8bf_m5stickv.bin` は3460KBあるらしい
要調査

## TOOD

M5StickVのファームウェアってsipeedとM5stackそれぞれから配布されていて、どちらを使うべきなのかよくわからない。

- sipeed: Githubのソースを自分でビルド or [バイナリ](http://dl.sipeed.com/MAIX/MaixPy/release/master/)をダウンロード
- M5Stack: Quickstartにリンクされてる[kfpkg] (https://docs.m5stack.com/#/en/quick_start/m5stickv/m5stickv_quick_start)

M5Stackが配布しているものはファームウェアとサンプルのモデルファイルがセットになったものに見える。
M5Stackが配布してるファームウェアは恐らくsipeedのコードからビルドされたものと思われるが、何か差分があるんだろうか？現時点で最新の `M5StickV_Firmware_1022_beta.kfpkg` に含まれているMaixPyは `v0.4.0-52` と最新からはだいぶ古そうなので問題なければsipeedの方を使ってみたい。
【Laravel+React】Herokuプッシュ時のつまずき

#初期環境
Laravelアプリの作成

```
composer create-project laravel/laravel アプリ名
```
git push

```
git push heroku master
```

#つまずき①

```
heroku open
```
するとトップページがForbidden．

####解決法

```:Procfile
web: vendor/bin/heroku-php-apache2 public
```
を作成．これでサイトアクセスエントリページがpublicフォルダに設定される．

#つまずき①

```
heroku open
```
するとトップページが500 server error．

####解決法

```:ターミナル 
heroku run "php artisan key:generate --show" --app=アプリ名
```
ここに出てくる値をHerokuのSettingタブ内下画像のAPP_KEYに設定．
<img width="1232" alt="スクリーンショット 2020-03-07 23.20.02.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/458915/56607ed8-80f3-bdb9-d729-dc3f4b0daf29.png">


これで無事本番対応終了
javaでAtCoder Beginner Contest 158を解く

AtCoder Beginner Contest 158お疲れ様でした！
[公式ページ](https://atcoder.jp/contests/abc158)

今回の自分の書いたコードは[こちら](https://github.com/ko-flavor/atcoder-java/tree/master/atcoder/src/abc/abc158)
結果はA-DまでACできました。

以下簡単に解説します。

##[問題A](https://atcoder.jp/contests/abc158/tasks/abc158_a)

引数に文字長3の文字列が与えられて、それが`AAA`か`BBB`なら`No`と出力すればOKです。

##[問題B](https://atcoder.jp/contests/abc158/tasks/abc158_b)

N, A, Bが与えられて、N / (A+B)が大事になってくる問題。
Nこの列にA個の青いボールとB個の赤いボールを交互に並べていくので、このN/(A+B)が繰り返された回数となります。

(N/(A+B))*AをベースにN%(A+B)に青いボールが何個あるのかを足せばOKです。

##[問題C](https://atcoder.jp/contests/abc158/tasks/abc158_c)

消費税が8%なら税金がA円、10%なら税金がB円です。
ここで、以下に注目。

```math
1 \leqq A \leqq B \leqq 100
```

もとの値段を1～1000円まで計算して、該当するものを出力すればOKです。
A円、B円からもとの値段を算出しようとすると大変です。

##[問題D](https://atcoder.jp/contests/abc158/tasks/abc158_d)

文字列を反転させたり、末尾や先頭に加えたりする問題です。
いちいち反転させていたら間に合わないな、と思ったので、反転フラグみたいなものを作って、実際に文字列を反転せずに、反転かどうかはそこで管理しました。

そして、末尾か先頭に文字を足す部分ですが、反転かどうかのフラグを見てどっちに足すか判断するようにしました。
これでTLEだったので、文字列の頭に文字を足すことが計算量が多いと推測しました。

なので、先頭に加えるべき文字列というのを別途管理することでACになりました。

具体的なコードでは、加えるときは以下のような感じで

```java
int f = sc.nextInt();
if ((f == 1 && !isReverse) || (f == 2 && isReverse)) {
	front.append(sc.next());
} else {
	sb.append(sc.next());
}
```

出力するときはこんな感じ

```java
if (isReverse) {
	print(sb.reverse().toString() + front.toString());
} else {
	print(front.reverse().toString() + sb.toString());
}
```


##[問題E](https://atcoder.jp/contests/abc158/tasks/abc158_e)

問題の方針は最後の最後で出たのですが、時間切れ。

3543を3で割る例で考えます。
3000/3500/3540を3で割った余りと、
3/43/543を3で割った余りと、
3543を3で割った余りがあれば、求める答えはでてきます。

今回は3543を3で割った余りが0です。
3000を3で割った余りも0なので、3/43/543の中から3で割った余りが0のものを見つけてくれば、それらを除いた部分文字列は3で割り切れます。

3000と3540を3で割った余りが0、3と543を3で割った余りが0なので2*2
3500を3で割った余りが2、43を3で割った余りが1なので、1*1
今回は3543が3で割り切れるので+1

で6と答えがでます。

3000を3で割った余りですが、3543を3で割った余りと、543を3で割った余りがあれば計算できます。
ので、計算すべきは3/43/543/3543と、末尾から1つずつ値を増やしていった余りを貯蔵しておけばよさそうです。

43を割った余りを保持していれば(5 mod 3) * (100 mod 3)で計算できます。
この桁数ぶんのmodも保持して計算しておきます。

なんかうまく言葉で言い表せないんですけど、これで解けると思います。。

##[問題F](https://atcoder.jp/contests/abc158/tasks/abc158_f)

手つかずです。笑

----

レーティングは計算中ですが下がっていそうです。。
(追記)
974→979と微妙に上がりました笑

E問題に手が届きそうっていうのがしばらく続いていたのですが、今回は少し遠かったなぁ・・・
今回のようにE問題がなかなかの難易度だと、A-D問題をいかに早く解くかで順位が多きく変わってきますね。。

基本的なfor文とか書くのに時間結構使っている気がするので、もうちょい効率化できるところはしていきたいと思います、、
学習記録#3

#やったこと
Udemy「PythonによるWebスクレイピング〜入門編〜【業務効率化への第一歩】」の§6 画像の収集

- 画像の読み込み・保存にはpillowが便利
- .get_attribute('src')でソースが取得できる
- for index,elem in enumerate(elems):とするとindexも増えていく

#読んだもの
https://qiita.com/Hexans/items/12c6483bbce90b470a69
スクレイピングの一例として、株価データの取得。
面白そう。

#その他
- Udemy「PythonによるWebスクレイピング〜入門編〜【業務効率化への第一歩】」は一通り終わったけど、まだまだ空では書けないので何周かやってみる。
- 文法とかをひたすらやるのではなく、何かを作るタイプの講座に手を出してみたい。
【VSCode】WEB受託会社で働くコーダーが使うVSCodeのショートカットキー

# WEB受託会社で働くコーダーが使うVSCodeのショートカットキー

## 一括コメントアウト
```
ctrl + /
```
### かなり便利です。

## マルチカーソル
### 先頭にカーソルを置いて、、、
```
ctrl + alt + shift + 下
```

## 一括でインデントを修正
```
shift + alt + F
```

## 長文コードの折り返し
```
alt + z
```

## 特定のコードを移動させる
```
alt + 上下
```

## 行をコピー
### ※マウスでコピーしたい行をわざわざ選択せずともカーソルを置くだけで可能
```
ctrl + c
```
## 言語モード選択
### ※ちょっとしたメモを取る際に.md形式で保存したい場合など
```
ctrl + K M
```

## コマンドラインを出現
```
ctrl + @
```

## コマンドパレットを出現
```
ctrl + shift + p
```

## エディタを２つ以上使いたい場合
### 2つ目のタブを開く場合
```
ctrl + 2
```

## 余談
今まで記事を書く際は、ヒントを見ながらqiitaのエディタに直接記述していたのですが、今回vscodeのmdファイルに記述しました。
マークダウンの記法を覚えるとこっちの方が楽ですね。
最近閲覧しドワンゴのN予備校の教材開発に携わっている大学生エンジニアさんによれば、メモなどもマークダウンファイルに残しているとのこと。
[N予備校のプログラミング教材編集に約3年携わって得られた知見](https://qiita.com/ryo-a/items/355a667a407a67e4657d)
使えるスキルが増えるのは楽しいですね。
w2uiのgridにソート機能を追加する

## やりたいこと
前回導入したgridにソート機能を追加したい

前回記事:
https://qiita.com/wancoro/items/44de3104866cd6694b62

## 実装
前回作成したスクリプト

```
<script>
  $(function () {
    $('#grid').w2grid({
      name: 'grid_name', 
      header: 'List of Tasks',
      url: {
        get: '/parent_tasks.json'
      },
      method: 'GET',
      show: {
        toolbar: true,
      },
      recid: 'id',
      limit: 10,
      columns: [
        { field: 'id', caption: 'id', size: '8%' },
        { field: 'name', caption: 'name', size: '30%' },
        { field: 'priority', caption: 'priority', size: '10%' },
        { field: 'status', caption: 'status', size: '10%' },
        { field: 'created_at', caption: 'created_at', size: '40%' }
      ],
      sortData: [
        { field: 'id', direction: 'asc' },
      ],
    });
  });
</script>
```
columnsの部分に`sortable: true`を追加します

```
<script>
  $(function () {
    $('#grid').w2grid({
      name: 'grid_name', 
      header: 'List of Tasks',
      url: {
        get: '/parent_tasks.json'
      },
      method: 'GET',
      show: {
        toolbar: true,
      },
      recid: 'id',
      limit: 10,
      columns: [
        { field: 'id', caption: 'id', size: '8%', sortable: true }, # ここ
        { field: 'name', caption: 'name', size: '30%', sortable: true },
        { field: 'priority', caption: 'priority', size: '10%', sortable: true },
        { field: 'status', caption: 'status', size: '10%', sortable: true },
        { field: 'created_at', caption: 'created_at', size: '40%', sortable: true }
      ],
      sortData: [
        { field: 'id', direction: 'asc' },
      ],
    });
  });
</script>
```

ローカルデータを使用する場合はこの記述だけでソートができるようになるのですが、
リモートデータを使用する場合は、サーバ側でリクエストの処理を追記する必要があります

`sortable: true`の状態でをgridのカラム名をクリックすると
urlで指定したパスに以下のようなパラメータが送信されます

```
request: {"cmd":"get","selected":[],"limit":10,"offset":0,"sort":[{"field":"id","direction":"asc"}]}
```
コントローラに処理を追加します

```
def index
  if params[:request]
    request = JSON.parse(params[:request])
    request.each do |key, value|
      case key
      when "limit"
        @limit = value
      when "sort"
        @column = value[0]["field"]
        @direction = value[0]["direction"]
      end
    end
    @tasks = ParentTask.limit(@limit).order("#{@column} #{@direction}")
  else
    @tasks = ParentTask.limit(10)
  end

  respond_to do |format|
    format.html
    format.json
  end
end
```
これでソートボタンがクリックされるたびに、DBからレコードをorderByで取得して
viewに渡すことができます

もっとキレイなソースコードの書き方があれば、ご教示頂けますと幸いです
バッチからPostgreSQLにCSVインポートを行う

#バッチからPostgreSQLにCSVインポート

##環境
- DBサーバ：Windows10 PostgreSQL11.6
- クライアント端末：Windows10

※ローカル端末とDBサーバは別の端末にしています。

## 詳細
PostgreSQLでCSVのインポートを行うにはCOPYコマンドを使用します。
「**COPY**」コマンドにも2種類あり、**COPY**と**\COPY**があります。
なにが違うのか？

#####[COPY]
- SQLコマンドが実行されるDBサーバーのファイルを読み込む。
- 複数行にわたって記述できる。
- [公式ドキュメント](https://www.postgresql.jp/document/11/html/sql-copy.html)

#####[\COPY]
- ローカルサーバー（ターミナルを開いているサーバー）のファイルを読み込む。
- 1行で記述しなければいけない。
- [公式ドキュメント](https://www.postgresql.jp/document/11/html/app-psql.html#APP-PSQL-META-COMMANDS-COPY)

##サンプル
```sql
COPY table1 (col1, col2) FROM :'CSV_PATH' with encoding 'SJIS' format csv force_not_null(col1, col2) HEADER;
```
※with句について
encoding： csv    読み込むファイルの文字コードがSJIS
format： 'SJIS'   ファイルフォーマットがCSV形式
force_not_null：  指定したカラムが空文字の場合にNULLに設定
HEADER：          ヘッダ行がある場合は記載する
※他にもオプションあり
※「COPY」と「\COPY」で使えるオプションが違う。

##補足
`COPY テーブル名 FROM ファイル名`   (ファイルからテーブルにデータを読み込む)
`COPY テーブル名 TO ファイル名`     (テーブルからファイルにデータを出力)
・「COPY」の場合はDBサーバ側にCSVを配置してインポートを行い、DBサーバ側にCSVが出力される。
・「\COPY」の場合はクライアント端末側にCSVを配置してインポートを行い、DBサーバ側にCSVが出力される。
Next.js + WordPress（REST API）でURLそのままに、該当記事が無ければNot Foundなページ（ステータスコードも返しつつ）のビューを表示させる

こんにちは。
カラオケ屋で深夜バイトしながら、Webサイト制作を趣味にしています。

そんな雑魚な僕は、React.jsを1ミリも分からない状態でNext.jsを触るという無謀な挑戦をしています。

今回は、
Next.jsでダイナミックルート（ `page/[id].js` 等）でfetchしたデータに投稿データが無かったときにURLはそのままに「該当の投稿はありません！」というビューに切り分けることにチャレンジしてみました。

# 実際のコード

```javascript:pages/magazine/[magazine_id].js
class MagazinePost extends React.Component {

  // SSRの処理（サーバー側）
  static async getInitialProps(context) {
    const { magazine_id } = context.query;
    const magazinePosts = await fetch(`https://xxxxxxx.com/wp-json/wp/v2/magazine/${magazine_id}?_embed`);
    const magazine = await magazinePosts.json();

    let statusCode = 200;
    
    // JSONデータからエラーっぽい感じの条件を自分なりに付ける
    if(magazine.code && magazine.message) {
      // WordPressのREST APIから発行されるステータスコードを取得
      statusCode = magazine.data.status;
      // ブラウザに通知するステータスコードを変更
      context.res.statusCode = statusCode;
    }

    return {
      magazine: magazine, // 投稿データ
      statusCode: statusCode // ステータスコード
    }
  }

  // CSRの処理（クライアント側）
  render(res) {
    if(this.props.statusCode === 200) {
      return (
        <>
          <p>記事がありました！</p>
        </>
      );
    } else {
      return (
        <>
          <p>ステータスコード： {this.props.statusCode}</p>
          <p>記事がありません...。<p/>
        </>
      );
    }
  }
}

export default MagazinePost;
```

とりあえず動くものはできました。

- URLから直接アクセス
- next/link経由のアクセス

で問題なく動作することが確認できています。

---

例：WordPress側の投稿スラッグ => no-problem
http://xxxxxx.com/magazine/no-problem
では、正しく表示され、
http://xxxxxx.com/magazine/fjewiofjewio
では404の表示となりました。
また、ブラウザ側にも404ステータスコードが通知されます。

---

Next.js含めReact.jsすら１週間前に触り始めたばかりなので、
他に良い方法があれば教えてください...！

---

## [公開後に追記]少々問題がありました。

ブラウザの「進む」や「戻る」でこのページにアクセスした際に問題がありましたので、少しだけ手を加えました。

### 何があったのか？
![98fb88d41d5196622b8804aaa439e259.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/35783/8a5ac544-de9a-ef61-f524-26a30c7aad00.png)

ブラウザバックをした際に、`getInitialProps` の中の `context.res` がundefinedになり処理の妨げになりました。これを回避するために条件式を追加しました。

```javascript:pages/magazine/[magazine_id].js
MagazinePost.getInitialProps = async function(context) {
  const { magazine_id } = context.query;
  const magazinePosts = await fetch(`https://xxxxxx.com/wp-json/wp/v2/magazine/${magazine_id}?_embed`);
  const magazine = await magazinePosts.json();

  let statusCode = 200;

  if(magazine.code && magazine.message) {
    // 追加したのはここ！
    if(context.res !== void 0) {
      // context.resがundefinedではない場合
      // ステータスコードを割り当てる
      statusCode = magazine.data.status; // ビュー振り分け用
      context.res.statusCode = statusCode;
    } else {
      // context.resがundefinedの場合
      // context.res.statusを書かない
      statusCode = undefined; // ビュー振り分け用
    }
  }

  return {
    magazine: magazine, // 投稿データ
    statusCode: statusCode // ステータスコード
  }
};
```

この対策によって現時点では

- URLから直接アクセス
- next/link経由のアクセス
- ブラウザの「進む」や「戻る」

をしても問題なく閲覧できることを確認しています。
そもそもdocumentが404ステータスでSPAで閲覧している状態で良くないのかも？よく分かりませんが、とりあえずやりたいことはできたので良しとします。

問題があれば教えてください！
AtCoder Beginner Contest 158 参戦記

# AtCoder Beginner Contest 158 参戦記

## [ABC158A - Station and Bus](https://atcoder.jp/contests/abc158/tasks/abc158_a)

2分で突破. 書くだけ. 1種類か、2種類か、それだけ.

```python
S = input()

if len(set(S)) == 1:
    print('No')
else:
    print('Yes')
```

## [ABC158B - Count Balls](https://atcoder.jp/contests/abc158/tasks/abc158_b)

3分半で突破. N が操作何回分を含むかを計算. n 回であれば n * A 個青いボールがある. 途中かけになった分については、A個以内であればその個数が、そうでなければA個青いボールがある.

```python
N, A, B = map(int, input().split())

result = 0
result += N // (A + B) * A
result += min(N % (A + B), A)
print(result)
```

## [ABC158C - Tax Increase](https://atcoder.jp/contests/abc158/tasks/abc158_c)

4分半で突破. A≤B≤100 ってことは、たかだか1000くらいが答えになるので総当りで OK! もっとクレバーにやることもできるだろうけど、ここ2回くらいそれで WA を食らって懲りたのである. クレバーより愚直に安全.

```python
A, B = map(int, input().split())

for i in range(2000):
    if int(i * 0.08) == A and int(i * 0.1) == B:
        print(i)
        exit()
print(-1)
```

追記: 解説 PDF で *O*(1) で解く課題が出てたので.

```python
A, B = map(int, input().split())

x_low = (A * 100 + 7) // 8
x_high = ((A + 1) * 100 + 7) // 8 - 1
y_low = (B * 100 + 9) // 10
y_high = ((B + 1) * 100 + 9) // 10 - 1

result = max(x_low, y_low)
if result > min(x_high, y_high):
    result = -1
print(result)
```

## [ABC158D - String Formation](https://atcoder.jp/contests/abc158/tasks/abc158_d)

17分で突破. もちろん言われたとおりに文字列操作をしたら TLE まっしぐら. 右からも左からも足し込むので deque を使うのは見え見え. 後は反転をいちいちしていると TLE になるので、必要であれば最後に1回するだけにつじつまを合わせるだけ.

```python
from collections import deque

S = input()
Q = int(input())

t = deque(S)
reverse = False
for _ in range(Q):
    query = input()
    if query[0] == '1':
        reverse = not reverse
    elif query[0] == '2':
        _, F, C = query.split()
        if F == '1':
            if reverse:
                t.append(C)
            else:
                t.appendleft(C)
        elif F == '2':
            if reverse:
                t.appendleft(C)
            else:
                t.append(C)
result = ''.join(t)
if reverse:
    result = result[::-1]
print(result)
```

## [ABC158E - Divisible Substring](https://atcoder.jp/contests/abc158/tasks/abc158_e)

敗退. *O*(*N*<sup>2</sup>) から削る手段が全く思いつかず. と、コンテスト中に書いたが、終了5分前に桁ごとに余りとその組み合わせ数を引き回して1桁づつ進めれば DP で解けるんじゃないかと気づいたが時すでに遅かった.

追記: P が2と5のときは簡単で、一番下の桁が2の倍数、5の倍数のときに割りきれるので、後は左に伸ばせる数を積算すれば求まる. その他の P については、例えば S<sub>6</sub>S<sub>5</sub>S<sub>4</sub>S<sub>3</sub>S<sub>2</sub>S<sub>1</sub>S<sub>0</sub> の S<sub>6</sub>S<sub>5</sub>S<sub>4</sub>S<sub>3</sub> が P で割り切れたとすると、S<sub>6</sub>S<sub>5</sub>S<sub>4</sub>S<sub>3</sub>S<sub>2</sub>S<sub>1</sub>S<sub>0</sub> ≡ S<sub>2</sub>S<sub>1</sub>S<sub>0</sub> (mod P) なので、余りを記録しながら左に伸ばして、同じ余りのものの個数を積算すれば求まる.

```python
N, P = map(int, input().split())
S = input()

S = S[::-1]
result = 0
if P == 2 or P == 5:
    for i in range(N):
        if int(S[i]) % P == 0:
            result += N - i
else:
    t = [0] * P
    m = 1
    n = 0
    for i in range(len(S)):
        t[n] += 1
        n += int(S[i]) * m
        n %= P
        result += t[n]
        m *= 10
        m %= P
print(result)
```
ApacheのアクセスログからURLごと、時間帯別でURLごとにアクセスを集計する

### パラメータを除外し、URLごとに集計
```
cat access.log | awk -F\" '{print $2}' | awk -F' ' '{print $2}' | cut -f1 -d? | sort | uniq -c | sort -n -r > output.txt
```

### 時間帯のURLごとに集計
例) 2016/04/27/ 18:00 台の時間帯にアクセスのあったURLごとの集計

```
cat access.log | grep '\[27/Apr/2016:18:00:' | awk -F\" '{print $2}' | awk -F' ' '{print $2}' | cut -f1 -d? | sort | uniq -c | sort -n -r > output_1800.txt
```

### その他
複数あるアクセスログファイルを1つにまとめる

```
cat access1.log access2.log access3.log > total_access.log
```
【条件指定】RubyでDBから特定のidかつ最新のデータを取得する

１.特定のidを持つ投稿を指定

```
where(location_id: 1)
```
2.最新のデータを持つ投稿を指定

```
order(updated_at: :desc).limit(1)
```

3.つなぎ合わせる(特定のIDかつ最新)

```
@posts = Post.where(location_id: 1).order(updated_at: :desc).limit(1)
```
完了
仙台CTF 2019 Lab1.パケット解析 100

#問題

http://ctf.sectanlab.jp/2019/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/7670a580-b006-4dbb-7362-1dcac1161018.png)

#解いてみた

問題のファイルを見ます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/a3dbc874-d7dc-5bae-fcb0-8b7adb7202ce.png)

pcapファイルなのでwiresharkで見ます。
IPの一覧を見てみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/17681/11529c66-9e90-64b0-22ea-e5c288777c84.png)

問題文に「DMZ内部セグメント：192.168.100.0/24」と書いてあって、それに当てはまるのは1つしかありませんでした。
なのでこれが答えになります。
TomcatのAJP接続でエラーに遭遇。

CentOS8にApacheとTomcatを入れAJPで繋ぐいつもの設定を行う。

Server version: Apache/2.4.37 (centos)
java version "13.0.2" 2020-01-14
Tomcat : 9.0.31

だが、AJPでApacheから接続できない。
Tomcatのログを見るとAJPでこけている。
最初、エラーログを見てもよくわからなかったがよくよく見るとどうも原因はこれらしい。

Caused by: java.lang.IllegalArgumentException: The AJP Connector is configured with secretRequired="true" but the secret attribute is either null or "". This combination is not valid.

いつものGoogle検索でもなかなかヒットしなかったがどうやらこれらしい。

https://communities.bmc.com/docs/DOC-126517

これで解決。
ECK の Kibana に外部から疎通可能な IP を LoadbalancerIP で設定する

## はじめに
ECK (Elastic Cloud on Kubernetes) の Kibana は [QuickStart](https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-quickstart.html)を踏襲すると、  `kubectl port-forward` でのポートフォワードでのアクセスのみで、外から直接 IP で表示ができない。
そこで LoadbalancerIP を設定して、外部疎通可能な `EXTERNAL-IP` をアサインして直接 IP で外部ネットワークから疎通(ブラウザで表示)できるように設定する。

## Kibana設定

kibana 向けの yaml に下記を追加すると、作成される Service が type: LoadBalancer で作成される。 

 - kind: Kibana
    - spec.http.service.spec
        - type: LoadBalancer
            - 作成する Service を LoadBalancer とする。(デフォルトは ClusterIP)
        - loadBalancerIP: [固定IP]
            - LoadBalancer で付与される IP を固定 IP でアサインする
            - 設定しないと自動で EXTERNAL-IP がアサインされる

```yaml:Loadbalancer追加
spec:
  http:
    service:
      spec:
        type: LoadBalancer
        loadBalancerIP: [固定IP]
```

全体例としては下記となる。 (name, namespace, アサインしたip は [実施環境の ElasticStack](https://qiita.com/suzuyui/items/5307e767ec0745c9ad23
) , [Loadbalancer](https://qiita.com/suzuyui/items/c83554dd055ef0f4253a
) で適応した例)

```yaml:kibana.yaml
apiVersion: kibana.k8s.elastic.co/v1
kind: Kibana
metadata:
  name: monitoring-kibana
  namespace: elastic-monitoring
spec:
  version: 7.6.0
  count: 1
  elasticsearchRef:
    name: monitoring-elasticsearch
  http:
    service:
      spec:
        type: LoadBalancer
        loadBalancerIP: 192.168.131.1
```

上記適応後は下記のように EXTERNAL-IP がアサインされ、アサインされた IP でブラウザからアクセスできるようになる。

```
$ kubectl get svc -n elastic-monitoring
NAME                                      TYPE           CLUSTER-IP      EXTERNAL-IP     PORT(S)             AGE
monitoring-kibana-kb-http                 LoadBalancer   10.233.50.138   192.168.131.1   5601:30588/TCP      4d18h
```

ブラウザでのアクセス例。

![スクリーンショット 2020-03-07 18.08.06.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/326183/4c243994-fc1f-5531-e9a6-f76b9407b2f0.png)


### 参考
https://www.elastic.co/guide/en/cloud-on-k8s/master/k8s-services.html#k8s-allow-public-access

### 実施環境
ECK https://qiita.com/suzuyui/items/5307e767ec0745c9ad23

オンプレLoadbalancer https://qiita.com/suzuyui/items/c83554dd055ef0f4253a
Railsアプリにw2uiのgridを導入した話

## やりたいこと
* Railsアプリにw2uiのgridを導入する
* DBからデータを取得してgridに表示させる

## w2uiとは
Javascriptのライブラリです
今回はその中のGridというマスタテーブルを生成できるライブラリを使用しました

## 開発環境
* Ubuntu 18.04
* Rails 5.2
* MariaDB

## 導入方法

以下３文をヘッダーに追加します

```
<head>
...
<link rel="stylesheet" type="text/css" href="http://w2ui.com/src/w2ui-1.5.rc1.min.css" />
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script type="text/javascript" src="http://w2ui.com/src/w2ui-1.5.rc1.min.js"></script>
</head>
```

girdを挿入したい部分にdivを追加します

```
<div id="grid" style="width: 100%; height: 250px;"></div>
```

スクリプトを記述します

```
<script>
  $(function () {
    $('#grid').w2grid({
      name: 'grid_name', 
      header: 'List of Tasks',
      url: {
        get: '/parent_tasks.json'
      },
      method: 'GET',
      show: {
        toolbar: true,
      },
      recid: 'id',
      limit: 10,
      columns: [
        { field: 'id', caption: 'id', size: '8%' },
        { field: 'name', caption: 'name', size: '30%' },
        { field: 'priority', caption: 'priority', size: '10%' },
        { field: 'status', caption: 'status', size: '10%' },
        { field: 'created_at', caption: 'created_at', size: '40%' }
      ],
      sortData: [
        { field: 'id', direction: 'asc' },
      ],
    });
  });
</script>
```

|項目|概要|
|:--|:--|
|name|gridの名前|
|header|gridのヘッダーに表示される文言|
|url|データをリモートから取得する際のURL|
|method|Ajaxリクエストのメソッドを上書き|
|show|gridに表示する項目を指定|
|recid|recidに設定するカラムを指定|
|limit|取得するレコード数を指定|
|columns|カラムを定義|
|sortData|ソートを指定|

columnsの中身

|項目|概要|
|:--|:--|
|field|フィールド名|
|caption|表示するカラム名|
|size|列幅を指定|

## DBからw2uiにレコードを渡す

コントローラにJSONの処理を追加します

```
class ParentTasksController < ApplicationController
  def index
    @task = ParentTasks.limit(10)
    respond_to do |format|
      format.html
      format.json
    end
```
jbuilderを追加します
表示したいデータを`records`でくくってあげます

```
# index.json.jbuilder

json.records do
  json.array!(@tasks) do |task|
    json.extract! task, :id, :name, :priority, :status, :created_at
  end
end
```
これでサーバから取得したデータをgridで表示できるようになりました

![grid.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/324514/c2799633-e85c-0a39-7c33-702b884b84ca.png)


## 参考情報
* http://w2ui.com/web/demo/grid
* https://tr.you84815.space/w2ui_grid/index.html
* https://qiita.com/nakatomodesu/items/8909621929f03f7ceaa7#grid
【Javascript】複数の要素からクリックで特定の要素を取得して処理を行う

ポートフォリオ作成と同時並行で、最近は純粋なjavascriptのコーディングを練習しているのですが、いいねボタン実装のときにせっかくだからjavascriptを使おうと思って挑戦したら少し躓いてしまったので、そこんとこメモしとこうと思います。

#実現したいこと
複数の要素の中から特定の要素を取得し、その要素にのみ処理を行う。

今回は、「複数のボタンのうち、特定のボタンをクリックしたら、そのボタンのみに処理が行われる」コードを書いていきます。

#HTML
まずはhtmlのコードから。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="test.js" type="text/javascript"></script>
</head>
<body>
    <div>
        <div>
            <button class="icon-btn">三橋</button>
        </div>
        <div class="box">
            <button class="icon-btn">阿部</button>
        </div>
        <div class="box">
            <button class="icon-btn">田島</button>
        </div>
        <div class="box">
            <button class="icon-btn">花井</button>
        </div>
    </div>
</body>
</html>
```

それぞれのbuttonタグに、class="icon-btn"を振っています。

この中のうち一つを取得したいのであれば、まずはclass="icon-btn"全てを取得する必要があります。

#Javascript
jsファイルには以下のように記述しました。

```test.js
document.addEventListener('DOMContentLoaded',function(){
    var btns = document.querySelectorAll('.icon-btn');
    for(var i = 0; i < btns.length; i++){
        btns[i].addEventListener('click',function(){
            alert('クリックされたよ！');
            this.style.color = 'blue';
        },false);
    }
},false);
```

順番に見ていきましょう。

※ 3/8 コメントにて文字列リテラルが統一されてないとご指摘を受けたので一部修正しています。

##全ての要素を取得
querySelectorはhtmlからタグやらクラスやらidやらを取得してきてくれる良い子です。

getElementsByNameなどより、cssに近い形で記述できるのがいいですね。

しかし、querySelectorはあくまで一番最初に合致した要素しか取得してくれないので、今回実現したいことには向いてません。

なので、querySelectorAllを使用しています。

querySelectorAllは該当する全ての要素を取得してきてくれるので、リストやクラスを取得したいときに便利。

```test.js
var btns = document.querySelectorAll('.icon-btn');
```

今回は、その取得した要素を変数btnsに入れました。

##繰り返し処理と特定要素の取得
全ての要素を取得できたので、あとはそれらを繰り返し処理で一つ一つ判別できるようにします。

```test.js
for(var i = 0; i < btns.length; i++){
    btns[i].addEventListener('click',function(){
         this.style.color = 'blue';
    },false);
}
```

まずはfor文でbtnsに格納されている要素の長さ分だけ、変数iに1を足していきます。

そしてbtns[i]のように、iでインデックス番号を表現します。
これでbtnsを一つ一つ判別することができました。

###addEventListener
addEventListenerはイベントとそのときの処理について書くことができます。
クリックイベントであれば、onclick="changeColor()"みたいな感じのやつです。

onclickを使っても良かったのですが、最近観たUdemyの動画ではあまりhtmlにjavascriptの処理を書くのは良くないと非推奨にされていたため、今回はaddEventListenerを使用しました。

addEventListener内には、とりあえずボタンのテキストの色を変更するために

```test.js
btns[i].addEventListener('click',function(){
     this.style.color = 'blue';
},false);
```

と書いてます。

thisでクリックされたボタンを持ってきて、そのボタンのテキストの色を変更しているといったイメージでしょうか。

このコードで動かしてもらえれば、正常に動作するはずです。

#まとめ
今回はポートフォリオのいいね機能実装のために挑戦しましたが、javascriptは便利機能が多すぎるが故に結構戸惑ってしまいました。

ともあれ純粋なjavascriptコードを書くのは楽しかったので良かったです。

この記事が誰かの参考になれば幸いです。

ではでは。
Xavierの初期値とは？？　〜機械学習の用語まとめ〜

#重みの初期値の重要性
ニューラルネットワークの学習においては、Optimizerに従って重みが最適化される。その際、学習を始める前に重みの初期値を設定しなければいけない。

実は、重みの初期値はニューラルネットワークの精度に大きく関わってくる。
例えば、[SGD(確率的勾配法)](https://qiita.com/Becon147/items/8962c85fddf7168e631a)では、初期値の位置によっては極小値で停滞してしまい、最小値にたどり着くことができないことがある。
精度だけでなく、学習の速度にも大きく関わってくる。

#重みの初期値によって発生する問題
では、重みの初期値はどのように設定すればいいのか？
重みの値が大きくなってしまうと、過学習が起きやすくなってしまうため、重みはできるだけ小さくしようと考える。ならば重みの初期値も小さくしようと考えるのは自然であろう。

では、重みの初期値を0にしたらどうだろう。
これは学習を悪化させてしまう。0にすることが問題というより、重みを均一することが問題なのである。
仮に全ての重みの初期値を0にして伝播させると、順伝播で同じ値が伝播してしまう。よって重みが同じように更新されてしまい、表現の幅が狭くなってしまう。

他にも発生する問題がいくつかある。

#勾配消失
逆伝播の値が0に近いと重みの更新量が小さくなり、重みが停滞してしまい、学習が進まなくなってしまうことを指す。
この原因の一つが重みの初期値によるものである。
そのため、適切な初期値の設定が求められる。

#表現力の制限
活性化関数のあとの出力データ(**アクティべーション**)が偏ってしまうと、ニューラルネットワークの表現の幅が狭くなってしまう。
アクティべーションが偏るということはつまり、各ニューロンの出力する値にあまり違いがでないということになってしまうので、複数のニューロンを持つ意味がなくなってしまう。
アノテーションがいろんな値をとることで、様々な表現が可能になるので、アノテーションが偏らない初期値設定が重要になってくる。

このように重みの初期値は学習の様々な問題に関わってくるため、重みの初期値の設定は、非常に重要であると言える。これらの問題を解決するのが**Xavierの初期値**である。

#Xavierの初期値
Xavierの初期値は、2010年にXavier氏などによって書かれた [Understanding the difficulty of training deep feedforward neural networks](http://proceedings.mlr.press/v9/glorot10a/glorot10a.pdf)において提案された手法である。
Xavierの初期値は、各層のアクティベーションが同様の広がりの分布になるように、前層のノードがn個のとき、平均0,標準偏差$\frac{1}{\sqrt{n}}$である正規分布から初期値を生成する、というものである。

Xavierの初期値を用いることで、各層のアクティベーションが広がりを持った分布になり、先ほど述べた問題が発生しにくくなる。

Xavierの初期値は、主にシグモイド関数等を活性化関数として用いた時に効果を発揮する初期値である。

#まとめ
ニューラルネットワークにおける重みの初期値は、学習の精度、速度に大きく影響する非常に重要な問題であり、勾配消失、アクティベーションの偏りなどが起こらないようにしなければいけない。
そこで提案されたのが「Xaiverの初期値」である。
Xavierの初期値によるアクティベーションは、広がった分布となり、高い表現力を有する。
活性化関数としてシグモイド関数などを用いるときはおすすめである。


###参考
[ゼロから作るDeep Learning ―Pythonで学ぶディープラーニングの理論と実装](https://www.amazon.co.jp/dp/4873117585)
nodejsのpathモジュールの使い方

pathモジュールの使い方をまとめました。

# 前提条件
- npmがインストールされていること

# 使い方
## 設定

`touch`コマンドでファイルを作成します。

```shell
$ touch test.js
```

```javascript:test.js
const path = require('path')

console.log('basename:', path.basename('./dir/test.txt'))
console.log('dirname:', path.dirname('./dir/test.txt'))
console.log('extname:', path.extname('./dir/test.txt'))
console.log('parse:', path.parse('./dir/test.txt'))
console.log('join:', path.join('dir', 'dir2', 'test.txt'))
console.log('relative:', path.relative('./dir', './dir2/test.txt'))
```

## 実行
`node`コマンドを実行します。

```shell
$ node test
```

## 出力結果
```console
basename: test.txt
dirname: ./dir
extname: .txt
parse: { root: '',
  dir: './dir',
  base: 'test.txt',
  ext: '.txt',
  name: 'test' }
join: dir/dir2/test.txt
relative: ../dir2/test.txt
```

# 参考文献

この記事は以下の情報を参考にして執筆しました。

- [パス操作(path)とファイル操作(fs)](https://www.wakuwakubank.com/posts/663-nodejs-fs-path/)
kubectlコマンドでタブ補完を使えるようにする

#はじめに
シェルはbash派なんですが、bashだとタブを押すとでコマンドを補完してくれます。
kubectlコマンドもシェルで補完してくれますが、サブコマンドは補完してくれません。
kubectl get podくらいなら別にいいんですが、describeとかは地味に面倒。そこで調べてみると、サブコマンドまでタブで補完してくれる機能があったので、試してみました。

#環境変数の設定
「.bashrc」ファイルに以下の一行を追記する。
_source <(kubectl completion bash)_

```bash:.bashrc
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# Uncomment the following line if you don't like systemctl's auto-paging feature:
# export SYSTEMD_PAGER=

# User specific aliases and functions

source <(kubectl completion bash) #added
```

ドット実行で反映させる。

```
$ . .bashrc
```

#動作確認
```
$ kubectl de
delete    describe
$ kubectl describe p
persistentvolumeclaims             poddisruptionbudgets.policy        pods.metrics.k8s.io                podtemplates
persistentvolumes                  pods                               podsecuritypolicies.policy         priorityclasses.scheduling.k8s.io
$ kubectl describe pod -n sock-shop carts-
carts-5fc45568c4-r4fqk     carts-db-64ff6c747f-vlghp
```

これだけだと感動が伝わらないんですが、サブコマンドだけでなく、namespaceやリソース名なんかもタブで補完できるようになりました。
特にPodはシステムがランダムな英数字を付与するし、起動するたびにそこが変わるので、毎回確認する必要があったけど、これで確認する手間が省けるようになりました。

ちょっとしたことですが、これでだいぶ楽になります！
Dockerで立ち上げたサービスのログをWeb上から簡単に見れる「Dozzle」

ローカル開発環境でdockerを利用していると、`docker logs`なり`docker-compose logs`コマンドでログを見ると思いますが確認するときにコマンド叩かなきゃいけなかったりで少し面倒ですよね。

調べてみたらいい感じにシンプルにweb上でdockerのログが見れるアプリケーションがあったので共有です。

# Dozzle https://dozzle.dev/

Dozzleはめちゃくちゃ簡単にdockerのリアルタイムログが確認できるアプリケーションです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/7056/7b05a71a-3fbd-4db9-4198-f2b9786727e5.png)


## とりあえず使うだけなら

```
docker run --detach --volume=/var/run/docker.sock:/var/run/docker.sock -p 9999:8080 amir20/dozzle
```

これだけ打つだけでdockerのログを確認することができるweb uiが`http://localhost:9999`に立ち上がります。

## docker-compose.ymlに埋め込むなら

正直私はこっちがメイン

```yml
dozzle:
  image: amir20/dozzle:latest
  environment: 
    - DOZZLE_ENABLE_ACTIONS=true
    - DOZZLE_FILTER=status=running
  volumes:
    - /var/run/docker.sock:/var/run/docker.sock
  ports:
    - "9999:8080"
```

こんな感じに。

https://github.com/amir20/dozzle#environment-variables-and-configuration
に設定できるEnvironmentが書かれています。

# さいごに

正直毎回毎回コマンド経由でログを見るのは忘れたりとかしやすいのもあるので、こんな風にシンプルなアプリケーションがあるのは嬉しい。
spam 対策として、とりあえず postscreen を有効化しておく

# 要約

Postfix でメールサーバを運用している管理者は、すべからく [postscreen(8)](http://www.postfix.org/POSTSCREEN_README.html) を有効化しておくべし。

# 背景

3000人規模のアクティブユーザがいるメールサーバを Postfix で運用しています。今回、遠隔地 DC にラックを借りて設置していたメールサーバを廃止して、パブリッククラウド上の仮想マシンに引っ越しすることになり、それに併せて Postfix の設定の棚卸しを行ないました。その過程で、[postscreen(8)](http://www.postfix.org/POSTSCREEN_README.html) を発見。

> SMTP サーバがグリーティングメッセージを返す段階で遅延させて、spam ボットに接続をあきらめさせる？ああ、[Starpit](https://stealthinu.hatenadiary.jp/entry/20060706/p5) みたいな対策か。まあ、あれもすぐに効かなくなったからなあ…

と思いつつ、半信半疑で有効化してみました。すると、約8時間で以下のような成績になりました。

|分類|件数|
|:---|---:|
|postscreen によって弾かれたメール|11988|
|smtpd によって弾かれたメール（送信者ドメインが見つからない等）|1982|
|実際に受信・配送されたメール|7684|

実に55％もの負荷低減です。[Starpit](https://stealthinu.hatenadiary.jp/entry/20060706/p5) よりもさらに設定が簡単なので、Postfix でメールサーバを運用している方は、とりあえず設定しておいて損はないと思います。

# 設定

以下のように、`/etc/postfix/master.cf` で smtp の行をコメントアウトして、postscreen の行と smtpd の行を有効化します。基本的な設定は、これだけです！

```conf:/etc/postfix/master.cf
# ==========================================================================
# service type  private unpriv  chroot  wakeup  maxproc command + args
#               (yes)   (yes)   (no)    (never) (100)
# ==========================================================================
#smtp      inet  n       -       y       -       -       smtpd
smtp      inet  n       -       y       -       1       postscreen
smtpd     pass  -       -       y       -       -       smtpd
```

後は、好みの設定をいくつか。筆者の環境では、以下のように、自組織のネットワークに対するホワイトリストに登録し、グリーティングメッセージの遅延を少し増やし（デフォルト6秒→15秒）、グリーティングメッセージを無視するなどプロトコルエラーをした接続元は接続拒否、という設定をしています。

```conf:/etc/postfix/main.cf
postscreen_access_list = permit_mynetworks, cidr:/etc/postfix/postscreen_access.cidr
postscreen_greet_wait = 15s
postscreen_greet_action = enforce
```

```conf:/etc/postfix/postscreen_access.cidr
192.0.2.0/24	permit
```
Mac Audacity(オーダシティ)のインストールを行う

# 目的

- Podcasterの味方AudacityをMacにインストールする方法をまとめる
- 誰でもこの投稿を見ればインストール可能な様にまとめる

# 導入環境

- PC  
    - 本体: MacBook Air (11-inch, Mid 2012)
    - プロセッサ: 1.7 GHz デュアルコアIntel Core i5
    - メモリ: 8 GB 1600 MHz DDR3
    - グラフィック: Intel HD Graphics 4000 1536 MB
- OS
    - macOS Catalina(10.15.3)

# 実施手順概要

1. ダウンロード
1. インストール
1. 録音確認

# 実施手順詳細

1. ダウンロード
    1. 下記のリンク先を表示する。
        - [https://www.fosshub.com/Audacity.html](https://www.fosshub.com/Audacity.html)
    1. 下記が表示される。
        ![スクリーンショット 2020-03-05 20.53.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/258386a9-01c2-4fa3-4ad4-abbcb814ad75.png)
    1. 「Audacity macOS SMG」をクリックする。
        ![スクリーンショット 2020-03-05 20.54.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/89932e44-de33-c565-8766-d944699afe30.png)
    1. ダウンロードが開始されるので完了するまで待機する。
        ![スクリーンショット 2020-03-05 20.55.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/45680729-c041-6e73-1bb3-88dce92bb7fb.png)
    1. ダウンロードフォルダを開く
    1. ダウンロードしたインストーラ(audacity-macos-X.X.X.dmg)が存在することを確認する。
1. インストール
    1. ダウンロードフォルダを開く
    1. ダウンロードしたインストーラ(audacity-macos-X.X.X.dmg)をダブルクリックで起動する。
        ![スクリーンショット 2020-03-05 20.57.12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/7132dc1d-936c-e87b-dd38-6c636fbd696d.png)
    1. 下記のウインドウが出たら同ウインドウ上でAudacityのアイコンをアプリケーションフォルダにドラックする。
        ![スクリーンショット 2020-03-05 20.17.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b661d90c-107f-6942-2d58-c9cf57ad3867.png)
    1. アプリケーションフォルダにAudacityが追加されたことを確認する。
        ![スクリーンショット 2020-03-05 20.19.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/ed2f8de9-1025-a584-e9bb-26f14e974296.png)
    1. アプリケーションフォルダのAudacityアイコンをダブルクリックする。
    1. 下記のウインドウが開いたら「開く」をクリックする。
        ![スクリーンショット 2020-03-05 20.21.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/b40377ad-d747-2b21-232c-953186d5ab6d.png)
    1. アプリが起動し下記のウインドウが開いたらインストールは完了である。
        ![スクリーンショット 2020-03-05 20.58.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/f3c8a982-77ae-429e-52bd-043a134db375.png)
    1. ヘルプ情報のご案内ウインドウの「閉じる」をクリックする。
1. 録音確認
    1. Audacityを起動し、下記の画面が開いていることを確認する。
        ![スクリーンショット 2020-03-05 21.04.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/d57a563f-893a-5c7a-1eb7-90d80ede650a.png)
    1. 自分のMacに内蔵マイクと内蔵スピーカーが存在していることを確認しウインドウの上部の帯のマイクマークの右横のウインドウに「内蔵マイク」、スピーカーマークの右横に「内蔵出力」となっていることを確認する。(内蔵音声入出力がないMacの場合は取り付け後、内蔵音声入出力端末を選択する。)
    1. ![スクリーンショット 2020-03-05 21.11.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/306417/94e70115-7e25-9c2e-8705-4b134ad46897.png)
    1. ウインドウの上部の帯の録音ボタン(赤い丸)をクリックする。
    1. 下記の様に音声の波形が表示されることを確認する。
kubectlでUnable to connect to the serverが出てきちゃう

## 概要

EKSのクラスターに繋ぐように設定していたkubectlで以下のエラーが。

```
$ kubectl get pods

Unable to connect to the server: dial tcp: lookup [API サーバーエンドポイント]: no such host
```

そういえばkubeconfigを作成した後、EKSでそのクラスターが削除されてたのを思い出した。


## やったこと

**結論から言うと、kubeconfigを一旦作り直しました。**


やったことには悪手も含まれているので、どういうエラーが返ってきたかは参考になると思いますがコピペは責任取れませんmm


### 現状把握

```
$ kubectl config view

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: DATA+OMITTED
    server: [旧API サーバーエンドポイント]
  name: [旧クラスター ARN]
contexts:
- context:
    cluster: [旧クラスター ARN]
    user: [旧クラスター ARN]
  name: [旧クラスター ARN]
current-context: [旧クラスター ARN]
・
・
・
```

という感じで、kubectlくんが既に存在しないクラスターの情報を見に行ってるようです。

本来の手順としては

- `kubectl config delete-cluster hoge` で旧クラスターを削除
- `kubectl config delete-context fuga` で旧コンテキストも削除
- `kubectl config set-cluster spam` で新クラスターを登録
- `kubectl config set-context ham` で新コンテキストを登録
- ・
- ・
- ・

とか、まだあると思いますが、基本的にはそのように登録を進めていけばいいはずです。

私はここで、vimを使って~/.kube/config内のファイルを編集してしまい、よく分からん挙動になってしまいました。

詳しく書くと更に読者を混乱させるのでやめておきます。


### kubeconfigを作成し直す

```
$ mv ~/.kube/config ~/Desktop
$ aws eks --region [リージョン] update-kubeconfig --name [新クラスター名]

Added new context [新クラスターのARN] to /Users/myname/.kube/config
```


実際にkubectlを打ち込むと正常に起動します。catでみても問題なさそう。

コマンドがあるのに我流でvimは良くないですね、自戒。
３ヶ月のJavaとSpring研修を終えて

#書いた目的
マークダウン記述法の理解
自分用のメモ

#これまでのプログラミング経験
HTML,CSS,JavaScript,php
Vue,Laravel
バックエンドは苦手であり、フロントエンド周りを中心にスクールをきっかけに独学で勉強をしていた。

#Javaに対して純粋に感じたこと
 - 良かった点
  - １つの処理を記述すれば、あとは特に考えずデータを渡してやればいいので楽
  - 実行前にエラーが大抵わかる
  - 型指定が厳しい為にデータの扱いがきちんとできる
  - そもそもプログラミング言語とは？が学べる
  - ハードに依存しない


 - 悪かった点
  - とにかく記述量が多い
  - 冗長になりやすい
  - 型が厳密すぎて初学者にはハードルが高い
  - モダンじゃない
  - ウォーターフォールになりやすいかも
  - 学びのコスパが悪い
  - 必然的に時間がかかる

#Spring(SpringBoot)に対して純粋に感じたこと
 - 良かった点
  - アノテーションがめちゃくちゃ便利
  - MVCで分かれているのでエラー箇所を突き止めやすい
  - 規約重視なので他人のコードも読みやすい
  - 同じ処理の再利用が考えやすい

 - 悪かった点
  - 自ページに戻る可能性があるControllerの記述はどこのページの何の処理か不明になる場合がある（個人的）
  - アノテーションが便利なので基本的なエラーに気づけない可能性（初学者の場合）
  - 冗長になりやすい
  - STSツールのバージョンなどがわかりづらい・・・。

#何を作ったのか？
###ECサイト
　**実装項目**
　　管理者とユーザー毎のログイン機能（SpringSecurityは使用不可）
　　カート機能
　　ページング
　　DBへの新規登録、更新、追加、検索、複合条件検索、論理削除


###レンタカー予約サイト
　**実装項目**
　　*上記の４項目*
　　管理者のフラグ判別でのページルーティング
　　DBのテーブル結合によるデータ抽出、修正

#開発環境（verは省略）
　　**eclipse**

　　**Spring tool suite3**
　　　Spring Boot
　　　Spring Jdbc
　　　Spring Web
　　　Bean Validation

　　**Thymeleaf**
　　　
　　**MysqlWorkBench**
　　　AWS　S3

#開発で詰まった点
###ネットのリソースが古い
詰まる度にぐぐるが、結構前の記事が多かった。
動かないわけではないが、モダンな書き方や技術なのかが不安になった。
###Modelの種類はどこまで切り分けるべきか
DBに合わせてEntityを作っていたが、EntityはViewに直接表示すべきでないと言われたので、表示用のModel（コード内容はコンストラクター以外はEntityと全く同じ）を作りコンストラクターの引数にEntityを指定し詰め替えを行っていた。
ここはCloneメソッドでもいいかと思ったが、Cloneをする必要はないとのこと。
一番悩んだのが、DBのレコード更新などでForm用のModelを作るべきかという点。
研修が全て終わって聞いたところによると、プロダクトによるとのことだった。
Modelは基本的に切り分けずに、一個のModelで行っていいとのことだったが将来的にDBの内容が変更になる可能性がある場合や、大規模開発の場合などは切り分けてModelを使い分けたがよいとのことだった。
###型が厳格で詰まった
もう慣れたので、詰まることは少ないと思うが **List<>** からの値の抽出と詰替やViewで入力してDBから戻ってくる値の型が違う場合などは最初の頃はずっと詰まって進むことができなかった。
値の数やデータの型など把握すべき内容で詰まっていた。
その状況でDBのjoinが関わってきたので更に混乱した。
特にTimestampとDateは気をつけないとDBのデータとのやりとりが煩わしくなった覚えがある。
###データはHttpSessionとModelのどっちで受け渡すべきか
開発中に思ったのは、バリデーションが関わったり、値が変わる可能性があるのは全てModelで受け渡しを行うべきだと感じた。
逆にほとんどの場合はセッションに保持しておき、いざと慣ればinvalidate()で全削除でいいのかと思っていた。
inputのhiddenで受け渡す方法もあるがアンチパターンになると思うので使うのを避けた。
###DBとのやりとり
最も詰まったのがDBとのデータの受け渡しであった。
まず、Mysqlのエラーメッセージが親切ではなかった。
そして、データの数が多くなると何がどこまで渡されていて、現状何が入っているのかも把握できなくなっていた。
Constantsの定数で把握しやすくするのも一つの手段であったが、個人的には逆にわかりにくく使うのを避けた。

#JavaとSpringの具体的に身についた知識
####compareToメソッド
`変数1.compareTo(変数2)`

メソッドの呼び出し元の値(変数1)が、引数の値(変数2)より小さい場合は”負の値”
メソッドの呼び出し元の値(変数1)が、引数の値(変数2)より大きい場合は”正の値”
メソッドの呼び出し元の値(変数1)が、引数の値(変数2)と同じ場合は”0”
[侍アカデミーより引用](https://www.sejuku.net/blog/24996)

日付の重複チェックなどで容易に使うことができ便利と感じた。
####随時更新予定
【Rails】brakeman設定からCircleCIで動かすまで

# brakemanとは

Ruby on Railsアプリケーション用の静的セキュリティ脆弱性解析スキャナーです。
使うことのデメリットはないので、デフォルトで設定しましょう。

# 環境

- Rails 5.2.3
- [brakeman](https://github.com/presidentbeef/brakeman) v4.8.0

# インストール

```ruby:Gemfile
group :development do
  gem 'brakeman'
end
```

# コマンド実行例

### ヘルプ（オプションなどを表示）

```
$ bundle exec brakeman --help
```

### 全てのチェックを行う

```
$ bundle exec brakeman -A
```

### 警告のうち、無視してよい項目を指定するファイルを作成する
コメント（無視してよい理由）も書けるので、きちんと書いておきましょう。
デフォルトでは config/brakeman.ignore にファイルが作られます。

```
$ bundle exec brakeman -I

// -A と合わせて使う時は -IA とします。
$ bundle exec brakeman -IA
```

### オプション指定例

```
$ bundle exec brakeman -5 -A -w1

-5 Railsのバージョンを指定。無くても自動検出してくれるので通常は指定不要です。Rails4 や 6 の場合は、それぞれ -4 や -6 を指定します。
-A 全ての項目をチェックします。
-w1 チェックする項目のレベル設定で、1〜3まで指定可能です。1は全警告を出力し、3は重要度の高い警告のみ出力します。

実際の運用（CircleCI上で動かす時）では -A -w1 を指定しています。
```

# CircleCIでbrakemanを動かす

[このCircleCIの設定](https://qiita.com/luigiii/items/8addbc04982dcd40c076#%E8%A8%AD%E5%AE%9A%E4%BE%8B) で以下の箇所を参照してください。

- run_brakeman
- brakeman_job

# 警告例
## Missing Encryption - ForceSSL

```
Confidence: High
Category: Missing Encryption
Check: ForceSSL
Message: The application does not force use of HTTPS: `config.force_ssl` is not enabled
File: config/environments/production.rb
Line: 1
```

「`production.rb`で`config.force_ssl`の設定がされていない」という内容ですが、多くの環境ではLoad BalancerでSSLの暗号化/復号化を行うので、そういう場合は`ignore list`に入れましょう。

## Unscoped Find - UnscopedFind

```
Confidence: Weak
Category: Unscoped Find
Check: UnscopedFind
Message: Unscoped call to `Foo#find`
Code: Foo.find(params[:id])
File: app/controllers/foos_controller.rb
Line: 100
```

[brakemanのdocument](https://brakemanscanner.org/docs/warning_types/unscoped_find/) に説明があります。
以下、翻訳（意訳）です。
偽陽性が高いので、対応の必要がなければ`ignore list`に入れましょう。

別のモデルに属するモデルは、通常スコープクエリ（scoped query）を介してアクセスする必要があります。
たとえば、`User belongs_to Account`というアソシエーションの場合、これは安全ではない範囲指定された検索である可能性があります。

```ruby
Account.find(params[:id])
```

アクションによっては、攻撃者が自分以外のアカウントにアクセスできる可能性があります。
代わりに、現在ログインしているユーザーのスコープを設定する必要があります。

```ruby
current_user = User.find(session[:user_id])
current_user.accounts.find(params[:id])
```
Spring Boot 2.1.13.RELEASE にしたら外部からアクセスできなくなった件の対応について

## 事象
Sping Boot をバージョンアップして 2.1.13.RELEASE にしたら、外部からアクセスできなくなりました。

## 原因
原因はロードバランサからのヘルスチェックが無反応だった(AJP/1.3のためのポートに接続できなくなっていた)ためでした。
その原因はバージョンアップした Spring Boot に組み込みの Tomcat が 9.0.31 になり、デフォルトでは AJP が無効、そして、バインドアドレスがループバックアドレスとなっていて、外部からの接続が受け付けられないようになっているため。

参照
[Apache Tomcat 9 (9.0.31) - Changelog](https://tomcat.apache.org/tomcat-9.0-doc/changelog.html#Tomcat_9.0.31_(markt))

## 対処
AJP で Apache Httpd と連携させるため、WebServerFactoryCutomizer インターフェースを実装したクラスで設定します。
バインドアドレスをプロパティで変更可能にします。

```TomcatCustomizer.java
package com.example.demo;

import java.net.InetAddress;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.boot.web.server.WebServerFactoryCustomizer;
import org.springframework.stereotype.Component;

@Component
public class TomcatCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

	private Logger log = LoggerFactory.getLogger(getClass());
	
	@Value("${tomcat.ajp.address:127.0.0.1}")
	private String address;
	
	@Value("${tomcat.ajp.port:9009}")
	private int port;
	
	@Value("${tomcat.ajp.secretRequired:false}")
	private boolean secretRequired;
	
	@Override
	public void customize(TomcatServletWebServerFactory factory) {
		log.debug("address: {}", address);
		log.debug("port: {}", port);
		log.debug("secretRequired: {}", secretRequired);

		if (port == 0) {
			return;
		}

		try {
			InetAddress address = InetAddress.getByName(this.address);
			factory.setAddress(address);
		}
		catch (Exception e) {
			log.error("bad address", e);
		}

		factory.setProtocol("AJP/1.3");
		factory.setPort(port);

		factory.getTomcatConnectorCustomizers()
		.add(c -> c.setAttribute("secretRequired", secretRequired));
	}
}


```
円の内部の点か調べる

## 円の方程式
[円の方程式](https://qiita.com/tydesign/items/cb47c4001b211d1d9067) 参照

## 円と点の位置関係と判定方法

![円の内部の点か調べる_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384860/36635871-8127-7a06-0d94-75241193c14c.png)

円と点の位置関係は

- 円の内部の点 $(Q_1)$
- 円周上の点 $(Q_2)$
- 円の外部の点 $(Q_3)$

の3通り。
その判定方法は、円の中心から調べる点までの長さと、半径を比較して、

- 半径より小さい場合は、円の内部の点 $(CQ_1<r)$
- 半径と同じ場合は、円周上のの点 $(CQ_2=r)$
- 半径より大きい場合は、円の外部の点 $(CQ_3>r)$

となる。
円の中心の座標を$(a,b)$、半径を$r$、調べる点$Q$の座標を$(x,y)$としたとき、
$$ \sqrt{(x - a)^2 + (y - b)^2}<r$$
両辺を二乗して、
$$ (x - a)^2 + (y - b)^2<r^2$$
を満たす場合、円の内部の点と判断できる。
円周上の点も内部とみなす場合の判定式は、
$$ (x - a)^2 + (y - b)^2 \leqq r^2$$
となる。
#### 【例】　中心(3,2) 半径 5 の円に対して、
![円の内部の点か調べる_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384860/6a6002bf-f43e-c6d6-dff3-14780985cf57.png)
(1) $Q_1(2,6)$は、

```math
(2-3)^2+(6-2)^2=1+16=17\\ 
r^2=5^2=25\\ 
17<25\quad なので\quad Q_1は円の内部の点
```
(2) $Q_2(7,5)$は、

```math
(7-3)^2+(5-2)^2=16+9=25\\ 
r^2=5^2=25\\ 
25=25\quad なので\quad Q_2は円周上の点
```
(3) $Q_3(8,-2)$は、

```math
(8-3)^2+(-2-2)^2=25+16=41\\ 
r^2=5^2=25\\ 
41>25\quad なので\quad Q_3は円の外部の点
```
## 判定プログラム
```scheme
;; 円周上の点か調べる
;; Args - cx : 円の中心のx座標
;;        cy : 円の中心のy座標
;;        cr : 円の半径
;;         x : 調べる点のx座標
;;         y : 調べる点のy座標
(defun circle:IsOn (cx cy cr x y)
    (equal (+ (expt (- x cx) 2) (expt (- y cy) 2)) (* cr cr) 1e-8)
)

;; 円の内部の点か調べる
(defun circle:Contains (cx cy cr x y)
    (< (+ (expt (- x cx) 2) (expt (- y cy) 2)) (* cr cr))
)

;; 円の内部の点か調べる
;; 円周上の点も含める
(defun circle:IsOnOrContains (cx cy cr x y)
    (or (circle:IsOn cx cy cr x y) (circle:Contains cx cy cr x y))
)

;; < Example >
(circle:IsOn 3. 2. 5. 2. 6.)  ;;Q1
;; -> T
(circle:IsOn 3. 2. 5. 7. 5.)  ;;Q2
;; -> nil
(circle:IsOn 3. 2. 5. 8. -2.) ;;Q3
;; -> nil
(circle:Contains 3. 2. 5. 2. 6.)  ;;Q1
;; -> nil
(circle:Contains 3. 2. 5. 7. 5.)  ;;Q2
;; -> T
(circle:Contains 3. 2. 5. 8. -2.) ;;Q3
;; -> nil
(circle:IsOnOrContains 3. 2. 5. 2. 6.)  ;;Q1
;; -> T
(circle:IsOnOrContains 3. 2. 5. 7. 5.)  ;;Q2
;; -> T
(circle:IsOnOrContains 3. 2. 5. 8. -2.) ;;Q3
;; -> nil
```
Linux学習記録①計画とか

急遽業務上の都合でLinuxスキルが必要になった。
せっかくなので、技術獲得に向けての七転八倒と阿鼻叫喚を記録したいと思う。

【私の経歴】
・インフラエンジニア（half decade）
・メインフレーム関係のシステム構築やら保守やら
・経験クライアント業界は色々

【なぜLinuxを触ることになったか】
・今後のキャリアを考えた時、メインフレームの知識しか無い現状が心もと無く思えた。
　→職場のプロジェクトでサーバー系のチームが未経験可のヘルプ要員募集をかけていたので、手を挙げたら運よく採用。
　　
【学習プラン（ざっくりの予定）】
・自宅PCに環境構築
・『新しいLinuxの教科書』を終わらせる

ヘルプ先が慈悲深くもLinux勉強期間の猶予を恵んでくださったので、迷える子羊としてはお喜び頂ける人材になるべく精進する決意であります。

記録はまず3日続けばいいや。
るんるんやります。