OmniAICreator/Qiita-1.07M huggingface dataset:
Ubuntu で CGI.pm のインストール方法

CGI を使う次のプログラムを走らせてみた時、

```pl:test_cgi.pl
#!/usr/bin/perl
#
use CGI;
my $qq = new CGI;
print $qq->header(-charset=>"utf-8");
print $qq->start_html(-title=>"Perl CGI のテスト", -BGCOLOR=>'#ffffff'),
    $qq->center($qq->h1('Perl CGI のテスト')),
    $qq->hr,
    $qq->ul(
        $qq->li('Python3'),
        $qq->li('Node.js'),
        $qq->li('Ruby'),
        $qq->li('PHP'),
        $qq->li('Perl')
    ),
    $qq->br,
    $qq->br,
    $qq->a({href=>"https://ekzemplaro.org/"}, "トップページ"),
    $qq->br,
    $qq->br,
    $qq->strong("Jun/20/2020"),
    $qq->end_html;
exit;
```

以下のようになった時の対策です。

```text
$ ./test_cgi.pl 
Can't locate CGI.pm in @INC (you may need to install the CGI module) (@INC contains: /etc/perl /usr/local/lib/x86_64-linux-gnu/perl/5.26.1 /usr/local/share/perl/5.26.1 /usr/lib/x86_64-linux-gnu/perl5/5.26 /usr/share/perl5 /usr/lib/x86_64-linux-gnu/perl/5.26 /usr/share/perl/5.26 /usr/local/lib/site_perl /usr/lib/x86_64-linux-gnu/perl-base) at ./test_cgi.pl line 3.
BEGIN failed--compilation aborted at ./test_cgi.pl line 3.
```

ライブラリーをインストールします。

```bash
sudo apt install libcgi-session-perl
```

再びプログラムを走らせると次のようになります。

```text
$ ./test_cgi.pl 
Content-Type: text/html; charset=utf-8

<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
<head>
<title>Perl CGI のテスト</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body bgcolor="#ffffff">
<center><h1>Perl CGI のテスト</h1></center><hr /><ul><li>Python3</li> <li>Node.js</li> <li>Ruby</li> <li>PHP</li> <li>Perl</li></ul><br /><br /><a href="https://ekzemplaro.org/">トップページ</a><br /><br /><strong>Jun/20/2020</strong>
</body>
</html>
```

追加情報

エラーメッセージ

```text
Can't locate Jcode.pm in @INC (you may need to install the Jcode module)
```

>対策

>```bash
sudo apt install libjcode-pm-perl
```

エラーメッセージ

```text
Can't locate Image/Magick.pm in @INC (you may need to install the Image::Magick module)
```

>対策

>```bash
sudo apt install libimage-magick-perl
```

エラーメッセージ

```text
Can't locate LWP/Simple.pm in @INC (you may need to install the LWP::Simple module)
```

>対策

>```bash
sudo apt install libwww-perl
```

エラーメッセージ

```text
Can't locate WWW/Google/PageRank.pm in @INC
```

>対策

>```bash
sudo apt install build-essential
```

>```text
sudo cpan
cpan[1]> install WWW::Google::PageRank
```

モジュールの確認方法

```bash
sudo apachectl -M
```
WslRegisterDistribution failed with error: 0x800701bc

WSL2でubuntu(20.04LTS)が起動しなくなった。
ちょいちょいあることなんで溜息を付きつつ、アンインストール→ストアからインストールやら色々するがダメで、[エラーメッセージの一部でぐぐってみると解決方法が載って](https://www.google.com/search?q=WslRegisterDistribution+failed+with+error:+0x800701bc&sxsrf=ALeKk02cgMPsq7Fmpnlag6SJNP1Ks7p6ng:1592605279856&source=lnt&tbs=qdr:m&sa=X&ved=2ahUKEwjsnOT_9I7qAhWIwZQKHWk6CJsQpwV6BAgMECA&biw=1362&bih=922)いた。

>Installing, this may take a few minutes...
WslRegisterDistribution failed with error: 0x800701bc
Error: 0x800701bc WSL 2 requires an update to its kernel component. For information please visit https://aka.ms/wsl2kernel

でてたのはこんなメッセージ。
※上のはホントは嘘で、あたしんちの環境だと日本語でなんかメッセージが出てた（たぶん）。たぶんというのは文字化けしてて「?????」が並んでるだけだったので。上のやつは同様の症状のときのメッセージを持ってきて貼ったもの。
つまるとこ https://aka.ms/wsl2kernel にいって、新しいkernel componentをインストールしてよ、ということだったみたい。文字化けしてたら読めない。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20417/1293826f-9a44-5f1f-6614-6c4b239dd04c.png)

上のurlとぶとこういうmicrosoft.com配下のサイトに飛ぶんで、「最新の WSL2 Linux カーネル更新プログラム パッケージをダウンロード」のとこでインストーラを取得、それを入れ直しておしまい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/20417/5ab04a61-3068-b78b-fd93-029231708d54.png)
Chatter: Salesforce モバイルアプリケーションで使用できない機能とその新機能


+ [Salesforce モバイルアプリケーションで使用できない機能とその新機能](https://help.salesforce.com/s/articleView?id=sf.limits_mobile_sf1_parent.htm&type=5)

Salesforce モバイルアプリケーションには、デスクトップの Lightning Experience で使用可能な一部の機能が含まれていません。ここでは、使用できない Salesforce 機能、デスクトップの Lightning Experience で使用する機能との機能上の差異、または動作が異なる Salesforce 機能について説明します。

https://help.salesforce.com/articleView?id=limits_mobile_sf1_chatter.htm
コピペでいける、Googleスプレッドシートでシートの内容をJSON形式でダウンロードする方法(Google Colab使用)

## 【コピペ可能】 GoogleスプレッドシートをJSON形式でダウンロードする方法

まずはコードから。
Google Colabを開いて、下に記載された２つのコードをコピペするだけで指定したシート内の値をJSON形式でPCのローカルにダウンロードすることが可能です。

### １．認証

下のコードをColab上で実行すると、認証を行うためのリンクなどが表示されるので、画面の指示に従って実行してください。

```python
from google.colab import auth
from oauth2client.client import GoogleCredentials
import gspread

auth.authenticate_user()
gc = gspread.authorize(GoogleCredentials.get_application_default())
```

### 2.JSON形式でダウンロード

下記のコードをColabにコピペして、`ダウンロードしたいスプレッドシートのファイル名` と `JSON形式でダウンロードしたいシート名` というところを書き換えてから、実行してください。
ローカルPCにJSONファイルがダウンロードされます。

```python
import os
import json
from google.colab import files

ss_name = "ダウンロードしたいスプレッドシートのファイル名"
workbook = gc.open(ss_name)
worksheet = workbook.worksheet("JSON形式でダウンロードしたいシート名")
dict_list = worksheet.get_all_records()

temp_file_path = worksheet.title + '.json'

with open(temp_file_path, 'w') as f:
  f.write(json.dumps(dict_list))

files.download(temp_file_path)

os.remove(temp_file_path)
```

## 解説

今回の処理に関する簡単な解説のようなものを書き残しておきます。

Colab内にデフォルトでインストールされている`gspread`というライブラリを利用して今回の処理を実行しています。

`gspread`の`get_all_records()`を使うことで、シート内の値を`dict(辞書)のリスト`として取得することができるので、そちらを元にしてJSONデータを作成、その後一度ファイルに書き出した後にローカルにダウンロードしています。
書き出したファイルは最後に削除を行うため、何度でも繰り返し実行できるようにしています。

## 最後に

Google スプレッドシートの内容をJSON形式でダウンロードする方法としては、他にGoogle Apps Scriptに処理を書いて実行する方法もありますが、Google Colabならこれらのコードをコピペすれば1分ほどでJSONファイルのダウンロードが実現できるので、思いついたときにサクッと実行できて便利！と思ったので、こちらに書かせていただきました。

他にもっと楽にJSON形式でダウンロードできる方法をご存知の方がいらっしゃいましたら、コメント頂けますと幸いです！

Google スプレッドシートをGoogle Colabから扱う方法については、以前Qiitaにも書いていますので、併せてご紹介させていただきます。
上に書いたコードをアレンジするときなどにもご利用いただけたらと思います。
[Google ColabからGoogle スプレッドシートを扱うときのサンプルコードまとめ](https://qiita.com/safa/items/bfa52430f920ac562bec)
VBAのデバッグ方法まとめ

# Option Explicitをオンにする
Option Explicitステートメントをモジュール内で使用すると、そのモジュールでは変数を宣言しないとマクロが動かなくなります。Option Explicitを使うことで、変数入力ミス時にどこの変数が入力ミスしているか黄色ハイライトで教えてくれます。オフにしていると、エラーメッセージが出ないので、変数の入力ミスに気づくことができません。
VBEの設定を変更して、新規マクロ作成時に自動でOption Explicitが入力されるようにしましょう。
参考）[Option Explicitって何？](http://officetanaka.net/excel/vba/beginner/11.htm)

# Debug.Printを使って、変数に格納されている値を確認する
Debug.Print 変数名　を入力してマクロを実行すると、画面右下のイミディエイトウィンドウに変数に格納されている値が表示されます。想定している値が変数に格納されているか確認することで、ソースの間違えを発見できることがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/ce9e7e26-2686-01ac-7441-cb9fdd84c7b6.png)


# 変数名をわざと小文字で入力する
変数名は大文字小文字を区別します。大文字込みで変数を宣言している場合、その変数を使用するときに変数名をすべて小文字で入力して次の行に移動すると、自動で大文字込みに修正されます。
ソースを書くときは変数名をわざと小文字で入力します。次の行に移動しても大文字に自動変換されない場合は、変数名の入力間違えを把握することができます。

↓大文字込みで宣言した変数を、あえて小文字だけで入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/4460875c-54b1-2ae9-bd65-9af79aa008c0.png)

↓Enterを押したり、他の行に移動すると、自動で大文字込みになる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/02cefa08-ba5d-7659-c8b3-e73712c377a4.png)
VBAで図形内の文字を置換する

図形（オートシェイプ）内のテキストを置換するマクロです。
検索対象の文字列をB1セルに入力し、置換後の文字列をB2セルに入力し、マクロを実行すると、図形内の文字列が変換されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/fd9abb78-609f-2246-440b-5fba689c09bb.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/262601/85504751-ee10-1d47-d389-64d811f9fa2e.png)


```vb
'Option Explicitステートメントは、モジュールの中で使用すると
'そのモジュールでは変数を宣言しないとマクロが動かなくなる。
'Option Explicitを使うことで、変数入力ミス時にどこの変数が入力ミスしているか黄色ハイライトで教えてくれる
Option Explicit

Sub TextReplacementForShapes()

 Dim TargetWorkSheet As Worksheet '置換対象のシート
 Dim TargetShape As Shape '置換対象の図形
 Dim TargetText As String '置換対象のテキスト

 Dim SearchText As String '検索するテキスト
 SearchText = Range("B1")

 Dim ReplaceText As String '置換後のテキスト
 ReplaceText = Range("B2")
 
 Set TargetWorkSheet = Application.ActiveSheet 'アクティブシートを置換対象シートの変数に格納

 '図形のテキストを置換
 'For Eachでブック内の全てのオブジェクトを対象に処理する
 'For Each構文
 ' For Each オブジェクト変数 In オブジェクト
 ' 繰り返し処理
 ' Next オブジェクト変数

 For Each TargetShape In TargetWorkSheet.Shapes
  If TargetShape.TextFrame2.HasText Then 'テキストがある場合、以下の処理を実行
   TargetText = TargetShape.TextFrame.Characters.Text
   TargetShape.TextFrame.Characters.Text = Replace(TargetText, SearchText, ReplaceText) 'Replace(置換対象の文字列, 検索する文字列, 置換後の文字列)
  End If
 Next TargetShape

 Set TargetWorkSheet = Nothing

End Sub
```
(自分用)Flask_4(ドロップダウンメニュー、txtデータの表示(表を使って))

# 項目
1. ドロップダウンメニューの作成
2. txtデータの読み込み
3. txtを整える

# 1.ドロップダウンメニューの作成
```python:python
from flask import Flask, request, render_template
app = Flask(__name__)

players = ["勇者", "戦士", "魔法使い", "忍者"]

@app.route("/")
def show():
    message = "あらたなモンスターがあらわれた！"
    return render_template("battle.html", message = message, players = players)
```
- 今回はpy側に作ったリストを項目としてメニューを作成
- リストに関してはそのまま
- `return`にリスト名入れるの忘れない様に

```html:html
<form action="/result" method="post">
    <select name="name">
        {% for player in players %}
            <option value="{{ player }}">{{ player }}</option>
        {% endfor %}
    </select>
    <p></p>
    <button type="submit">たたかう</button>
</form>
```
- `selectタグ`でドロップダウンメニュー(セレクトボックスとも)を作るよと宣言
- `<option value="{{ player }}">{{ player }}`に関しては、`optionタグ`はメニューの項目を入力するもの<br>ここではfor文を使って表示される項目名とvalueの名前を一致させている
- これで`submit`ボタンを押すと、選択した項目が入力される。

# 2.txtデータの読み込み
- 用意するtxtデータは末尾を改行しておく

```python:python
from flask import Flask, request, render_template
import codecs
app = Flask(__name__)

@app.route("/")
def bbs():
    file = codecs.open("articles.txt", "r", "utf-8")
    lines = file.readlines()
    file.close()
    return render_template("bbs.html", lines = lines)

@app.route("/result", methods=["POST"])
def result():
    article = request.form["article"]
    name = request.form["name"]
    return render_template("bbs.html", article = article, name = name)
```
- `import codecs`を宣言しておく<br>codecsを使うと指定した文字コードとかでデータを読み込めるらしい
- `file = codecs.open("articles.txt", "r", "utf-8")`で指定したtxtを`r`モードのutf-8で`file変数`に入れている
- `lines = file.readlines()`で1行ごとのリストでデータを全て読み込んでいる<br>ちなみに`.readline()`なら1行だけ読み込み、`.read()`ならリストとか関係なしに全部読み込む
- ファイルは`.open`した後、必ず`file.close()`する

```html:html
{% for line in lines: %}
    <p>{{ line.rstrip() }} </p>
{% endfor %}
```
- for文で１つずつlineに代入されたデータを表示していくだけ
- `.rstrip()`で行末の改行コード１つのみを消している

# 3.読み込んだtxtデータを整える
- 体裁を整えるだけのhtml的な話なのでpyは触れなくてOK

```html:html
<table>
    <tr><th>投稿</th><th>名前</th></tr>
        {% for line in lines: %}
            {% set column = line.rstrip().split(",") %}
            <tr>
                {% for item in column: %}
                    <td>{{ item }}</td>
                {% endfor %}
            </tr>
        {% endfor %}
</table>
```
- １つ上にあるhtmlをこれに置き換える
- まず`tableタグ`で表を作るよと宣言する
- `trタグ`で横軸の中身を触るよと宣言し、タグの中で`thタグ`によって表の項目名を設定する
- `set`でcolumnの中にlineのデータをforの試行ごとに入れていく<br>今回は行末の改行コードを`.rstrip`で消した後に、`.split(",")`によって「,」でデータを区切っている
- それらのデータを`trタグ`によって横軸方向に入れるよと言ったのち、おもむろにfor文で区切られたデータ単体を`item`に入れ、`tdタグ`というデータ入力専用のタグにてデータを入力する
- ↑ちょい分かりにくいので補足<br>例えば

```:txt
Hello World,peko
Hello Ruby,oz
Hello Sinatra,toramaru
世界の皆さんコンニチハ,霧島
にゃー,ネコ

```
というtxtデータだとすると、forの試行1回目では

- lineには`Hello World,peko(改行コード)`というデータ
- columnには`Hello World , peko`というデータ(データを綺麗にしている)
- itemには`Hello World`というデータのみ(区切られていた為にこれ単体で取り出された)

が入っている。一応`trタグ`で横方向に入れるって宣言したのも忘れない様に

# 4.終わりに
- なし
Vimのヘルプの見方

自分はVimの操作をすぐに忘れてしまって、インターネット検索に頼ってばかりいて、いちいち面倒だなあと思っていたのですが、ヘルプの見方が少しわかっただけで楽になったので共有したいと思います。

## Vimの基本操作
コマンドラインから`vimtutor`と入力すると、Vimのチュートリアルが見られます。
まずはこれで基本操作を覚えます。ヘルプを見るのにも必要になってくるので…。

## ヘルプの開き方
Vimを起動して`:h`してEnter
(`:help`でも同じ)

## ヘルプの見方
- 基本的なことはヘルプを開いた直後の画面に書いてあります。
- 編集画面と同じように、ヘルプ画面の中を移動できます。
- ヘルプは内容ごとに複数のページで構成されていて、`CTRL`-`]`で別のページにジャンプできます。（タグジャンプ）。前のページに戻るときは`CTRL`-`O`です。（ヘルプを開いた直後のページに書いてあります）

## よく使うコマンドを調べる
ヘルプを1ページ分くらい下にスクロールすると、以下のような記述が見つかります。

```vim
BASIC:
quickref        Overview of the most common commands you will use
```

この`quickref`という文字のところまでカーソルを移動してタグジャンプ`CTRL`-`]`すると、よく使うコマンドのページにジャンプできます。こんな感じのページにジャンプするはずです。

```vim
                                                           quickref Contents
   tag      subject                        tag      subject
  Q_ct    list of help files              Q_re    Repeating commands
  Q_lr    motion: Left-right              Q_km    Key mapping
  Q_ud    motion: Up-down                 Q_ab    Abbreviations
  Q_tm    motion: Text object             Q_op    Options
  Q_pa    motion: Pattern searches        Q_ur    Undo/Redo commands
  Q_ma    motion: Marks                   Q_et    External commands
  Q_vm    motion: Various                 Q_qf    Quickfix commands
  Q_ta    motion: Using tags              Q_vc    Various commands
  Q_sc    Scrolling                       Q_ce    Ex: Command-line editing
  Q_in    insert: Inserting text          Q_ra    Ex: Ranges
  Q_ai    insert: Keys                    Q_ex    Ex: Special characters
```
motion（移動）、insert（挿入）…など、やりたいことごとに、さらにタグジャンプできるようになっています。

## 例
```vim
Q_de    change: Deleting text
```

自分は**行末の改行を削除して次の行とくっつける**ということをしたかったので、ここからジャンプしました。

```vim
J       N  J            join N-1 lines (delete <EOL>s)
```

ジャンプした先でこのような記述を見つけました。大文字のJをタイプするだけで良いようだとわかりました。
Alias settings in Gmail

# Alias settings in Gmail

Gmail has an alias feature that allows you to make one address into another.
Addresses will change, but they will be sent to the same account and can be managed centrally, and they can also be sent from an alias.
This feature is useful for filtering by address and creating multiple accounts for web applications.

## Table of Contents
- [alias by plus] (# alias by plus)
- [Alias by dot] (# Alias by dot)
- [Source setting](#Source setting)
- [at the end] (# at the end)

## Alias by Plus.

If you add `+` and any number of characters at the end of the user (before the @) of a Gmail address, it becomes an alias.

Example :
- foo+bar@gmail.com
- foo+hoge@gmail.com
- foo+1@gmail.com

and can be created in any number of ways.

## Alias by dot
If you add `. ` (dot) to the user (before the @) of a Gmail address to create an alias.

Example:
- f.oo@gmail.com
- fo.o@gmail.com 
- f.o.o@gmail.com

In this case, the length of the user part limits the number of aliases you can create.


## Source settings.

1. open the PC version of Gmail to set up the source (desktop view if you have a smartphone)
Click on the `settings` icon.
1. Click `See ll settings`.
1. Select `Account and Import`
1. Click on 'Add another email address' in the `Send mail as`.
1. Enter the alias in the `Email address` prompt and click on the next step.

Now you can choose an alias for the mail from.
Also, by default, replies to emails sent to your alias will be sent from Alias.

## At the end.

Depending on the site or app, you may be able to set an alias for multiple accounts as the same address. You may not be able to create them.

## My Accounts
<a href="https://github.com/mao2009"><img src="https://mao2009.github.io/qiita_template/GitHub-Mark-64px.png" width="50px"></a><a href="https://twitter.com/loach_mao"> <img src="https://mao2009.github.io/qiita_template/Twitter_Social_Icon_Circle_Color.png" width="50px"></a>


Translated with www.DeepL.com/Translator (free version)
AtCoderのテストが楽にできる拡張機能を作った

# おしらせ
AtCoderのサーバーに負荷をかけてしまうため、7/6付けでスクリプトを非公開としました。

代替としてはローカルで実行するOnline-Judge-Toolsなどがあり、実行も高速なのでそちらの利用をご検討ください。
Gmailのエイリアス設定

# Gmailのエイリアス設定

Gmailにはエイリアス機能があり、一つのアドレスを別のアドレスにすることができます。
アドレスは変わりますが同じアカウントに送信されて一元管理が可能で、エイリアスからも送信も可能です。
アドレスによるフィルタリングやウェブアプリのマルチアカウント作成に役に立ちます。

## 目次
- [プラスによるエイリアス](#プラスによるエイリアス)
- [ドットによるエイリアス](#ドットによるエイリアス)
- [送信元設定](#送信元設定)
- [終わりに](#終わりに)

## プラスによるエイリアス

Gmailアドレスのユーザー(@の前)部分の最後に `+` と適当な文字数字を付け加えるとエイリアスとなります。

例:
- foo+bar@gmail.com
- foo+hoge@gmail.com
- foo+1@gmail.com

といくらでも作成可能です.

## ドットによるエイリアス
Gmailアドレスのユーザー(@の前)部分に `.` (ドット)を加えるとエイリアスとなります。

例:
- f.oo@gmail.com
- fo.o@gmail.com
- f.o.o@gmail.com

こちらの場合はユーザー部分の長さによって作成可能なエイリアスが制限されます。


## 送信元設定

1. 送信元を設定するにはPC版Gmailを開く(スマホの場合はデスクトップ表示にする)
1. 設定アイコンをクリック
1. すべての設定を開くをクリック
1. アカウントとインポートを選択
1. 名前の`他のメールアドレスを追加`をクリック
1. プロンプトの`メールアドレス`にエイリアスを入力し、次のステップをクリック
これで送信元にエイリアスを選択できるようになります。
また設定したエイリアスに送られてきたメールの返信の送信元アドレスはデフォルトでエイリアスになります。

## 終わりに

サイトやアプリによってはエイリアスを設定しても同一のアドレスとしてマルチアカウントを作成できないこともあります。

## My Accounts
<a href="https://github.com/mao2009"><img src="https://mao2009.github.io/qiita_template/GitHub-Mark-64px.png" width="50px"></a><a href="https://twitter.com/loach_mao"> <img src="https://mao2009.github.io/qiita_template/Twitter_Social_Icon_Circle_Color.png" width="50px"></a>
railsで開発中にAWSから高額請求された件、、、

EC2に750時間/月の無料利用枠、RDSにdb.t2.microという無料のインスタンスサイズが存在しているが、これには大きな落とし穴がある（見事に落ちました。。。）
実は、EC2のインスタンスやRDSのインスタンスサイズ 

EC2の考え方は、作成数 X 利用時間 = 合計利用時間 という計算になっており、
無料利用枠 = 合計利用時間なのである。
私の場合EC2を2個走らせていた。
幸い、月の半分程で気づいたので請求はされなかったが、危なかった。
急いで両方の停止を実行し、開発中のみ起動するようにした。


RDSの場合、インスタンスサイズ(CPU、メモリ、ストレージ、ネットワークキャパシティーの組み合わせによって構成されている)を自由に選択でき、db.t2.microが無料利用枠として存在する。これが最低レベルであり、性能に比例して値段が上がる。
私の場合、db.m5.xlargeというインスタンスサイズが選択されており(原因不明。。。)、**1ヶ月で500$近い請求をくらった。。。。。**

すぐさま該当のDBインスタンスをdb.m5.xlarge ➡️ db.t2.microに変更しようとするが、下記のエラーが発生。
DB Instance class db.t2.micro does not support encryption at rest (Service: AmazonRDS; Status Code: 400; Error Code: InvalidParameterCombination; Request ID: cfbf5c05-7c57-492b-b9e3-6145a6f2c640)

どうやら、db.t2.microは保存時の暗号化をサポートしていないので変更できないようだ。
下記を参考に暗号化を試みるも、暗号化ボタンが有効にならず諦める。
https://dev.classmethod.jp/articles/encrypt-unencrypted-rds-db-instance-ja/

無料枠のdb.t2.microは諦めてもその次の構成である、db.t2.smallなら変更が可能なようだ。
db.m5.xlarge ➡️ db.t2.small への変更を実行し、利用料金の大幅な減額に成功した。


次回からAWSを使用し、EC2コンテナ上でアプリケーションサーバーをたて、DBはRDSで構築する場合は、
`可動しているEC2は何個で合計利用時間はどれだけか？`
`RDSのインスタンスサイズは無料枠であるdb.t2.micro(もしくはそれに近いもの)か？`
という2点を常に確認して利用したい。


上記以外にも次の設定にも注意したい。
ストレージタイプというものが以下の3種から選択可能で、これも$150の高額請求が来ていた。。。
`汎用(SSD)`
`プロビジョンド IOPS(SSD)` ⬅️ 初期選択
`マグネティック`
次の記事を参考に設定を以下のように変更した
https://blog.manabusakai.com/2015/07/rds-cost-down/
プロビジョンド IOPS(SSD) ➡️ 汎用(SSD) 変更時に注意(ロード時間が長くなる可能性あり)

実際の請求明細には以下の記述があり、参考記事が正しければ$146.67のコストダウンだ。もっと早く知りたかった。。。
USD 0.24 per IOPS-month of Multi-AZ Provisioned IOPS611.111 IOPS-Mo$146.67
USD 0.30 per GB-month of provisioned Multi-AZ IO1 storage61.111 GB-Mo$18.33

また、初心者が陥る料金発生には以下のようなものもあるらしい。
https://qiita.com/Yuji-Ishibashi/items/bb1c0042fd16a9350c5a
さらに、設定を一歩間違えると下記のような超高額請求もあるらしい。
https://qiita.com/mochizukikotaro/items/a0e98ff0063a77e7b694

最後に、私と同じような高額請求に、この記事が少しでも助けになることを願うばかりである。
初心者によるプログラミング学習ログ 350日目

#100日チャレンジの350日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
350日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>350日目　2.0h<br>・架空LP16日目1.0h(<a href="https://twitter.com/ririru_123?ref_src=twsrc%5Etfw">@ririru_123</a>)<br>・ipad版のプロフィール部分作成<br>・Udemyで、フロントエンド講座　1.0h<br><br>なんかあんまり捗りませんでした<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/1274069286886113280?ref_src=twsrc%5Etfw">June 19, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
HTMLとPHPで作る簡易チェックアプリ。(のような物)


# HTMLとPHPで作る簡易チェックアプリ。(のような物)

PHPでHTMLのformタグを使って値を渡す方法のチェックボックス編。
パラメータで渡した値で簡単に体調管理アプリ(のような物)を作り備忘録としました。
可読性を上げるためヘッダーとフッターは分割して部分テンプレート化し、
require文で呼び出してます。

## 入力側

```php:container_input.php
<?php require './header.php'?>
<form action="container_output.php" method="post">

<p>今朝の体調は？</p>

<?php
//チェックボックスの項目。
$check = ['高熱','微熱','吐き気','めまい','悪寒','特に何もなし'];

//name属性に配列を使うことで複数の値が使える。
foreach ($check as $status) {
	echo '<input type="checkbox" name="check[]" value="', $status, '">';
	echo $status;
}
?>

<p><input type="submit" value="診断"></p>

</form>
<?php require './footer.php'?>
```

## 出力側

```php:container_output.php
<?php require './header.php'?>
<?php

//それぞれのポイントを収納する空の配列を用意。
$point = [];

//値、つまりもしもチェックボックスにチェックが入っていたら…
if (isset($_REQUEST['check'])){

	//入力側でチェックを入れた項目の要素を取り出して…
	foreach ($_REQUEST['check'] as $status){
		//条件に一致したチェック項目ごとに値を割り振り、ポイントを収納する配列に値が入る。
		switch($status){
			case '高熱':
				$point[] = 5;
				break;
			case '微熱':
				$point[] = 4;
				break;
			case '吐き気':
				$point[] = 3;
				break;
			case 'めまい':
				$point[] = 2;
				break;
			case '悪寒':
				$point[] = 1;
				break;
			case '特に何もなし':
				$point[] = 0;
				break;
		}
	}

	//array_sum関数で配列の各要素のポイントの合計を計算。
	$total = array_sum($point);

		//switchにtrueを指定し、数値と文字列を明確に判断。
		switch(true){
			
			//配列の各要素のポイントの合計に応じて…
			case ($total >= 5):
				echo '病院に行きましょう';
				break;
			case ($total >= 3 && $total < 5):
				echo '無理せず寝ていましょう';
				break;
			case ($total >= 1 && $total < 3):
				echo 'お気をつけて。';
				break;
			default:
				echo 'お元気ですね。';

		}
}

?>
<?php require './footer.php'?>
```

あくまで勉強と備忘録を兼ねたものであって、医学的な根拠は全くありませんのでご注意ください。

---------------------------------------
![check_input.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609500/dadb95e2-5e9f-37ba-0472-6f5c34337134.png)
---------------------------------------

チェックボックスを選択して↑診断ボタンを押すと↓

---------------------------------------
![check_output.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/609500/48d92a35-a7a3-103c-c5b2-e03c368c449f.png)
---------------------------------------

チェックボックスごとに割り振られたポイントの合計によってメッセージが変化します。
ReactのReduxでstateは更新されているのにwebページ上では値が更新されない場合の要因

## 問題
`redux-logger`で見るstateでは値が更新されていたが、webページ上では値が更新されなかった。

## 解決策
__reducerで配列や連想配列のデータを全て上書きする場合に以下のように記述する。__

- 配列の場合：　`[...newArray]`
- 連想配列の場合 `{...newDict}`


## まとめ
単だが意外と気付きにくいバグだと感じたので記録として残しました。
MySQLでSELECTした結果をファイルに保存する

# INTO OUTFILEを使う

```sql
SELECT * FROM table INTO OUTFILE '/tmp/select.dump'
```

# リダイレクトする

権限がないとHY000 などのエラーが発生してINTO OUTFILEが使えないのでリダイレクトで対応する

```sql
mysql -h {host} -u{user} -p {DB} -e "SELECT * FROM table" > /tmp/select.dump
```

出力がtsvになるためcsvにする場合はsedで置換してからリダイレクトする
Node.jsのCLIツールでURLを既定のブラウザで開く

[open](https://www.npmjs.com/package/open) パッケージを使用すると、クロスプラットフォームでその辺の処理をよしなにやってくれる。
実行時にHTTPサーバを立てたり、ライセンスなどを表示したりするようなCLIツールで便利かもしれない。

## Install

```sh
yarn add open
```

## Usage

非常にシンプル。

```js
const open = require('open');

open('https://qiita.com/');
```

async/await を使用した実用的な例などは [README](https://www.npmjs.com/package/open) を確認されたい。

なお、従来は[opn](https://www.npmjs.com/package/opn)という名称だったものがrenameされたらしい。
Git2.26.0以下の脆弱性のためMacのgitをアプデする

# Git2.26.0以下の脆弱性のためMacのgitをアプデする

1. `git --version`で現在のバージョン確認
2. `brew upgrade git`をして`git --version`が2.26.1以上になればOK。失敗した場合はhomebrewのgitを使うように設定
3. 一度`which git`で現在のgitのインストール先を確認
4. `/usr/local/bin/git`になっている場合はmacデフォルトのgitを使っているのでhomebrewからインストールしたgitを使うようにする
5. `brew install git`
6. パスを通すために`export PATH="/usr/local/opt/git/bin:$PATH"`を.bash_profileに追記
7. `source ~/.bash_profile`でパスを反映させる
8. `git --version`で2.26.1以上になればOK

参考リンク

- [Git2.26.0以下にある深刻な脆弱性を回避する](https://qiita.com/orimomo/items/2669c8cc10870ee92c7f)
JavaScript関数の書き方 まとめ

備忘録として残します。

```Javascript
// 関数宣言
function double(x) {
  return x * 2;
}

// 関数式
const double = function(x) {
  return x * 2;
}

// アロー関数
const double = (x) => {
  return x * 2;
}

// 引数が一つの場合（）省略可能
const double = x => {
  return x * 2;
}

// 一行の場合は{}も省略可能
const double = x =>  x * 2;

```
Mac VScode Maven でJunit 使ってみた

# はじめに

とりあえずVSCodeでJUnit使ってユニットテスト体験してみたい人が対象です。
まだJavaすらMacに入れてないんだ！って人は[こちら](https://qiita.com/tayatamn/items/a38386288c50233c6a90)を参考にしてみてください。

## 動作環境

- macOS : Catalina 10.15.5
- VSCode : 1.46.1
- Java : Amazon Correto 1.8.0_252

別に他のJDKでも構いませんが、今回はとりあえず1.8を使うことにします。


## VScodeにJavaの拡張機能をインストールする

まず、[Java Extension Pack](https://marketplace.visualstudio.com/items?itemName=vscjava.vscode-java-pack)をVSCodeに入れましょう。
<img width="528" alt="スクリーンショット 2020-06-20 1.47.40.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318867/f00dd235-8412-666b-94c5-d4ae9087a769.png">

こちらにはMavenの拡張機能も含まれており、今回必須となります。

## Mavenプロジェクトを作成する

拡張機能をインストールしたら、`Cmd + Shift + p`でコマンドパレットを開き、`Maven: Create Maven Project`を選択しましょう。

<img width="602" alt="スクリーンショット 2020-06-20 1.52.33.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318867/75d65804-f169-f66e-1484-51534676c349.png">

archtypeは`archtype-quickstart-jdk8`を選択します。
JDK1.8以外を使用している方は`maven-archtype-quickstart`を選択してください。
その場合はこの後の実行結果が変わってくる可能性があるので注意してください。
私はとりあえず簡単にJUnitを実行することしか考えていません。

<img width="601" alt="スクリーンショット 2020-06-20 2.45.45.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318867/1bddcfc9-a67e-20b7-2505-f9e0d43985f3.png">

バージョンはとりあえず最新の2.0.0を選んでおきましょう。

<img width="602" alt="スクリーンショット 2020-06-20 2.00.32.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318867/d9116646-72bf-ae7d-1426-ba3738e1f4e5.png">

ここでどこのディレクトリに作成するか聞かれるので、任意のディレクトリを選択してください。
そうするとVSCodeのターミナルで対話式でどのようなプロジェクトを作成するか問われます。
今回は以下のように作成しました。

<img width="819" alt="スクリーンショット 2020-06-20 2.07.47.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318867/62e0a4dc-e5a5-6da4-52d8-33ae5a94629a.png">

`groupID`はdemo,`artifactID`をcom.demoとしました。
上記のように作成が成功すると、以下のようなディレクトリ構成になります。

<img width="236" alt="スクリーンショット 2020-06-20 2.20.39.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318867/379a6e48-c2f8-7e2a-86c6-650ed45fcb63.png">

## テスト実行してみる

`AppTest.java`を開くと以下のようにテストコードが表示されるので、`Run Test`をクリックしてください。
テストが実行されます。

<img width="186" alt="スクリーンショット 2020-06-20 2.35.53.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/318867/1780f5b3-cc54-217a-182a-60e9e1686236.png">
AWS Cloud9 でGitクライアントを使う

# 0. はじめに

AWS Cloud9 で GUIのGitクライアント( [ungit](https://github.com/FredrikNoren/ungit) )を設定する手順です。

# 1. ungitをインストールする

[ungitの公式サイト](https://github.com/FredrikNoren/ungit)の通り、`npm` でインストールします。

```bash
$ npm install -g ungit
```

# 2. ungitにポートを割り当てる

ユーザのホームディレクトリにungit用の設定ファイルを作ります。

```bash
$ touch ~/.ungitrc
```

設定ファイルにungitに割り当てたい任意のポートとIPアドレスを書いておきます。

```json
{
  "port": 8080,
  "ungitBindIp": "0.0.0.0"
}
```

ちなみに、AWS Cloud9では、ターミナル上のパス形式の文字列を選択すると、OPENからエディタが開きます。
![kyato-9mfjx.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549788/6e89578b-a1ab-ead0-c134-a0c072277cde.gif)

# 3. ポートを開放する

AWS Cloud9 の **[View Details]** からIDEの詳細画面を開きます。

<img width="908" alt="スクリーンショット 2020-06-20 2.24.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549788/494ac472-933f-3ca2-eef0-6fa829311315.png">

詳細画面の **[Security groups]** のリンクを開きます。

<img width="788" alt="スクリーンショット 2020-06-20 2.24.50.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549788/53892275-a7da-daf8-f7cf-a25686e9afff.png">

インバウンドルールを編集して、`.ungitrc` に書いたポートを開放します。

<img width="964" alt="スクリーンショット 2020-06-20 2.28.41.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549788/d5b97a36-77ed-4bb0-48f5-788c667468d9.png">

# 3. ungitを起動する

gitリポジトリがあるディレクトリで、ターミナルからungitを起動します。

```bash
$ ungit
```

ターミナルに表示されるリンクをクリックしてOPENを選択すると、ungitの画面が表示されます。

<img width="762" alt="スクリーンショット 2020-06-20 2.40.05.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/549788/8a3b2244-9742-cc6f-80ca-17eb83193d35.png">

ungitの使い方は[公式サイト](https://github.com/FredrikNoren/ungit)を参考にしてください。

# 4. 最後に

AWS Cloud9で利用できる他のGit クライアントがあればぜひ教えてください。
Ubuntu20.04でw3mが使えない

私はLinuxやBashにほとんど触ったことのない初心者です。
解決に大分時間がかかったのでメモを残しておきます。
# 問題
WSL(Windows Subsystem for Linux)上にUbuntu20.04をインストールし、w3mを使おうとしたもののうまくいかない。

```
:~$ w3m google.co.jp
Wrong __data_start/_end pair
Aborted (core dumped)
```

# 試行錯誤
上記のエラーメッセージは管理すべきメモリの範囲の取得に失敗したことを示すらしい。
https://teratail.com/questions/150464
以下のリンクを参考にulimitでスタックサイズを変更してみたものの、状況は変わらず。
https://askubuntu.com/questions/1142308/cannot-launch-inkscape-and-w3m-with-same-error-message-wrong-data-start-end
# 解決？
以下のリンクを参考にして、ubuntu18.04を新たにインストールし、そちらでw3mをインストールしたら何事もなく動いた。
https://askubuntu.com/questions/1241669/cannot-launch-inkscape-in-windows-subsystem-for-ubuntu

結局何故ubuntu20.04でw3mが動かなかったのかは分からずじまい。
どなたか詳しい方がいらっしゃたらご教示ください。
TouchDesignerとpython間でOSC

# 背景
TouchDesignerには内部でpythonスクリプトを実行することが出来ますが、様々な事情によりTouchDesigner内部ではないpython （もちろん、他のマシン含め）とやり取りをしなければならない日が来ることもあります。

というケースが数回有りましたので、記録しておきます。

環境：
windows10, macos, TouchDesigner 2020.23680
python 3.7



# OSC
TouchDesignerでのOSCについて
https://qiita.com/kodai100/items/5b614fed5f3e17b7f8f6
http://satoruhiga.com/TDWS2018/day9/

#python側

pythonoscを使います。

```python:OSC-Python.py

'''
setup instruction 
for Install pythonosc
pip install python-osc

'''

from pythonosc import dispatcher
from pythonosc import osc_server
from pythonosc import udp_client

def messege_handler(unused_addr, *p):
    try:
        print(p)
        client.send_message("/message_echo", p)
    except ValueError: pass

dispatcher = dispatcher.Dispatcher()
dispatcher.map("/message", messege_handler)
server = osc_server.ThreadingOSCUDPServer(("127.0.0.1", 5005), dispatcher)
print("Serving on {}".format(server.server_address))

client = udp_client.SimpleUDPClient("127.0.0.1", 5006)

server.serve_forever()
```

ここでは、port5005で受け取ったデータをそのまま、port5006へ送り返すようにしています。


# TouchDesinger側
`OSC OutDAT`と`OSC InDAT`を使います。ポート番号が違うのに注意。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/70810/c7f095a4-bf99-7366-be77-c80f70f70434.png)

OSCを送るテストとして、textDATに下記を記載して、runします。

```python:textDat

n = op('oscout1')
n.sendOSC('/message',['something', 9999])
```

#Round Trip
同一マシン内（Windows10のRyzen 3960X CPU）でTD→Python→TDの経過時間は6msでした。IP指定をすれば他のマシンとのやり取りも可能です。

#code
https://gist.github.com/shks/711411b5ea6151c099d7ca29ff901a29
railsのバージョン

UdemyでRailsを学習していたが、バージョンが古くて講座のバージョンにしたかったがやり方がわからなかった。
調べて見たところ

```ruby:qiita.rb
gem install rails -v 5.2.１

```

これでインストールが実行されて、バージョンアップ完了。。
初歩の初歩だと思うので、記念に記録に残しておこう。

逆にバージョンダウンも可能そうだけど、その場合はgemのバージョンを下げるよりかは

```ruby:qiita.rb
rails _5.x.x._ new "ディレクトリ名"
```

これを使って、任意のバージョンを使えるようにしておくという認識でいいのだろうか。とりあえず一旦記録へ残す。
No key could be detected.の対処法メモ

## エラーログ
```
Traceback (most recent call last):
  File "/app/.heroku/python/lib/python3.7/site-packages/firebase_admin/credentials.py", line 96, in __init__
    json_data, scopes=_scopes)
  File "/app/.heroku/python/lib/python3.7/site-packages/google/oauth2/service_account.py", line 201, in from_service_account_info
    info, require=["client_email", "token_uri"]
  File "/app/.heroku/python/lib/python3.7/site-packages/google/auth/_service_account_info.py", line 55, in from_dict
    signer = crypt.RSASigner.from_service_account_info(data)
  File "/app/.heroku/python/lib/python3.7/site-packages/google/auth/crypt/base.py", line 114, in from_service_account_info
    info[_JSON_FILE_PRIVATE_KEY], info.get(_JSON_FILE_PRIVATE_KEY_ID)
  File "/app/.heroku/python/lib/python3.7/site-packages/google/auth/crypt/_python_rsa.py", line 171, in from_string
    raise ValueError("No key could be detected.")
ValueError: No key could be detected.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "main.py", line 28, in <module>
    "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-vbo7h%40jun-remind.iam.gserviceaccount.com"
  File "/app/.heroku/python/lib/python3.7/site-packages/firebase_admin/credentials.py", line 99, in __init__
    'Caused by: "{0}"'.format(error))
ValueError: Failed to initialize a certificate credential. Caused by: "No key could be detected."
```

## 対処法

1. herokuの環境変数のキーを大文字に変更
2. private_keyの改行コードを変換

```
os.environ["PRIVATE_KEY"].replace('\\n', '\n')
```

## 参考
https://github.com/firebase/firebase-admin-python/issues/188
JAVA＋STS（Spring Tool Suite）の環境構築手順

# 目次
- [はじめに](#はじめに)
- [Javaの設定](#Javaの設定)
- [STSのインストール](#STSのインストール)

# はじめに

JAVA＋STS（Spring Tool Suite）の環境構築手順です。  
本手順に従い、java openjdk-12.0.2とSTS（Spring Tool Suite）4をインストールできることが目標です。

# Javaの設定
- [jdkのオフィシャルサイト](https://jdk.java.net/archive/)から、openjdk-12.0.2のzipファイルをダウンロードします。
- ダウンロードしたzipをCドライブに解凍し、`C:\jdk-12.0.2`のように展開されることを確認します。
- windosの検索バーに`環境`を入力し、`環境変数を編集`を開きます。
![環境変数設定起動](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252890/e2725ff7-d0bb-9844-e011-93c6b50b28fa.png)

- `システム環境変数`に、`Path`をクリックし、`編集`ボタンを押します。
- `新規`ボタンを押し、パス`C:\jdk-12.0.2\bin`を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/252890/ab5b9940-7f9d-81e0-5787-862803da7863.png)

- 上記`環境変数名の編集`ダイアログの`OK`ボタンを押して、`環境変数`ダイアログの`OK`ボタンも押して、環境変数の設定を終了します。
- コマンドプロンプトで下記のコマンドを入力し、enterキーを押します。  

  ```sh
  java -version
  ```
- 下記の出力が表示されれば成功です。

```sh
openjdk version "12.0.2" 2019-07-16
OpenJDK Runtime Environment (build 12.0.2+10) 
OpenJDK 64-Bit Server VM (build 12.0.2+10, mixed mode, sharing)
```

# Spring Tools 4(略してSTS4)のインストール
- [Springのオフィシャルサイト](https://spring.io/tools)から、Spring Tools 4 for Eclipseをダウンロードします。
- ダウンロードしたjarファイルをCドライブの直下に移動します。
- コマンドプロンプトで下記のコマンドを入力し、enterキーを押します。(ダウンロードタイミングによってバージョンが違ったりするかもしれないので、その場合、ダウンロードしたファイル名に合わせて下記コマンドを編集してください)

  ```sh
  java -jar C://spring-tool-suite-4-4.7.0.RELEASE-e4.16.0-win32.win32.x86_64.self-extracting.jar
  ```

- ユーザーのルートフォルダにインストールされます。C:\Users\あなたのユーザ名\sts-4.7.0.RELEASE
Reactのstate機能

# プログラミングの勉強日記
2020年6月20日　Progate Lv.137
ReactⅠ

##stateとは
　React ではユーザの動きに合わせて変わる値のことをstateという。
　今回はボタンを押すとstateが変わり表示させる文字列をを変えるプログラムを作成する。

##stateの定義
　constructorの中でオブジェクトとして定義する。この定義したオブジェクトがstateの初期値となる。

```react
constructor(props) {
    super(props);
    //オブジェクトとして定義した{count: 0}をthis.stateに代入
    this.state = {count: 0}; 
}
```
　この`constructor(props) `や`super(props);`の処理はいつも同じ記述なので、定型文として覚えてもよい。


##stateの取得
　定義したstateは`this.state`で取得できる。

```react
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 0};
  }
  render(){
    console.log(this.state);
  ...
```

```:コンソール
{count: 0}
```
　コンソールにはオブジェクトが出力される。コンソールの出力で文字列はダブルクォーテーションで囲まれるが気にしなくてよい。

##stateの表示
　`this.state`はオブジェクトなので、`this.state.プロパティ名`とすることで、指定したstateのプロパティに対応する値を取得できる。

```react
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 0};
  }
  render(){
    return(
      <h1>現在ののカウントは{this.state.count}です</h1>
    );
  }
}
```

##stateの変更
　`this.setState({プロパティ:変更する値})`とすると、指定されたプロパティに対応するstateの値が変更される。<font color=blue>Reactではstateの値に直接代入することで値を変更していてはいけない。（値を変更するときはsetStateを使う）</font>

```react
render(){
  return(
    <h1>現在ののカウントは{this.state.count}です</h1>
    {/*ボタンがクリックされたときにcountの表示を変える*/}
    <button onClick = { ()=> {this.setState({count:2})}}>
      2
    </button>
  );
}
```

##stateを変更するメソッド
　今回はhandleClickメソッドを作成する。

```react:メソッドの定義
class App extends React.Component {
  handleClick(){  
    //stateのcountプロパティの値を変更する処理
  }
}
```

```react:onClickイベントでメソッドを呼び出す
<button onClick={()=>{this.handleClick()}} > 
  +
</button>
```

```react:メソッドを引数を渡す
class App extends React.Component {
  handleClick(count){
    this.setState({count:count);
  }
  ...
    <button onClick={()=>{this.handleClick(1)}} > 
      +
    </button>
  ...
```
　引数countを使ってstateのcountプロパティの値を変更する。
  
##カウントアップ機能を作る
　ここまでの知識を利用して、ボタンをクリックすると数字が1ずつ増えるカウントアップ機能を作る。

```react:App.js
import React from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {count: 0};
  }
  
  handleClick(){
    this.setState({count:this.state.count+1});
  }
  
  render() {
    return (
      <div>
        <h1>
          {this.state.count}
        </h1>
        <button onClick={()=>{this.handleClick()}} >+</button>
        
      </div>
    );
  }
}

export default App;
```
画像再構成OSSリスト

#はじめに
この記事では、画像再構成計算が可能なオープンソースソフトウェア(OSS)を紹介します。
再構成計算を手軽に実行できるお試しツールのようなものも含まれます。
使ったことのないソフトウェアがほとんどです。

#汎用
[Radon Transform](https://imagej.nih.gov/ij/plugins/radon-transform.html) (ImageJ)
[Scikit-Image](https://scikit-image.org/docs/dev/auto_examples/transform/plot_radon_transform.html) (Python)
[Image processing toolbox](https://jp.mathworks.com/discovery/image-reconstruction.html) (Matlab)
[MIRT](https://web.eecs.umich.edu/~fessler/code/) (Matlab, Julia)
[learnCT](https://github.com/dmnfarrell/learnct) (Java)
[ODL](https://odlgroup.github.io/odl/) (Python)
[TomoPy](https://tomopy.readthedocs.io/en/latest/index.html) (Python)

#PET
[STIR](http://stir.sourceforge.net/) (C/C++) [[Ref]](https://doi.org/10.1088/0031-9155/57/4/867)
[CASToR](http://www.castor-project.org/) (C/C++) [[Ref]](https://doi.org/10.1088/1361-6560/aadac1)
[NiftyPET](https://github.com/NiftyPET/NiftyPET) (Python) [[Ref]](https://doi.org/10.1007/s12021-017-9352-y)
[PET_sim_recon](https://github.com/ashrafinia/PET_sim_recon) (Matlab)

#X線CT
[RTK](http://www.openrtk.org/) (C/C++) [[Ref]](http://dx.doi.org/doi:10.1088/1742-6596/489/1/012079)
[ASTRA](http://www.astra-toolbox.com/) (Matlab,Python) [[Ref]](https://doi.org/10.1364/OE.24.025129)
[TIGRE](https://github.com/CERN/TIGRE) (Matlab,Python) [[Ref]](https://doi.org/10.1088/2057-1976/2/5/055010)
[CONRAD](http://conrad.stanford.edu/home/index.html) (Java) [[Ref]](https://doi.org/10.1118/1.4824926)
[ToMoBAR](https://github.com/dkazanc/ToMoBAR) (Matlab, Python)
[OSCaR](http://www.cs.toronto.edu/~nrezvani/OSCaR.html)
[CIL](https://ccpi.ac.uk/cil/) (Python)

※下記のRTKのサイトでもOSSが紹介されています。一部はここで紹介しているOSSと被っています。
[RTK Alternative platforms](https://www.openrtk.org/RTK/resources/alternatives.html)

#GitHub Topics
https://github.com/topics/tomography
https://github.com/topics/computed-tomography
https://github.com/topics/positron-emission-tomography
https://github.com/topics/medical-imaging
https://github.com/topics/image-reconstruction
https://github.com/topics/pet-image-reconstruction
https://github.com/topics/iterative-reconstruction
https://github.com/topics/compressed-sensing
https://github.com/topics/image-restoration

#その他

https://paperswithcode.com/task/image-reconstruction

https://www.opensourceimaging.org/
空テーブルに対する固定値SELECTのFROM有無でハマった件

しょうもないことでハマってしまったので自分の反省を覚えとくための小ネタです。

- 検証環境: `MariaDB 10.4.13`

## 前提
とある履歴テーブルにおいて、現在時刻よりX分以内に履歴があった場合はスキップ、
なかった場合は履歴レコードを追加する、というようなロジックがありました。

```sql
-- こんな履歴テーブル定義
CREATE TABLE hoge_history (
  id int(10) unsigned NOT NULL AUTO_INCREMENT,
  label varchar(100) NOT NULL,
  timestamp timestamp NOT NULL DEFAULT current_timestamp(),
  PRIMARY KEY (id)
);
```

```sql
-- こんな感じのSQLで履歴を入れてた
INSERT INTO hoge_history (label)
SELECT CONCAT('exec: ', NOW()) AS label
FROM hoge_history 
WHERE NOT EXISTS (
	SELECT 1 FROM hoge_history WHERE timestamp >= SUBTIME(NOW(), '00:15;00') 
)
LIMIT 1;
```

## 事象
開発用の好きに使っていいDBを、一度空っぽにして新しく作り直したところ、
履歴レコードが一切入らずエラーになってしまった。
運用が始まっているプロダクトコードでは起こった事のない事象。

## 原因・解決
`FROM句` が悪さしてた。

```sql
INSERT INTO hoge_history (label)
SELECT CONCAT('exec: ', NOW()) AS label
-- ↓ここ↓
FROM hoge_history 
WHERE NOT EXISTS (
	SELECT 1 FROM hoge_history WHERE timestamp >= SUBTIME(NOW(), '00:15:00') 
)
LIMIT 1;
```

一度DBを空っぽにしたため `hoge_history` テーブルは空っぽの状態になっていた。
SQL内でSELECT結果として固定値を出力していたとしても、
FROM句があるときはテーブルの中身に引きずられる。たとえば…

```bash
MariaDB [test]> SELECT COUNT(1) FROM example;
+----------+
| COUNT(1) |
+----------+
|        0 |
+----------+
1 row in set (0.00 sec)

MariaDB [test]> SELECT 1 AS const FROM example;
Empty set (0.00 sec)

MariaDB [test]> SELECT 1 AS const;
+-------+
| const |
+-------+
|     1 |
+-------+
1 row in set (0.00 sec)
```

といった感じに、固定値で何の問題もなく出力できる結果も、空テーブルを `FROM` に持つかどうかで結果が変わる。
なので、WHERE句の結果がTRUEになったとしてもSELECTの結果がEmptyになってしまい、意図通りにINSERTされなかった。

っていうか、SELECTの挙動考えれば当たり前だったね。

```bash
MariaDB [test]> SELECT 1 AS const FROM example WHERE name = 'hoge';
Empty set (0.00 sec)

MariaDB [test]> SELECT 1 AS const FROM example LIMIT 1;
Empty set (0.00 sec)

MariaDB [test]> INSERT INTO example(id, name) VALUES(1, 'hoge');
Query OK, 1 row affected (0.01 sec)

MariaDB [test]> INSERT INTO example(id, name) VALUES(2, 'fuga');
Query OK, 1 row affected (0.00 sec)

MariaDB [test]> SELECT COUNT(1) FROM example;
+----------+
| COUNT(1) |
+----------+
|        2 |
+----------+
1 row in set (0.00 sec)

MariaDB [test]> SELECT 1 AS const FROM example;
+-------+
| const |
+-------+
|     1 |
|     1 |
+-------+
2 rows in set (0.00 sec)

MariaDB [test]> SELECT 1 AS const;
+-------+
| const |
+-------+
|     1 |
+-------+
1 row in set (0.00 sec)

MariaDB [test]> SELECT 1 AS const FROM example WHERE name = 'hoge';
+-------+
| const |
+-------+
|     1 |
+-------+
1 row in set (0.00 sec)

MariaDB [test]> SELECT 1 AS const FROM example LIMIT 1;
+-------+
| const |
+-------+
|     1 |
+-------+
1 row in set (0.00 sec)
```

FROMのテーブルに入っているデータから、を前提にして出力を考えてて、
そこに固定値しかないといっても処理としては関係ないのであった。


ということで、シンプルにFROM句を外す。
`LIMIT 1` も `FROM` なしで固定値を出す分には影響ないから外してもよさそう。

```sql
INSERT INTO hoge_history (label)
SELECT CONCAT('exec: ', NOW()) AS label
WHERE NOT EXISTS (
	SELECT 1 FROM hoge_history WHERE timestamp >= SUBTIME(NOW(), '00:15:00') 
);
```

実にしょうもないことで、めちゃくちゃ焦った……。
UnityでVRゲームを緩く作ってみた

#初めに

コロナ自粛中にあまりにも暇であまりにも外に出て鬼ごっこがしたかったので、Oculus Quest（VR-HMD)上で動く、簡単な鬼ごっこゲームを作りました。ゲームプレイ体験記です。

技術的なお話は一切しません。ただただ自己満足の記事です。Qiitaに載せるなよって思われそうですが、許してください。はてなブログみたいなとこでゆるゆるした記事を書きたいのですが~~開設するのがめんどくさいので~~Qiitaに載せちゃいます。
一応宣伝ですが、他にもバイオハザードとかスーパーマリオ~~のパクリ~~を作ったりしてます。

後、この記事の画像は著しく画質が低いですが多分気のせいです
（VRの画面をスマホにミラーリングしてそれを画面収録するという、最底辺の収録法をとったのが理由です）

#鬼ごっこ開始！
![S__11706398.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/e0fe5666-1774-4ed1-b02f-567d624be1d8.jpeg)

今日はこちらのUnity-Chanと鬼ごっこをします。
なぜこの人を選んだかというと、~~実装が簡単~~かわいいからです。

#お手並み拝見

![S__11706405.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/15459c7c-e46b-f863-a8e8-e6638999635b.jpeg)

最初から全力で逃げるため、フィールドの端っこの林の奥に身を潜めることにしました。
この林、密です。

![S__11706406.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/4b511930-56e5-8866-5fbf-f1f83191352a.jpeg)
おや、画面中心あたりに怪しい影が...

![S__11706407.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/bdc73db9-9b62-e663-95cd-79168cedf9d2.jpeg)

すぐにつかまりました。やりますねえ！！！
ソーシャルディスタンス

#もっと込み入ったところに隠れよう
![S__11706402.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/e74193bc-9131-0143-9e24-96656aaeddde.jpeg)
次は街のハズレの物陰に身を潜めます。ここなら大丈夫なはず...


![S__11706403.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/ba22903d-6bd6-6e3b-6fa6-c46c7aa8f4ee.jpeg)
![S__11706404.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/2370c4b5-e3d8-69b3-abe0-38ee9b97c328.jpeg)

まさかの壁をすり抜けて突撃してきましたw
この家にMesh Collider(当たり判定)をつけるの忘れてました
これは緊急事態宣言ですね

#山に逃げよう
![S__11706408.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/28b774bb-c289-465e-2ca5-003ab75d678d.jpeg)
最後の手段として、登山をすることにしました。なぜなら、頑張って山を作ったからです。
ちなみにこの山、VRのハンドトラッキングを利用してボルタリングもできます。
![S__11706409.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/43ad8453-61fd-ade5-8c7a-38ca7911dc75.jpeg)
20秒ほどで登頂しました。眼下には綺麗な街並みが広がっていますね（いいえ）
まあここまで逃げれば大丈夫でしょ
![S__11706411.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/4e527705-17ff-e311-b886-474bc064b3ee.jpeg)
いい山ですね！素晴らしい！！！
![S__11706412.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/aefe4444-ff1b-4084-f13f-de7904c2b566.jpeg)
![S__11706413.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/663eb41d-b03a-c7b0-1907-650254690624.jpeg)
![S__11706414.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/7c5890af-48af-64cb-4da4-55f7e87c5b70.jpeg)
###うわああああああああああああああああああああ
#最後まで見てくれてありがとう
![S__11706415.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/404591/4c2b8323-3b3c-d9f5-3d29-f5d5cff4aa7f.jpeg)

こんな感じでたま〜にゲーム作って遊んでます。
最後まで読んでくださりありがとうございます。
矢印記号(←↓↑→)が0.1秒で打てる方法　　※日本語ローマ字入力時

# 矢印(←↓↑→)を日本語ローマ字入力するとき、私は今まで1秒は必要でした。かつては2秒。でも、0.1秒で入力する方法がありました。
些細なことですが、感動したのでメモ。（常識だったらすみません:bow_tone1:）




## 方法
#### 「 z + l（エル） 」。　あとはEnter。
たったそれだけで 右矢印を打つことができます。

私はかつて、右矢印を入力したいときは　「やじるし」　と打って、変換で右矢印を探してました。
2秒必要でした。

そのあと、同僚に　「みぎ」　と打って、変換で探す方が早いよと教わりました。
1秒になりました。
　

そして今日、 zl と打つだけで右矢印が打てるようになりました。0.1秒しかかかりません。とても感動です。

　



`矢印ショートカット一覧`

|打つローマ字key|出てくる矢印|
|:------------------:|:------------------:|
|zh|←|
|zj|↓|
|zk|↑|
|zl|→|

このほかにも、「z」との組み合わせで、記号が入力できるそうなのですが、私の環境（MacBookPro,英字キーボード,ひらがな入力時）では再現しませんでした。。でも矢印さえ解決されれば満足です！

　


---

(:santa_tone1:振り返り:santa_tone1:)

今回は中国の言語コード(zh)を英字入力で打ち込む際、たまたまローマ字入力になっているまま打ち込んでしまい、
左矢印が出てきて偶然知ることができました。

ショートカットは一度知ったらとても便利で使いまくるのですが、調べるまでになかなか腰が上がらないです。。
でもやっぱり素敵ですね!


以上！



---
### 参考文献
[PCの日本語入力をもっと快適に、Win10標準搭載の「Microsoft IME」徹底活用術](https://xtech.nikkei.com/atcl/nxt/column/18/01212/022500004/?P=2)
[ローマ字入力で矢印「←↑→↓」を簡単に入力する方法](https://keikenchi.com/how-to-enter-arrows-easily-in-roman-character-input)
無料で閲覧出来るHTML/CSS入門講座

どうも、高校生初心者プログラミング学習者 白乃黒子です。今回は僕が勉強しているHTML/CSSの講座についてご紹介させていただきます。
#実際の講座
とにかくサイトだけ聞かせてくれ！あとはいいから！
という方のために講座だけ紹介させていただきます。それはテックアカデミーさんの『はじめてのHTML入門講座』並びに『はじめてのCSS入門講座』です。
こちらはテックアカデミーさんのチャンネルで無料公開をされているものです。
［title］https://www.youtube.com/playlist?list=PLjw-30bsJNVU87F5iCPAW9kB4QDUGQxUG
［title］https://www.youtube.com/playlist?list=PLjw-30bsJNVVa4PuUseJ5YPN1K2dJr041
他にも様々な有益な情報動画があるので是非ご覧になってください。
#なぜ紹介したのか
僕が今日紹介させて頂いたテックアカデミーさん、もしかしたらもう知ってる、当たり前だ と思った方もいたかも知れません。何日か勉強するとテックアカデミーさんの名前はよく聞きます。しかしほんとに初めの時、何を見たらいいか、どこから手を出せばいいかということはほんとに分かりませんでした。とくに無料となると非常に探すのが難しいです。しかし中学生や高校生が親の支援無しに勉強を始めようとするとどうしてもお金が無く探すのは無料教材です。
僕はこの記事を投稿して少しでもそういう学生の手助けになればと思って投稿させて頂きました。
今後も僕がみつけた無料教材は是非とも共有していきたいので、是非ともフォローよろしくお願いします。
ActiveHashでもwhereが使いたい！！

# 結論：できない

なので諦めろ

とは言わない。

苦し紛れだがなんとかなる。安心してくれ

### ActiveHashを定義する

```SpaceType.rb
class SpaceType < ActiveHash::Base
  self.data = [
    {id: 1, name: "会議室"},
    {id: 2, name: "イベントスペース"},
    {id: 3, name: "シェアオフィス"},
    {id: 4, name: "フロア"},
  ]
end
```

(案件の内容がバレる...。)

ここは普通に定義

ここからが本題

idが1と2と3を取得したいときは

```rb
SpaceType.find [1, 2, 3]
```

とすればいい。

出力結果

```rb
[#<SpaceType:0x00007ffb6193ed60 @attributes={:id=>1, :name=>"会議室"}>, #<SpaceType:0x00007ffb6193eab8 @attributes={:id=>2, :name=>"イベントスペース"}>, #<SpaceType:0x00007ffb6193e860 @attributes={:id=>3, :name=>"シェアオフィス"}>]
```

で、自分的に使いたかったのが、selectでの表示の制限

その場合は

```rb
<%= form.select :space_type_id, options_for_select((SpaceType.find [1, 2, 3]).map{|st| [st.name, st.id]}), {include_blank: "選択してください"} %>
```

と書けばOK

![スクリーンショット 2020-06-20 1.08.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/289120/289df69d-1d36-f5a2-1fd5-e34c99bab3e0.png)

無事、絞り込んだ内容だけが表示され、whereと同じ役割を果たすことができました。

---

このほかにもメソッドが定義されれいるので知りたい方は[こちらの記事](https://qiita.com/Toman1223/items/8633142312bfa886d50b)もご参照ください。

### mission complete
仕事は楽しいかね　システム開発

#仕事は楽しいかね
久しぶりに読んで（聴いて）みて
『システム開発に通じる部分がありそう』ということで、心に湧き上がるものをメモメモ。

「仕事は楽しいかね？ 」
https://www.amazon.co.jp/dp/B07CM51G74
ストーリー仕立てになっており非常に楽しく読めますし、量も少ないです。
仕事に疲れてきたときに読むと少し心のゲージが回復できます。

#明日は今日とは違うことをする。変わり続ける。
できるだけネタバレはしたくはないので、
あまり内容は書きませんが最初に読んだときに一番記憶に刻まれた言葉です。

「改善し続ける」ではなく「変わり続ける」というのがいいのだと思います。
「改善」だと常に良い方向にだけ変え続けるイメージですが、
「変わり続ける」というのは、改悪する場合も含めて
いろいろなことを試しながら進めるということかなと感じています。

言い方は悪いですが、
頭でっかちに考えて試しもせずに成功する道だけを探して立ち止まり続けるよりは、
いろいろ考えながらいろいろなものを試し、知識、経験を得て新しいことに挑み続けるほうが、
最終的にはより一歩先に早く進めるのかなと実体験からも感じています。

#試してみることに失敗はない
アジャイルのやろうとしている根幹と上の「変わり続ける」は通じるものがあるかなと考えています。
本の中でも出てきている「試してみること・・・」の思想はアジャイルの中によく溶け込んでいると思っています。

開発の現場では試すことにはコストがかかり、ものによっては一時的な成果、利益への貢献度としては
マイナスに見える試しも実際にはあります。

しかし試したことにより知見が得られ同じ失敗をしなかったり、
より理解が進むことでより効率化できるアイデアが浮かんだりしたことが、
私の経験ではそのようなことがたびたびありました。

ウォーターフォールと呼ばれる開発プロセスとアジャイルは対比するようなものでもないのでしょうが、
過去の経験上、ウォーターフォールのプロセスで設計書を書いているときに
全く試しをせず机上だけで仕上げたものは
実際に開発してみると全然間違ってたりするってことがよくありました。
そうなると設計し直しとなり、予定していた工数では収まらなくなってしまう事態もありました。

設計書を書いてる間はコードを触っちゃいけない、試しちゃいけないというような
思い込みが大きいのかなと思います。

#変わり続ける
改めて本を読んで、今後変わり続ける姿勢を持っていこうと思いました。
飽き性の自分には変化がある方が楽しいですし、忘れずにやっていこうと思います。
Boost.Asioでサーバを実装する際のパフォーマンス改善

# 内容
Boost.AsioでHTTPサーバ処理を実装してみたところ、同じ環境にインストールしたnginxと比較して妙に遅い。メモリをキャッシュしてみたりしても遅い。いろいろ試したところ、io_service(io_context)の使い方に問題があった。

# 解決策
[io_service の使い方](https://amedama1x1.hatenablog.com/entry/2015/12/14/000000_1)にあるように、一つのio_service(io_context)を複数スレッドで使い回すと遅い。

## 実装

最初にlistenしておいて複数のスレッドでacceptする。

~~~C++
    auto endpoint = boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v6(), port);
    acceptor.open(endpoint.protocol());
    acceptor.bind(endpoint);
    acceptor.listen();
~~~

実際に各スレッドでacceptする処理では上記のacceptorから`native_handle()`で取得した値を使えばよい。

~~~C++
    boost::asio::io_context io_context;
    boost::asio::ip::tcp::acceptor acceptor2(io_context);

    acceptor2.assign(boost::asio::ip::tcp::v6(), acceptor.native_handle());
    acceptor2.async_accept(...);
~~~

`boost::asio::io_context`を1スレッドで使うのならstrandを使わなくてもよい。

~~~C++
    int thread_count = std::thread::hardware_concurrency();
    for (int i = 0; i < thread_count; ++i) {
        auto p = std::make_unique<std::thread>([] {
            boost::asio::io_context io_context(1);

            // acceptする

            io_context.run();
            return;
        });
        threads.push_back(std::move(p));
    }
~~~