OmniAICreator/Qiita-1.07M huggingface dataset:
[Rails]whereとfindの違いについて

# はじめに
公式ドキュメントを見ながら、黙々と開発をしている中で、whereとfindの違いについて危険な勘違いをしていたのでここで共有します。

# 私の勘違い
私はこれまで、whereとfindの違いを、条件に一致したオブジェクトを複数返すか、1個返すかの違いでしかありませんでした。しかし、先日以下のようなコードを書いた時にうまく動かなくて、、、、じつは上述の考え方は50点でした


```ruby
@game=Game.where(id:3)　#1個だけしか当てはまらない
puts"#{@game.name}"　#だからこんな感じでと！って動かない
```

#正しい考え方
私の考えに足りなかったのは、どう返ってくるかという点です。whereが条件に一致した複数のオブジェクトを返すというのは正しいのですが、実は配列として返ってくるのです。つまり上記のコードを動かそうとするのであれば、以下のような形にしなければなりません。

```ruby
game=Game.where(id:3)　
@first_game=game.first　#配列で返ってきた物から、1つ目の要素を取得
puts"#{@first_game.name}"　
```

# 終わりに
こうした基礎の奥を見ていくことは本当に重要ですね。わかったふりして使っていても、いずれエラーにぶち当たるかと思うので、基礎の深掘りをすることをお勧めします！
機械翻訳に日英翻訳をより正確にしてもらうためのコツ - Tips for Japanese to English Machine Translation

‘Intel® Community‘などのコミュニティー・サイトでは機械翻訳機能を提供して、言葉の障壁を低くする取り組みがされています。数ある言語の中でも難しいとされている日本語の機械翻訳をより正確にするためのコツを共有したいと思います。

#なぜ日本語の機械翻訳は難しい
検索をすると、日本語から英語への翻訳が難しい理由は数多く出てきます。必ずしも主語が必要ない、単語の間にスペースがない、語順の自由度が高い、文字通りに翻訳することのできない単語やフレーズが多くある、などが主な理由のようです。
残念ながらこのような日本語の特徴は今更どうすることもできません。そこで機械翻訳の実装をしているスペシャリストに、いかに機械翻訳エンジンに日本語文章を正確に翻訳してもらうか、を教えてもらいました。

#コツ1 – 機械翻訳エンジンを混乱させない日本語文章を書く
誤字、句読点の欠如、または単語（特に主語）の欠落など英文法と比較して情報が不正確だったり不十分であったりすると、機械翻訳エンジンは混乱して翻訳の正確性に大きな影響を与えます。これは、通常では機械翻訳エンジンが適切に記述されたソース文とターゲット文でトレーニングされているからです。人間が何回か読んでやっと理解できるような日本語文章は、機械翻訳がうまくいかない可能性を高めます。

#コツ2 – 文の長さを長すぎず短すぎずに保つ
長くて複雑な文章、例えば20から25文節以上からなる文章は、機械翻訳エンジンの仕事を難しくします。
逆に短すぎる文も適切ではありません。理由の一つ目は、短すぎる文では主語などが省略されていることが多いから。理由の2つ目は、機械翻訳エンジンがキャプチャできる文脈がないためです。
主語があることを確認し、文節を20未満にしてみましょう。試しにいくつかの文章の文節を数えてみると、どの程度の文字数がどの程度の文節の数に相当するのかというおおよその目処をつけることができるようになります。文節は「言葉を細かく区切った際に不自然でない最小単位」ですので、この直前の文章の文節は以下のようになり、1分節は3.2文字平均でした。区切りに「ね」を入れて自然であればその区切りは文節です。

`主語が（ね）/ある（ね）/ことを（ね）/確認し（ね）、/文節の（ね）/長さを（ね）/15語程度に（ね）/して（ね）/みましょう（ね）。`

ほとんどの文章作成ソフトウェアは日本語の文節数を数える機能を持っていません。ですが文字数を数えることは多くの文章作成ソフトウェアではできるので、文字数からおおまかな文節数を推定できます。

#コツ3 – 文脈をくみ取らなくても理解できる言葉を選ぶ
単語によっては、文脈をくみ取らないと正しく翻訳できないものがあり、このような単語を含む文章は機械翻訳エンジンにとっては非常にデリケートな文章となります。専門用語集によってトレーニングされていない機械翻訳エンジンは、文脈を掴むことができない場合、最も一般的な語を翻訳結果として使用します。
例えば、単純に「チップ」と書いた場合、それは「ポテトチップ」であったり、「半導体チップ」であったり、または「カジノのチップ」の可能性もあります。機械翻訳エンジンに文脈を推測させてしまう「チップ」を使用するのではなく、機械翻訳エンジンが推測なしで理解できる「半導体チップ」のような単語を選択しましょう。

#コツ4 – あれ、これ、それ、では伝わらないので使わない
人間同士、特に親密な関係の人同士では、「あれ取って」、「これを直しておいて」、「それは壊れているよ」で話は通じるでしょう。しかし、「あれ」、「これ」、「それ」のような語は機械翻訳エンジンにとってはとても挑戦的です。良い翻訳結果を得るためには、「これ」が何であるかを明確にしましょう。「あれ」に似たような語をもっと知りたい方は、「指示語」を調べてください。

#コツ5 – 文章の適切な分割を意識する
コツ1の中で、句読点の欠落をひとつの問題として紹介しましたが、句読点を含む「セグメンテーション（分割）」を意識して文章を区切ることが重要です。ほとんどの機械翻訳エンジンは、一般的な区切り文字（句点、読点、ピリオド、改行）を利用して、文章を管理しやすい塊に分割するという事前処理をします。
反対に、一行の文字数を揃えるために、本来は不要な改行を文章の途中に入れたりすると、翻訳を奇妙にすることになります。

#さいごに
いかがでしたでしょうか。機械翻訳エンジンはこれからも精度を上げていくでしょうが、今の段階では人間が機械翻訳に適した文章を書くという工程が必要です。今回紹介したコツを適用して機械翻訳を有効活用することで、英語のサポート体制しかない製品は使わないといった残念な事例を解消したり、皆さんが注力したいところに時間をかけられるようになればと思います。

#Notices & Disclaimers
Intel technologies may require enabled hardware, software, or service activation.
No product or component can be absolutely secure. 
Your costs and results may vary. 
© Intel Corporation.  Intel, the Intel logo, and other Intel marks are trademarks of Intel Corporation or its subsidiaries.  Other names and brands may be claimed as the property of others.
【Express】res.send()メソッドが実行済みか判定する

`res.send()`メソッドは1回だけ実行できる。2回目はエラーになる。

```js
res.send('1');
res.send('2'); // Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
```

`res.send()`メソッドが実行済みか判定するには`res.writableEnded`プロパティを使う。

```js
consle.log(res.writableEnded) // false

res.send('1');

consle.log(res.writableEnded) // true

if (!res.writableEnded) {
  res.send('2'); // 実行されない
}
```

参考
<https://nodejs.org/api/http.html#http_response_writableended>
Yahoo!ショッピング商品検索(v3)を使ってJANコードから商品名を検索する


# はじめに

https://developer.yahoo.co.jp/webapi/shopping/shopping/v3/itemsearch.html

商品の裏についているバーコードが有りますが、このバーコードはバーコードリーダーで読み取れたとして、それを使って商品名を検索できる方法はないかと考えてみました。インターネットを調べてみると手軽に使える[Yahoo!ショッピング商品検索(v3)](https://developer.yahoo.co.jp/webapi/shopping/shopping/v3/itemsearch.html)というものがあるらしいので試しに使ってみました。

# REST API

使い方はとっても簡単です。GETリクエストにリクエストパラメータをつけてアクセスするとjsonが返ってきます。

## URL

```text:

https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch

```

## パラメータ

指定できるパラメータは[ここ](https://developer.yahoo.co.jp/webapi/shopping/shopping/v3/itemsearch.html)にのってます。
今回つかうのは`appid`、`jan_code`、`results`のみです。つまり、下記のようなGETリクエストを行います。

## 例

```text:GETリクエスト
https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch?appid=<app_idを入れる>&jan_code=<jan_code>&results=1

```


# コード

## GETリクエスト

```python:GETリクエストの部分
import json
from urllib.request import urlopen
from urllib.error import URLError

url = f"https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch?appid={APPID}&jan_code={code}&results=1"

try:
    with urlopen(url) as resp:
        res = json.load(resp)
except URLError as err:
    print(err.reason, file=sys.stderr)
```

リクエストは上のようなコードで行います。`urllib.request`の`urlopen()`を使用しています。ドキュメントのサンプルコードを見たらwithで上のような感じで使っていましたので、それを真似てみてます。urlエラーになることは想定してないので、使うことはないかも知れないですが一応`try`と`except`で例外処理も記述しています。

これだけでAPIから取得したjsonを変数に格納できます。

あとはこれを関数で記述してすこしだけ、使いやすくすればテストプログラムの完成です。というわけで出来たのがこちら

## サンプルプログラム

```python:search.py
import sys
import json
from urllib.request import urlopen
from urllib.error import URLError

APPID = "<APPID>"


def jancode_to_name(code):
    product_name = None
    url = f"https://shopping.yahooapis.jp/ShoppingWebService/V3/itemSearch?appid={APPID}&jan_code={code}&results=1"

    try:
        with urlopen(url) as resp:
            res = json.load(resp)

    except URLError as err:
        print(err.reason, file=sys.stderr)
        return None


    if "hits" in res and res['hits']:
        product_name = res["hits"][0]["name"]
    return product_name


if len(sys.argv) != 2:
    sys.exit("example: search.py <jan_code>")

name = jancode_to_name(sys.argv[1])
if name is None:
    sys.exit("Not found")
print(name)
```

こんな感じのソースコードになりました。エラーになったり存在しなかったら`jancode_to_name()`はNoneを返してきます。

## 使い方

```bash:使い方
$ python search.py 4901777273696
炭酸飲料 ペプシ リフレッシュショット サントリー 200ml 30本 1ケース  のし・ギフト・サンプル各種対応不可
```

上のようにjan_codeを後ろにつけて実行すると商品名が表示されます。

見つからなかった時とURLErrorになったら、エラー出力にNotFoundを表示してステータスコード1で終了します。つまり取得できたときだけ0（成功）で終了すると思います（たぶん）。これはbash等で使うことを想定しています。

# おわりに

リクエストパラメータは他にもいろいろ使えるみたいですし、もともと検索APIですから商品の写真とかもこのやり方でとってこれるみたいです。とても便利ですね。ちなみにこのAPIを利用するには[ここからデベローパー登録](https://e.developer.yahoo.co.jp/register)が必要ですが、個人用というチェックもあるので、趣味でも作業効率化でもいろいろ使ってみては面白いのではないでしょうか。M5StackやRaspberryPiでいろいろ面白いことができそうです。

この記事が誰かの参考になれば幸いです。
Ubuntuのファイアウォールを設定する

# 概要
セキュリティを強化するためにUbuntuサーバ毎にUbuntu標準ファイルウォールufwを設定します。

## 状況確認
sudo ufw status

**詳細**
sudo ufw status verbose

# 有効／無効にする
sudo ufw enable
sudo ufw disable

# ポートを開放する (IPv4とIPv6で開放)
sudo ufw allow <ポート番号>

例：
sudo ufw allow 80

# ポートを開放する(IPv4のみ)
全IPから特定のポートをアクセスできるようにする
sudo ufw allow proto tcp to 0.0.0.0/0 port <ポート番号>

#  ウェルノウンポート
|No.|サービス名|ポート番号|
|---|---|---|
|1.|ftp|20,21|
|2.|ssh|22|
|3.|telnet|23|
|4.|SMTP|25|
|5.|DNS|53|
|6.|HTTP|80|
|7.|NTP|123|
|8.|SNMP|161|
|9.|HTTPS|443|


# ルールの削除
1. 削除するルールの番号を見つける<br/>sudo ufw status numbered
1. ルールを削除する<br/>sudo ufw delete <ルール番号>

以上
Xserverで同一ドメインで複数のLaravelプロジェクトをデプロイ

Xserverで同一ドメイン内で複数のLaravelプロジェクトをデプロイするときのメモ

#前提
* バージョン：Laravel6
* ドメイン名：hoge.com
* プロジェクト名：funya
* composer導入済み

##①hoge.com直下にプロジェクトを作成
下記コマンドでプロジェクトを作成する。 

```
$ php artisan create-project --prefer-dist laravel/laravel funya "6.*"
```
または、作成済のプロジェクトをアップロードする。

##②プロジェクト内のpublicフォルダを移動
funya内のpublicフォルダをhoge.com内のpublic_html内に移動する。 
その際にpublicフォルダをfunyaにリネームする

##③index.phpを編集
funya（元public）フォルダ内のindex.phpを下記のように変更する。

```php
//24行と38行にあるこれらを、、、
require __DIR__.'/../vendor/autoload.php';
$app = require_once __DIR__.'/../bootstrap/app.php';

//プロジェクトfunyaにパスが通るように修正する
require __DIR__.'/../../funya/vendor/autoload.php';
$app = require_once __DIR__.'/../../funya/bootstrap/app.php';
```

#結果
hoge.com/funya でプロジェクトにアクセス可能になる。
同じ処理をすれば複数のプロジェクトを同一ドメイン内におさめることができる。
ports skeleton を portsnap cron で更新が止まった時の対応

#一週間様子見て見よったのじゃがのぉ🙄

2021/4/13あたりから、ports の更新が止まっているように見えちょったのじゃが、[web](https://cgit.freebsd.org/)見よったら普通に更新されちょる。

メールは先に進んどらん感じのんしか送られてこん。

```text:チャーリー君のメール
Subject: Cron <root@marine> /usr/sbin/portsnap cron
X-Cron-Env: <MAILTO=je3kmz>
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin>
X-Cron-Env: <LOGNAME=root>
X-Cron-Env: <USER=root>

Looking up portsnap.FreeBSD.org mirrors... 4 mirrors found.
Fetching snapshot tag from ipv4.aws.portsnap.freebsd.org... done.
Fetching snapshot metadata... 
```

google 先生に問い合わせよると複数の答えらしきフォーラムが出てきよったのじゃが、ワシの環境じゃと、どうも serverlist の生成に失敗しよったみたいで、想定外の不具合で正しく about せんのが loop しよってたようじゃ😿

その影響で ipv4.aws.portsnap.freebsd.org から fetch 出来んくなった場合の follow up 出来ずに、ウンスンでコマンドを終了しよった見たい...

#ほじゃ、具体的にどうするんじゃ？

portsnap が提供されちょる鯖は複数用意されとって、ipv4.aws.portsnap.freebsd.org だけ見に行かんようにしよったら、回避出来よった。

```text:更新失敗してる時
# cat /var/db/portsnap/serverlist
1 10 ipv4.aws.portsnap.freebsd.org
2 10 ipv6.aws.portsnap.freebsd.org
3 10 metapeer.portsnap.freebsd.org
3 10 your-org.portsnap.freebsd.org
```

```text:更新成功
# cat /var/db/portsnap/serverlist
2 10 ipv6.aws.portsnap.freebsd.org
3 10 metapeer.portsnap.freebsd.org
3 10 your-org.portsnap.freebsd.org
```

じゃけ、手動で "2 10 ipv6.aws.portsnap.freebsd.org" の行を削除しよったら、翌日から更新し始めよった👏
Rustのファイル分割

# Rustのモジュールシステム(ファイル分割)
## ディレクトリを作らない例(同階層のファイル)
```
workspace
├ src/
|  ├ main.rs
|  └ module_a.rs
├ Cargo.toml
└ Cargo.lock
```


```rust:module_a.rs
pub fn somefunction() {
  ...
}
```

```rust:main.rs
mod module_a; // module宣言

fn main() {
   module_a::somefunction();
}
```

または(呼び出しを短くしたいとき)

```rust:main.rs
use module_a::somefuncition();

fn main() {
   somefunction();
}
```

## ディレクトリ分割(その1 同名スクリプト作成)

```
workspace
├ src/
|  ├ main.rs
|  ├ module_dir.rs //module_dirと同名+(.rs)
|  └ module_dir/
|      └ module_dir_a.rs
├ Cargo.toml
└ Cargo.lock
```

```rust:module_dir_a.rs
pub fn somefunction() {
  ...
}
```


```rust:module_dir.rs
pub mod module_dir_a;
```


```rust:main.rs
mod module_dir;

fn main() {
   module_dir_a::module_dir_a::somefunction(); //呼び出しが長い。
}
```

または(呼び出しを短くしたい場合)

```rust:main.rs
mod module_dir;
use module_dir::module_dir_a;

fn main() {
   module_dir_a::somefunction();
}
```


## ディレクトリ分割(その2: mod.rs)
```
workspace
├ src/
|  ├ main.rs
|  └ module_dir/
|      ├ mod.rs
|      └ module_dir_a.rs
├ Cargo.toml
└ Cargo.lock
```


```rust:module_dir_a.rs
pub fn somefunction() {
  ...
}
```


```rust:mod.rs
pub mod module_dir_a;
```


```rust:main.rs
mod module_dir;
use module_dir;
fn main() {
  module_dir::module_dir_a::somefunction()
}
```

または(呼び出しを短くしたい場合)

```rust:main.rs
mod module_dir;
use module_dir::module_dir_a;

fn main() {
  module_dir::module_dir_a::somefunction()
}
```

## まとめ
* 同階層の場合、mod宣言で呼び出せる。
* ディレクトリ分割の場合
  * ディレクトリ名と同じ名前のrsファイルをおき、そこでサブモジュールのmod宣言。
  * ディレクトリ配下にmod.rsをおきそこでサブモジュールのmod宣言
  * かつ、呼び出し側ではモジュールのmod宣言
  * useを使うと、サブモジュールをスコープ内に持ち込めるので、呼び出しが短くなる。

↓これが

```rust:main.rs
mod some_module;
fn main(){
  somemodule::submodule::somefunction()
}

```

↓こうなる。

```rust:main.rs
mod some_module;
use some_module::submodule;
fn main(){
  submodule::somefunction()
}
```

また、こう書くこともできる。

```rust:main.rs
mod some_module;
use some_module::submodule::*;
fn main(){
  somefunction()
}
```
Python3+LSPの開発環境をPipenvで整える

# はじめに

- Python3の環境を作る際の自分メモをまとめ直したものです
- `Spacemacs`の`Python layer`を利用するために試行錯誤しました
- `pyenv`は使わず`Pipenv`で整えます

# 入れるパッケージ

`Spacemacs`の`Python layer`に記述されているパッケージの中からこの組み合わせにします。

- PEP8 Syntax checking: `flake8`
- Test runner: `pytest`
- Language Server Protocol backend: `pyls`
 - and Additionally: `pyls-isort`, `pyls-mypy`, `pyls-black`
- Suppression of unused import: `autoflake`
- Import support: `importmagic`, `epc`


# 手順

1. `Python3`をOSのパッケージ管理を用いてインストールする

   `yum`, `apt`, `dep`、... などを使ってインストールしてください。
   その際は使いたいversionである必要はなくて`pip`, `pipenv`を動かす程度の位置付けであることに注意下さい(同じでも構わない)

1. `pip`を最新にする

    ```bash
    python -m pip install --upgrade pip
    ```

1. `pipenv`をインストールする

    ```bash
    pip install pipenv
    ```

1. `pipenv`で3系の最新、もしくは使いたいversionを指定して初期化する

    ```bash
    pipenv --three
    ```

1. 開発を補佐するパッケージをインストールする
    ポイントは`--dev`を付けて`pipenv install`する点です。

    ```bash
    pipenv install --dev flake8 autoflake pytest pyls pyls-isort pyls-mypy pyls-black importmagic epc
    ```

1. 目的のパッケージをインストールする
    例として`MySQL Connector/Python`を使います。

    ```bash
    pipenv install mysql-connector-python
    ```

以上です。
リモート先のチェックディスク結果をPowerShellで読む


#何をしたいか
PCの様子変ですね調べますよ
→チェックディスクかける
→イベントビューア開く
→対象コンピュータ名指定
→Applicationログ開く
→フィルタ wininit
→読む

めんどくさいので対象コンピュータ名指定したら結果読めるくらいにしたい。

#どうしたらいいか

##リモートレジストリサービスを有効にする

リモート先のイベントログをPowerShellで読む場合、相手側でリモートレジストリサービス`RemoteRegistry`が動いてないとエラーになり読めない。
`Set-Service`で設定を手動起動／実行中に変える。

`Set-Service $ServiceName -Status Running`には同じ操作になる別のコマンドレット`Start-Service`があるが、スタートアップの種類を変更するコマンドレットは他に無いようだ。

リモートレジストリを無効にする必要があればあとから戻すこと。`Set-Service $ServiceName -Status Disabled`で無効にできる。

```powershell:リモートでサービス操作
#リモートレジストリサービス状態の取得
$Resp_ServiceStatus = Get-Service RemoteRegistry -ComputerName $ComputerName
$Resp_ServiceStatus.StartupType    #スタートアップの種類
$Resp_ServiceStatus.Status         #状態

#スタートアップの種類を 手動：Manualにする
Set-Service RemoteRegistry -ComputerName $ComputerName -StartupType Manual

#サービスの状態を 実行中：Runningにする
Set-Service RemoteRegistry -ComputerName $ComputerName -Status Running
```

##リモート先のイベントログを読む

`Get-Eventlog`で読める。`Newest 1`を指定してやると最新のログから検索して1つだけ見つけてくれるので、チェックディスク後に探せばその最新のログが引っかかる。
ログが見つからない場合最古のログまで読むのでかなり時間をとられる。ログ300個読んで見つからなければ打ち切り、などとする必要があり若干工夫がいる。（具体例は省略）

見つからない場合はエラーになるのだが、見つからないのは見つからないという正常な結果であってエラーではないのでは？と思う…
止まらないエラーなので`catch`したいときは`-ErrorAction Stop`をつける。

```powershell:Get-Eventlog
$Param_GetEventlog = @{
  ComputerName = $ComputerName
  LogName = "Application"
  Source = "Wininit"
  Newest = "1"
}
try{
    (Get-EventLog @Param_GetEventlog -ErrorAction Stop).Message
}
catch{
    $_.CategoryInfo.Category
    $_.Exception
    Write-Host "chkdskログが見つかりませんでした。"
}
```

#出来上がり

```powershell:GetChkdskLog.ps1
Write-Host "対象コンピュータのイベントログからchkdsk結果を検索し表示します。"
$ComputerName = Read-Host "ComputerName"

#応答チェック
$Resp_Ping = Test-Connection $ComputerName -Quiet
if($Resp_Ping -ne "True"){
    Write-Host "対象コンピュータから応答がありません。"
    Read-Host "キーを押すと終了します。[ENTER]"
    exit
}

#リモートレジストリサービスの操作
$Resp_ServiceStatus = Get-Service RemoteRegistry -ComputerName $ComputerName

if($Resp.StartType -eq "Disabled"){
    Set-Service RemoteRegistry -ComputerName $ComputerName -StartupType Manual
}

if($Resp_ServiceStatus.Status -ne "Running"){
    Set-Service RemoteRegistry -ComputerName $ComputerName -Status Running
}

#イベントログ表示
Write-Host "`r`nchkdskログ検索開始...`r`n"

$Param_GetEventlog = @{
  ComputerName = $ComputerName
  LogName = "Application"
  Source = "Wininit"
  Newest = "1"
}
try{
    (Get-EventLog @Param_GetEventlog -ErrorAction Stop).Message
}
catch{
    $_.CategoryInfo.Category
    $_.Exception
    Write-Host "chkdskログが見つかりませんでした。"
}

Read-Host "キーを押すと終了します。[ENTER]"
```
RedshiftでERROR: relation "table_name" does not exist



```
ERROR: relation "activities" does not exist
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117099/684b0338-5ceb-6ae9-d4ae-db6f9fd75486.png)


結論、ユーザー名とスキーマ名を揃えると解決します。

# 1. Show search path.

```psql
SHOW search_path;
```

で確認してみると、

```psql
$user, public
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/117099/2382e32b-4a4d-2442-07d2-74a274a99ccf.png)

userがpublicになっているので、スキーマ名にする。


# 2. Set schema name.

```psql
set search_path to schema_name;
```

# ref
https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/r_search_path.html


# Appendix

もしくはqueryでschemaを指定してもOK。

```psql
select * from schema_name.table_name;
```
HTML,CSS による静的サイトをHerokuにデプロイ

#0. はじめに

　案件などで稼ぎたいときにエンジニアはポートフォリオを作成するだろう。そして誰もが躓くのが公開(以下デプロイ)だ。今回は無料でサーバを利用できるHerokuでポートフォリオをデプロイする方法について紹介する。デプロイにはgitを用いる。

#1. 準備

　今回はPHPを用いてデプロイしていく。「PHP使ったことない」という人でも簡単に実装できるから身構えないでほしい。
　まずはじめにポートフォリオ用のディレクトリを作らず、他のHTMLファイルなどが混在している場合はポートフォリオ用のディレクトリを作成し、ファイルを入れる。ここで、HTML用、CSS用等ディレクトリを分けている場合は、HTMLファイルポートフォリオ用ディレクトリ直下に移動する。(HTMLファイルが複数ある場合はトップページのファイルのみ)
　以下のようなファイル構成にしてほしい。(HTMLやCSS等をディレクトリに分けなくても良い)

```:dir
Portfolio/
        ├ "ファイル名".html
        ├ HTML/
        │    └ "ファイル名".html(あれば)
        ├ CSS/
        │   └ "ファイル名".css
        └ JavaScript/
                   └ "ファイル名".js
```

#2. PHPファイルとjsonファイル作成

　PHPのファイルを作成する。ポートフォリオ用ディレクトリ直下に`index.php`というファイルを作成し、以下を入力する。(ファイル名が`index.php`でないとサイトを開くことができない)

```php:index.php
<?php include_once("'ファイル名`.html"); ?>
```

　次にjsonファイルを作成する。サイトの設定などを記入するファイルである。ポートフォリオ用ディレクトリ直下に'composer.json'を作成し以下を入力する。(ファイル名が'composer.json'でないとサイトを開くことができない)

```:composer.json
{}
```

#3. デプロイ

　ここから実際にサーバー上にファイルを置きデプロイする。shellを開きカレントディレクトリをポートフォリオ用ディレクトリに移動、以下コマンドを叩く。

```powershell:shell
heroku login
heroku create "アプリ名"
git init
git remote add heroku https://git.heroku.com/<アプリケーション名>.git
git add .
git commit -m "first commit"
git push heroku master
```

　エラーが起こらなければデプロイ完了だ。デプロイしたサイトを開くには`heroku open`コマンドで開くことができる。

#4. まとめ

　今回は静的サイトをHerokuにデプロイする方法を紹介した。ポートフォリオをデプロイする際に参考にしてほしい。
コマンドプロンプトでtelnetを使えるようにする

「コントロールパネル」を開く。
「プログラムと機能」を開く。
「Windowsの機能の有効化または無効化」をクリックする。
「Telnet クライアント」にチェックをつけて「OK」をクリックする。

これでコマンドプロンプトからtelnetが使えるようになる。

```
telnet 接続先のIPアドレス ポート番号(指定する場合)
```
PHPの小ネタ

PHPを使いながら、役に立ちそうなコードを集めて行くメモです。


## PHP ckeck memory's usage 

```php
echo "first:".memory_get_usage() / (1024 * 1024)."MB\n";

$arr = [];
for($i=0;$i<10000;$i++) {
    $arr[] = $i;
}

echo "now:".memory_get_usage() / (1024 * 1024)."MB\n";
```



## PHP check the launch time

```php
$time_start = microtime(true);

// ...計測したい処理

$time = microtime(true) - $time_start;
echo "{$time} 秒";
```
InSpecを利用してAzureリソースのテストを実行してみた！

Azureリソースを構築したあとに、ちゃんとリソースができているかの
テストを行う際にInspecというものがあると知ったので使ってみました。

# InSpecとは
Rubyで作成されており、環境構築が正しく行われているかを
確認するためのオープンソースのツールとなります。
Azure、AWS、GCPのクラウドでの構築にも対応しています。

# 環境
* RedHat:8.3
* InSpec:4.33.1

# 事前に準備が必要なもの
InSpecでAzureに接続するためのサービスプリンシパルが必要となりますので
事前に作成しておいてください。
また、以下の情報が接続時に必要となります。

* サブスクリプションID
* クライアントID
* クライアントシークレット
* テナントID

# 参考サイト
以下サイトを参考にしながら実施してみました。

* https://docs.chef.io/inspec/
* https://github.com/inspec/inspec-azure

# InSpecのインストール

```
# curl https://omnitruck.chef.io/install.sh | sudo bash -s -- -P inspec
```
インストールされたバージョンを下記コマンドで確認します。

```
# inspec version
4.33.1
```

# Azure環境変数の設定
InSpecがAzure環境に接続するための環境変数を設定していきます。

```
# export AZURE_SUBSCRIPTION_ID="xxxxxxxx-xxx-xxxx-xxxx-xxxxxxxxxxxx"
# export AZURE_CLIENT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx"
# export AZURE_CLIENT_SECRET="xxxxxxxxxxxxxxxx"
# export AZURE_TENANT_ID="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
#
```

# InSpecのAzure用のプロファイルを作成
以下コマンドでプロファイルを作成していきます。
※カレントディレクトリに作成されます。

```
# inspec init profile --platform azure azure_test
```
※`azure_test`はプロファイル名で任意に設定できます。

プロファイルは以下のように作成されます。

```
# ls -lR azure_test
azure_test:
total 8
drwxr-xr-x. 2 root root  xx xxx xx xx:xx controls
-rw-r--r--. 1 root root  xx xxx xx xx:xx inspec.yml
-rw-r--r--. 1 root root  xx xxx xx xx:xx README.md

azure_test/controls:
total 4
-rw-r--r--. 1 root root  xx xxx xx xx:xx example.rb
#
```

# テストコードの記載
テストコードはプロファイル内の`controls`配下に格納していきます。
いまある`example.rb`とは別に`ck_vnet.rb`を作成します。

テストの内容はリソースグループ`test_group`に`test-vnet`というVNETが存在するかという確認になります。

```
describe azurerm_virtual_networks(resource_group: 'test_group')
  .where(name: 'test-vnet') do
  it              { should exist }
end
```

# テストの実行

```
# inspec exec azure_test -t azure://

Profile: Azure InSpec Profile (azure_test)
Version: 0.1.0
Target:  azure://[tenantid]

  Azure Virtual Networks - api_version: 2018-02-01 user_provided test_group Microsoft.Network/virtualNetworks with name == "test-vnet"
     ?  is expected to exist

Profile: Azure Resource Pack (inspec-azure)
Version: 1.43.5
Target:  azure://[tenantid]

     No tests executed.

Test Summary: 1 successful, 0 failures, 0 skipped
#
```

上記は1つのテスト成功した旨が表示されています。
本当は色が成功したテスト緑色、失敗した場合は赤色で表示され視覚的にもわかりやすいです。


# 最後に
今回試したのは簡単なテストでしたが、[比較する方法](https://docs.chef.io/inspec/matchers/)もいろいろと用意されているみたいなので組み合わせていくことでいろんなテストができそうでした。
InSpecを利用することでテストの自動化もしやすくなるのかなと思いました。
Git ローカルリポジトリに紐付いているリモートリポジトリ名を変更する

# 目的

- ローカルリポジトリに紐付いているリモートリポジトリ名を変更する方法をまとめる

# 方法

1. ローカルリポジトリ内で下記コマンドを実行することでリモートリポジトリ名を変更する事ができる。

    ```termianl
    $ git remote rename 現在の名前 変更後の名前
    ```

1. リモートリポジトリ名をoriginからorigin_02に変えたい時は下記のようになる。

    ```termianl
    $ git remote rename 'origin' 'origin_02'
    ```
ファイル名(1).jpgなどの重複ファイルを一括削除するコマンド

# 環境
##OS
WSL
##使用コマンド代替ツール
find = fd
grep = rg


# まず目的のファイルを見つける

```:jpgファイルを見つける
find jpg
find -e jpg
```
```:hogeファイルを見つける
find hoge
```

```:(1)がついたファイルを見つける
find . | grep -e "\(1\)"
```

## 本題

上で見つけたファイルたちを`rm`で削除する。
こうゆうときに便利なのがバッククォート。これを使えばrmに検索結果を渡すことができる。

```:(1)がついたファイルを強制削除する
rm -f `find . | grep -e "\(1\)"`
```

`-f`つけなければ、１つづく確認して削除が行える


# まとめ

シェルは便利だね
本番環境のエラーログを確認する(cloud9)

忘備録！！！！

linuxにログインしてログを確認。

##nginxのエラーログを確認する

```console:linux
$ sudo tail -f /var/log/nginx/error.log
```

##Railsのエラーログを確認する。

```console:linux
$ sudo tail -f log/production.log
```

##エラーログのみ出力

```console:linux
$ tail -f ファイルパス | grep ERROR
```

##Heroku

```console:cloud9のコンソール
$ heroku login -i
$ heroku logs
```
wheneverコマンド

## wheneverコマンドメモ

```bash
cd /path/to/root_dir

# リセット
bundle exec whenever --clear-crontab --set environment=local

# 時間返るとか
vim config/schedule.rb

# セット、更新
bundle exec whenever --set environment=local
bundle exec whenever --update-crontab --set environment=local

# 確認とか
crontab -l
tail -f log/*

# 時刻のチェック
date -u "+%Y-%m-%d-%H-%M-%S"
```
picoCTF Practice Writeup 7

picoCTF Practice Writeup 7
[picoGym Practice Challenges page=7](https://play.picoctf.org/practice?page=7) の４問を勉強した記録

WaniCTF'21-springが始まるので途中だけど，公開しとこっと。

このページの難問は，
240 solves  の Let's get dynamic　（gdbの問題）


# shark on wire 1
Category: Forensics
Description:
We found this packet capture. Recover the flag.
Hints:
1. Try using a tool like Wireshark
2. What are streams?

Solution:
7,091 solvesの割りには苦戦した。
Protocol HierachyやConversationsとか見ても目立ったものが無い。
ヒント頼み。
UDP Stram eq 1 から順番に見ていく
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/bf653cc3-e057-0115-f03f-310460df1d95.png)
赤ペンで丸したところをポチポチする。
UDP Stram eq 6
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/9463fc4a-04af-edd0-1f40-b04b559355fe.png)
ビンゴ


# extensions
Category: Forensics
Description
This is a really weird text file TXT? Can you find the flag?

Solution:
拡張子をpngに変えるだけ。



# What Lies Within
Description:
There's something in the building. Can you retrieve the flag?
Hints:
There is data encoded somewhere... there might be an online decoder.
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/a260c28e-711d-e13d-cc97-cbb806c9f83d.png)

Solution:
青い空を見上げればいつもそこに白い猫
赤色ビット0　に反応
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/2ce757de-a591-0f6a-4d58-48749603a43c.png)
なんか変
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/195daf05-7b09-3c38-e56e-023bd5ea17a0.png)
緑色ビット0　に反応
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/1e88d9d2-0c40-34a7-7d4a-0a185fe3e4dd.png)
青もかな？
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1163572/8830f6ed-95eb-5df7-541f-4f969a52e584.png)
ビンゴ



# Let's get dynamic
[picoCTF Practice Let's get dynamic をGhidraで解いたが。。。](https://qiita.com/housu_jp/items/c02b9f8f71b8506fa049)
【PostgresSQL】IN句をEXIST句に変更したら速度改善された

## 前提
DB：postgres9.4くらい

## 概要
SQL抽出要件でとあるテーブルには存在して、とあるテーブルには存在しないデータがあり、
その差分を抽出する要件があった。

プライマリーキーはID。
とあるテーブルにはおよそ50万件ほどデータが存在。

## 結論
EXIST句は早かった。

## まずIN句で差分を抽出
30分以上かかり中断。

```html:IN句で書く
-- すべてデータ存在するテーブル
WITH all_data AS (
SELECT ID1,ID2 FROM all_data
)

## データ一部欠損してるテーブル
, missing_data AS (
SELECT ID1,ID2 FROM missing_data 
)

-- 差分検索
SELECT * FROM all_data WHERE (ID1,ID2) NOT IN (SELECT ID1,ID2 FROM missing_data );
```

## EXIST句で差分を抽出
数秒で抽出。

```html:EXIST句で書く
-- すべてデータ存在するテーブル
WITH all_data AS (
SELECT ID1,ID2 FROM all_data
)

-- データ一部欠損してるテーブル
, missing_data AS (
SELECT ID1,ID2 FROM missing_data 
)

-- 差分検索
SELECT * FROM all_data WHERE NOT EXISTS (
  SELECT * FROM missing_data WHERE ID1 = all_data.ID1 AND ID2 = all_data.ID2
);
```

## なぜIN句は遅いのか
以下サイトや他サイトによると、「IN」または「NOT IN」を入れると、クエリエンジンはすべての行を調べて条件が満たされているかどうかを一々確認する「テーブルフルスキャン」を行うから遅いとのこと。
https://itnews.org/news_contents/sql-201-10-ways-to-tweak-slow-running-queries-3pkb

## 補足
未検証だがPostgres以外だと上記通りIN句が遅いとは限らないとのこと。

以上
ゲームでよくあるアイテムが手前に来るやつ

#ゲームでよくあるやつ
先日、推しが配信で「フードデリバリーサービス」というゲームをプレイしていた。
そのゲームの以下のような描写を見て「作れそう」と思ったので作りました。
![コンポ 2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503642/f68d07ed-1b04-f38a-19dd-e74bf61c3fd2.gif)
#ソースコード
```c#:LookingItemBehaviour.cs
using UnityEngine;

public class LookingItemBehaviour : MonoBehaviour
{
    [SerializeField]
    private Transform target;

    [SerializeField] 
    private float moveDuration = 2f;

    private float moveProgress = 0f;
    
    private bool isNeedMove = false;

    private bool isNeedReturn = false;
    
    private Vector3 startPosition;

    private Quaternion startRotation;
    
    void Start()
    {
        startPosition = transform.position;
        startRotation = transform.rotation;
    }

    void Update()
    {
        // Test
        if (Input.GetKeyDown(KeyCode.Return)) StartMove();
        if (Input.GetKeyDown(KeyCode.Space)) StartReturn();
        
        if (isNeedMove)
        {
            moveProgress += Time.deltaTime / moveDuration;
            if (moveProgress >= 1f) moveProgress = 1f;
            transform.position = Vector3.Lerp(startPosition, target.position, moveProgress);
            transform.rotation = Quaternion.Lerp(startRotation, target.rotation, moveProgress);
        }
        else if(isNeedReturn)
        {
            moveProgress -= Time.deltaTime / moveDuration;
            if (moveProgress <= 0f) moveProgress = 0f;
            transform.position = Vector3.Lerp(startPosition, target.position, moveProgress);
            transform.rotation = Quaternion.Lerp(startRotation, target.rotation, moveProgress);
        }
    }

    public void StartMove()
    {
        isNeedMove = true;
        isNeedReturn = false;
    }

    public void StartReturn()
    {
        isNeedReturn = true;
        isNeedMove = false;
    }
    
}
```
仕組みはいたって単純
ターゲットを指定してそのターゲットと同じpositionとrotationに指定時間で変化するというもの。

#動作テスト
SmartPhoneというオブジェクトにLookingItemBehaviourをアタッチしています。
シーンビューの赤い球がtargetに指定してあるItemPositionの位置です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503642/c8a96e33-00be-b9b7-b7c4-69963e08f40c.png)
テスト用にEnterキーで手前に、Spaceキーで元の場所に戻るようコード内に記述をしています。
以下、動作している様子
![コンポ 3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/503642/41b990ca-3d60-fb03-e7f0-07e3fb415026.gif)
うごいたー
#今後の改良
このままではゲームに組み込みづらいので移動終了時のイベントなどを追加してもっと汎用的に使えるよう改良しようと思います。いつか
Rspec入門

# Rspec入門してみよう

本記事はRspecの勉強を始めて一日目の若造が書く記事なので、間違っているところがあったら教えてください！！！！！

## そもそもRspecって何？
Rspec(アールスペック)は,RubyやRuby on Railsの代表的なテストツールのことで、クラスメソッド単位でテストするために使用するものです。

##そもそもテストを書く意味とはなんぞや？？ 
※以下抜粋
###1.安全ネットとしての役割
- テストコードはアプリケーションの安全ネット、命綱、防弾チョッキ
- 機能を追加・変更しても、他の部分が壊れていないことを保証する
- RubyやRails,gemをアップデートしても壊れていないことを保証する

####なぜテストを書くのか
- 大規模なプログラムを毎回作業で再テストするのは非現実的だから
- プログラムが壊れると顧客や利用者に迷惑がかかるから
- 今後も長く運用される見込みが高いから

###2.実装の正しさを証明する役割
- 実装した要件を満たしていることや、仕様通りに動くことを検証する
- テストがパスされれば、自信をもってリリースすることができる

####なぜテストを書くのか？
- 顧客や利用者に対して不具合がないことを担保する必要があるから
- 人間と違って自動テストは疲れたり、見間違いをしないから

参考文献
https://speakerdeck.com/jnchito/number-tamarubykaigi01

↑この記事はすごくわかりやすかったので是非見てください！！

以上テストを書く理由とRspecとはなんぞや？？っていう記事でした
明日以降Rspecの構文について触れていきたいと思います。
Pyinstaller でsklearn.neighbors.typedefs　がnot foundと出る場合

初投稿ですので書き方は不慣れです
アドバイスありましたらよろしくお願いします。


＜要約＞
scikit-learn==0.24.1 python 3.8.8 の環境下で作成したプログラムを
pyinstaller==4.3　でEXE化しようとしました。

すると、warningで
sklearn.neighbors.typedefs　が not foundと　が出ていました。

この改善は、

Lib\site-packages\_pyinstaller_hooks_contrib\hooks\stdhooks\hook-sklearn.metrics.cluster.py
を訂正する事で改善しました。

＜状況＞
1) scikit-learn==0.24.1 python 3.8.8 の環境下で作成したプログラムを
pyinstaller==4.3　でEXE化しようとしました。
すると、warningで
sklearn.neighbors.typedefs　が not foundと　が出ていました。

2) また、exe化に成功してもプログラムが動かない状況となりました。

3) ライブラリーからsklearn.neighborsのフォルダー内にtypedefsを探したところ、
それは存在しなくて_typedefsならありました。

＜推定原因＞
Lib\site-packages\_pyinstaller_hooks_contrib\hooks\stdhooks\hook-sklearn.metrics.cluster.py
のプログラムを見ると

iddenimports = []
if is_module_satisfies("sklearn >= 0.22"):
    # 0.22 and later
のsklearn >= 0.22となっています。

これが、scikit-learn　>= 0.22 の誤りであると推定されます。

＜原因の根拠＞、
上記の本来　if文でTrue判定にならなければいけない所が、Falseとなっていた事が原因可能性


print (is_module_satisfies("sklearn >= 0.22"))
False と表示

print (is_module_satisfies("scikit-learn >= 0.22"))
True と表示


＜改善内容＞
＜改善前＞
iddenimports = []
if is_module_satisfies("sklearn >= 0.22"):
    # 0.22 and later

＜改善後＞
iddenimports = []
if is_module_satisfies("scikit-learn >= 0.22"):
    # 0.22 and later

＜結果＞
warningでsklearn.neighbors.typedefs　が not foundと　が出力されなくなりました。


＜コメント＞
まだ、exeファイルは起動せず
37263 INFO:   Matplotlib backend "GTK3Agg": ignored
    backend Gtk3Agg requires cairo
と出力されています。

次はこの確認です。

> "GTK3Agg": ignored　は関係ありませんでした。

起動しなかったのは、ModuleNotFoundError: No module named 'sklearn.utils._weight_vector'
が原因でした。

＜解決方法＞　hidden-importで対応する
pyinstaller ****.py --hidden-import=sklearn.utils._weight_vector
Lightning Web Component初心者のハマりどころ

Visualforceでの開発時代が長かったのですが、重い腰を上げてLWCに移行を試みています。
LWCを開発するにあたり、Vue.jsでの開発をやっていたのですが、LWC開発にあたってはjs系のフレームワークを勉強しておくとスムーズにいくかもしれません。
SalesforceのLightning Web Componentについてはまだまだ情報が少ないために、開発になれるまで時間がかかるかもしれません。ここでは、そんなみなさんの羅針盤になるような情報をまとめていくつもりです。

## LWCのざっくりとした理解
フロントエンドをjsで書き、バックエンドをApexで書く形になります。
Apexは@AuraEnabledアノテーションを付与することで、フロントエンド側からデータへのアクセスが可能になります。

## ハマったところ
### 'foobaa' is not defined
LWCでは、恐らくその性質上、カスタムクラスを作って1レコードの中に、複数のオブジェクトやパラメータを含めてフロントエンドに返すようなことをよくやると思います。
Apexではエラーが出ないのに、いざWebブラウザで開くと
'foobaa' is not defined
というエラーが返ってくるということがあります。
これは、カスタムクラスに入れたカラムが@AuraEnabledになっていなかったり、
jsファイル内で@apiを定義していなくてhtmlファイル側からアクセス出来なかったりすることが多いです。

もう一つは、そもそも値がnullだった場合に参照していると同様のエラーが出ます。
こういう場合は、htmlファイル側で

```
<template if:true={d.timeline.eventID__c}>
</template>
```

こんなふうにして値の存在を確認してから出力するようにします。

### Lightning iconを使う
https://www.lightningdesignsystem.com/icons/
Lightning Design Systemのサイトのコンポーネントには、頻繁に使われているのですが
例：https://www.lightningdesignsystem.com/components/activity-timeline/#site-main-content

```
<svg class="slds-button__icon slds-timeline__details-action-icon" aria-hidden="true">
 <use xlink:href="/assets/icons/utility-sprite/svg/symbols.svg#switch"></use>
</svg>
```

これはそのままでは使えません。
この３行をまとめて以下のように書きます。

```

<lightning-icon icon-name="standard:form" alternative-text="form" title="form"></lightning-icon>
```

割とシンプルですよね。

なんでLightning Design SystemのサイトはLWC対応のコードの提供をしてくれないんだろうか。いちいち調べるのが面倒すぎるのでなんとかしてほしい。

### リンクをテンプレートにハードコーディングしてはいけない
Vue.jsなんかもそうなんですよね。js使って飛ばしましょうというやり方になります。
参考にしたのはこちらのQiitaでした。
Lightning Web ComponentでURLにParameterを追加する方法
https://qiita.com/10kaoru12/items/015b0294b5fcccf35024
パラメータの受け取り方、受け渡し方についてはこのままの実装で問題ありませんでした。

### LWCからApexへの値渡し
Lightning Web ComponentsからApexクラスにJSONデータを受け渡す方法
https://note.com/koji_matae/n/n2344bde286bc
こちらを参照しました。
フロントエンドからはJSONを文字列に変換して送信。ApexではStringで受け取ったものをJSON.deserializeUntypedで解析して使います。

### @AuraEnabledなApexのテストの書き方
↑に書いたとおり、JSONをStringで渡すので、正規の書き方で入ってくるようなJSON文字列を生成してStringに乗せて、クラスに食わせればOKという感じですね。

### 英語のリソースを探したほうが早い
例えば今回LWCでLightning Web ComponentのActivity Timelineの実装を行いました。
https://lightningdesignsystem.com/components/activity-timeline/#site-main-content
ここに書いてあるHTMLのサンプルコードはこのままでは使えません。そのため、LWC ActivityTimelineみたいなキーワードで検索してソースを探してみると、Githubがヒットします。
https://github.com/anandbn/timeline-lwc
膨大な量に見えるので最初は戸惑うかもしれませんが、色々なパターンでコードが提供されており勉強になります。
jsで詳細データの開閉する部分とかは見れば一発で分かる感じになっています。使ってみてください。

### to be continued...
まだまだあると思うのでまた書きます。

続編：Lightning Web Component実装例1
https://qiita.com/geeorgey/items/ff2ab9503091366dfb7d
ど初心者がgolangでhello worldをする

# ローカルで実行環境を用意
https://golang.org/dl/
からそれぞれ環境にあったインストーラーをダウンロード
※僕のPCはMacなのでMacOSのインストーラーをダウンロードします

```
# インストーラーのダウンロードができたらコマンドラインでバージョンを確認
$ go versoin
-> go version go1.16.3 darwin/amd64
```
このようにgoのバージョンが表示されたら成功
# hello worldの準備
```
$ mkdir hello
$ cd hello
$ go mod init example.com/hello # modがパッケージ管理ツール?
$ touch hello.go
```

そしたら以下のコードをhello.goに記述

```go
package main

import "fmt"

func main() {
	fmt.Println("Hello, World!")
}
```
コードを実行

```
$ go run .
-> Hello, World!
```
よく落ちるサービスを自動再起動させる

Windows管理ツール
↓
サービス
↓
対象のサービスを右クリック → プロパティ
↓
回復タブ
↓
最初のエラー            ：サービスを再起動する
次のエラー　            ：サービスを再起動する
その後のエラー          ：何もしない
エラーカウントのリセット：1日後に行う
サービスの再起動        ：1分後に行う
・・・という設定にして適用

「その後のエラー」も「サービスを再起動する」にしても良いと思うが、
これだけ落ちたらさすがに変だろうと思えるように「何もしない」にしている。
（3回目以降は落ちっぱなしになる）

エラーカウントのリセットを1日後に行うことによって、
この場合だと「1日に2回までは自動再起動、3回目以降は落ちっぱなし」となっていると思う。
GitHub Actionsで現在時刻を正しく取得してくれない。


https://qiita.com/fake-deli-ca/items/23865a6da7c198cb38c5

元々、上記記事で設定したものは、以下のようになっていたのだが（現在は修正済み）

```.github/workflows/build.yml(抜粋)
    - name: Build with Maven
      run: mvn -B verify --file pom.xml
```

これだとテストケースで、SessionExpireのテストがあった際に、正しく動作しないと連絡を受けた。毎回ではなく、時々うまくいかないらしい。またローカルでは全く問題ないらしい。となるとGithubActions側の問題であろう。
元々何も設定しなかった場合、TimeZoneはUTCで動作することになって、それはよいのだが、

> セッション有効期限の期待値：Fri Apr 23 12:38:41 UTC 2021　　※4/23 21:08頃に実施した場合。UTCなので -9h です。
> セッション有効期限の実際値：Fri Apr 23 00:38:41 UTC 2021　　※UTCでもなくさらに -12h の時刻で生成されています。

色々調べてもよくわからなかったのだが、UTC -12hといえば普段は利用していないはずの値である。どうやら時刻が不定になってるっぽいので、TimeZoneを指定することにした。

```.github/workflows/build.yml(抜粋)
    - name: Build with Maven
      run: mvn -B verify --file pom.xml
      env:
        TZ: 'Asia/Tokyo'
```

いまいち半信半疑ではあったものの、これで試すと問題ないことから、時刻を利用した挙動をする場合は、環境変数でTimeZoneを設定するほうが正しいのであろう。
[Rails] マイグレーションファイルをUPの状態で消した際の対処法

# 記事の内容
#### マイグレーションファイルがUPの状態で誤って消してしまい、migrateするとerrorが出てしまう。そんな時の対処法をお伝えします。

# 前提
#### Ruby：2.6.5
####Rails 6.0.0
#### MySql

# 流れ
#### 1.rails db:migrate:statusで消してしまったファイルの確認、コピーする。
#### ２.dbに手動でファイルを作成する。
#### ３.rails db:rollbackでdownにし、手動でファイルを消す。

# 1.rails db:migrate:statusで消してしまったファイルの確認
####ターミナルでrails db:migrate:statusとコマンド、消してしまったファイル名を確認
```ターミナル.
Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210416062030  Devise create users
   up     20210421093836  Create photos
   up     20210421095230  Create active storage tablesactive storage
   up     20210422031359  Create areas
   up     20210427013219   Noｆile
　　　　　　　　↑こちらの数字をコピーする
```
# ２.dbに手動でファイルを作成する。
####db内に手動でファイルを作成します。
```db/20210427013219_sample.rb←sampleの部分は任意のファイル名で大丈夫です。
class Sample < ActiveRecord::Migration[6.0]
  def change
  end
end
```
# 3.rails db:rollbackでdownにし、消す。
#### ターミナルでrails db:rollbackをコマンドし、後はファイルをゴミ箱に入れれば完了。
```ターミナル.
 Status   Migration ID    Migration Name
--------------------------------------------------
   up     20210416062030  Devise create users
   up     20210421093836  Create photos
   up     20210421095230  Create active storage tablesactive storage
   up     20210422031359  Create areas
  down    20210427013219  Sample
　　↑downしていることを確認し、手動で削除すれば完了です。
```

# まとめ
#### githubで編集内容を削除し、誤ってマイグレーションも消してしまう場面が多々あります。この記事を参考にerrorを解決していただけたら幸いです。
Changing from an HTTPS function to an background triggered function is not allowed.

# HTTPSリクエストのファンクションだったものをスケジュールに変更するとエラーが出る時の解決方法

```
exports.XXX = functions.https.onRequest((request, response) => {
```
のようにhttpsのリクエストを受けるファンクションとして定義してdeployしたあとに

```
exports.XXX = functions.pubsub
.schedule(スケジュール)
〜
```
のようにスケジューリングされたファンクションに変更してdeployしようとすると以下のエラーが出る

>Changing from an HTTPS function to an background triggered function is not allowed. Please delete your function and create a new one instead.


###■解決方法
対象のファンクションをこのように一度削除して再度deployすればOKです。
`firebase functions:delete XXX`
CentOSで対象のサービスが脆弱になっているか確認する方法


# ソースコードからコンパイルの前に
JVNなどのサイトで脆弱性が公開された時、運用中のパッケージは影響を受けるのか！？気になるところですよね。
ソースからコンパイルして他のサービスと連携・・・、の前に下記手順で確認してみてください。
## JVNで確認
[OpenSSL に複数の脆弱性](https://jvn.jp/vu/JVNVU92126369/index.html)
openssl1.0.2はサポートが終了している事実を知るものの、徐に下記コマンドを実行。

`yum install openssl
パッケージ 1:openssl-1.0.2k-21.el7_9.x86_64 はインストール済みか最新バージョンです
何もしません`

そうだよねー。
影響を受けるシステム：「CVE-2021-3449」をメモる。

## そしてRedHatで確認
下記サイトで上記でメモった番号で検索。
[Red Hat Customer Portal](https://access.redhat.com/security/security-updates/#/cve)

今回はCentOS7なので、下記赤枠を確認して「Not affected」になっていることを確認。
![image.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/24113/9bc9b822-36bf-ca5f-b0b0-b73380bf8472.jpeg)

サポートがあるまで（7は2024年6月）こんな感じで確認してyumでアップデートで行けそうな感じだけど、opensslは脆弱性でやすいのと、TLSv1.3に対応するためにもapache or nginxも含めソースからのコンパイルも視野にいれとこう。

追記）debianはこちら
https://security-tracker.debian.org/tracker/
ランチにPicoはいかがでしょうか～第7話　Arduino用ライブラリでキャラクタLCD～

ごきげんよう、ちゃまおです。

[前回の記事](https://qiita.com/Chamaotaku/items/13cf0429dc27bc151fbe)では、Arduino IDEを用いた開発環境の導入方法について、解説しました。

その際の注意点として、「これまでのArduino用ライブラリがそのまま使えるかは未確認。」と書きましたが、キャラクタLCDで使える事を確認したので、紹介します。

# キャラクタLCDとは
昔のレジの値段表示などに使われている製品です。
最近は、I2C接続と言って、データをやり取りする信号線が2本で済むタイプもありますが、今回紹介するのは8文字×2行表示のタイプで、ピンが14本あります。このタイプの製品をマイコンで制御する際には、データシートのタイミングチャートと、ビット演算を駆使してソースコードを書くのですが、非常に面倒です。ただし、ArduinoでキャラクタLCDを制御する場合、ライブラリとサンプルコードが用意されているので、非常に楽に制御できます。

# 用意する物
- キャラクタLCD
今回は、[ACM0802C-NLW-BBH](https://akizukidenshi.com/catalog/g/gP-02801/)を使用しました。

- 10kΩ可変抵抗
今回は、[こちらの半固定ボリューム](https://akizukidenshi.com/catalog/g/gP-06110/)を使用しました。キャラクタLCDにバックライトが無ければ、この部品は不要です。

- Raspberry Pi Pico

# 各部品の配線
見辛いかも知れませんが、以下のように配線しました。ACM0802Cのデータシートに書いてある各ピンの番号(および名称)と、サンプルコードの定数を合わせながら配線するだけの簡単なお仕事です。

(注)今回の製品のように、キャラクタLCDは動作の為に5V入力が必要な場合が多い為、Raspberry Pi PicoのVBUSを用いるか、3V3(OUT)から[5V出力昇圧DCDCコンバーター](https://akizukidenshi.com/catalog/g/gK-13065/)を使うと良いです。

![配線図.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930492/520fd8f0-d5ac-9055-8b1c-36a7c7fa0e49.jpeg)

# ソースコード
Arduino IDEの「ファイル -> スケッチ例 -> LiquidCrystal -> HelloWorld」を使用しました。ただし、```lcd.print()```の中身をデフォルトのまま使うと、文字が途切れてしまう為、"Hello!"に変更しました。

# 実行結果
無事に書き込みが終わると、下図のように1行目に"Hello!"、2行目に数字のカウント表示がされます。

![helloLCD.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/930492/92641af9-68f9-1156-e0a5-b3e1bc7fe5d5.jpeg)

# 感想
キャラクタLCDの制御をどうするか悩んでいましたが、Arduino用ライブラリをそのまま使う事が出来た為、開発しやすくなったと思いました。他のライブラリを試す機会があって、成功したらまた記事にしたいと思います。
日付の取得

#概要
日付と税込み価格をアラートで表示

#日付を取得

```index.js
function date (){
        const dd =  new Date;
        const year = dd.getFullYear();
        const month = dd.getMonth() +1;
        const d = dd.getDate();
        const mon = [year,month,d];
        console.log(mon);
        return mon;
        
      }
```
①ddに現在日時を保存
②現在日時をそれぞれyear,month,d,にメソッドで変更します。
　*Monthは海外では文字列（sundeyとか）ですが、日本では1~12月で表されます。その都合で、0始まりになっています。なので、呼び出すときは、+1をします。1を足し忘れると−1月で表示されました。
③それらデータをまとめてリターンするので、配列にします。

#アラートで表示

```index.js
 　　　const m = date();
      const sub = totalTax();

      const win =[m,sub];

      window.alert(win);
      
```

そして今回の目的は、taxと日時をアラートで出したいので、配列にします。

#配列
データを一列に並べたものです。
配列として1つの定数に保存することで、大量のデータを扱うことができます。
JavaのBigDecimalの割り算の丸め処理をPythonに書き換える

最近Javaで書かれたバッチをPythonに書き換えている。
Javaで正確な丸めを行うために`BigDecimal`を使ったコードがある。
それをPythonに書き換える際に対応するメソッドがなく困った。
本記事では対応策をまとめる。


# Java側

Javaのコードが以下のようだとする。

```java
import java.math.BigDecimal;
import java.math.RoundingMode;

class BigDecimalDivideTest {
        public static void main(String[] args) {
                BigDecimal someValue = BigDecimal.valueOf(3215);
                BigDecimal BD_100 = BigDecimal.valueOf(1000);
                int SCALE_2 = 2;

                System.out.println(someValue.divide(BD_100, SCALE_2, RoundingMode.HALF_UP));
                // 3.22が表示される
        }
  }
```

# Python側

```python
from decimal import *

some_value = Decimal('3215')
bd_100 = Decimal('1000')
scale_2 = 2

divided_value = some_value / bd_100
scaled_decimal = Decimal(str(10 ** - scale_2)) # => Decimal('0.01')になる。

# 丸め処理にはquantizeメソッドを使う
divided_value.quantize(scaled_decimal, rounding=ROUND_HALF_UP)
# => Decimal('3.22')
```

## 説明

Pythonにおける、Javaの`BigDecimal`に対応するライブラリは`decimal`である。

* https://docs.python.org/ja/3/library/decimal.html

だが `decimal` の `divide` メソッドでは、Javaのようにスケールや丸めについて引数を取るものがない。
なので、スケール処理と丸めは`quantize`で割り算のあとに行う。

なお、`quantize`でエラーが出る場合がある。

```python
from decimal import *

getcontext().prec = 2 # 追加
some_value = Decimal('3215')
bd_100 = Decimal('1000')
scale_2 = 2

divided_value = some_value / bd_100
scaled_decimal = Decimal(str(10 ** - scale_2))

divided_value.quantize(scaled_decimal, rounding=ROUND_HALF_UP)
# => decimal.InvalidOperation 例外が発生する
```

* https://docs.python.org/ja/3/library/decimal.html#decimal.Decimal.quantize

> 他の操作と違い、打ち切り(quantize)操作後の係数の長さが精度を越えた場合には、 InvalidOperation がシグナルされます。

`getcontext().prec = 2`を追加した上でquantizeを行うと、quantize結果が数値全体で2桁(3.2とか)でないとエラーになる。
今回はquantize結果は3.22であり結果が3桁になるので、InvalidOperationが出る。

---

## なんで書こうと思ったか

Pythonのドキュメントの一番上で以下のようなコードが書いてある。

```python
from decimal import *

getcontext().prec = 6
Decimal(1) / Decimal(7)
# => Decimal('0.142857')
```

これを見て、私は桁数を指定するには`getcontext().prec`を指定すればいいのかとミスリードした。
precは数値全体の桁数の話なので、prec = 6としても小数点以下6桁を保証してくれるわけではない。

例えば上記の割り算の対象数字が大きかったとすると、以下のようになる。

```python
from decimal import *

getcontext().prec = 6
print(Decimal(10000000) / Decimal(7))
# => Decimal('1.42857E+6')

print(float(Decimal(10000000) / Decimal(7)))
# floatに変換すると1428570.0
# prec = 有効桁数は6なので、142857までの6桁までは計算結果が保持されるがそれ以降は0に
```

# 参考

* [なぜBigDecimalを使わなければならないのか | Java好き](https://javazuki.com/articles/bigdecimal-why.html)
  * BigDecimalを使う理由が理解できた。
簡易的なレコメンド機能の実装

## タイトル：「あなたへのオススメ」機能の実装

### レコメンド機能の実装：強調フィルタリング機能

主要なWebサービスでよく見かけるレコメンド機能("あなたへのオススメ"みたいな)について実装したので記事にいたします。
簡易的なやり方ですのでそこまで難易度は高くないです！

### レコメンド機能とは？
レコメンド機能とはAmazonやメルカリなどの主要サービスでよくみる「あなたへのおすすめ！」みたいなやつです。
例えを今回私が作成したサービスであるAbility(アプリの情報共有サービス)を例に説明します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/41090040-e3cd-e0a8-123e-20dec25b56ca.png)

各ユーザがレビューしたアプリ

| 名前  | Trello | Asana | Notion |
| ----- | ------ | ----- | ------ |
| Aさん | 1      | 1     | -      |
| Bさん | -      | 1     | 1      |
| Cさん | 1      | 1     | 1      |
| Dさん | -      | -     | 1      |

Aさんは"Trello"、"Asana"、のレビューをした
Bさんは"Asana"、"Notion"のレビューをした
Cさんは"Trello"、"Asana"、"Notion"のレビューをした
Dさんは"Notion"のレビューをした

ここでAさんがログインしたときにオススメのアプリを出すことを考えます。
検討方針としては下記の順番です。

1. Aさんのレビューしたアプリに相関が近い人を探す。後で詳しく書きますがここではCさん
2. CさんがレビューしていてAさんがレビューしていないアプリをオススメに出す

詳しく記載していきます。

### 1.Aさんのレビューしたアプリに相関が近い人を探す。

ここではJaccard(ジャッカード)指数を用いて相関を出します。
Jaccard(ジャッカード)指数とは類似度の計算で使うものです。

数式は下記です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/ba75f083-7e48-6bee-e486-c66a7e707702.png)

わかりやすく図で表すと下記になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/bd78a4d4-fd7b-e54f-9036-0a0c5a008dae.png)

参考リンク：https://mieruca-ai.com/ai/jaccard_dice_simpson/

AさんとBさんのレビューしたアプリをそれぞれ集合とするとJaccard(ジャッカード)指数は以下になります。
例えばAさん、Bさんのジャッカード指数計算すると

|A∩B| = 1 
|A∪B| =  3 
1 / 3 = 0.33....
となる。

同様にCさんとDさんも計算すると下記の図のとおりになる。

| 名前  | Trello | Asana | Notion | Jaccard指数 |
| ----- | ------ | ----- | ------ | ----------- |
| Aさん | 1      | 1     | -      | ☓           |
| Bさん | -      | 1     | 1      | 0.333....   |
| Cさん | 1      | 1     | 1      | 0.666....   |
| Dさん | -      | -     | 1      | 0           |

よってAさんと相関が高いのはCさんとなる。

### 2.CさんがレビューしていてAさんがレビューしていないアプリをオススメに出す
図で言うと下記の部分。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/943494/0269e283-a229-c884-daba-2ee6df276a49.png)

ここではNotionになるので、Aさんのオススメに表示する。

コードは別途記載していきます！！
下記、今回作成したサービス。
https://ability-applications.com/home
AWS Cloud Formation 毎回迷子にならないように・・・

AWSのリソースはCloud Formationを利用して、作成すると複製や削除が非常に楽になるので利用しているのですが、毎回「このリソースってどう書けばいいの・・・」っていうのが分からなくなるのでメモ書き。

# AWS Cloud Formation って何？
テンプレート(yamlやjson)ファイルを利用して、AWS上に様々なリソースを作成できるサービス。
Cloud Formationのスタックにテンプレートを展開し、リソースを作成できる。
作成したテンプレートファイルがあれば同じリソースを作成することが可能なので、AWSコンソールを操作して作成という手間がなくなる。
あとスタックを削除するとそのテンプレートから作成されたリソースは全て削除されるため、不要になったリソースを削除するときに便利。

# リソースの一覧
これが一番知りたかった。
やっと見つけました。

「AWS CloudFormation Resource types」と検索すると引っかかるようです。

https://docs.aws.amazon.com/en_us/AWSCloudFormation/latest/UserGuide/aws-template-resource-type-ref.html

# テンプレートセクションの詳細
各セクションの説明はこちら。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/template-anatomy.html

# 依存関係のあるリソースを作成する場合
例えばリソースAはリソースBの作成後に作成しないとエラーになる場合、DependsOn 属性を使用することでリソースの作成の順番を指定できる。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/aws-attribute-dependson.html

# よく使う組み込み関数
個人的によく使う組み込み関数を以下に記載します。

## Ref
パラメータの値を参照するときに使用する。

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-ref.html

使用例：

```
    Value: !Ref SampleParameter
```


## Fn::Sub
https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-sub.html

パラメータなどの値を文字列に埋め込んだりするときに使用する。

使用例：

```
Description: !Sub '${EnvironmentName} sample'
```

```
Name: !Sub
  - www.${Domain}
  - { Domain: !Ref RootDomainName }
```

## Fn::GetAtt

https://docs.aws.amazon.com/ja_jp/AWSCloudFormation/latest/UserGuide/intrinsic-function-reference-getatt.html

同一テンプレート内で作成したリソースの値を参照したいときに使用する。

使用例：

```
  securityGroup:
    Type: AWS::EC2::SecurityGroup
    Properties: 
      ～省略～
```

```
  dbCluster:
    Type: 'AWS::DocDB::DBCluster'
    Properties:
      ～省略～
      VpcSecurityGroupIds:
        - !GetAtt securityGroup.GroupId
    DependsOn: securityGroup
```

先に作成したセキュリティグループのグループIDをDBクラスターを作成するときに参照できる。
この時、DependsOn属性を付けておいたほうが安心。
はてぶで「Wasp」というのを見つけたのでサイトを見たら5分でお試しできるということなので試してみた

![スクリーンショット 2021-04-27 10.17.55のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6280/7202df22-6967-238c-2c01-f7f72c1173af.png)

# はじめに
タイトルで記事を書いたきっかけ全部書いた

# Waspについて
サイトに書いてる説明をそのまま引用

> A simple language for developing full-stack web apps with less code.
> Describe high-level features with Wasp DSL and write the rest of your logic in React, Node.js and Prisma.

■ DeepL翻訳
より少ないコードでフルスタックのWebアプリを開発するためのシンプルな言語です。
ハイレベルな機能はWasp DSLで記述し、残りのロジックはReact、Node.js、Prismaで記述します。

なお、Y Combinator[^Y Combinator]がバックアップしており、Product Hunt[^Product Hunt]のデイリーランキングで1位をとったこともあります。

[^Y Combinator]: スタートアップに投資している会社。有名どころだと「Dropbox」「Airbnb」など。
[^Product Hunt]: プロダクト投稿サイトで、投票によってランキングがでるサイト。

# お試しする
それでは早速お試しする

## 環境や前提条件
- macOS Big Sur バージョン 11.2.3
- MacBook Pro (13-inch, 2019, Four Thunderbolt 3 ports)
  - プロセッサ　2.4 GHz クアッドコアIntel Core i5
  - メモリ　16 GB 2133 MHz LPDDR3

## 試してみる
サイトに書かれてる「Try Wasp in 5 minutes →」の通りにまずは実行してみる。

### 1. Open your terminal and run:
```bash:
$ curl -sSL http://get.wasp-lang.dev | sh
```

実行結果した結果の中に以下のメッセージがあったのでPATH設定する必要ありそう。。。

```bash:
・・・
Wasp has been successfully installed! To create your first app, do:
 - Add wasp to your PATH as described above.
 - wasp new MyApp
```

### 2. Create a new project:

```
$ wasp new MyFirstApp
```

を実行したら案の定、PATH通ってなくて

```
$ wasp new MyFirstApp
zsh: command not found: wasp
```

と実行できなかったのでパスを通してから再度

```
$ wasp new MyFirstApp
Created new Wasp app in ./MyFirstApp directory!
To run it, do:

    cd MyFirstApp
    wasp start

NOTE: Wasp is still in Alpha, therefore not yet production ready and might change significantly in the future versions.
```

### 3. Run your first app:

```
$ cd MyFirstApp && wasp start
```

実行すると、

![スクリーンショット 2021-04-27 10.17.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6280/66859bec-7cf6-1ba1-0f40-9a8f8098fb6f.png)

とブラウザの権限要求してきたので「OK」をクリック。
しばらく待っていたら勝手にブラウザ開いて以下の画面表示されました。

![スクリーンショット 2021-04-27 10.17.55のコピー.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/6280/7202df22-6967-238c-2c01-f7f72c1173af.png)

# まとめ
- 本当に5分でできた
- もう少し詳しい話知りたい人は公式ドキュメントチェック[Getting Started | Wasp](https://wasp-lang.dev/docs/)
- product huntでデイリー1位をとったのは、2020年12月6日なのでもっと早めにキャッチアップできたら良いなと思いました。

# Appendix
## 参考サイト
- [Wasp | Wasp](https://wasp-lang.dev/)
- [Y Combinator](https://www.ycombinator.com/)
- [Wasp-lang Alpha - Develop web apps in React & Nodejs with no boilerplate | Product Hunt](https://www.producthunt.com/posts/wasp-lang-alpha?utm_source=badge-top-post-badge&utm_medium=badge&utm_souce=badge-wasp-lang-alpha)

## ご意見・ご感想をお待ちしております
今回の記事はいかがでしたか？
・こういう記事が読みたい
・こういうところが良かった
・こうした方が良いのではないか
などなど、率直なご意見を募集しております。
頂いたお声は、今後の記事の質向上に役立たせて頂きますので、お気軽に
コメント欄にてご投稿ください。[Twitter](https://twitter.com/narinarita1980)でもご意見を受け付けております。
皆様のメッセージをお待ちしております。