OmniAICreator/Qiita-1.07M huggingface dataset:
エクセルシート上で、DNA配列の多重アラインメントのSNPに着色するマクロ

#はじめに
複数のDNA配列のアラインメントについて、エクセルシート上で、コンセンサス配列と異なるところに色をつけたいことってありますよね。

今回は、多重配列アラインメント(1セル 1塩基)からコンセンサス配列を求めるマクロと、多重配列アラインメントの中のコンセンサス配列と異なる塩基のセルの色を変えるマクロ、の2つを記述します。
#目標とする機能

こんなデータを、
<img width="304" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595771/a53b5fe6-9136-e1aa-5935-8961e32e3b59.png">

こんな風にします。

<img width="304" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/595771/1b24a8cb-2f4d-5e79-7790-cb4aeb067c19.png">

もちろん配列の数がもっと多くても、あるいはもっと長くても大丈夫なように作ります。

#コンセンサス配列を作るマクロ
コンセンサス配列を求めたい多重アラインメント部分を選択した上で、マクロを実行すると、選択した各列について、1行目のセルに最も登場頻度が高かった文字を出力するようにします。一番上の行は空けておかないといけないことになります。

MacだとVBAでは辞書機能が使えないということで(衝撃)、DNA限定で作ります。

```vb
Sub コンセンサス()

Dim a As Integer
Dim c As Integer
Dim g As Integer
Dim t As Integer
Dim char As String

For Column = Selection(1).Column To Selection(Selection.Count).Column
    a = 0
    c = 0
    g = 0
    t = 0

    For Row = Selection(1).Row To Selection(Selection.Count).Row
        char = UCase(Cells(Row, Column).value)'入力が小文字の時もあるかもしれないので大文字に。
        If char = "A" Then a = a + 1
        If char = "C" Then c = c + 1
        If char = "G" Then g = g + 1
        If char = "T" Then t = t + 1
    Next Row

    If a > c And a > g And a > t Then
        Cells(1, Column) = "A"
    ElseIf c > a And c > g And c > t Then
        Cells(1, Column) = "C"
    ElseIf g > a And g > c And g > t Then
        Cells(1, Column) = "G"
    ElseIf t > a And t > c And t > g Then
        Cells(1, Column) = "T"
    Else
        Cells(1, Column) = "?"
    End If
    
Next Column
End Sub
```
...特に難しいところはありませんでしたね。同数の場合は?となるようになっています。これで1行目にコンセンサス配列が表示されるようになりました。
続けて、コンセンサスと異なるところに色をつけるようにします。

```vb
Sub 異なるところに色を塗る()

'コンセンサス配列を1行目に入れておく
'選択範囲の各セルについて、1行目と異なれば、背景色を赤にする。

For Row = Selection(1).Row To Selection(Selection.Count).Row
    For Column = Selection(1).Column To Selection(Selection.Count).Column
        If Cells(Row, Column).value <> Cells(1, Column).value Then
                If Cells(Row, Column).value = "A" Then
                    Cells(Row, Column).Interior.ColorIndex = 4
                ElseIf Cells(Row, Column).value = "C" Then
                    Cells(Row, Column).Interior.ColorIndex = 33
                ElseIf Cells(Row, Column).value = "G" Then
                    Cells(Row, Column).Interior.ColorIndex = 15
                ElseIf Cells(Row, Column).value = "T" Then
                    Cells(Row, Column).Interior.ColorIndex = 3
                Else
                    Cells(Row, Column).Interior.ColorIndex = 44
                End If
       End If
    Next Column
Next Row

End Sub
```
これでコンセンサスと異なるところに色を塗れるようになりました。

#終わりに
二回マクロを実行するのが面倒なら、一度に両方やってくれるようにしても良いかもしれません。思ったものができたということで、今回はこれで終わりにしたいと思います。
【laravel】ヘルパーメソッドが使えない時の対処法

## 今回はlaravel学習初期でつまづいたエラーの解決法をお伝えします。

今回起きたエラーはこちら。

<img src="https://i.gyazo.com/9eb2a11b82644b94ec3f6e727b34e424.png" alt="Image from Gyazo" width="500"/>

**エラー文⬇︎**
##### <font color="red">Call to undefined function str_limit()
---
laravelのヘルパーメソッドである`str_limit`が定義されていません。とのことでした。

<details><summary>laravelのヘルパーメソッド一覧（参照サイト）</summary><div>
メソッドは違うけど上記のようなundefined functionエラーが出ている場合は、以下サイトで検索してみてください。あれば`ヘルパーメソッド`ということです。

[Laravel 5.5 ヘルパ](https://readouble.com/laravel/5.5/ja/helpers.html)
</div></details>

## 解決策
今回のようなヘルパーメソッドが使えない場合は、 **ヘルパーメソッド自体をインストールする** ことで解決できます。
以下コマンドを実行してください。

```:ターミナル
$ composer require laravel/helpers
```

<details><summary>正常に実行できた場合</summary><div>
以下のような内容が表示されます。

```:ターミナル
Using version ^1.2 for laravel/helpers
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 1 install, 0 updates, 0 removals
  - Installing laravel/helpers (v1.2.0): Downloading (100%)         
Writing lock file
Generating optimized autoload files
> Illuminate\Foundation\ComposerScripts::postAutoloadDump
> @php artisan package:discover --ansi
Discovered Package: facade/ignition
Discovered Package: fideloper/proxy
Discovered Package: fruitcake/laravel-cors
Discovered Package: laravel/tinker
Discovered Package: nesbot/carbon
Discovered Package: nunomaduro/collision
Package manifest generated successfully.
25 packages you are using are looking for funding.
Use the `composer fund` command to find out more!
```
</div></derails>

あとはプラウザをリロードすれば、このエラーは解決できているかと思います。

今回のエラー解決は以上です。
ありがとうございました。

## 参照記事
2019年09月11日更新[【Laravel 6】ヘルパが使えない!?](https://oversealife.work/2019/09/11/laravel-6-helper/)
GASとSlackの連携

# GASでSlackのbotを作成するときの備忘録

独学でプログラミングを勉強中の備忘録として投稿する。
全てが初めての作業でかなり詰まったのでそれらについて記載する



## 作りたかったのも

Slackの特定のチャンネルに文字を投稿した場合に、スプレッドシートにある文言をランダムで返すbot


## 作成の大枠

#### スプレッドシートの文字をSlackへの投稿
Slackにてアプリの作成
SlackにてIncoming Webhookの設定
GASにてプログラムを作成


#### Slackの投稿に対して反応して投稿を返す
SlackにてOutgoing Webhookの設定
スクリプトエディタ にて設定


## 参考にした記事
https://tech.camph.net/slack-bot-with-gas/
https://techblog.gmo-ap.jp/2019/09/06/slack%E3%81%A8%E3%82%B9%E3%83%97%E3%83%AC%E3%83%83%E3%83%89%E3%82%B7%E3%83%BC%E3%83%88%E3%82%92%E9%80%A3%E6%90%BA%E3%81%97%E3%81%A6%E7%AD%8B%E3%83%88%E3%83%AC%E7%AE%A1%E7%90%86%E3%82%92%E3%81%99/

大変参考になりました。
ありがとうございます。

##
基本的には上記の記事を参考に進めていきました。

##詰まったところ

コード自体は正しい（ほぼコピペだし・・・）が、Slackからのpostに対して応答しない

スクリプトエディタからの実行ではSlackに応答を返すので問題なし
Outgoing Webhookの設定も問題なさそう
残すは、Outgoing Webhookがpostする先の設定が影響してそうということで、調査

## 原因1
公開アプリケーションの公開範囲はAnyone every anonymous
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/365337/100bae2e-a10c-10b2-16ba-e0981893c105.png)


## 原因2
コードの内容を変更する度にバージョン管理と公開しているアプリケーションのアップデートが必要

スクリプトエディタ の　ファイル > 版を管理
にてsave new versionを押下し最新バージョンを作成

公開 > ウェブアプリケーションとして公開
よりProject version を最新版にして更新

これに関しては、公開しているアプリケーションにcurlで応答を投げながら気づいた

帰ってくるエラー：TypeError: undefined　の指すエラー箇所の行数が永遠と同じ
何回コードを修正しても同じ、なんならその行を消したのにエラー

これは、アプリケーションが更新されていないと睨み上記の問題点に到達した。
（駆け出しプログラマの辛いところですね・・・）


curl -XPOST　”自分の公開URL”  -H "Accept: application/json" -H "Content-type: application/json" -d "{\"value\":\"lisz-works\"}"


## 今後やりたいこと
なんとかSlackとスプレッドシート の連携ができたのでここからやりたいことを実現させていきたい

タスク管理
Slincky（Chormoe拡張機能）によるURL収集をスプレッドシート へ反映
Googleカレンダーへの予定入力とGoogleハングアウトの予定入力

駆け出しエンジニアの奮闘は続く・・・・
ancestryの表示方法

ancestryの使い方は見かけますが、表示のさせ方はなかったので備忘録として投稿いたします。

ancestryについてはこちらの記事でご確認ください。
https://atora1992.hatenablog.com/entry/2019/07/08/215444

作成の都合上、viewファイルはhamlで記述しております。


今回はカテゴリーをこの様に表示をさせたい場合です。
<img width="635" alt="9f27f649a8d79dd1afa5b238f6efa2ed.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/606154/6473a347-2aef-7b65-d6d9-d1b1b2d2da18.png">

まずはcontrollerを記載します。
productテーブルから商品情報を取得、
その後にcategoryテーブルより親要素を取得します。

```rb

省略

  def show
    @product = Product.find(params[:id])
    @parents = Category.where(ancestry:nil)
  end

省略

  private
  def product_params
    params.require(:product)
  end

end
```

こちらがviewファイルになります。
＠parentsをeachで分けていきます。
そしてproductテーブルのcategories_idとcategoryテーブルのidが一致する場合、表示させる様に記述します。

```rb

//親要素だけの場合
- @parents.each do |parent|
  -if @product.categories_id == parent.id
    = link_to '#' do
      = parent.name
      %br
//子要素までの場合
  - parent.children.each do |child|
    -if @product.categories_id == child.id
      = link_to '#' do
        = parent.name
        %br
      = link_to '#' do
        = child.name
        %br
//孫要素までの場合
    - child.children.each do |grandchild|
      -if @product.categories_id == grandchild.id
        = link_to '#' do
          = parent.name
        %br
        = link_to '#' do
          = child.name
        %br
        = link_to '#' do
          = grandchild.name
        %br


```

こちらで表示が完了です。
今回、表示までの内容ですので、リンク先は未記載です。
ご了承ください。
メソッドの作成方法

※下記内容は、UdemyのURL教材を元に学習しております。
https://www.udemy.com/share/101Wu4AEIbd1ZRRHoF/

<h2>メソッドとは</h2>
処理に名前をつけていつでも呼び出せるようにしたもの。
例えば、「Hello　World」と10回記述したかった時、、、

```java:method.jave
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
System.out.println("Hello World");
```

と、わざわざ書くのは面倒。
メソッドを使えば下記のように記述可能。

```java:method.jave
void sayHelloWorld(int n){
  for(int i=1; i<=n; i++){
  System.out.println("Hello World");
  }
}
sayHelloWorld(10) 
```
一度、その処理のメソッドを作成してしまえば好きな時に、呼び出すことができる。

<h2>メソッドの作成方法</h2>
基本的には、変数の作成の時とほぼ同様。
引数を記述する部分と処理を記述する部分がある。
上記の例で言うと、
①「void」で、表示する結果の型を指定している。
②「sayHelloWorld」はメソッドの名前（呼び出す時に使用する名前）を決めている。
③「(int n)」では引数を指定できる。（指定しない場合は、メソッドの名前の後ろに「（）」のみ表記する。）
④「{}」の内部のコードで実行する処理を指定。
⑤「sayHelloWorld(10)」では上記で作成した処理を１０回実行。


<h4>戻り値</h4>
上記で紹介した様なメソッドの場合、処理は文字入力のみとなる。
メソッドの中身で結果を出すときに、戻り値として設定した場合、そのメソッドの処理の結果を別の処理につなげる時に活用することができる。

もちろん、型名が「void」の場合でも「System.out.println();」で計算した結果を出すことは可能であるが
処理の結果を「文字列」としてではなく、「有動小数点や整数値、真偽値」として得たい時に戻り値は有効である。

例えば、
ある商品の定価と、その商品の割引率（何%オフ）かを、入れることで、自動的に計算した結果を得たいとする。

```java:method２.jv
double calculationOfDiscountPrice(int price, double discountRate){
  double discountPrice = price - (price*discountRate/100);
  return discountPrice
}
calculationOfDiscountPrice(1000,10)
```
↓
９００

といった様に結果をえることができる。

<h4>パラメータ</h4>
尚、「method2.jv」の１行目に記載の
「double calculationOfDiscountPrice(int price, double discountRate)」
の（）の中身の部分はパラメータと言い、複数設定することができる。（メソッド内で与えることのできる変数）
「calculationOfDiscountPrice(1000,10)」
の（1000,10）の部分は「引数」と言い、パラメータに入れる数値/文字列である。
CircleCIのMachineでdocker-compose使いつつpytest走らせるよ

# 前提

-  Docker Executorとdocker-composeを組み合わせると想定外の動きをする可能性があるので、Machine Executorsを利用する
-  ただし将来的に追加料金がかかる可能性があるらしいので[こちら](https://circleci.com/docs/ja/2.0/docker-compose/)を要チェック


# コメント

-  imageはcircleci/classic系統を使おうとしたが、pyenvのインストール時にOpenSSLのエラー？が出たり、pytestを動かすうえで必要なライブラリが入らなかったので `ubuntu-1604:201903-01` を指定しました。
    -  ほかに指定できるimageは[こちら](https://circleci.com/docs/2.0/configuration-reference/#machine)で一覧になってます

- CircleCI特有の便利環境変数が結構いろいろ設定されているので（例えばCIや）pytestはそれを考慮して動かすと便利かも！



# 試行錯誤した結果のconfig.yml

- **！！キャッシュは全く設定していないので必要に応じて設定してください！！**

```yaml
version: 2
jobs:
  build:
    machine:
      image: ubuntu-1604:201903-01
    working_directory: ~/repo
    steps:
      - checkout
      - run:
          name: Install Docker Compose
          command: |
            curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` > ~/docker-compose
            chmod +x ~/docker-compose
            sudo mv ~/docker-compose /usr/local/bin/docker-compose
      - run:
          name: docker-compose up
          command: |
            set -x
            docker-compose up --build -d
      - run:
          name: docker-compose stop
          command: |
            set -x
            docker-compose stop
      - run:
          name: docker-compose up
          command: |
            set -x
            docker-compose up -d
      - run:
          name: wait for rdb
          command: |
            set -x
            chmod 777 wait-for-it.sh
            sudo bash ./wait-for-it.sh -h 127.0.0.1 -p 3306 # ←テストDBが起動するまで待つ
      - run:
          name: library setup
          command: |
            set -x
            sudo apt update
            sudo apt install mysql-common libmysqlclient20 libmysqlclient-dev # ←pytestで内で必要だったので入れました
            sudo apt install python-dev imagemagick-6.q16 # ←pytestで内で必要だったので入れました

      - run:
          name: pyenv setup
          command: |
            set -x
            git clone git://github.com/yyuu/pyenv-update.git /opt/circleci/.pyenv/plugins/pyenv-update  # ←デフォルトだと選べるバージョンが少ないのでupdateする
            pyenv update
            pyenv install 3.8.2
            pyenv global 3.8.2
            which python
            python -V
            pip install --upgrade pip
            pip -V

      - run:
          name: test
          command: |
            set -x
            pip install -e '.[test]' # ←テスト
            mkdir /tmp/test-results
            ENV=test pytest -v --junitxml=/tmp/test-results/pytest-junit.xml
      - store_test_results:
          path: /tmp/test-results

      - run:
          name: docker-compose down
          command: docker-compose down

```
windowsパソコンをchromebook化(CloudReady)してみる

## 以下、メモ書きです。

下記サイトを参考にさせてもらいました。というか、下記サイトを参考にしてもらえればほぼほぼ問題ないです。
https://qiita.com/rootpia/items/5599947b791cc54dcda4

### ネットワークチェックツールでOKが出るかを確認
https://guide.neverware.com/critical-requirements/#check-network

#### なぜか1項目だけNG
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/274506/6d76e5c1-5e07-cec0-abe2-a2214c92cba7.png)

※このままインストールを続けましたが、特に問題ありませんでした。


### Live USB作成用ツールを以下からダウンロードする。
https://usb-maker-downloads.neverware.com/stable/cloudready-free/cloudready-usb-maker.exe

ダウンロード後は、ダイアログをそのまま実行すればOK。Sundiskは推奨しないと記載あったので注意。検証はしていません。と、8G or 16Gのメモリと書いてあったようですが、東芝製32GUSBメモリでも問題はなかったです。また、USBからのブートが必要となりBIOSにて起動順序を変更する必要がありますが、今回インストールしたPC（下記参照）は、PC起動時F2でBIOS画面を起動できました。

### LiveUSBの使用感
USB起動のみで試しに動かしてみました。2年以上前の5万円ぐらいのASUSパソコンでしたが、サクサクという感じではなかったです。USBからの読み込みのせいなのか、スペックが低いのか。。。あの感じだと、Windows10のままでよさそう。

## 参考サイト
- Windows7がサポート終了したのでCloudReady（ChromeOS, ChromiumOS）を入れて再利用する(https://qiita.com/rootpia/items/5599947b791cc54dcda4)
- ダウンロード(https://www.neverware.com/freedownload)
CentOS ダウンロード手順

# CentOS ダウンロード手順について

本手順では、仮想環境で稼働させるための OS として CentOS をダウンロードする手順を記載します。
Hyper-V のインストールがまだの場合は、[Windows 10 に Hyper-V をインストールする](https://qiita.com/bitterrich/items/899c751eb7e79ebdbaca) を参照ください。

画面ショットは chrome を使用してます。
2020年4月の時点の画面になります。


# 最新の CentOS ダウンロード手順

## 01. ブラウザを起動して以下のアドレスを入力してダウンロードサイトに移動

https://www.centos.org/download/

CentOS Linux DVD ISO のバナーをクリック

![CentOSDownload_000.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/7d50f507-5ae7-9f8c-15f9-902fbf5a15aa.png)

## 02. いくつかのダウンロード先から選択して iso ファイルをダウンロード

![CentOSDownload_001.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/476093dd-e3ea-7341-8a97-07b3bce380bb.png)

## 03. 適切な場所に iso ファイルを保存

![CentOSDownload_002.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/4bf0b90b-6410-7b16-de79-1aae173d5207.png)


# 旧バージョンの CentOS ダウンロード手順

## 01. Older Versions の then click hire をクリック

![CentOSDownload_003.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/bd3d8b6c-788e-9501-1706-85817755bba1.png)

## 02. CentOS7.4 をダウンロードする場合 CentOS7.4 の tree をクリック

![CentOSDownload_004.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/e4e77864-336c-5c25-11c3-497f703396b7.png)

## 03. isos/ をクリック

![CentOSDownload_005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/f653879a-7410-73f9-6cd5-a66eeb9ae140.png)

## 04. x86_64/ をクリック

![CentOSDownload_006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/5fd7c041-be31-f8b3-6569-622bc97f77ae.png)

## 05. CentOS-7-x86_64-DVD-1708.iso をクリック

![CentOSDownload_007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/617437/64a36346-e257-1309-0b90-be5545545f55.png)

実は iso ファイルをクリックしてもダウンロードできない。
帯域節約のためミラーサイトに転送されるが、転送先で再度同様のディレクトリ階層を辿ることでダウンロード可能。
Reactサンプル：redux-sagaとreact-router v4（をv5にしたうえ）でWebAPIの結果に応じて画面遷移させる。（更新情報）

約二年前の2018年春頃、redux-saga を使う仕事をしていたときに、

- [Reactサンプル：redux-sagaとreact-router v4でWebAPIの結果に応じて画面遷移させる。（前編）](https://qiita.com/jun68ykt/items/f2dc1f7c076c76188834)
- [Reactサンプル：redux-sagaとreact-router v4でWebAPIの結果に応じて画面遷移させる。（後編）](https://qiita.com/jun68ykt/items/541cc8247900e126ac5b)

という記事を書いて、時々「いいね（LGTMに変わったようだ）」を頂いたり、あるいは、サンプルコードのコミットログにあるメールアドレスに技術的な問い合わせのメールを頂いたり、teratailでredux-saga関連の質問への回答の中で引用したりしている。先日もteratailで「[「Redux-saga」action実行後にリダイレクトしたい](https://teratail.com/questions/252755)」というご質問への[回答](https://teratail.com/questions/252755#reply-364872)から上記の記事を参照したが、回答した後に、Githubの[レポジトリ](https://github.com/jun68ykt/saga-and-router4)を確認すると、使用しているNodeモジュールのバージョンの問題で、Security Alertsが出ていたのと、APIとして利用させて頂いている郵便番号APIサービスの仕様が変わっていたので、これらに対応して問題なく動くようにした。（なので、この記事の投稿時には、Security Alertsは消えている。）

対応した点は以下の２点

- [使用モジュールを最新にした](https://git.io/JvjsS)。（最新にしたら、react-router は v5 になっていた。）
- 利用させて頂いている[郵便番号住所検索サービスの仕様変更に対応した](https://git.io/JvjsH)こと

[ここにコメント](https://github.com/jun68ykt/saga-and-router4/blob/master/src/api/postcode-jp.js#L6) したとおり、郵便番号住所検索サービス [PostcodeJP API](https://postcode-jp.com/) にユーザー登録して、取得したAPIキーを`apikey` の値として書く必要がある。
スパコン ITO のバッチ処理で TensorFlow の実行手順

[スパコンITO](https://www.cc.kyushu-u.ac.jp/scp/index.html) のサブシステムB（[ITO-B](https://www.cc.kyushu-u.ac.jp/scp/system/ITO/01_intro.html)）には GPU が搭載されています．ITO-B で TensorFlow を実行する方法を紹介します．GPU を使うためにバッチ処理が必要となります．そのため，Jupyterではなく，Pythonコードとして実行する必要があります．
スパコンITOのフロントエンドにおいて，TensorFlow を実行する手順は[こちらの記事](https://qiita.com/jsasaki/items/07b6f6630653eae4ee4f)で紹介しました．手順はフロントエンドの場合と共通する部分が多いですが，ITO-Bでのバッチ処理の方が簡単です．
**以下の手順はすべて スパコンITO の ログインノード で行います．**

# TensorFlow のインストール
Minicondaで構築した Python の base 環境を前提とします．`anaconda channel` で仮想環境を構築し，`anaconda channel` で `tensorflow-gpu` パッケージをインストールします．この経緯は[こちらの記事](https://qiita.com/drafts/07b6f6630653eae4ee4f/edit)を参照ください．
[こちらの記事](https://qiita.com/jsasaki/items/c807e155753468a0cfbc)で整備した Miniconda を用い，新しい仮想環境 tf を用意して，インストール作業を進めます．

```bash
$ conda create -c anaconda -n tf
$ conda activate tf
$ conda install -c anaconda tensorflow-gpu
```

ログインノードでは GPU が使用できないため，この段階で動作確認はできません．

# バッチ処理スクリプトの作成
バッチ処理については[公式サイト](https://www.cc.kyushu-u.ac.jp/scp/system/ITO/02-2_batch.html)を参照ください．GPU の load を含む環境の整備やPythonコードの実行方法を含む bash script を作成します．以下は GPU を1つ使用する場合の，bash script `ito_b.sh` です．矢印部分 `←` 以降はコメントですので，実際は削除してください．リソースグループは[公式サイト](https://www.cc.kyushu-u.ac.jp/scp/system/ITO/subsystem/06_limit.html)を参照して決めます．

```bash:ito_b.sh
#!/bin/bash
#PJM -L "rscunit=ito-b"          ← ITO-B を指定       
#PJM -L "rscgrp=ito-g-1"       ← リソースグループ指定
#PJM -L "vnode=1"          ← 使用するノード数を指定
#PJM -L "vnode-core=9"          ← ノード当たりのコア数を指定
#PJM -L "elapse=12:00:00"          ← 最大の計算時間の指定（12時間を指定）
#PJM -X          ← ログインノードの環境変数をバッチ処理でも引き継ぐ指定

source ~/.bashrc     # ← MinicondaがPythonの設定を.bashrcに書き込んでおり，これを読み込みます
module load cuda/10.1     # ← GPU を使用するため，CUDA 10.1 を load します
module list     # ← CUDA が load されたことを確認します
conda activate tf     # ← 仮想環境 tf に入ります
conda info -e     # ← 仮想環境 tf に入ったことを確認します

python ann_experiments.py     # ← Pythonコードを実行します
conda deactivate     # ← 仮想環境から抜けます
```

バッチ処理はログインノードの環境を（環境変数以外は）引き継ぎませんので，CUDA の load や Python 環境の構築が必要になります．ログインノードで tf 仮想環境に入る必要はありません．この例では Python コードと `ito_b.sh` は同一ディレクトリに存在していることを前提としています．

# バッチジョブの投入
作成したバッチ処理スクリプト `ito_b.sh` をバッチジョブとしてバッチ処理システムに投入します．

```bash
$ pjsub ito_b.sh
```

後は処理が終わるまで待つだけですので，ログアウトして構いません．
ジョブの状況を確認するには以下のようにします．

```bash
$ pjstat
```

バッチジョブが終わると，標準出力および標準エラー出力が，それぞれ `ito_b.sh.o0000000` および `ito_b.sh.e0000000` のようなファイル名で出力されます．ファイル名はバッチ処理スクリプト名に加え，oまたはeと7桁の数字で構成されています．標準出力ファイルが大きくなりすぎないよう，注意が必要です．
Ansible Tower(AWX)でワイルドカード証明書を自動更新してみた

Let's Encryptで証明書を作るときワイルドカード証明書を作りたい場合DNSによるドメイン証明をする必要があるので、自動化するためのワークフロー作ってみました

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335255/f1a8a5a8-090f-70fa-726e-d4af0a912679.png)

作ったものはこちらに
https://github.com/miyuk/ansible_cert_update

# 作った理由

うちの自宅にあるWebアプリケーションあるけど直接通信したくないから、DMZにLB入れていて運用していたんですが複数のLB作ることになったので`証明書をまとめたい`ってのと`複数のLBに同時に最新の証明書入れたい`て思ったんで解決してみました。

# 使用ツール

- Ansible AWX
- ワイルドカード証明書が使えるリバースプロキシ(BIG-IP, Nginx, HAProxy)

# workflow_cert_update

週一回ワークフローを動かすことで、証明書更新している。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335255/64c32f96-0887-d3b1-f6b0-44b1598481ae.png)

ワークフローは下記の3フェーズに分かれている。

### job_update_cert

AWX上で、Let's Encryptを更新する。更新したファイルはAWX上に保管し次回実行でも利用する。
内容としては、
1. Let's Encryptの証明書検証で利用する鍵、アカウントなどを用意
2. Let's Encryptチャレンジリクエスト
3. リクエストで取得したトークンをDNSにセット。今回、Cloudflare APIを使ってDNSの動的アップデートを行っている
4. Let's Encrypt証明書要求
5. 成功すれば、証明書をプロジェクトフォルダに保管

### job_deploy_xxxx

各LB毎に証明書ファイルをアップロードしてデプロイする。
今回、BIG-IP、Nginx、HAProxyで証明書更新(サービス再起動)できるようにしている。
また、自宅環境がDockerによって構成されているので、Nginx、HAProxyはDockerで更新をすることもできるようにしている。

### job_cert_update_report

証明書更新が実際にできたかどうかを通知する。
AWXの通知でも良かったが、どこまで完了しているかは把握したかったので作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335255/3abbdbd0-43ae-a01c-f8a8-cdc6bd5b1b93.png)




# おわりに

この方法だと、複数の拠点にあるリバースプロキシあてでも証明書を更新することができるのでテスト環境で信頼できる証明書を色んなサーバに入れておきたいというニーズでも答えれるのかなと思います。
通知部分やAWX内での証明書の持ち方については、もう少し考察必要できればいいなと考えてますがAnsible関わる機会が減り、なかなか手つかず。
PythonでABC162のA~Cを解く

### はじめに
今回はABC三完でした。dは文字列系の問題なので飛ばして、Eを考えてました。

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

**考えたこと**
strで引いてinで確認する

```python
n = input()
if '7' in n:
    print('Yes')
else:
    print('No')
```

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

**考えたこと**
普通にfizzbuzzするだけ

```python
n = int(input())

ans = 0
for i in range(n+1):
    if i % 3 != 0 and i % 5 != 0:
        ans += i
print(ans)
```

### C問題
[問題](https://atcoder.jp/contests/abc162/tasks/abc162_c)
1TLE

**考えたこと**
嫌い。高々$200^3$のループだから全探索しようと思ったら、TLEしました。pythonのmath.gcdは遅いらしい。TLEしたので、math.gcdを使わずにpypyで通した。この20分もったいない。

```python
k = int(input())

ans = 0
def gcd(x,y):
    while y:
        x, y = y, x % y
    return x

for i in range(1,k+1):
    for j in range(1,k+1):
        for s in range(1,k+1):
            ans += gcd(gcd(i,j),s)

print(ans)
```
pypyでもmathが使えることを知っていれば...

### まとめ
つらい。言い訳ですが、サーバーが重くてpypyでmathが使えるか確認できなかった。ローカルでもpypyの環境作ってない自分が悪いです。色々と悲しい。おやすみなさい
WindowsでOpehSSHサーバーを立ち上げる

# 概要

chocolateyをつかってWindowsにSSHサーバーを立てた時のメモ。
最近のWindows10なんかは標準で入っていたりするらしいので需要ないかな。

# 書いていないこと

* chocolatey導入手順
* 公開鍵の配置手順の詳細


# 導入するもの

* ~~[Win32 OpenSSH (Universal Installer)
8.1.0-beta](https://chocolatey.org/packages/openssh#releasenotes)~~ [^20200921]
*  [Win32 OpenSSH (Universal Installer)
8.0.0.1](https://chocolatey.org/packages/openssh/8.0.0.1) 

[^20200921]: 手順通り導入するとbetaは導入されないことに気づいたので訂正( 2020.9.21)

# 環境

* Windows Server 2012R2
* chocolatey v0.10.15

# インストール


PowerShellを管理者として立ち上げて、以下のコマンド実施します

```powershell:管理者：WindowsPowerShell
choco install openssh -params '"/SSHServerFeature"' -confirm
```

インストールが完了したら、path変更を反映させるために別のPowerShellを開き、以下のコマンド実行します。

```powershell:管理者：WindowsPowerShell
ssh Administrator@localhost
```

パスワードはWindowsログイン用のものと同じ。エラーなくログインできればインストール完了です。

* Administratorでログインできることはこの際おいときましょう
* Windows Server 2012R2上でsshコマンドを実行しとたんpowershellの挙動がおかしくなったのですが、
  サーバとしての挙動は問題なさそうなのでこれもいったんおいておきます。
（フォントがラスターフォントになるとか、powershellが急に落ちるとか）

## インストール時に設定するパラメーターについて

### /SSHServerFeature

Windowsサービスとしてインストールする場合に指定するパラメータです。
`sshd`という名前のサービスが追加されます。
ポート番号を22以外に変更したい場合は
`-params '"/SSHServerFeature /SSHServerPort:3834"'`
とかするといいようです


### /KeyBasedAuthenticationFeature は指定不要

たまに `/KeyBasedAuthenticationFeature` をつけてインストールしている記事を見かけますが、今は不要になってるぽいです。

* [Version 0.0.2.0](https://chocolatey.org/packages/openssh/0.0.2.0) のDiscriptionより引用

> RETIRED: -params '"/KeyBasedAuthenticationFeature"'
> NO LONGER NECESSARY - KeyBasedAuthentiation is always  configured
> if the /SSHServerFeature switch is used.

※ これがこの記事を書きたかった一番の理由だったり:yum:

---
# 設定

## キーペア設定

せっかくなんで、ed25519を使ったキーペアを作ってこれまでの鍵を置き換えました。
それまではRSA 2048bit使ってたのですが、あと10年ぐらいで非推奨になっちゃうので。

```powershell:キーペア作成
ssh-keygen -t ed25519 -C 'COMMENT'
```
2つのファイルが作成されるのでそれぞれ所定の場所に格納します

* 公開鍵: `id_ed25519.pub` → 内容をサーバの `~\.ssh\authorized_keys` ファイルに追加
* 秘密鍵: `id_ed25519` → クライアントの `~\.ssh\id_ed25519` として格納
  * Windowsの`~/.ssh`フォルダは`C:\Users\{ユーザ名}\.ssh`

## sshd_config 設定

パスワードによるログイン禁止

* ssh 設定ファイル： `C:\ProgramData\ssh\sshd_config`

```diff:sshd_configの変更箇所
# To disable tunneled clear text passwords, change to no here!
- #PasswordAuthentication yes
+ PasswordAuthentication no
#PermitEmptyPasswords no
```

変更後はsshdサービスを再起動が必要。以下のコマンドで実施。

```powershell:管理者：WindowsPowerShell
Restart-Service sshd
```

---

# 補足

## Universal Installerって

ここまで書いてなんですが、わざわざChocolately使わなくても同じパッケージがインストールできるようです。

> This package is actually a universal installer that can install in any scenario - including without Chocolatey.

詳細は[こちら](https://gitlab.com/DarwinJS/ChocoPackages/tree/master/openssh)
余裕ができたら他のインストール方法調べてみます。

# おまけ：chocolateyのアップデート方法

管理者のPowerShellで以下実行

```powershell:管理者：WindowsPowerShell
choco upgrade chocolatey
```
DB設計でつまづいたことをまとめてみた

カリキュラムで使った文字列の型をまとめます。
案外用途を忘れているもので…（自分だけ？）

#DB設計でつまづいたこと
　１.カラムで使う文字列の型
　２.リレーション

##１.カラムで使う文字列の型　一覧
　 - string
 　- text
　 - integer
　 - references
 
###　 ★string
####　　文字列（250字以内）
　　　　＜使用カラム例＞
　　　　 - name
　　　　 - address
　　　　 - tel
　　　　 - office
　　　　　　　　など

###　 ★text
####　　文字列　（250字以上）
　　　＜使用カラム例＞
　　　　 - post
　　　　 - comment
　　　　　　　　など

###　 ★integer
####　　整数型
　　　＜使用カラム例＞
　　　　 - id
　　　　 - user_id
　　　　 - post_id
　　　 　　　　　など
  
###　 ★references
####　　外部キーの定義
　　　　　他テーブルへの外部キーの定義
　　　　　_idがついた整数
　　　　　※referencesは_idを省略する事ができる

##２.リレーション
ER図において、リレーションを示すあの変な矢印
＜その１＞
 → has_many を表す　※１対多
<img width="101" alt="スクリーンショット 2020-04-12 22.54.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591023/be0c29a4-68f5-c083-4b08-c1e1768051e0.png">
 ← belongs_to を表す　※多対１


＜その２＞
<img width="100" alt="スクリーンショット 2020-04-12 22.54.30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591023/522e024c-6f2c-d87e-d5d0-a2507f20bcd3.png">
　⇆ has_one を表す　※１対１

この辺がよく理解できてからはある程度スムーズに進められた。


以上
蟻本　辞書順最小

@drkenさんの[AtCoder 版！蟻本 (初級編)](https://qiita.com/drken/items/e77685614f3c6bf86f44#2-1-%E3%81%99%E3%81%B9%E3%81%A6%E3%81%AE%E5%9F%BA%E6%9C%AC-%E5%85%A8%E6%8E%A2%E7%B4%A2)のBest Cow Line (POJ No.3617)の類題を2問触って見ました

##ABC 076 C Dubious Document 2　

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

int main(){
    string s,t;
    cin >> s >> t;
    for(int i = s.size()-1;i >= 0;i--){
        string p = s.substr(i,t.size());
        if(p.size() != t.size()) continue;
        bool ok = true;
        for(int j = 0;j < p.size();j++){
            if(p[j] == '?') continue;
            if(p[j] != t[j]) ok = false;
        }
        if(ok){
            int cnt = 0;
            for(int j = i;j < i+t.size();j++){
                s[j] = t[cnt];
                cnt++;
            }
            replace(s.begin(),s.end(),'?','a');
            cout << s << endl;
            return 0;
        }
    }
    cout << "UNRESTORABLE" << endl;
}

```

##ABC 007 B 辞書式順序

```c++

#include <bits/stdc++.h>
#define rep(i,n) for(int i = 0;i < (n);i++)
using namespace std;
using ll = long long;
using pii = pair<int,int>;

int main(){
    string a;
    cin >> a;
    if(a == "a"){
        cout << -1 << endl;
        return 0;
    }
    cout << 'a' << endl;
}

```

###感想
今回は、Best Cow Line (POJ No.3617)の類題を触ってみました。今回は、目標ではないところで少しつまりましたがなんとかなりました。
HackMDのこれは使えると思った機能

## はじめに
何かとここ最近、HackMDやCodiMDを利用する機会が増えた。
チュートリアルに書いてあるので、まめ知識ってほどではないけど、漫然と使っていると知らないもの。
自分用のメモとして残しておく。

## ショートカット系
Typora使いとしては、もっとショートカットが欲しいところ。

- Ctrl + ]　：インデント下げ

- Ctrl + [　：インデント上げ



## マークダウン書式
他と互換性ないので、多用しない方がいいかも…。
けど、使えるなぁって思ったもの。



- 黄色蛍光マーカーで塗られる。
`==マーカー==`


- アラートエリア
![AlertArea.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/384185/6afb18ac-873d-7434-f5c0-ea9814f84b7e.png)

```
::: success
みどりの帯と文字
:::
```

```
::: info
青の帯と文字
:::
```

```
::: warning
黄色の帯と文字
:::
```

```
::: danger
赤の帯と文字
:::
```

```
::: spoiler
隠せる
:::
```




## スライドモード

スライドモードでRevealを実行できる（要はプレゼンできる）
https://qiita.com/suzuki_/items/08cbd75599bd78dcaca2

※一部（下ページの「--」とか）は、Revealとは異なり使えないので注意。
　右上の「共有」から実行できる。


## ブックモード
目次ページみたいなのを作成して、まとめてみられるよ～て機能。
VirtualBoxでCent8.1を全画面表示にする方法

# VirtualBoxで全画面表示
VirtualBoxにてCent8.1を全画面表示(VirtualBoxのウィンドウサイズと同じサイズになるようにする)際のトラブルシューティングをまとめておきます。

Guest OS：Cent8.1

Guset OS起動後に、Virtual Boxのメニューから「デバイス」->
「Guest Additions CDイメージの挿入」
そしてインストールを実行後に発生したエラーのトラブルシュートです。

エラーの通りに不足しているパッケージをインストールすることで宇インストール可能でした。
## kernel headersが無い
kernel headerをインストールする必要がある。

```kernel&nbsp;headerをインストール
sudo dnf install kernel-4.18.0-147.5.1.el8_l.x86_64
sudo dnf install kernel-headers-4.18.0-147.5.1.el8_l.x86_64
sudo dnf install kernel-devel-4.18.0-147.5.1.el8_l.x86_64
```
パッケージマネージャ(dnf)は環境に応じてyum, apt-get等に置換してください。
インストールが必要なkernelのバージョンは以下のコマンドで確認するか、エラーコード内に記載があります。

```kernel確認
uname -r
>4.18.0-147.5.1.el8_l.x86_64
```

## gcc make perlが無い
インストールしましょう。

```gcc,make,perlのインストール
sudo dnf install gcc make perl
```

##libelf-devが無い
インストールしま…

```libelf-devのインストール
sudo dnf install elfutils-libelf-devel
```

installするパッケージは、環境によってlibelf-dev, libelf-develの場合があるため試行してください。

##解決しない場合

Errorメッセージを確認し、それでも問題が分からない場合は以下のファイルを見ましょう。

```CheckLog
less /var/log/vboxadd-setup.log
```

ここのエラーに対処するだけでインストール可能なため、よほどマイナーなディストリビューションでなければ苦労しないと思います。

#最後に
Cent8.1は上記で正常にインストールできましたが、どうしてもインストールできなかったら大人しくググりましょう。
初投稿ですが、初歩的過ぎでしょうか。私のような人の参考になれば幸いです。
Content-Type: application/jsonでPOSTする

### はじめに
JSON形式でPOSTをしたときに、どのようにパラメータが送られるのかをまとめます。

### POST

usersコントローラーへパラメーターを送ります。

```zsh
$ curl -X POST -H "Content-Type: application/json" -d '{"name": "hoge", "email": "mail@example.com"}' http://localhost:3000/users
```

すると、パラメーターは次のようになります。

```
Parameters: {"name"=>"hoge", "email"=>"mail@example.com", "user"=>{"name"=>"hoge", "email"=>"mail@example.com"}}
```

これ、送ったパラメーターをコントローラー名で勝手にネストしてくれているそうです。</br>
そうすることで、railsでは`params[:user][:name]`という形でパラメーターを使うことができていたんですね！

userでネストされていないパラメーターも使うことができます。
しかし、セキュリティの観点からも使用しないほうが良さそうですね。
ストロングパラメータではせっかくモデル名を指定して例外のパラメータを除外しているので、それに乗るのがいいでしょう！

参考
https://railsguides.jp/action_controller_overview.html

https://api.rubyonrails.org/classes/ActionController/ParamsWrapper.html

~~Qiitaの下書きに残したまま忘れていたので今投稿します~~
簡易的なPHP開発環境

簡単なPHPを使ったサイト（データベースなどは使用していない）の確認を行いたい。
でもウェブサーバ建てるのは面倒すぎる...
という人向け

```bash
cd <document root>
sudo php -S localhost:80
```
あとは`http://localhost:80`にアクセスすればおｋ

### 追加情報
`-t`でディレクトリを指定できるようです。

```bash
sudo php -t <document root> -S localhost:80
```
iPhoneでCプログラミングしてみた

#はじめに
今回、[**モバイル C [ C/C++ コンパイラ ]**][app]というiOSアプリを使いました。
やはり、今更感はありますかね?
インストールから間もなくて、あまり使い慣れていませんが
行ってみましょう...

#実行環境

```console
端末：iPhone7 (最近バッテリーが貧弱)
アプリ：モバイルC[C/C++コンパイラ] (無料版)
```
#エディタ画面
縦画面でもできますし、フリック入力のキーボードでも入力できました。
画面のテーマ変更もできました。(これはdark)
![エディタ画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506931/ce8c3dc4-1fa6-f93c-1a88-674c633145ed.png)


#色々実行してみた
実行は`ランボタン`もしくは`コンソールでファイル名を指定`するとできるみたい。
アプリ上での実行結果をコピペしてます。
###①おはよう世界
```c:ex01.c
#include <stdio.h>
int main() {
    printf("Hello iOS World!\n");
    return 0;
}
```

```console:mosh
qiita> ex01.c
Hello iOS World!
```
###②君の名は

```c:ex02.c
#include <stdio.h>
int main(){
    char name[64];
    printf("名前を入力してください\n");
    scanf("%s",name);
    printf("あなたの名前は%sです",name);
    return 0;
}
```
```console:mosh
qiita> ex02.c
名前を入力してください
RoaaaA
あなたの名前はRoaaaAです
```
おお！ちゃんと動く！

###③中置記法された数式の計算プログラム
ソースコードは[こちら][c]

```console:mosh
qiita> ex03.c
Expression = ((1+2)+3)
Value = 6
Expression = (((1+2)-(-(3+4)))/2)
Value = 5
Expression = (1+2+3)
(1+2+3)
    ^
error: 不適切な式
Expression =
qiita>
```
値なんかを入れるプログラムも正常に動きますね！

###④前回作った円周率を求めるプログラム
ソースコードは[こちら][m]

```console:mosh
qiita> mcpi.c
処理時間：1121.452889[秒]
１回の描画点数：940000[個]
モンテカルロ法：100[回]
四分円内の点数：73830269[個]
四分円外の点数：20169731[個]
円周率：3.1417136
今回の精度：99.99615％
```
いやぁ、この結果にはびっくりしましたね。
最初、待てど待てど何も出力されなくて、ダメかと思ったんですけど
単純に処理が遅いって話でした :sweat_smile:
このプログラムに関していえばざっとPCの0.00597倍...
マンガ読んでる間に実行が終わってました。

#実行画面
こんな感じの実行画面です。
画面が小さいから横画面結構見にくい...

###ランボタン
![ランボタン][r1]
![実行画面][r2]

###コンソール
![コンソール][c1]

#感想
使ってみた感じ、iOSでここまでできることに驚きました。
実行時間についてはしょうがないですね...

ほんとはできるのかもしれないし、できないのかもしれないですけど、
`./a.out > result.txt`的な実行結果をテキストファイルで残すことが、
今のとこ自分はしきらんかったです。できるんかな？

`-lm`オプション付けなくて実行できるのはなぜなんだろう？
近いうち調べてみますか？(あまりCはやらないんですけど...)

少し大きめのプログラム([中置記法のやつ][c])とかになってくるとエディタ上での移動がめんどくさくなったりしそうです。
小さめのプログラムを思いついたときに、手元にPCがなければとても便利だなって感じです。
Pythonも使えるみたいなので、個人的にはありがたいアプリですね。

アプリ開発者様ってすごいですね。尊敬しますね:sparkles:

以上！

#参考
- 中置記法ソースコード：[中置記法に基づく計算プログラム][c]
- 円周率推定ソースコード：[[改訂]今更だけどモンテカルロ法で円周率推定][m]
[app]:https://apps.apple.com/jp/app/%E3%83%A2%E3%83%90%E3%82%A4%E3%83%AB-c-c-c-%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9/id1090924591

[m]:https://qiita.com/RoaaaA/items/a3eb795c5292b90eeb5e
[c]:https://qiita.com/RoaaaA/private/4b2f48dc9198943f6ef9

[r1]:https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506931/ccd27575-cced-1edc-372c-c05951bf2d42.png
[r2]:https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506931/1b9d74b9-8577-6280-118b-03eb542505f1.png
[c1]:https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/506931/a24bb295-ae59-2170-cf59-4f4c13540326.png
PCI-DSSに関する情報


[PCI SSC日本語サイト](https://ja.pcisecuritystandards.org/minisite/env2/)

[JCDSC 日本カード情報セキュリティ協議会](https://www.jcdsc.org/)

[PCI DSS準拠の方法と JCDSC によるサポート体制](https://www.jcdsc.org/topics/pdf/PCIDSS-20190215.pdf)

[突然PCI DSS担当になった人が話すPCI DSS入門](https://www.slideshare.net/OhgushiKiyokatsu/pci-dsspci-dss)

[【意外と知らない】簡単準拠！システム更改時にPCI DSS準拠する方法](https://www.tis.jp/special/platform_knowledge/pci02/)

[グループウォレットアプリ6gramの運用をはじめてみた](https://speakerdeck.com/ryosan470/6gram-sre-next-2020)

[［JCB］外部専門家と連携し、世間を揺るがす脆弱性に早期対処](https://xtech.nikkei.com/it/atcl/column/16/080500167/082500008/)

[@IT オール・ザッツ・PCI DSS 連載インデックス](https://www.atmarkit.co.jp/fsecurity/index/index_pcidss.html)
ECS+Fargateでコンテナを起動する際、ECRにアクセスできない現象の解決方法


## 現象
ECSをlanchType、Fargateにて構築した際に躓いた点がありましたので共有します。
Serviceを構築してECRからイメージを取得してTaskを立ち上げようとしたら
ステータスがpendingから進まない現象が発生した。
最終的にステータスがstopになりイベントの詳細をみるとECRのアクセスがtimeout
で失敗していた。

## 原因
ECRのアクセスに失敗しているようだったのでIAMRoleに対してPolicyのアタッチが
漏れているかと思ったがそうではなかった。
ECRからTaskを起動させる際HTTP経由で外から通信してImageを取得するとのことで、
Serviceのネットワーク構成で指定したサブネットから外に通信ができないのが原因だった。

## 解決方法

### 解決策1
起動Taskをパブリックサブネットに配置して直接InternetGateWay経由で外に
アクセスしてECRからイメージを取得する方法。
注意点としてはSerivceを構築する際に「パブリックIPの自動割り当て」を
「Enable」にして起動TaskにパブリックIPを割り振る必要がある。
後Taskを再度デプロイした場合はパブリックIPは変更されてしまう。

![ecs-public-subnet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68719/c96ce0bd-275e-ea84-9d82-2743c7e5f0be.png)

### 解決策2
起動Taskをプライベートサブネットに配置して、NatGateWay経由でInternetGateWayから
外にアクセスしてECRからイメージを取得する方法。
この方法なら外にでるIPはNatGateWayで固定される。

![private-subnet.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68719/903f4be6-0798-1215-047a-e7be8e4c0ee1.png)

## まとめ
私の場合は最初から解決策2で構築していたのですがNatGateWayの構築に不備があり、
外に出れることができず発生しておりました。。
設定を直して無事策2で解決することができました。
因みにLunchTypeをEC2にした場合「パブリックIPの自動割り当て」Enableに
できないらしいので解決策2を必然的にとる必要がありそうです。
AMP初心者 メモ(随時更新)

:warning:注意今すぐAMPを実装したいという方は違う記事を探しましょう。:warning:


# :calling:AMPとは
AMP(Accelerated Mobile Pages)とはGoogleが推奨しているコンテンツを高速に表示させるための手法であり、GoogleとTwitterで共同開発されている、モバイル端末でウェブページを高速表示するためのプロジェクト、またはそのためのフレームワーク(AMP HTML)のことです。
[公式ドキュメント(一部日本語訳)](https://amp.dev/ja/)

## :gear:AMPの仕組み　
通常、ウェブページにアクセスする場合、サイトのあるサーバーにリクエストし、ファイルを受け取り、それをレンダリングして、ページを表示するという段階を踏むことになります。

AMPではウェブページの情報をあらかじめGoogleやTwitter側でキャッシュとして保存しておき、検索などのリンクをクリックした際には、その情報を直接クライアントに受け渡すことで、ステップを大幅に削減しています。

## :open_file_folder:AMPの構成
AMPを構成する主要素としては、以下の４つがあります。

- HTML5（AMP HTML）
- CSS 3（Custom Styling）
- JavaScript (AMP JS)
- グローバル プロキシ キャッシュ (AMP Cache)

このAMP HTMLというフレームワークはオープンソースとして公開されており、あらかじめその仕様に沿ってモバイルサイトを作成することで、Googleの検索結果やTwitterからリンクを開く際の表示速度を高速化することができます。:basketball_player:

## :bride_with_veil_tone2:メリット
- ページの高速化

  検索サイトからAMPページを読み込む平均時間は0.5秒以内に短縮されます。
- エンゲージメントの増加

AMPを導入するとウェブサイトへのトラフィックが10%増加し、ユーザーがページに滞在する時間が2倍になると言われています。

- 収益の増加

ECサイトではコンバージョン率が20%増加し、広告クリック率が上がったサイトが85%にのぼります。

参考ページがかなりみやすくわかりやすかったです
[参考サイト](https://gomobile.jp/rabbit/#amp-box)

### :hammer_pick:AMPで使える機能たち

一部をざっと説明
#### amp-analytics
AMP ドキュメントからアナリティクス データを収集します。
#### amp-autocomplete
検索フォームに入力中のテキストに対しECサイトに登録されている商品名やカテゴリーなどから候補を表示し、フォームに反映する機能
#### amp-carousel
横軸に沿って複数の類似コンテンツを表示します。
#### amp-ad
広告を表示するコンテナです。(これ使うと広告出るってやつです)
#### amp-list
データを動的にダウンロードし、テンプレートを使用してリスト項目を作成します。


[AMPコンポーネント集](https://amp.dev/ja/documentation/components/)




ざっとこんな大枠はこんな感じでしょうか。
随時わかったことなどあれば追加していきます。

## 参考
ドキュメント
https://amp.dev/ja/
https://amp.dev/ja/documentation/components/
rabbitさん
https://gomobile.jp/rabbit/#amp-box
Swift　初心者

# Swiftの基本情報 

・行末に;はつかない

・=の意味は右辺のデータを左辺に代入する

・""で囲むと数字であっても文字列扱いになる　　　　　　
　　　　　　【例】"500"は文字列　500は数値





# varとlet

letは税率や円周率など後から書き換えることができないものに使う。（定数）


varは一度データを入れても、あとでデータを書き替えることができる。（変数）


### 型

Int型…整数を扱う
Double型…小数を扱う
Prometheus用の自作Exporterを作成する

# 自作Exporterの構築方法

## Motivation

シェルなどを用いて独自のメトリクスを収集したい

Prometheus用のExporterを自作しメトリクスを確認したい



## 本当に最低限exporterを作る

metricsというファイル名で、prometheus形式でデータを登録する

```
❯ cat metrics 
# HELP osushi これはお寿司の数です
# TYPE osushi counter
osushi 1.101010101e+10
# HELP yakiniku これは焼肉の数
# TYPE yakiniku counter
yakiniku 1.101010101e+10
```

上記ファイルを公開するために、pythonを用いて可児的なwebサーバを立てる

```
python3 -m http.server
```

8000番ポートでwebサーバが動作して、先ほどのファイルの内容を参照することができる

```
❯ curl localhost:8000/metrics
# HELP osushi これはお寿司の数です
# TYPE osushi counter
osushi 1.101010101e+10
# HELP yakiniku これは焼肉の数
# TYPE yakiniku counter
yakiniku 1.101010101e+10
```



Prometheusの設定(prometheus.yml)内のscrape_config内に、exporterのurlを記載する

```
❯ cat prometheus.yml
# my global config
global:
  scrape_interval:     15s # Set the scrape interval to every 15 seconds. Default is every 1 minute.
  evaluation_interval: 15s # Evaluate rules every 15 seconds. The default is every 1 minute.
  # scrape_timeout is set to the global default (10s).

# Alertmanager configuration
alerting:
  alertmanagers:
  - static_configs:
    - targets:
      # - alertmanager:9093

# Load rules once and periodically evaluate them according to the global 'evaluation_interval'.
rule_files:
  # - "first_rules.yml"
  # - "second_rules.yml"

scrape_configs:
  - job_name: 'simple_file'
    static_configs:
      - targets: ['localhost:8000']

```

prometheusのUIからosushiというメトリクスが取得できることを確認できる

![simple_exporter.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/94861/142fb34a-8df4-8469-807d-81601fcedafd.png)


あとは、該当のファイルをシェル等で更新していくことで、シェルなどの既存資産を用いてexporterを簡易的に自作できる。



## [補足]exporter作成用のライブラリを用いて自作exporter作成

下記に各言語用のExporter作成用ライブラリが存在する

https://prometheus.io/docs/instrumenting/clientlibs/
JWT認証を外部サーバーで実装する時に詰まった話

#はじめに


```:開発環境
- Heroku
- PHP
  - laravel
```

もちろんローカルでは動作確認済み。

#詰まったところ

どうやらJWT認証がうまくいかない。

#解決法

jwtの秘密鍵が登録されていなかったからエラーが出た。
外部サーバーにも秘密鍵を登録する。

```shell:
$ heroku run php artisan jwt:secret
Running php artisan jwt:secret on ⬢ アプリ名... up, （省略）
jwt-auth secret [ 秘密鍵 ] set successfully.
```

ローカル環境なら環境変数も .env に自動で登録してくれるのだが、外部サーバーでは .env を読み込んでくれないので手動で登録する。

```shell:
$ heroku config:set \
> JWT_SECRET=秘密鍵
Setting JWT_SECRET and restarting ⬢ アプリ名... done, v17
JWT_SECRET: 秘密鍵
```
これでJWT認証が使えるようになった。
RuboCopの"The following cops were added to RuboCop, but are not configured."の対処方法

**2020-11-03 更新**
**RuboCop 1.0がリリースされましたので最新情報を追記しました。**

先日RuboCopを最新バージョンにしたところ、これまでと違うメッセージが表示されました。
この記事ではメッセージの意味と対処方法の解説を行います。

```bash
$ bundle list | grep rubocop
  * rubocop (0.81.0)

$ bundle exec rubocop
The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.yml` file:
 - Lint/RaiseException (0.81)
 - Lint/StructNewOverride (0.81)
 - Style/HashEachMethods (0.80)
 - Style/HashTransformKeys (0.80)
 - Style/HashTransformValues (0.80)
For more information: https://docs.rubocop.org/en/latest/versioning/
```

# メッセージの意訳

これらのルールを追加したが、まだ有効化していない。`.rubocop.yml`に有効または無効の設定を書いてほしい。
さらに詳しい情報: ~~https://docs.rubocop.org/en/latest/versioning/~~

**2020-11-03 追記**
最近URLが変更となったようです。
https://docs.rubocop.org/rubocop/versioning.html

# メッセージの目的

RuboCopに新ルールを追加する時、それをバージョンアップと同時に有効化しない方針にしたようです。
機能自体の追加は0.79 (リリース2020/01/6)、運用開始は0.80 (リリース2020/02/18)からでした。

このメッセージが表示されることによって、利用者は有効化までの期間にプロジェクトの事情に合わせた対処がやりやすくなりました。

# 対処方法

今後のRuboCopのバージョンアップで新ルールは有効化されるため、このメッセージも自動的に表示されなくなります。
これはエラーや警告のメッセージではないため、無視してもいいのかもしれません。

ただ、やはり表示されないに越したことはないため、メッセージが表示されないようにしておきたいと思います。

## 方法1. 書かれている通りに各ルールの設定を書く

表示された新ルールの設定を全て書けばメッセージは表示されなくなります。
全てを有効化する場合、 `.rubocop.yml` に以下を追記します。

```yaml:.rubocop.yml
Lint/RaiseException:
  Enabled: true
Lint/StructNewOverride:
  Enabled: true
Style/HashEachMethods:
  Enabled: true
Style/HashTransformKeys:
  Enabled: true
Style/HashTransformValues:
  Enabled: true
```

## 方法2. ルールが追加された時の挙動を設定する

ルールをバージョンアップと同時に有効化してもよい場合、以下のように設定することも可能です。

```yaml:.rubocop.yml
AllCops:
  NewCops: enable
```

```bash:bash
$ bundle exec rubocop --enable-pending-cops
```

~~ただし、ドキュメントに記載が既にありますが、この機能は投稿時点の最新0.81で未実装です。~~
~~以下のPRが先日マージされましたので、次期0.82で追加される模様です。~~
~~https://github.com/rubocop-hq/rubocop/pull/7856~~

私のプロジェクトの場合、RuboCopのバージョンアップと新ルール対応が同時に可能なので、これが入ってきたら適用したいと考えています。

**2020-04-20 追記**
2020-04-16に0.82がリリースされ、上記が有効になりました。

# 新ルールがデフォルトで有効となるタイミング

ドキュメントによると「メジャーバージョンアップによって保留状態のルールが一括で有効化される」とのことなので、RuboCop1.0リリースのタイミングで有効になると思われます。

**2020-04-20 追記**
先日2020-10-21にRuboCop 1.0がリリースされ、これまでペンディングとなっていたルールが一斉に有効となりました。
[RuboCop 1.0 Release](https://github.com/rubocop-hq/rubocop/releases/tag/v1.0.0)

なお、1.1以降に追加されるルールは0.82～0.93と同様にペンディングとして追加され、2.0で一斉に有効となるようです。
ですので、この記事は今後も有効な内容となると思われます。
セルフメモ　SQL



テーブルを調べる
https://memo.morelents.com/table-list-sql/

テーブルの中身を見る
select * from テーブル名;

select * from テーブル名 = 値 where 抽出条件;


SQLテーブル作成
CREATE TABLE　テーブル名（カラム名 データ型 制約  [, 列名 データ型 制約 …] );
テーブル内の全レコードの削除
DELETE FROM [テーブル名];
レコードを削除する
DELETE FROM [テーブル名]　WHERE [条件];
AWS日記② (AWS Lambda)

# はじめに
今回はLambdaを利用してサーバレスなWEBページを作成します。

[作成したLambda関数](https://github.com/tanaka-takurou/serverless-single-page-go)

# 準備
Lambda , API Gateway を設定し、サンプルコードを実行出来るようにします。
もしAWSアカウントを持っていなければ、[AWSアカウントを作成](https://qiita.com/tanaka_takurou/items/24023e8af389cfc02864) します

[AWS Lambda](https://ap-northeast-1.console.aws.amazon.com/lambda/home?region=ap-northeast-1#/)の管理ページから関数を作成します。
Lambdaにコードをデプロイした後、基本設定のハンドラを 「main」 に設定します。

![lambda_setting.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586707/53e74c3c-3f92-aa6a-a41f-d2a6dadab159.jpeg)


[API Gateway](https://ap-northeast-1.console.aws.amazon.com/apigateway/main/apis?region=ap-northeast-1&apiId=unselected)の管理ページからAPIを作成します。
API Gatewayの設定から GETメソッドを作成し、Lambdaにつなげます。
![apigateway3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586707/b2934bdc-4efc-7485-2b0b-3c281cb2fd45.jpeg)



[参考資料]
[API Gateway + LambdaでREST API開発を体験しよう [10分で完成編]](https://qiita.com/tamura_CD/items/46ba8a2f3bfd5484843f)
[[AWS] Lambda + API Gatewayでサーバレスを始める １](https://qiita.com/naoki_koreeda/items/c2a32198c86e8d9a5bb6)

# WEBページ作成
GO言語のAWS Lambda関数ハンドラー aws-lambda-go を使用してHTMLを返す処理を作成します。

[参考資料]
[Go の AWS Lambda 関数ハンドラー](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/golang-handler.html)
[AWS Lambda で Go が使えるようになったので試してみた](https://dev.classmethod.jp/articles/aws-lambda-supports-go/)
[golang で html/template でのテンプレートの継承と、HTML エスケープしないで変数を出力する方法](https://qiita.com/peketamin/items/1b9b5c74fdb38d52ad77)


HTMLを返すため、レスポンスヘッダの Content-Type に text/html を設定します。

```golang:main.go
Headers: map[string]string{
  Content-Type: "text/html",
},
```

# 公開
カスタムドメインを設定し、独自のURLでアクセス出来るようにします。

今回は [Amazon Route 53](https://console.aws.amazon.com/route53/home?#) を利用してドメインを登録します。
![route53.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/586707/36126b9a-dfaf-f9af-bcb4-cb3bf944b9f2.jpeg)



[参考資料]
[ドメイン名の登録](https://aws.amazon.com/jp/getting-started/tutorials/get-a-domain/)
[API GatewayをカスタムドメインでHTTPS化する](https://dev.classmethod.jp/articles/api-gateway-custom-domain-ssl/)
[API Gatewayでカスタムドメインを利用する](https://dev.classmethod.jp/articles/api-gateway-custom-domain/)

# 終わりに
参考資料が豊富で、ほぼ資料通りに進めるだけでサーバレスなWEBページを作成できます。
資料が古い場合、AWSの設定画面が変更されている部分があるため柔軟に読み替える必要があります。
クラスの定義

####オブジェクト
クラスは設計図、オブジェクトは実体を指す。
オブジェクトとインスタンスはほぼニュアンスだという認識でOK
クラスに基づいてオブジェクトを生成していくという認識。

```ruby:ruby
class User  #クラスの作成
   def initialize(name, age)
      puts '#{name}さん、#{age}歳'
   end
end

User.new('Bob', 20)  #オブジェクトの作成
#=> Bobさん、20歳
```

###インスタンス変数
・インスタンス変数の変数名は必ず@で始める。
例：　@name = name

・インスタンス変数を参照できるのは、initializeメソッドとオブジェクトのインスタンスメソッドのみ。

・クラス内部ではインスタンス変数を使用可能。クラス外部から参照したい場合は参照用のメソッドを作成。

```ruby:ruby
class User
   def initialize(name)
      @name = name
   end

   def name  #オブジェクトのインスタンスメソッド
      @name
   end
end
user = User.new('Bob')
user.name #=> "Bob"
#.name：　nameメソッドを経由して@nameを取得している
```
Go言語: ポインターとそれに関する型(uintptr, unsafe.Pointer)

# この記事について
Go言語の以下のポインター関連の型について簡単に整理します。

- `&` で取得するアドレス
- uintptr
- unsafe.Pointer

## `&` で取得するアドレス

- 変数のアドレスを表す整数値
- 値は整数値だが、型はそれが指す型に応じて異なる

```go:例
    i := 1
    s := []string{"x", "y"}

    pi := &i    // pi の型は *int
    ps := &s    // ps の型は *[]string
```

- 当然ながらアドレスを参照できる → `*pi`とする
- しかし、C言語のようにポインターの演算はできない → `pi++` とか出来ない   

## uintptr
- Go言語の Builtin 型であり、アドレスを格納できる大きさを持つ「整数型」
- 単なる整数型なので、アドレスを参照することはできない → `*pi` が出来ない
- 単なる整数型なので、演算ができる → `pi++` とかが出来る。
  - ただしC言語とは異なり単なる整数演算になる。`pi++` は値に１を足すだけで、次のオブジェクトを指すアドレスにインクリメントするのではない
- uintptr がオブジェクトのアドレスを指していても、そのオブジェクトは GC で回収されうる
  - GC は、uintptr をオブジェクトを参照してるものと見なさないため
  - 後述の注意事項も参照

## unsafe.Pointer
- すべての型のポインターを表せる型。C言語の `void *` という感じ
- 以下の特性を持つ
  - `任意の型のポインター` から `unsafe.Pointer`へ変換可能。またその逆も可能。
  - `uintptr` から `unsafe.Pointer`へ変換可能。またその逆も可能。
- Go の型管理の機構を迂回して任意のアドレスを読み書きてしまうため、危険であり通常使うことはない

## 注意
- uintptr と unsafe.Pointer の変換の間に GC が走る余地を入れないこと
  - [unsafeパッケージの説明](https://golang.org/pkg/unsafe/#Pointer) にあるように、uintptr をいったん変数に保持せず１つの式で変換を行う

```go:これは大丈夫
    p = unsafe.Pointer(uintptr(p) + offset)
```

```go:これは危険
    // 1行目と2行目の間に、p が GC で回収されるかも。
    u := uintptr(p)
    p = unsafe.Pointer(u + offset)
```


# サンプル
実用性は無いが、int32 のスライスを C言語のように処理して合計値を求める例。

```go
package main

import (
    "fmt"
    "unsafe"
)

func sum(ptr *int32, size int) int32 {
    var sum int32
    p := unsafe.Pointer(ptr)

    for i := 0; i < size; i++ {
        // 4バイト(32ビット)、ポインターを進める
        sum += *(*int32)(unsafe.Pointer(uintptr(p) + uintptr(i*4)))
    }
    return sum
}

func main() {
    s := []int32{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
    
    // sum には、スライスのアドレス &s ではなく、スライスが指してる配列の
    // 先頭アドレス &s[0] を渡す必要あり
    fmt.Printf("Sum = %d\n", sum(&s[0], len(s)))
}
```

実行結果: `Sum = 55`


# 参考
- [Package unsafe](https://golang.org/pkg/unsafe/)
- [Understanding uintptr in Golang](https://golangbyexample.com/understanding-uintptr-golang/)
Swiftでユニットテストを導入する上で押さえておきたいこと

## はじめに

技術書クラウドファンディングのPEAKSから販売されている[iOSテスト全書](https://peaks.cc/books/iOS_testing)の第2章・ユニットテストを読んで、ユニットテストを導入する上で押さえておきたい点を備忘録としてまとめました。

## ユニットテストとは

- ユニットテストとは、構造体やクラス、関数などのシステムにおける最小単位のコンポーネントに対して行うテストのこと
- **自動化**され、**繰り返し実行可能**で、**統一的な仕組みに支えられた**テスト
- 上記を満たすために、テストを資産として残すことが可能で、テストの実行や結果のレポートを行ってくれるテスティングフレームワーク（XCTest、Quick/Nimble）を用いる

## 導入するモチベーション

**1. より早い段階で不具合に気づく**
処理単位で正しいことを検証できたら早いタイミングで不具合に気づくことができ、手戻りを減らせる

**2. コードや設計を継続的に改善できる状態にする**
ユニットテストの整備が安全網として働き、コードや設計を継続的に改善できる状態になる
例えば修正しづらいコア機能にユニットテストを整備することで修正しやすくなる

**3. APIの利用方法をドキュメント化する**
ユニットテストを記述することで対象のAPIの利用方法がわかる仕様書としての役割を果たす
実際に動くコードによってAPIの利用方法がわかるのはメリットとして大きい

## 特徴

- 高速かつ正確に実行できる
- 網羅的なテストが行いやすい

## アサーション

- ある**状態**に対して、特定の**操作**を行い、その**結果**を**アサーション**で検証することが**ユニットテストの基本**
- 状態：テスト対象のオブジェクトの状態や環境
- 操作：テスト対象の関数やメソッドを呼び出すこと
- 結果：関数の戻り値やオブジェクトの状態の変化など
- アサーション：期待通りの結果になっていることを検証する

## 保守性

**1. テストのメソッド名**
「test<テスト対象のメソッド名>_テストの説明」という規則で命名することが一般的
メソッド名にテストの説明を含めることでテスティングフレームワークがテストケース名として認識できる

**2. 粒度**
1つのテストでは1つの観点に対してのみテストすることが大切

**3. 構造**
色々な場所で利用するテスト対象（**テストフィクスチャ**）は一箇所で生成する
テスティングフレームワークのグルーピング機能を用いてテストを性質ごとにグルーピングする

**4. エラーメッセージ**
テストに失敗したときに原因の調査や修正にかかるコストを下げるために、エラーメッセージは失敗理由も添えて出力する

## テストダブル

あるコンポーネントをテストしようとすると依存する別のコンポーネントまでテストしなければならない。テスト対象の依存するコンポーネントをテスト用に都合の良い振る舞いをする偽物に差し替えることでテスト対象を最小単位に留めることができる。このテクニックをテストダブルという。

テストダブルにはいくつかの役割があり、単体としての役割もあれば複数の役割を持ち合わせるテストダブルもある。
iOSアプリ開発のユニットテストにおいて利用頻度が高い役割は以下。

**スタブ**
依存コンポーネントのメソッドやプロパティにアクセスされた際に、テストに都合の良い値を返すように設定する

**モック**
依存コンポーネントのメソッドやプロパティへのアクセスについて、呼び出し回数や引数の値を記録し、記録した値が期待した通りか確認することで、テスト対象が依存コンポーネントと適切なコミュニケーションをしたかを検証できる