OmniAICreator/Qiita-1.07M huggingface dataset:
railsルーティングオプション「ネスト」について

#ネストオプションについて
ネストするとルーティングを「/boooks/本の投稿のid/favorite/いいねのid」のようにIDの後にIDを持ってくることができます。

例えば以下のテーブルとコントローラー名で本の投稿に「いいね」機能をつける場合。

###コントローラ名
本の投稿「books」
いいね機能「favorites」

###テーブル
![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/594922/ad7f674d-b6f7-637f-2afb-5923089add49.png)

いいね機能関連のルーティングを「/boooks/book_id/favorite/favorite_id」
としたいです。

この場合、以下のようにネストせずにルーティングを行うと。

```ruby:routes.rb(ネストして無い場合)
  resources :books
  resources :favorites, only: [:create, :destroy]
```
ターミナルで「rails routes」を実行。

```terminal:ネストしてない場合
favorites POST   /favorites(.:format)       favorites#create                                                              
 favorite DELETE /favorites/:id(.:format)   favorites#destroy
```                                                              


このように、「/boooks/book_id/favorite/favorite_id」とはならないです。

#ルーティングにネストオプションを追加する
ネストを追加するには以下のようにルーティングを記述します。

```ruby:routes.rb(ネストオプションを追加)
  resources :books, only: [:index, :new, :create, :show, :edit, :destroy, :update] do
  	resources :favorites, only: [:create, :destroy]
  end
```
ターミナルで「rails routes」を実行。

```terminal:ネストさせた後
book_favorites POST /books/:book_id/favorites(.:format)       favorites#create                                                     
book_favorite  DELETE /books/:book_id/favorites/:id(.:format) favorites#destroy                                                
```
ちゃんと「/boooks/book_id/favorite/favorite_id」とできました。
みんな大好き Let's Encrypt やらかし対処 影響ドメイン調査 recheck CAA

突然、こんな連絡が入って大混乱。
Let's Encryptの証明書の一部が3/4 9:00より失効処理されているとのこと。


> さくらのレンタルサーバ/マネージドサーバの無料SSL機能において認証局による
 一部SSL証明書の失効処理が行われました。該当証明書の再発行を行っておりま
 すが、数量が多く時間を要する見込みです。詳細は以下の情報をご確認ください。

https://support.sakura.ad.jp/mainte/mainteentry.php?id=27602

失効対象が分からないと対処の取りようもないので下記サイトで確認。
自分らが管理しているドメインは失効対象でないようで一安心。

https://checkhost.unboundtest.com/

> The certificate currently available on example.com is OK. It is not one of the certificates affected by the Let's Encrypt CAA rechecking problem. Its serial number is 0fd078dd48f1a2bd4d0f2ba96b6038fe0000

上記は問題なしらしい。google翻訳でなんとなく理解。。。
問題があるドメインの場合は証明書再発行が必要だけど、いつも動いているコマンドが動かないとの報告が散見されていて混乱の極み
[android studio] flutter Outlineがnothing to showの時の対処法

# 参考
[こちらが参考になります!](https://amzn.to/2ZThhBK)

# 対処法
nothing to showのときは、プロジェクトが古いと考えられるので、pubspec.yamlを開いてupgradeをクリックする

もしくはターミナルで `flutter pub upgrade`をする。

```terminal:
~/プロジェクトディレクトリ
❯ flutter pub upgrade
```
[Angular] valueChangesでMaximum call stack size exceededエラー

## やりたかったこと
リアクティブフォームをvalueChangesで監視し、
変更検知した値を加工してセットし直す。

## 実装イメージ
```js
this.formGroup.valueChanges
.subscribe(x => {
  const y = x + x;
  this.formGroup.get('hoge').setValue(y);
});
```

## しかし、こんなエラーが。。

```
Subscriber.js:244 Uncaught RangeError: Maximum call stack size exceeded
    at SafeSubscriber.Subscription.unsubscribe (Subscription.js:71)
    at SafeSubscriber.Subscriber.unsubscribe (Subscriber.js:125)
    at SafeSubscriber.__tryOrUnsub (Subscriber.js:243)
    at SafeSubscriber.next (Subscriber.js:187)
    at Subscriber._next (Subscriber.js:128)
    at Subscriber.next (Subscriber.js:92)
    at EventEmitter.Subject.next (Subject.js:56)
    at EventEmitter.emit (core.js:4322)
    at FormControlName.viewToModelUpdate (forms.js:7250)
    at eval (forms.js:2395)
```

## 原因

setValueの変更を検知して無限ループを引き起こしていた。

## 解決策

`setValue()`のoptionに`emitEvent:false`を与える。

```js
this.formGroup.valueChanges
.subscribe(x => {
  const y = x + x;
  this.formGroup.get('hoge').setValue(y, {emitEvent: false});
});
```
集中力が上がる(かもしれない)5行のbatファイル

##はじめに
(ある日のこと)
.
.
.
**勉強も終わったし、今日はあれをやろう！**
.
(30分後)
.

**う～ん、はまったなぁ...(調べながら)**
**あ、この記事面白そう！**
.
.
(n分後)
.
.
**「パズドラ　リーダー」**
**「パズドラ　リーダー　おすすめ」**
**「パズドラ　サブ　ランキング」**
.
**あ～、目が痛いし肩も痛い、、、頭も働いてない、、、**
(やりがち)

##本編
25分集中した後、5分休むサイクルを四回繰り返す、「ポモドーロ・テクニック」という集中法がある。
私も最近これを知って実践していて、5分休むごとに頭がすっきりし集中できている。
これを実践するにあたり、最初はキッチンタイマーか何かで25分を測ろうと思ったが、手動でパソコンをスリープするのは面倒くさい。意志力は有限ナリ。
そこで、プログラマの三大美徳である「怠惰」を発動し自動化することにした。
出来上がったのが以下のcronsleep.batである。

```bat:cronsleep.bat
:start
  timeout 1500
  psshutdown -d -t 0
  timeout -1
goto :start
```

###解説

```bat
:start
  (中略)
goto :start
```
↑ 無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に繰り返し。無限に（略)

```bat
timeout 1500
```
↑   1500秒(=60*25)待つ。sleepコマンドとは違って、待ち時間中にキーボード入力すると次の処理に行けて便利。


```bat
psshutdown -d -t 0
```
psshutdownコマンドは、デフォルトではwindowsにインストールされていないのでインストールする。Microsoft公式のWindows Sysinternalsというツール群に含まれている。-d -t 0でスリープ処理を指定する。

```bat
timeout -1
```
↑   キーボード入力があるまで待つ。5分の休憩も自動化しようと思ったが、柔軟にしたいのでこういう仕様になった。

##さいごに
皆さんも使ってみてほしい。
でもエビデンスは知らないのであしからず。
##おまけ
###さらに集中したい方へ
指定したサイトを開けなくする[Block Site](https://chrome.google.com/webstore/detail/block-site-website-blocke/eiimnmioipafcokbfikbljfdeojpcgbh?hl=ja)というchrome拡張がおすすめ。これでtwitterとかブロックしてる。

###宣伝
2020年4月に大学生になるのでインターンがしたいです。よろしくお願いします。(bakeratta35@gmail.com)

##おわり
###おわり
####おわり
#####おわり
おりわ
【Nuxt.js】nuxt.config.jsにproxyの設定をする（環境変数の設定）

## 関連記事
[【Nuxt.js】環境変数の設定とswagger mockの設定メモ](https://qiita.com/katu_/items/f87817460154a46365a3)

## 経緯
- [【Nuxt.js】環境変数の設定とswagger mockの設定メモ](https://qiita.com/katu_/items/f87817460154a46365a3)の方法では、NuxtでAPIを呼び出して登録データをPOSTできなかった
- proxyの設定が必要なことが判明

## proxyの設定
- envファイルで定義した`apiBaseUrl`を以下のようにproxyで設定すれば、環境ごとのパスでAPIを呼び出すことができる

```javascript:nuxt.config.js
const environment = process.env.NODE_ENV
const envSet = require(`./env.${environment}.js`)

export default {
  env: envSet,

  (省略)

  axios: {
    proxy: true
  },
  proxy: {
    "/api": envSet.apiBaseUrl
  },

  (省略)

}
```

- 例えば、開発環境でのパスを以下のように設定しているのであれば、

```javascript:env.development.js
module.exports = {
  apiBaseUrl: "http://localhost:3000"
}
```
- `/api/form`と記述することで、開発環境では`http://localhost:3000/api/form`というAPIのパスを呼び出すことができる

```vuejs:index.vue
<script>
const url = "/api/form"

export default {
  methods: {
    submit() {
      axios
        .post(url, data)
        .then(res => {
          // 省略
        })
        .catch(e => {
          // 省略
        })
    }
  }
}
</script>
```

## 参照
[Options - Axios Module - Nuxt.js](https://axios.nuxtjs.org/options)
PowerShellでファイル名をキーにフォルダ振り分け

#ファイル転送されてくるzipファイルの解凍
まず最初に躓いたのがzipファイルの解凍の方法でした。
PowerShellのバージョンアップで標準機能として搭載されましたが、以前はunzip使ってました。
最近のバージョンだと下記のコマンドで解凍できました。

```Unzip.ps1
[String]$FROM="解凍元zipファイルパス"
[String]$TO="解凍先フォルダパス"
Expand-Archive -Path $FROM -DestinationPath $TO -Force
```

#ファイル名一覧からキー情報を抜き出す
解凍したcsvファイルの一覧からネーミングルールに沿った文字列をキーとして取得します。
取得したキーをソートすると同時にユニークなものに絞ります。

```GetUniqueKey.ps1
$LIST = @(Get-ChildItem -include [0-9]*.csv -name $TO) -as [String[]]
foreach($FILE_NAME in $LIST){
    [String[]]$UNIQUE_KEY += $FILE_NAME.Substring(10,7)
}
$UNIQUE_KEY = $UNIQUE_KEY | Sort-Object | Get-Unique
```

#キー情報を元にフォルダを作成しファイルを移動させる
上で作成したユニークなキー毎にフォルダを作成し、ファイル名にキーを含むファイルを移動させます。

```MoveFile.ps1
foreach($FOLDER in $UNIQUE_KEY){
    [String]$MAKE_FOLDER=$TO + "\" + $FOLDER
    if(!(Test-Path $MAKE_FOLDER)){
        New-Item $MAKE_FOLDER -itemType Directory
    }
    [String]$CSV=$TO + "\*" + $FOLDER + "*.csv"
    Move-Item $CSV $MAKE_FOLDER -force
}
```
MacOS Catalinaにnodebrewを通じてNode.js(npm)を設定する

## 困ったこと
* MacOS Caltalinaの標準ターミナルであるzshにはnpmが標準で入っていない
<img width="710" alt="スクリーンショット 2020-03-04 7.38.22.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161180/658966f5-10e6-c581-0214-2974d5cc3811.png">

## 実行
手順
1. nodebrewをcurlを利用してインストール
```$curl -L git.io/nodebrew | perl - setup```
2. Vimを開いて下記nodebrewのパスを~/.zshrc(zshの設定ファイル)に記入
```export PATH=$HOME/.nodebrew/current/bin:$PATH```
<img width="541" alt="スクリーンショット 2020-03-04 7.48.26 1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161180/2695ccb4-6f5c-0732-286c-43273bbeb3b8.png">
3. ~/.zshrcをリロードして適応
```$source ~/.zshrc```
4. node.jsの最新バージョンをインストール
```$nodebrew install latest```
5. nodebrewで使用するnode.jsのバージョンを指定
下記、赤枠部のようにインストール時にバージョン番号が表示されるため、それを利用してnode.jsのバージョン指定。
(X.X.Xの部分は各環境によって変わる)
<img width="1440" alt="スクリーンショット 2020-03-04 9.29.36.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161180/d16797a6-1f65-c508-d983-b397cb7381d8.png">
```$nodebrew use v.X.X.X```
6. コマンドで動作確認
```$npm -v```
<img width="410" alt="スクリーンショット 2020-03-04 9.32.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/161180/0faf732c-46ba-63da-1110-d4c23b832f8d.png">


## 参照文献
* [macOS Catalinaでnode.jsをインストール](https://qiita.com/kakuta_yu/items/a61e2b6a6e8a82dbbd96)
* [node.jsのversionを管理するためにnodebrewを利用する](https://qiita.com/sinmetal/items/154e81823f386279b33c)
* [Homebrewのnodebrewではnode.jsがインストールできないっぽいので、nodebrewを別にインストールしてnode.jsを入れた](https://tako1192.hatenablog.com/entry/2015/10/11/070311)
【Rails】ストロングパラメータについて

railsでコントローラーを記述する際、理解しておくべき基本中の基本。
ストロングパラメータ。

改めて勉強し直したので、めちゃくちゃざっくり概要をまとめます。

#ストロングパラメータとは
結論から言っちゃうと以下です。

- web上から受け取ったパラメータが安全なものか検証する
- 安全なデータを取得する

この2点をおさえとけばとりあえず大丈夫だと思います。

あらかじめ登録や更新を許可するカラムを設定してあげたら、意図しないパラメータが渡ってきたとしても守ってくれます。

とても優しい。

#具体例
ではさっそく具体例を。

```erb:post.html.erb
<%= form_tag(home_create_path) do %>
    <div>タイトル</div>
    <input type="text" name="title" maxlength="15" value="<%= @post.title %>" class="form-control" placeholder="15字まで入力できます。">

    <div>著者</div>
    <input type="text" name="author" maxlength="15" value="<%= @post.author %>" class="form-control" placeholder="15字まで入力できます。">

    <div class="center-block">
        <input type="submit" class="input-submit " value="投稿">
    </div>
<% end %>
```
post.html.erbではformからタイトルと著者を入力して送信できるようにしています。

送信されたパラメータはコントローラ側で受け取り処理します。

```home_controller.rb
class HomeController < ApplicationController
before_action :set_post, only: [:edit, :update, :destroy]
before_action :authenticate_user!, only: [:show, :create, :new, :edit, :destroy]

  def index
    @posts = Post.all.order(id: "DESC")
  end

  def new
    @post=Post.new
  end

  def create
    @post=Post.create(post_params)
    if @post.save(post_params)
      redirect_to(home_index_path)
    else
      render(home_new_path)
    end
  end

  def edit
  end

  def update
    if @post.update(post_params)
      redirect_to(home_index_path)
    else
      render(home_edit_path)
    end
  end

  private
  def set_post
    @post = Post.find_by(id: params[:id])
  end

  def post_params
    params.permit(
      :title,
      :author
    ).merge(
      user_id: current_user.id
    )
  end
end
```

ここではcreateアクションとupdateアクションで使用されています。

どちらもpost_paramsの記述が見られると思いますが、これがprivate以下に書かれているストロングパラメータです。

post_paramsではpermitメソッドに、検証したいカラムであるtitleとauthorをハッシュ形式で呼び出しています。

また、permitでは呼び出せないパラメータも検証したい場合は、mergeメソッドでつなげてあげると一緒に検証してくれるます。

これだけで安全なデータが取得されるので、とっても便利ですね。

#まとめ
今回は「概要をざっくりつかむ」という目的で書きました。

いきなり「ストロングパラメータ」って言われたら初心者は「なに？なに？」となりがちですが（経験済）、わかればなんてことないとても優しい機能です。

とりあえず、

- web上から受け取ったパラメータが安全なものか検証する
- 安全なデータを取得する

この2つをおさえておけば最初のうちは特に問題ないと思いますので、「ストロングパラメータってなんだっけ？」と思った時にでも、軽く読み返してください。

ではでは。
VPCエンドポイントを設定してEC2-S3間で接続しようとしたらAccess Deniedになったときの見落とし

#結論
`An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied`が出てしまうとき…
インスタンス側のロールにもちゃんと権限を付与しましょうという話だった。

#経緯
わい「EC2からS3にAWS CLIを使ってデータを送りたいな。先輩の話によるとVPCエンドポイントなるものを使うとできるらしい」

（「VPCエンドポイント EC2 S3」で検索）

わい「ふむふむ…要するにVPCのエンドポイントを作成して、ルートテーブルを設定してやれば動かせるって話か。」

（実際にやってみる）

わい「よっしゃ、じゃあ、`aws s3 ls s3://[BACKET_NAME]/` を入力して確認しよう」

AWS「`An error occurred (AccessDenied) when calling the ListObjects operation: Access Denied`」

わい「なんでや」

#状況
+ SSMからインスタンスに接続してAWS-CLIを実行
+ 自分はS3にアクセスできる権限がある
+ VPCエンドポイントの設定は問題ない
+ ルートテーブルの設定も問題ない

#原因と解決策
インスタンスに`AmazonS3FullAccess`の権限を持ったロールをアタッチする必要がありました。
インスタンスがコマンドを実行するので、あたりまえとはいえ当たり前ではあるのですが、見落としがちになるので注意しましょう。

| ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541975/906ca68e-8221-3e66-9271-a353d1ca57aa.png) |
|:--------------------------------------------:|

#参考資料
[[AWS] VPCエンドポイント経由でEC2からS3へファイル転送](https://agohack.com/file-transfer-ec2-to-s3-via-vpc-endpoints/#toc_id_1)
[VPCエンドポイント経由して別AWSアカウントのS3バケットにアクセスしてみた](https://dev.classmethod.jp/cloud/aws/s3-cross-account-access-iamrole/)
Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#7(データベース)

Google Cloud Platform (GCP)のサービスで正式名称や略称はともかく、読み方がわからずに困ることがよくあるのでまとめてみました。


クラウド コンピューティング サービス  |  Google Cloud
https://cloud.google.com/?hl=ja


## Amazon Web Services (AWS)のまとめはこちら！

Amazon Web Services (AWS)サービスの正式名称・略称・読み方チートシート - Qiita
https://qiita.com/kai_kou/items/cb29d261c8acc49fd22a

Amazon Web Services (AWS)サービスの正式名称・略称・読み方まとめ #1 (コンピューティング) - Qiita
https://qiita.com/kai_kou/items/a6795dbab7e707b0d1a6


## まとめルール

まとめルールについては下記を参考ください。

Google Cloud Platform (GCP)サービスの正式名称・略称・読み方まとめ#1(AI と機械学習/AI ビルディング ブロック) - Qiita
https://qiita.com/kai_kou/items/fa930eef23470c2f8f0b


## 概要について

サービス一覧ベージの概要を引用しています。

プロダクトとサービス  |  Google Cloud
https://cloud.google.com/products?hl=ja#product-launch-stages


間違いや、こんな呼び方あるよーなどありましたらコメントお願いします！


## Databases - データベース

### Cloud Bigtable

NoSQL ワイドカラム データベース サービス。

- 正式名称: Cloud Bigtable
- https://cloud.google.com/bigtable
- 読み方: クラウド ビッグテーブル
- 略称: なし
- 俗称: なし


### Cloud Firestore

モバイルアプリとウェブアプリのデータ向けの NoSQL ドキュメント データベース。

- 正式名称: Cloud Firestore
- https://cloud.google.com/firestore
- 読み方: ファイアストア
- 略称: なし
- 俗称: なし


### Cloud Memorystore

フルマネージドのインメモリ データストア サービス。

- 正式名称: Cloud Memorystore
- https://cloud.google.com/memorystore
- 読み方: メモリストア
- 略称: なし
- 俗称: なし


### CLOUD SPANNER

ミッションクリティカルでスケーラブルなリレーショナル データベース サービス。

- 正式名称: CLOUD SPANNER
- https://cloud.google.com/spanner
- 読み方: クラウド スパナ
    - 参考: [Spanner \(データベース\) \- Wikipedia](https://ja.wikipedia.org/wiki/Spanner_(%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9))
- 略称: なし
- 俗称: なし


### Cloud SQL

MySQL、PostgreSQL、SQL Server のデータベース サービス。

- 正式名称: Cloud SQL
- https://cloud.google.com/sql
- 読み方: クラウド エスキューエル
- 略称: なし
- 俗称: なし


### Firebase Realtime Database

データの保管と同期をリアルタイムで行います。

- 正式名称: Firebase Realtime Database
- https://firebase.google.com/products/realtime-database/
- 読み方: ファイアストア リアルタイム データベース
- 略称: なし
- 俗称: なし
【Python】ヒアドキュメントでエスケープシーケンスを展開する

ハマったので備忘。

ヒアドキュメントにそのままエスケープシーケンス（`\`）を書いてもエスケープシーケンスとして展開されない。

`\\`のように２つ続けて記述するか、raw文字列を使うと展開できる。

```python
>>> import json
>>>
>>> json_dict1 = json.loads('''
... {
...     "id": 1,
...     "name": "hoge",
...     "description": "ほげ\"ほげ\"ほげ"
... }
... ''')
Traceback (most recent call last):
  File "<stdin>", line 7, in <module>
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1776.0_x64__qbz5n2kfra8p0\lib\json\__init__.py", line 348, in loads
    return _default_decoder.decode(s)
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1776.0_x64__qbz5n2kfra8p0\lib\json\decoder.py", line 337, in decode
    obj, end = self.raw_decode(s, idx=_w(s, 0).end())
  File "C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.7_3.7.1776.0_x64__qbz5n2kfra8p0\lib\json\decoder.py", line 353, in raw_decode
    obj, end = self.scan_once(s, idx)
json.decoder.JSONDecodeError: Expecting ',' delimiter: line 5 column 24 (char 59)
>>> print(json_dict1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'json_dict1' is not defined
>>>
>>> json_dict2 = json.loads('''
... {
...     "id": 2,
...     "name": "hoge",
...     "description": "ほげ\\"ほげ\\"ほげ"
... }
... ''')
>>> print(json_dict2)
{'id': 2, 'name': 'hoge', 'description': 'ほげ"ほげ"ほげ'}
>>>
>>> json_dict3 = json.loads(r'''
... {
...     "id": 3,
...     "name": "hoge",
...     "description": "ほげ\"ほげ\"ほげ"
... }
... ''')
>>> print(json_dict3)
{'id': 3, 'name': 'hoge', 'description': 'ほげ"ほげ"ほげ'}
```
AWS Lambda で作った messagingAPI を、SAM ＋ ngrok でローカルテストする


## 目的

AWS Lambda(SAM)を使用した LINEBOT 作成をしたい人が、ローカル環境で動作をテスト出来るようになる。

### 環境

```txt
Python 3.7.4
SAM CLI 0.37.0
line-bot-sdk 1.15.0
pipenv 2018.11.26
```

## 概要

[ngrok](https://ngrok.com/)を用いる方法。
ローカルに立てたサーバをポートフォワーディングで一時的に外部通信できるようにして、
それを messagingAPI の webhook に引っ掛ける形で動作のテストをする。

※ngrok の会員登録は不要ですが、有料会員以外は時間制限(8 時間)があって毎回 URL が変わってしまうので、この方法でやるなら日付が変わるごとに messagingAPI の設定を変える必要があります。チョットメンドウ

## 手順

### sam local

作成したfunction をビルド
`$ sam build --use-container`

ビルドした function を立ち上げる。　デフォルトのポートは 3000。

```bash
$ sam local start-api --env-vars env_local.json --docker-network my-app

Mounting TestLineBotFunction at http://127.0.0.1:3000/line/reply [POST]
You can now browse to the above endpoints to invoke your functions. You do not need to restart/reload SAM CLI while working on your functions, changes will be reflected instantly/automatically. You only need to restart SAM CLI if you update your AWS SAM template
yyyy-mm-dd 15:05:36  * Running on http://127.0.0.1:3000/ (Press CTRL+C to quit)
```

### ngrok

ngrok をインストール
`$ brew cask install ngrok`

テストしたいローカルのポート番号を入れる。

```bash
$ ngrok http 3000

ngrok by @inconshreveable                                   (Ctrl+C to quit)

Session Status                online
Session Expires               7 hours, 52 minutes
Version                       2.3.35
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://hogehoge.ngrok.io -> http://localhost:3000
Forwarding                    https://hogehoge.ngrok.io -> http://localhost:3000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

HTTP Requests
-------------
```

### messagingAPI

LINE developers の管理画面から、messagingAPI の webhook に LINEBOT 用に切ったエンドポイントを登録する。
私の場合は LINEBOT の function を`line/reply`で切ったので、以下の様になる。
`https://hogehoge.ngrok.io/line/reply`

※「検証」ボタンは送られてくるリプライトークンが無効？らしくて上手く反応しない(しそれが割とデフォらしい)です。
実際の動作を試してみてサーバに反応があったら上手く紐づいてるな、くらいの確認でいいと思います。

## 動作テスト

LINE Developers の管理画面で友達登録の URL が見られるので、そこから登録する。
反応語彙等を確認。

終わったら ngrok と sam local 共に閉じて完了。

---

## 参考にさせていただいたもの

[ngrok が便利すぎる - Qiita](https://qiita.com/mininobu/items/b45dbc70faedf30f484e)
Windowsでdeoplete-clangを使う方法

## 環境(前提)

windows 10
neovim 0.4.3

## clangのインストール

[LLVM Clang の Windows へのインストールと使い方 ](http://yohshiy.blog.fc2.com/blog-entry-294.html)
に従いました。
必ず、PATHを通すようにしてください。

## neovimの設定

```toml:dein_lazy.toml
[[plugins]]
repo = 'zchee/deoplete-clang'
hook_source = '''
source ~/.config/nvim/plugins/deoplete-clang.vim
'''
on_ft = ['c', 'cpp', 'cmake']
```

このpathは、clangをシステムインストールした場合のものです

```vim:plugins/deoplete-clang.vim
let g:deoplete#sources#clang#libclang_path= 'C:/Program Files/LLVM/bin/libclang.dll'
let g:deoplete#sources#clang#clang_header = 'C:/Program Files/LLVM/lib/clang'
```

## もしかしたら必要かも

本当に必要なのか検証はしていませんが、エラーが出てきたのでやったこと
`pip install clang`

## 注意点

`deoplete`の設定をコピペで使っている人は、既に`g:deoplete#sources#clang#libclang_path`がlinuxのpathで設定されているかもしれません。確認してください。(ここにハマりました)
BIOS をアップデートしたら boot order が壊れた

パソコンを買った当初にも同じ設定をしたはずなのに、やり方を忘れてしまったのでメモ。

**この記事はただのメモです。参考にする方は、自己責任でお願いします。**


# 環境
- laptop: OMEN by HP 15-ax200/intel core i7
- OS: Windows 10(SSD) + Arch Linux(HDD)

# 何が起こったか
BIOS のアップデートを行なった後にマシンを再起動したら、Arch Linux ではなく Windows が立ち上がった。

# 解決方法
1. Windows の UEFI の設定から boot option を開く
1. Arch Linux を起動して、`efibootmgr` から、Arch Linux 用の新しい boot entry を作成
1. 再起動して、BIOS の起動設定から boot order を変更

## efibootmgr の使い方
efibootmgr を用いて boot order を設定します。以下 `sudo` は省略しているので、要求されたら適宜足してください。

ここでは私の環境で打ったコマンド(以下)を例に、efibootmgr のオプションを説明します。

```shell
$ efibootmgr -c -d /dev/sda -p 1 -L "Arch Linux" -l "\EFI\boot\bootx64.efi"
```

詳細は [Gentoo wiki](https://wiki.gentoo.org/wiki/Efibootmgr#Creating_a_boot_entry) を参照。

### -c: boot entry の作成
新たに boot entry を作成します。

### -d: ディスク
Linux がインストールされているディスクの名前を入力します。`lsblk` 等で確認できると思います。
私の環境だと Windows が `/dev/nvme0n1`、Arch Linux が `/dev/sda` にインストールされているので、`-d /dev/sda` としました。

### -p: EFI システムパーティション(ESP)の番号
`fdisk -l`, `parted -l` 等で確認できます。
私の環境だと 1 だったため、`-p 1` としました。

### -L: boot entry の名前
いい感じに名前をつけましょう。

### -l: efi ファイルのパス
grub 等のブートローダの設定ファイルを作るときに指定した、efi ファイルのパスを入れます。
ただし、**パスは`/`ではなく`\`を用いる**こと。

私の環境だと efi ファイルが `/boot/EFI/boot/bootx64.efi` にあったので、 `/boot` 以下のパスの`/`を`\`に変更して `-l "\EFI\boot\bootx64.efi"` としました。

## BIOS の起動設定から順序を変更
私の環境では、パソコンを再起動すると `efibootmgr` で設定した boot order がリセットされてしまいました。しかし boot entry 自体は正しく作成されていたため、BIOS の設定から起動順序を変更することができました。

boot entry 自体が見つからない場合は、前述の `-l` の値の設定等が間違っている可能性があります。`efibootmgr -v` で boot entry が正しく作成できたか確認してみてください。

# 最後に
間違っている箇所があったら、コメント等でお知らせください。ではでは。
Power Automateで一意なデータを取り出す方法

たとえばこんなデータがあったとしましょう。(2回目)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/77a43bf6-6269-172e-289e-f0b59dca0df4.png)
ここから、モデル名だけのリストを作りたい場合、または容量の違いを見ずに、モデル名とカラーだけのリストを作りたい場合、どうしたらよいでしょうか？ Power Automateで。

# 重複の排除
Power Appsだとあるんですよね。 *Distinct*関数が。これが指定した列で一意なリストを得ることができます。
Power Automateには、ありません。 Distinctみたいな関数はないです。
そんな重複の削除、リストの特定の列から一意な値だけを取得する方法を紹介します。

## まずはいつものSelect
まずは必要な列(というか一意にしたい列)だけで構成されるリスト(配列)を作る必要があります。これにはSelectアクションを利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/7dd8d5d3-a228-6969-9e2b-1568cc8e54d6.png)

出来た配列は、単純に最初のリストでCapacityを取り除いただけで、NameとColorは重複したままです。

## 一意が欲しいならunion()
**リストから一意な一覧を得たいなら、[union()](https://docs.microsoft.com/ja-jp/azure/logic-apps/workflow-definition-language-functions-reference#union)**を使いましょう！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/202779/d07d15eb-afcd-1cf6-abc7-326fdb5fd8b1.png)

重要なのは戻り値の説明にある「重複はありません」です。unionの結果は重複を許さないんです。
例えば、 [1,2,3,4]と[3,4,5]をunionすると、戻り値は[1,2,3,4,5]です。この性質を利用します。

Selectの結果は ```body('Select')``` です。これを踏まえて。

```
union(body('Select'),json('[]'))
```
これで完成です！
```json('[]')``` は空の配列をjsonとして生成しています。これと重複を含む配列をunionすると、元の配列からも重複が取り除かれた結果が得られます！

```distinct.json
[
  {
    "Name": "iPhone XR",
    "Color": "Red"
  },
  {
    "Name": "iPhone XR",
    "Color": "Black"
  },
  {
    "Name": "iPhone 11",
    "Color": "White"
  }
]
```
無事NameとColorで一意のリストができました！

# おわり
簡単なアクションとちょっとだけの数式で一意なリストを生成することができました。
今回のFlowは以下からダウンロードできますので、試してみてください。
https://github.com/mofumofu-dance/PowerApps365/blob/master/Samples/DistinctArray.zip

※友人のFlow忍者こと[John Liu](https://twitter.com/johnnliu) が動画で説明してくれています！ぜひご覧ください。
https://www.youtube.com/watch?v=dNvxMMdWmjk
よく使うlinuxコマンド

よく使うlinuxコマンドをまとめました。

# ls
現在のディレクトリのファイルを一覧表示する

```shell
$ ls
```

**オプション**
詳細の情報を含める

```shell
$ ls -l
```

隠しファイルを含める

```shell
$ ls -a
```

# cd
現在のディレクトリから指定したディレクトリに移動する

```shell
$ cd test
```

# mkdir
指定した名前でディレクトリを作成する

```shell
$ mkdir test
```

# touch
指定した名前でファイルを作成する

```shell
$ touch test.txt
```

# cp
指定したファイルを、指定した名前で複製する

```shell
$ cp test.txt test_copy.txt
```

**オプション**
指定したディレクトリを、指定した名前で複製する

```shell
$ cp -r test test_copy
```

# mv
指定したファイルやディレクトリを、指定した名前で移動する

```shell
$ mv test.txt ../test_copy.txt
```

# rm
指定した名前のファイルを削除する

```shell
$ rm test.txt
```

**オプション**
指定した名前のディレクトリを削除する

```shell
$ rm -r test
```

指定した名前のディレクトリを警告無しで確実に削除する

```shell
$ rm -rf test
```
Haxeはじめました。

今日も今日とてネットの海を彷徨っていたら、Haxeなるプログラミング言語があることを知った。
なんか面白そうなので、導入して世界に挨拶してみる。

#導入
[Haxeのホームページ](https://haxe.org/)から「Download X.X.X」を押して自分のOSのやつ押してダウンロードしたファイルを実行すればできる。

```zsh
❯ haxe
Haxe Compiler 4.0.5 - (C)2005-2019 Haxe Foundation
Usage: haxe <target> [options] [hxml files...]

(以下略)
```

こんな感じのが出ればOK。
#世界に挨拶
```haxe:HelloWorld.hx
class HelloWorld{
  static public function main(){
    trace("Hello World.");
  }
}
```
とりあえず実行してみる。

```zsh
❯ haxe -main HelloWorld --interp
HelloWorld.hx:3: Hello World.
```
大丈夫そう。次はPythonに変換してみる。

```zsh
❯ haxe -main HelloWorld -python HelloWorld.py
```
できたファイルを見てみる。

```python:HelloWorld.py
# Generated by Haxe 4.0.5
# coding: utf-8
import sys



class HelloWorld:
    __slots__ = ()

    @staticmethod
    def main():
        print("Hello World.")


class python_internal_MethodClosure:
    __slots__ = ("obj", "func")

    def __init__(self,obj,func):
        self.obj = obj
        self.func = func

    def __call__(self,*args):
        return self.func(self.obj,*args)




HelloWorld.main()
```
実行するとこんな感じ。

```zsh
❯ python3 HelloWorld.py
Hello World.
```

#あとがき
とりあえず今回はここまで。
飽きてなかったらなんかやります。多分。
初心者によるプログラミング学習ログ 253日目

#100日チャレンジの253日目

twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。

すでに100日超えましたが、継続。

100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。

253日目は、

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>253日目<br>・youtubeで、JSのミニアプリ模写<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1234931254450999296?ref_src=twsrc%5Etfw">March 3, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
mac CatalinaでTWELITEのビルドをする

MojaveからCatalinaにしたらビルドできなくなっていて結構詰まっていたのでメモ

### 環境
OS:macOS Catalina 10.15.2
VSCode:1.42.1
MWSDK:[2018/5月号](https://mono-wireless.com/download/SDK/MWSDK_201805/MWSDK_OSX_201805.tgz)
App_Tag:[2.1.5](https://mono-wireless.com/jp/products/TWE-APPS/App_Tag/firmware/App_Tag_src_2_1_5.zip)

### 手順
1. VSCodeをインストールする
ここからダウンロードして展開してアプリケーションフォルダに入れる
control推しながら起動するとその場で"開発元が〜〜〜"ってのを許可できるらしい
https://code.visualstudio.com/docs/?dv=osx

1. TWELITE C ライブラリ SDKをインストールする
ここからダウンロードして適当なフォルダに展開する
https://mono-wireless.com/jp/products/TWE-NET/index.html

1. ビルドしたいアプリを入れる
予め./MWSDK/Wks_TWELITEに突っ込んでおく(今回は/MWSDK/Wks_TWELITE/App_Tag_215に配置)
今回はApp_Tag 2.1.5
https://mono-wireless.com/jp/products/TWE-APPS/App_Tag/download.html

1. 「開発元を検証できないため開けません」エラーをひたすらつぶす
ビルドしたいアプリのBuildに移動してmakeする  

     ```bash
$ cd MWSDK/Wks_TWELITE/App_Tag_215/EndDevice_Input/Build
$ make TWELITE=RED clean
$ make TWELITE=RED
```
延々出てくる「開発元を検証できないため開けません」エラーを許可しては```make TWELITE=RED```を実行しつづける
1. ビルドできる
VSCodeのタスクを実行にApp_Tag_215が出てこないけど、気にしない
男は黙ってmake
Swift Notificationの利用法

TabBarメニューにてタブボタンをクリック時にてViewを更新表示する際のNotificationを利用する例を記載します。
Notificationは<font color="red">実行中のcalss</font>に対してメッセージを送りそのメッセージに対応した
処理を実行できる。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/101462/f39f9a39-d096-509f-eb1a-5ddd96186e18.png" width="300">

```swift
 //拡張のためextensionの下記をどこかのファイルに記載してください。
extension Notification.Name {
    static let notifyName = Notification.Name("notifyName")
}
 // tabbar選択の
 // 通知を送りたい箇所でこのように記述
    NotificationCenter.default.post(name: .notifyName, object: nil)

 func tabBar(_ tabBar: UITabBar, didSelect item: UITabBarItem) {
        switch item.tag {
        case 0:
            print("0")
            View1.isHidden = true
            View2.isHidden = true
            View3.isHidden = true
            View4.isHidden = true

        case 1:
            View1.isHidden = false
            View2.isHidden = true
            View3.isHidden = true
            View4.isHidden = true
        
            // 通知を送りたい箇所でこのように記述
            NotificationCenter.default.post(name: .notifyName, object: nil)           
        case 2:
            View1.isHidden = true
            View2.isHidden = false
            View3.isHidden = true
            View4.isHidden = true
        case 3:
            View1.isHidden = true
            View2.isHidden = true
            View3.isHidden = false
            View4.isHidden = true
        case 4:
            View1.isHidden = true
            View2.isHidden = true
            View3.isHidden = true
            View4.isHidden = false
        default:
            return
            
        }
    }
//受診先View
/// NotificationCenterを登録
        NotificationCenter.default.addObserver(self, selector: #selector(doSomething(_:)), name: .notifyName, object: nil)

    //Notification受取下記処理実行
    @objc func doSomething(_ notification: Notification)
    {
        print("doSomething")
        //下記処理実行
        refresh()
    }



```
[メモ]SSHのポートを22以外にしたときに忘れてはならないこと[CentOS7]

セキュリティのためにsshのポートを22以外にしておくのはよくある話ですが、ついつい忘れてしまうのがファイヤーウォールの設定。当方もこれを忘れてアタフタしておりました。
シングルモードでログインして、ファイヤーウォールの設定を忘れずに追加しておきましょう！

```
sudo firewall-cmd --permanent --add-port=[ポート番号]/tcp
sudo firewall-cmd --reload
```

これで、リモートログインできるかどうか試してみてくだいませ。できないときは別の設定が悪さしているようです。
php に xdebug を入れて phpstorm でデバッグする


## php に xdebug　を入れる

```
php -i | grep xdebug
php --version | grep xdebug
```
などにより php に xdebug が入っていないことを確認します。


```
pecl install xdebug
```

により xdebug をインストールします。

自分の環境では初めはインストールに失敗し、
https://www.findxfine.com/programming/php/995561772.html
を参考にして解決しました。

インストールに成功すると

```
php -i | grep xdebug
```
などで xdebug の行が出てくるかと思います。

次に php.ini で xdebug のパラメータを設定します。
以下のコマンドで php.ini の場所がわかります。

```
php -i | grep php.ini
```

```php.ini
xdebug.remote_enable = 1
```
など、環境に合わせて追記していきます。

サーバーを起動したまま作業しているようであれば、ここでサーバーを再起動して php.ini をリロードします。

## phpstorm でデバッグする
`Preference > language & flameworks > PHP`へ移動します。
`CLI Interpreter` に使用する php を追加します。

ここで自分は少し嵌ったのですが

```
which php
```
等で表示されるパスは実際の実行ファイルへのシンボリックリンクであるため、実際の実行ファイルのパスを入力するようにしましょう。

自分の場合は`/usr/local/Cellar/php/7.3.9/bin/php`でした。

次にデバッガを設定します。
`Preference > language & flameworks > PHP　> Debug`
より Debug Port を設定することができます。
php.ini を弄っていなければデフォルトは9000なので、この値を変更する必要はないはずです。

次にサーバーを設定します。
`Preference > language & flameworks > PHP　> Sever`で登録できます

- Name: なんでもよいです
- Host: localhost (phpやフレームワークのビルトインサーバーを使って開発している場合)
- port: 80
- Debugger: Xdebug

にしましょう

次に `run/debug configurations` に移動します。画面上部バー中央やや左よりのボタンより移動できます。

ここで先ほど作成したサーバーを選択し登録します。IDEKEYの箇所は入力しなくても大丈夫でしたが、どこかの記事で入力しないとエラーが出るというのも見たので、エラーが出るようであれば上部のボックスにチェックを入れると入力できるようになります。

上記ボタンの右側のにある、虫のようなマークと電話のようなマークでデバッグをスタートさせることができます。

最後に楽にデバッグに移行できるようブラウザに拡張機能をダウンロードします。
https://www.jetbrains.com/help/phpstorm/2019.3/browser-debugging-extensions.html?utm_campaign=PS&utm_content=2019.3&utm_medium=link&utm_source=product
このリンクより chrome と firefox の拡張機能のダウンロードページへ移動できます。

拡張機能を有効化し、目的のページにアクセスするとデバッグすることができます。





## 参考にしたサイト
- https://qiita.com/ponsuke0531/items/036378e5f460984e20a5
- https://takuya-1st.hatenablog.jp/entry/2016/05/02/153440
- https://www.findxfine.com/programming/php/995561772.html
- https://www.tam-tam.co.jp/tipsnote/program/post13770.html
RDKitを使って有機化合物を表示させる環境構築

#はじめに
はじめまして．私は有機系の研究室で化学合成を行っている大学生です．
近年MachineLearningやDeepLearningが様々な分野で盛んに行われていますが，化学屋ではChemoinfomaticsといった分野もありますがそれほど盛んではありません．

そのため環境構築に関する書籍や記事も少ないため，ここに表題の通りRDKitというPythonのモジュールを使って有機化合物を表示させるための環境構築方法を備忘録も兼ねて記します．


#手元の環境

macbook pro 2016
macOS Catalina 10.15.4


#RDKitとは
RDKitとはchemoinfomaticsに有用なオープンソースのツールです [RDKit公式サイト](https://www.rdkit.org/docs/Overview.html) より

数百万以上の化合物情報(e.g. 2D・3D情報や物性値)を無料で利用できます．


#環境構築手順

##1.Anacondaのインストール

Anacondaはデータサイエンス向けのPythonパッケージを多く扱うプラットフォームです．

私はすでにインストールしていたため行っていませんが，以下のような記事を参考にするといいと思います．

[Anaconda で Python 環境をインストールする](https://qiita.com/t2y/items/2a3eb58103e85d8064b6)


##2.RDKitをAnacondaでインストール
Anacondaでは`conda`コマンドでパッケージを管理し仮想環境を構築します．


[RDKit公式サイト](https://www.rdkit.org/docs/Install.html)の手順が非常に丁寧なので，その中で推奨されている方法をなぞって進めます．

```
conda create -c rdkit -n my-rdkit-env rdkit
```
を入力して

```
Proceed ([y]/n)?
```
などと表示されるので全て `y`で続行します．
すると多くのモジュールが自動でインストールされます．

```
conda activate my-rdkit-env
```
と入力して `my-rdkit-env` という仮装環境に入ることができます．成功していれば

```
(my-rdkit-env) パソコン名:user$ 
```
のようにターミナルに表示されているはずです．
もしここで問題が発生した場合は

```
cd [anaconda folder]/bin  #[anaconda folder]はanacondaのインストールされた場所
source activate my-rdkit-env
```
と試してみてください．
仮装環境から抜け出す際には，

```
conda deactivate
```
と入力すればよいです．


次に，仮想環境下でRDKitでよく用いるモジュールをインストールします．

```
conda install numpy matplotlib
conda install pubchempy
conda install cmake cairo pillow eigen pkg-config
conda install boost-cpp boost py-boost
```


ここまででRDKitを使うために必要最低限の環境構築は完成しました．次回(多分続く)は今回構築した環境を実際に利用して化合物を表示させてゆきます．


#おわりに

環境構築って一番難しいですよね．これまも環境構築で挫折したことが何度あったやら...今回は公式サイトがとても優秀だったのでスムーズに進みました．


それではまたいつか．
実装したAPIを確認する便利ツール3選

# [Advanced Rest Client](https://chrome.google.com/webstore/detail/advanced-rest-client/hgmloofddffdnphfgcellkdfbfbjeloo/details?hl=ja-JP)
クロームの拡張子。

# [Paw](https://paw.cloud/)
スタンドアロンアプリケーション。
# [Postman](https://www.postman.com/downloads/)
スタンドアロンアプリケーション。
# [httpie](https://httpie.org/doc#installation)
コマンドラインアプリケーション。
`$ http :3000/v1/contacts` とする。
【Data Base】busy状態が頻発したケーススタディ

#事象
初めての新規開発案件で、自分の製造した機能でbusy状態のエラーログが頻発してしまった。

##原因
調査の結果、原因は他機能同士でデッドロックが発生してしまうことに起因していた。

##調査方法
悲観ロックをかける順序を洗い出した。
例）昇格機能：対象の社員を確認 → 所属する店長グループを確定 → 配属エリアの選定 → 配属店舗の選定
　　　　　　　t_staff → t_maneger_group → t_area → t_shop
　　退職機能：所属店舗の確認 → 対象社員の上長を確認 → 対象社員の削除
　　　　　　　t_shop → t_manger_group → t_staff

（無理に例えると分かりにくい気もするけど、せっかく書いたし残します。）

##対策
テーブルをidなどで管理して、ロックする順序をプロジェクト全体で統一するのが一般的だよね～との事。

###最後に。
ある程度、デッドロックが原因であることは当たりがついていたが、それを起こしている機能がなかなか見つからずに困り果てていた。
やむを得ず先輩に助力を求めたところ、あっさりと原因の機能を見つけられたので調査方法の覚書として。

今回は、スケジュールがきつすぎてコーディング規約とかゆっるゆるで走り出してしまったせいで
これ以外にもたくさんの面倒くさいことが起こりました。
雁字搦めで作るのは鬱陶しいかもなとか思ってましたが、フリーダム過ぎると初歩的なミスが多発するということで非常に勉強になりました。

初投稿でよくわからないままにあげてしまいますが、最後まで読んで頂けたなら幸いです。
SAP　HANAの資格について教えてください。

１５年ぶりにSAP２０２５年問題でこの業界に帰ってきました。
今後この業界で頑張っていきたいため、SAPの資格を取りたいと思います。
SAP社のサイトを見ても、わからない為どなかた教えてもらえますか。
資格は、SAP　HANAの資格です。
BASISの資格より、旧来のFI（財務管理）、SD（販売管理）、MM（在庫管理）PP（生産管理）
コンサルタント系の資格を取りたいと考えてます。

例えば、旧来のFI系はこれ、SD系はこれ、MM系はこれ、PP系はこれなど
例えば下記の試験が旧来のなにと同じなのか。それとも旧来のやつと別物なのか等すら
わかりません。
宜しくお願いします。
試験コード：C_S4CS_1911
試験名称：SAP Certified Application Associate - SAP S/4HANA Cloud - Sales Implementation
WordPressでwp-adminに入るときに、管理者権限なのに「このページにアクセスする権限がありません。」と言われた

管理者権限なのに「このページにアクセスする権限がありません。」と妙なことを言われて悩みました。解決策がわかったので備忘録を記載。

# 原因
現状のデータベースのテーブルの接頭辞とデータベースの作成時のそれが食い違ってたから

# 修正方法
phpMyAdminなので、データベースを開きます。

そこで、

- テーブル接頭辞optionsの
 - 接頭辞user_roles1

- 接頭辞usermetaの
    - 接頭辞capabilities
    - 接頭辞user_level

を適宜修正すればログインできた。
Romeを試してみた

[JSer.info](https://jser.info/2020/03/03/react-v16.13.0-romejavascript-tool-chain-ember-octane/)で見かけて面白そうだから試してみた。

## Romeとは

ビルド周りのあれこれをまるっと面倒みてくれるツール。

> Rome is an experimental JavaScript toolchain
> A compiler, linter, formatter, bundler, testing framework and more

（ https://romejs.dev/ より引用）


## 試してみた

> It is not ready for production usage. The only way to use it is to build from source.

（https://github.com/facebookexperimental/rome より引用）

ということでビルドしないと試せないので、ビルドして動かすところまでをやってみた。

### 環境

- macOS Catalina 10.15.3
- Node.js v12.16.1

### 準備する

`rome`コマンドが使えるようになるとこまで。

#### 公式からリポジトリを持ってくる

公式から適当にとってくる。

```bash
$ git clone https://github.com/facebookexperimental/rome.git
$ cd rome
```
#### ビルドする

`npm install`もせずにおもむろにビルドのコマンドを叩く。

なんとビルドに必要なものはすでにリポジトリのnode_modulesにすでに入っている。

```bash
$ ./script/build-release dist
```

#### linkする

linkしてどこでも使えるようにする。

自分はnodenvを使っていたのでlinkした後に`nodenv rehash`が必要だった。

```bash
$ cd dist
$ npm link
```

### 使ってみる

とりあえずセットアップしてlintだけ。

#### セットアップ

使いたいプロジェクトのディレクトリで`rome init`する。
`rome.json`が生成される。

```bash
$ cd <適当なjsのプロジェクト>
$ rome init
```

#### lint

適当にコードを書いてlintしたらちゃんと怒ってくれた。

```bash
$ rome lint src/**/*.js
~~~ 略 ~~~
ℹ 2 files linted
✖ Found 4 problems
```

## おわりに

今回はとりあえず動かすのが目標だったのでlintしか試さなかった。

compileやparse、testなどまだまだ色々な機能があるので、これらも試してみたい。

今後の成長が楽しみ。
Alloyでパズル (1) ウソつき問題

# 導入： 考えない名探偵

我々には、問題をみると「どうやったら解決できるか」と考える癖がついている。
数独のようなパズルを見ても、どう考えたら解にたどり着けるか自分なりのアルゴリズムを探っている。

しかしここにコンピュータがある。
コンピュータが人間に勝る大きな点は圧倒的な計算速度による力技であり、総当たりの威力である。
総当たりの威力をもってすれば、数独のような単純な問題は**考えるまでもない**のだ。

状況を聞いただけで、考えるそぶりも見せずに解を出すそれは、さながら名探偵のよう。
考えない名探偵を相棒に得たとき、我々は何をできるのだろうか。

---

形式手法のひとつである Alloy、ツール Alloy Analyzer はこの名探偵のような存在です。
これを使う人間に必要なことは的確に状況を伝えること、すなわち **正確に仕様を記述すること** です。
問題の解法をプログラミングするのではなく、ルールや状況を記述するだけで、過程や結果を見せてくれる。
そうやってパズルを解かせるのは、自分で解くのともプログラミングで解かせるのとも違った面白さがあります。
そしてもちろん、正確な仕様記述は人間がプログラミングする場合にも役立ちます。

# 対象読者

パズルを解かせてみたい人、形式手法って聞いたことある(ない)けど難しそうという人など。

# 環境

Visual Studio Code に [Alloy](https://marketplace.visualstudio.com/items?itemName=ArashSahebolamri.alloy) プラグインがあるので、それを使うのがお勧めです。
シンタックスハイライト、VS Code内からの実行、マークダウン内埋め込みからの実行 などとても便利です。

Alloyの勉強には、やはり書籍『[抽象によるソフトウェア設計 ―Alloyではじめる形式手法](https://www.amazon.co.jp/dp/B07BKRG85J)』が必要でしょう。
例題としてパズルも数多く載っていて楽しめます。
いきなり通読するのは難しいかと思いますので、読めそうなところを読んで、あとは必要に応じて参照するとよいでしょう。
いきなり書籍を買いたくない場合は、リストを見て雰囲気を感じるところからでいいでしょう。

# パズル(1) ウソつき問題

## 問題
よくある、誰がウソつきかを当てる問題。
レイトン教授の例が Alloy 紹介の SlideShare に上がっていたので、やってみよう。
![](https://image.slidesharecdn.com/alloy-layton-110828112653-phpapp01/95/alloy-analyzer-18-728.jpg?cb=1325851032)

## リストと結果
両含意`<=>` を使うと簡潔に書ける。
問題文を書き写しただけで**解き方を一切書いていない**ことに注目。
Qiita では Alloy のシンタックスハイライトが効かないのが残念（Scalaが一番近い気がする）

```alloy:puzzle1.als
/* レイトン教授 より
    https://www.slideshare.net/osiire/alloy-analyzer
*/

// 本当のことしか言わないトンホー種とウソしか言わないソーウ種
enum 牛種 {トンホー種, ソーウ種}
abstract sig 牛 {type:牛種}
one sig A,B,C,D,E extends 牛 {}     // ５頭の牛がいる

fact {
    #(type.トンホー種) = 2    // ２頭はトンホー種（他はソーウ種）
    // 「X <=> Y」は、(XならばY) かつ (YならばX)
    (A.type = トンホー種) <=> (D.type = ソーウ種)       // A「Dはソーウ種だね」
    (B.type = トンホー種) <=> (C.type != トンホー種)    // B「Cはトンホー種じゃないよ」
    (C.type = トンホー種) <=> (A.type != ソーウ種)      // C「Aはソーウ種じゃない」
    (D.type = トンホー種) <=> (E.type = ソーウ種)       // D「Eはソーウ種です」
    (E.type = トンホー種) <=> (B.type != トンホー種)    // E「Bはトンホー種じゃないぞ」
}

run {}

// 以降は答え合わせ
// 「Bはトンホー種である」に対する反例があるか確認する
check { B.type = トンホー種 }

// 「Dはトンホー種である」に対する反例があるか確認する
check { D.type = トンホー種 }
```
<img width="511" alt="puzzle1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20005/422252c9-7e48-3181-ea27-245200434f54.png">

## 解説：両含意
日常言語の感覚とは異なるが、論理学の立場では「宿題やったらおやつ食べていいよ」は宿題をやらなかった場合に言及していないことになる。
宿題をやらなくてもおやつを食べていいかもしれないのだ。
形式仕様記述として明確さを求めるため、上記の言葉は Alloy では`宿題やった => おやつ食べていい`と書き、「おやつ食べていいのは宿題やったとき」を含む`宿題やった <=> おやつ食べていい`と明確に書き分ける。

日常言語でも「食べたらなくなる」の例なら「なくなるのは食べたとき」と言っているわけではない。
「たら」「なら」の意味が単独では確定しないということで、自然言語解析分野の話になる。

※ていうか、プログラマー的には
　　```if (宿題やった) おやつ食べていい```
　　```if (食べた) なくなる```
　と書いたらそういう意味になるのは当たり前だよね
　逆も必要ならそう書かないとダメで、よく使う表現だから簡単に書き分けられるよというだけの話

# 参考

- SlideShare : [レイトン教授で始めるAlloy Analyzer入門](https://www.slideshare.net/osiire/alloy-analyzer)
- Daniel Jackson : [抽象によるソフトウェア設計 ―Alloyではじめる形式手法](https://www.amazon.co.jp/dp/B07BKRG85J)
- 本家サイト : [alloy](https://alloytools.org/)
- (モデル置き場) : [jpwgad/alloy-models](https://github.com/jpwgad/alloy-models)

# あとがき
Alloyを勉強して２ヶ月強、それなりに使えるようになってきました。
ネットに残っている記事は古かったり掲載リストが難しかったりしたので、今やるならこうというサンプルを放流してみようかと。
形式手法を楽しいと感じて、気軽に付き合っていく助けになれたらいいなと思います。
raspberry piで最初からhttpsでサーバーをたてる

#はじめに
たててる最中に色々と間違い、5回も焼き直しをしたのでブチギレてまとめます。
サイトによって情報がバラバラだったりするので、現時点(2020/03/04)でうまくいった方法を載せます。
バージョンは以下のもの。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234613/275b5a3e-46a4-aa3d-173c-118075c129de.png)
ちなみにノートPCとモニターを使ってやります。

#基本の「K」
とりあえずSSH通信をする。
これは色々なサイトで載ってあり、ほぼ間違えることがないので省略。
次にpiの自動ログインを解除。
モニターがあれば設定から切ることができる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/234613/80738997-ab45-9944-6933-fdb632425398.png)
モニターがなければ```sudo raspi-config```からでも同じことが出来るらしい。
[Raspberry Pi 3 ログイン関連の設定変更](https://cycnote.wordpress.com/2018/02/25/raspberry-pi-3-%E3%83%AD%E3%82%B0%E3%82%A4%E3%83%B3%E9%96%A2%E9%80%A3%E3%81%AE%E8%A8%AD%E5%AE%9A%E5%A4%89%E6%9B%B4/)

#SSH通信がしたーい
焼き直しマスターの皆様なら起こると思いますが、同じIPアドレスでSSH通信しようとした時にエラーが起きます。

```
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@    WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!     @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
```

ｷﾞｴﾋﾟ～WARNINGだぽよ～
こういう時は

```
ssh-keygen -R [設定したいIPアドレス]
```
これで繋ぎなおせばOK!!
[ssh接続をする際に「WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED!」と出てつながらない](https://www.niandc.co.jp/sol/tech/date20150729_507.php)

#初期設定
[Raspberry Pi 初期設定](https://qiita.com/HeRo/items/c1c30d7267faeb304538)
これで一発!!
忘れてはならないのが```update```と```upgrade```は違うもの。
リスト更新か更新なのかはっきりしないとupgradeしないままになってまう

[Raspberry Piの初期設定](https://qiita.com/morinokami/items/aee081085dd679b1ea22#%E3%83%95%E3%82%A1%E3%82%A4%E3%82%A2%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%AB%E3%81%AE%E8%A8%AD%E5%AE%9A)
これでファイアーウォールも設定する。

```
$ sudo apt-get install ufw  # ufwのインストール
$ sudo ufw allow 22  # ポートの開放
$ sudo ufw allow 443  # https用     ←追加
$ sudo ufw default deny  # 許可されたポート以外を閉じる
$ sudo ufw enable  # ufwの有効化
$ sudo ufw status  # ファイアウォールの設定を確認
```
これ追加しておいてください。
割と忘れがち。

#piユーザー名変更
[[Raspbian]ユーザ名変更の個人的に「正しい」と思うやり方](https://jyn.jp/raspberrypi-username-change/)
これを見ながらすればなんとかなる。
ここで先ほど自動ログインを切ったのがきいてくる。

#apache2を入れる
[RaspbianにおけるApache2の設定](https://qiita.com/takey/items/75e6984468f0f6870a97)
入れてstartするだけ。
そこまで難しいことはない。
アクセス方法は```http://[IPアドレス]```

#アクセスできねぇ
[/var/www/html内のファイル編集する際のアクセス権について](https://teratail.com/questions/30637)
アクセス権を変更しなければならない。

```
chown -R [user名].[user名] /var/www
```

#閑話休題
ここまででアクセスは出来るようになりました。

次から外部からのアクセスを出来るようにしたいと思います。
ここまでで間違った人は次からのものをすると焼き直しになってしまうのできちんと設定してください。

#外部からアクセス
[Raspberry Pi 3 でIPアドレスを固定して、外部からSSH接続できるようにする](https://qiita.com/hujuu/items/f3799946d761006c9852)
これでhttpで見れるようになりました。

#HTTPSに対応させる
[RaspberryPiでApache2をHTTPSに対応させたい！](https://qiita.com/utti0307/items/3fc7418a8832c3e99ae4)
[第387回　UbuntuでSSLを利用したサービスを構築する](https://gihyo.jp/admin/serial/01/ubuntu-recipe/0387?page=2)
これでHTTPS通信ができるようになる。
ただし、鍵は1024bitにしてはいけないので、

```
openssl genrsa -des3 -out server.key.secure 2048
```
とする。

#完成
お疲れ様でした!!
間違いや指摘等があればコメントしていただけると嬉しいです。
色々なサイトを渡りまわっていたラズパイ焼き直し系エンジニアの方々の役に立てれば万々歳。
【Udemy Python3入門+応用】　33. if文

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**


##■if文
#####◆if文の基本
```python:if
x = -10

if x < 0:
    print('negative')
```
```:result
negative
```
`if`を使った行の次の行の先頭には、` `(スペース)を入れなくてはならない。
スペースは1個あればよいが、Pythonでは4つスペースを入れるのが暗黙のルールとなっている。

#####◆`else`
````python:else
x = 10

if x < 0:
    print('negative')
else:
    print('positive')
```
```:result
positive
```
`else`を用いることで、「そうでなければ」の場合を指定できる。


#####◆`elif`
```python:elif
x = 0

if x < 0:
    print('negative')
elif x == 0:
    print('zero')
else:
    print('positive')
```
```:result
zero
```
`elif`は"else if"の略。
ちなみに`a == b`は「aとbが等しい」の意味。
(a = bとするとbがaに代入されてしまう)


#####◆if文の中にif文
```python:if_in_if
a = 1
b = 2

if a > 0:
    print('a is positive')
    if b > 0:
        print('b is also positive')
```
```:result
a is positive
b is also positive
```
このとき、2番目のif文のインデント(字下げ)をそろえなくてはならない。

```python:if_in_if
a = 1
b = 2

if a > 0:
    print('a is positve')
     if b > 0:
        print('b is also positive')
```
```:result
  File "/Users/fumiya/PycharmProjects/python_programming/lesson.py", line 6
    if b > 0:
    ^
IndentationError: unexpected indent
```
インデントがズレているため、エラーとなった。
canvas でダブルバッファリング的なことをする

# やること

タイトルのままです。最近はブラウザの描画速度もかなり高速で、あんまり気にすることもないのですが、たまに必要になるので覚書です。

# コード

```double_buffer.js
function draw()
{
    var c1, ctx1;
    var c2, ctx2;
    var dat;

    c1 = document.getElementById("canvas1");
    ctx1 = c1.getContext("2d");
    if ( ctx1 == null ) return;

    c2 = document.getElementById("canvas2");
    ctx2 = c2.getContext("2d");
    if ( ctx2 == null ) return;

    ctx1.fillStyle = "gray";
    ctx1.fillRect( 0, 0, 300, 200 );

    dat = ctx1.getImageData(0,0, 300, 200);
    ctx2.putImageData(dat, 0,0 );
}

draw();
```

```double_buffer.html
<!DOCTYPE html>
<html>
<body>
    <canvas id="canvas1" width="300" height="200" hidden></canvas>
    <canvas id="canvas2" width="300" height="200"></canvas>
    <script src="double_buffer.js"></script>
</body>
</html>
```

hidden な canvas1 を gray に塗り潰して、それを canvas2 にコピーしているだけです。灰色の canvas が表示されたら成功です。失敗していれば、白色の(gray でない)canvasが表示されます。

# ポイント

hidden な canvas は clientWidth と clientHeight は 0 になるようです(ブラウザによるのかも)。なので、コピーする範囲は固定値にするとか、canvas タグ内から読むとか何か工夫が必要です(多分)。
Laravel Commandの実行ログをパラメータつきで出力させる

# 目的
Laravel Commandの開始時と終了時に実行コマンドのログを自動で出力するようにしたい。
パラメータ指定がある場合は合わせて出力させたい。

# バージョン
Laravel 5.7

# 実装
Laravel EventListnerを使って実装を行います。
## イベント/リスナ登録
`EventServiceProvider`の`$listen`に以下のようにイベントとリスナを登録します。
Commandの開始と終了のイベントは既に定義されているので、それに対応するリスナを自分で定義します。

```php
<?php

namespace App\Providers;

class EventServiceProvider extends ServiceProvider
{
    protected $listen = [
        CommandStarting::class => [
            CommandStartLogger::class
        ],
        CommandFinished::class => [
            CommandFinishLogger::class
        ]
    ];
}
```

## リスナ生成
以下のコマンドで上で定義したリスナを生成します。

```sh
$ php artisan event:generate
```

## リスナ実装

### 共通処理用親クラス
コマンドのパラメータを取得するのにひと手間が必要なので、共通処理用のクラス`App\Listeners\CommandLogger`を実装します。
また、Commandを定期実行するためのコマンド`schedule:run`は不要なので出力しないようにします。

```php
<?php

namespace App\Listeners;

abstract class CommandLogger
{
    protected function shouldLog($command)
    {
        $ignoredCommands = [
            'schedule:run'
        ];
        return !in_array($command, $ignoredCommands);
    }

    protected function getCommandDetail($event)
    {
        $input = (array) $event->input;
        $index =  '' . "\0" . 'Symfony\\Component\\Console\\Input\\ArgvInput' . "\0" . 'tokens';
        $command = implode(' ', $input[$index]);
        return $command;
    }
}
```

### コマンド開始リスナ
コマンド開始ログを出力するためのリスナを実装します。

```php
<?php

namespace App\Listeners;

use Log;

class CommandStartLogger extends CommandLogger
{
    public function handle($event)
    {
        if ($this->shouldLog($event->command)) {
            Log::info('Start  Command ' . $this->getCommandDetail($event));
        }
    }
}
```

### コマンド終了リスナ
コマンド終了ログを出力するためのリスナを実装します。
必要に応じてメモリ使用率などを出力してもいいと思います。

```php
<?php

namespace App\Listeners;

use Log;

class CommandFinishLogger extends CommandLogger
{
    public function handle($event)
    {
        if ($this->shouldLog($event->command)) {
            Log::info('Finish Command ' . $this->getCommandDetail($event));
        }
    }
}
```
# 試してみる
## テスト用コマンド実装

```php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class TestCommand extends Command
{
    protected $signature = 'command:test {--param=}';

    public function handle()
    {
        Log::info('This is test command.');
    }
}
```

## コマンド実行
```
$ php artisan command:test --param=hogehoge
```

## ログ確認
```
[2020-03-04 01:03:47] local.INFO: Start  Command command:test --param=hogehoge
[2020-03-04 01:03:47] local.INFO: This is test command.
[2020-03-04 01:03:47] local.INFO: Finish Command command:test --param=hogehoge
```
【Udemy Python3入門+応用】　32. 1行が長くなる時

**※この記事はUdemyの
「[現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル](https://www.udemy.com/course/python-beginner/ "現役シリコンバレーエンジニアが教えるPython3入門+応用+アメリカのシリコンバレー流コードスタイル")」
の講座を受講した上での、自分用の授業ノートです。
講師の[酒井潤](https://twitter.com/sakaijun "酒井潤")さんから許可をいただいた上で公開しています。**


##■1行が長くなる時
#####◆ルール
ルール上は、1行８０文字を超えると次の行にいかなくてはならない。
が、普通そこまでいく前に見やすくすべし。


#####◆普通に改行するとエラーになる
```python:new_line
t = 'aaaaaaaaaaaaaaaaaaaaaaa'
    + 'bbbbbbbbbbbbbbbbbb'
print(t)
```
```:result
  File "/Users/fumiya/PycharmProjects/python_programming/lesson.py", line 2
    + 'bbbbbbbbbbbbbbbbbb'
    ^
IndentationError: unexpected indent
```


#####◆`\`で改行
```python:new_line
t = 'aaaaaaaaaaaaaaaaaaaaaaa' \
    + 'bbbbbbbbbbbbbbbbbb'
print(t)
```
```:result
aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbb
```
`\`によって、「まだこの行は終わってませんよ」という意味になる。



#####◆`()`で改行
```python:new_line
t = ('aaaaaaaaaaaaaaaaaaaaaaa'
     + 'bbbbbbbbbbbbbbbbbb')
print(t)
```
```:result
aaaaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbb
```
こうしてもよい。