OmniAICreator/Qiita-1.07M huggingface dataset:
javascript HTML要素の作成、Class、Id、要素の追加、要素の削除、子要素の削除 勉強用

# HTML要素の作成、Class、Id、要素の追加、要素の削除、子要素の削除

# タグを作る

```javascript
document.createElement("タグ名");

const div = document.createElement("div");
const p = document.createElement("p");
const a = document.createElement("a");
```
# 作ったタグにクラスやIDを紐づける

```javascript
div.id = 'id';     //idを付ける
p.className = 'p'; //classを付ける
```
# タグに要素の追加

```javascript
const text = '要素の追加';
div.appendChild(text);
console.log(div);
```

# 指定したHTML要素を削除する
removeメソッドを使って、指定したHTML要素自身を削除。

```javascript
const list_element = document.querySelector(".list");
list_element.remove(); //listで取ってきた要素が全て削除される
```
```html
削除された要素
<!--<ul class="list">-->
<!--<li>テキスト</li>-->
<!--<li>テキスト2</li>-->
<!--<li>テキスト2</li>-->
<!--<li>テキスト3</li>-->
<!--</ul>-->
```

# 指定したHTML要素の子要素を削除する

```javascript
const list_element = document.querySelector(".list");

const remove_element = list_element.removeChild(list_element.firstElementChild);
//list_element要素にある初めの子要素が削除される
```
```html
削除された要素
<ul class="list">
<!--<li>テキスト1</li>-->
<li>テキスト2</li>
<li>テキスト3</li>
</ul>
```

# 指定したHTML要素の子孫要素を削除する
指定したHTML要素の直下にある子要素ではなく、さらに下に位置する子孫要素をピンポイントで削除する場合はquerySelectorメソッドを使う。

```javascript
const list_element = document.querySelector(".list");
list_element.querySelector("li strong").remove();
```
```html
削除された要素
<ul class="list">
    <li>テキスト</li> <!--<strong>1</strong>-->
    <li>テキスト<strong>2</strong></li>
    <li>テキスト<strong>3</strong></li>
    <li>テキスト<strong>4</strong></li>
    <li>テキスト<strong>5</strong></li>
  </ul>
```
# 指定したHTML要素の親要素を削除する
指定したHTML要素の親要素を削除する場合は、parentNodeプロパティとremoveメソッドを組み合わせて行う。

```javascript
const list_element = document.querySelector(".list");
list_element.parentNode.remove();
```
```html
削除された要素
<!--<ul class="list">-->
<!--<li>テキスト</li>-->
<!--<li>テキスト2</li>-->
<!--<li>テキスト3</li>-->
<!--</ul>-->
```

# 指定したHTML要素の隣り合う要素を削除する
指定したHTML要素の隣り合う要素をする場合は、previousElementSiblingプロパティかnextElementSiblingプロパティと、removeメソッドを組み合わせて行う。

previousElementSiblingプロパティは隣り合う1つ前のHTML要素を取得する。
nextElementSiblingプロパティは隣り合う次のHTML要素を取得する。

```javascript
const li_element = document.querySelector("li:nth-child(3)"); //<li>テキスト3</li>の要素を取得

li_element.previousElementSibling.remove();//隣り合う1つ前のHTML要素を取得して削除
li_element.nextElementSibling.remove();//隣り合う次のHTML要素を取得して削除
```
```html
削除された要素
<ul class="list">
<li>テキスト1</li>
<!--<li>テキスト2</li>-->
<li>テキスト3</li>
<!--<li>テキスト4</li>-->
</ul>
```
ニューラルネットワークを誤差伝播で学習するライブラリ「Chainer」を触ってみる

## Chainer概要と体感
・コンテンツを生成するタイプの人工知能として使える


・ニューラルネットワークを誤差伝播で学習するライブラリ

・Chainerは日本製ライブラリ

・環境構築が個人的に大変だった。
→Chainer周りのCUDA(クーダ)やcupy(くーぱい)
とかでなんかいろいろうまくいかず丸一日かかりました(汗)
CUDAはGPU向けの統合開発環境です。
cupyはpythonでよく使われている配列計算ライブラリ

・ちょっと試すだけなら、Colaboratory(完全にクラウドで実行される)
を使えば、はやい。ローカルで試すと学習に超絶時間がかかる。

## Chainerができること
・超解像画像の作成
→解像度の低い画像に対して処理を行なって、高解像度の画像出力を得る技術

・画像の自動生成
→Generative Adversarial Nets(GAN)というデータを生成するタイプの
ニュラルネットワークを使う

・画像のスタイル変換
→教師データと入力画像から画像を出力する、いわゆる画風変換とか有名

・文章の自動生成
→RNN(回帰型ニューラルネットワーク)やマルコフ連鎖を使った方法など

・画像のキャプションの生成(Neurl Image Caption)
→画像認識からさらに進んだもの。写真などの画像に写っているものを、自然な文章で
説明する説明文(キャプション)を生成するニュートラルネットワーク

## どんなことができるのか(文章自動生成)
●RNN
→回帰型ニューラルネットワーク
→音声や動画データが扱えるアルゴリズム
→時間や並びの順番に重要な意味を持つ時系列データを扱うことに適している
→サンプルリポジトリ(https://github.com/yusuketomoto/chainer-char-rnn)

●chainer+RNNを用いた実装の詳しい説明
https://qiita.com/GushiSnow/items/b34da4962dd930d1487a

●マルコフ連鎖
→Mecabを使って複数語からなる接頭語句と接頭語句に続く1語の接尾語に分割して、
オリジナルのテキストの統計に基づいて接頭語句の後ろにくる接尾語をランダムに選び、文章を出力する感じ
→元データを与えてマルコフ連鎖をやることで、元のデータとは異なるが大体意味の通じる
文章を生成することができる。
→ランダムに繋げている感じ
→こっちの方が精度マシだった。。。

●詳しい説明
https://kentarokuribayashi.com/journal/2004/04/15/20040415-1081998210

## マルコフ連鎖で利用するデータ
例) このメールにはありったけの魔力を込めて送る。

Mecabを使って、その単語を1つずつずらしながら3つずつの
塊を作ります。これをDBに登録。このように、3つずつの塊を
作る

| 接頭語句          |       接尾語 |
|:-----------------|------------------:|
| (開始) この             |              魔力 |
| の　魔力           |            。 |
| 送る             |              (終了) |

```
●1行目→ 「接頭語句 + ランダムに選ばれた接尾語」
●2行目→ 「直前の接尾語を含む接頭語句 + その接尾語から
ランダムに選ばれた語」
●3行目→ 「さらにまたその直前の接尾語を
含む接頭語句 + その接尾語から
ランダムに選ばれた語」…というふうに連鎖させていきます。
今回の例文は短いですが本来は当然もっと多くの種類の文章を対象にします。
```

## 出力結果
●学習した文章(中二病でも恋がしたい)

```
世界の果てはすなわちここ！だって地球は丸いもん！
このメールにはありったけの魔力を込めて送る
なかなかやるようデッスね！偽モリサマー
。。。など
```
●出力結果(ちょっと変だけど、それっぽい文章は生成されている)

```
邪王真眼が共鳴している！貴方を見つけるために、
幾星霜(いくせいそう)の時を経て此処(ここ)に来た。
うぅっ目が共鳴している。我の名はモリサマー。
ふっ、馬鹿言うなデス！うぅっ目が共鳴している。
```
●学習した文章(宮沢賢治の「雨ニモマケズ」の漢字バージョン)
雨にも負けず
風にも負けず
。。。など

●出力結果(ちょっと変だけど、それっぽい文章は生成されている)

```
行って看病してやり一日に玄米四合と
褒められもせず日照りの時は涙を流し
風にも夏の暑さにも負けぬ
```

## どんなことができるのか(画風変換)

→用意されているモデルを使うとすぐに動かせます。
●処理の流れ
→元画像から、画像の形状を”ほどほど”に保存しているレイヤーを取得
→スタイル画像から、画像のスタイルを”いい感じ”に表現しているレイヤーを取得
→損失を計算して補佐を生成画像に逆伝播させる(誤差逆伝播法)
→誤差逆伝播法は、教師データと出力されたデータを比較していって、
重みとかバイアスを修正していくやつ。これで、モデルの精度を高めていく

→2つの画像(コンテンツ画像とスタイル画像)を組み合わせることにより、
画風を変換することができる。

●描画の流れ
まずスタイル画像の模様を全体に描いて、それを少しずつコンテンツ画像にマッチするように変化させていくという流れ。
スタイル画像については、後ほど説明があります。
→サンプルリポジトリ(https://github.com/pfnet-research/chainer-gogh)
→(詳しくは) 
https://tech.preferred.jp/ja/blog/chainer-gogh/
https://www.renom.jp/ja/notebooks/tutorial/image_processing/neural-style-transfer/notebook.html

## 組み合わせる画像について
・スタイル画像とは・・・画風となるもの
・コンテンツ画像とは・・・形状が保たれるもの。これをベースに画風を変換したい
![(俺用)「chaienr触ってみた」.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/a179cbf7-79fc-abb8-4180-2cfeb76a6018.jpeg)

## 出力結果(推し注意)
![(俺用)「chaienr触ってみた」.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/4d6aab2a-5a5f-8a6e-2cde-ce16af05ad88.png)

## 感想
●chainerでできることはKerasでもできることが多い

●chainerでやってたら、なんかいろいろうまくいかないということが多かった。

●Keras(Deap learningのラッパーライブラリ)は
直感的にモデルを構築できるので、数学できないマンでもとりあえず動くものが作れる

●Kerasのほうが入門しやすいと思いました
GMOコインの過去取引データを1分足OHLCに集計する

## はじめに
### 目的
[前回](https://qiita.com/RioAki/items/dc9b0fdb63b63a1620b7)は、GMOコインから過去の取引データを取得しました。
今回は、ミリ秒のデータを1分足のOHLCデータ (open, high, low, close) に集計したいと思います。
### 前提
[前回](https://qiita.com/RioAki/items/dc9b0fdb63b63a1620b7)のコードにて、ダウンロードしたCSVを集計対象とします。

## 集計コード
実行すると、1分足で集計されたOHLCデータがone_min.csvが出力されます。

```py
from logging import getLogger,INFO,StreamHandler,FileHandler
import datetime
import traceback
import pandas as pd
import numpy as np

logger = getLogger(__name__)
logger.setLevel(INFO)
fh = FileHandler('one_min.csv')
logger.addHandler(fh)
            
if __name__ == '__main__':
    try:
        # ダウンロードしたCSVファイルの開始日 - 終了日を指定
        start_datetime = datetime.datetime.strptime("2021-04-01 00:00:00", "%Y-%m-%d %H:%M:%S")
        end_datetime = datetime.datetime.strptime("2021-05-01 00:00:00", "%Y-%m-%d %H:%M:%S")
        
        while start_datetime != end_datetime:
            print("converting :", start_datetime)
            year = str(start_datetime.year)
            month = str(start_datetime.strftime('%m'))
            day = str(start_datetime.strftime('%d'))
            filename = year + month + day + '_BTC_JPY.csv'
            
            # 元データ読み込み
            df = pd.read_csv(filename, names=('symbol', 'side', 'volume', 'price', 'timestamp'), skiprows=1)
            volume_values = df.volume.values
            price_values = df.price.values
            timestamp_values = df.timestamp.values
            
            ohlc = { 'open': '', 'high': '', 'low': '', 'close': '', 'volume': '' }
            current_min = -1
            for i in range(0, len(df)):
                price = float(price_values[i])
                volume = float(volume_values[i])
                trade_datetime = datetime.datetime.strptime(timestamp_values[i], "%Y-%m-%d %H:%M:%S.%f")
                
                if trade_datetime.minute == current_min:
                    ohlc['high'] = max(ohlc['high'], price)
                    ohlc['low'] = min(ohlc['low'], price)
                    ohlc['close'] = price
                    ohlc['volume'] += volume
                else:
                    # CSV 出力
                    if current_min != -1:
                        logger.info("{},{},{},{},{},{}".format(trade_datetime.strftime('%Y-%m-%d %H:%M:00'), ohlc['open'], ohlc['high'], ohlc['low'], ohlc['close'], ohlc['volume']))
                    
                    current_min = trade_datetime.minute
                    ohlc['open'] = price # 始値
                    ohlc['high'] = price # 高値
                    ohlc['low'] = price # 安値
                    ohlc['close'] = price # 終値
                    ohlc['volume'] = volume # 取引量
            
            # 1日加算
            start_datetime = start_datetime + datetime.timedelta(days=1)
    except KeyboardInterrupt:
        print("Stop with Keyboard Interrupt.")
    except Exception as e:
        print(traceback.format_exc())
    finally:
        print("All stopped.")
```
GMOコインから取引データをダウンロードする

## はじめに
### 目的
仮想通貨の取引所 GMOコイン から、過去の先物取引データをダウンロードしたいと思います。
### 投稿の意図
他の多くの取引所ではRest APIを用いる事で、ユーザーが指定した形式で集計した取引データの生データを取得出来ます。
しかし、GMOコインでは予め集計された日毎のデータ、且つ、gzファイルに圧縮されたファイルが公開されてます。

私の様に「過去半年間の1分毎に集計された物が欲しい」となった場合、自分で日毎のデータを1つ１つダウンロードし、1分毎データに集計しなければなりません。
この様な問題を抱えているユーザーは他にも居るのではと思い、プログラムを公開する事としました。

## 先物取引データ - ダウンロードコード

start_datetimeとend_datetimeで、開始日/終了日を指定します。取引データをダウンロードしたい期間で置き換えてください。
下記コードの場合、4月～5月のデータがダウンロードされます。
URL の BTC_JPYを任意の通貨で置き換え可能です。

```py
import os
import datetime
import urllib.request
import time
import traceback
import gzip
import codecs

def unzip(filename):
    with gzip.open(filename) as f:
        newname = filename.replace(".gz", "")
        reader = codecs.getreader("utf-8")
        contents = reader(f)
        with open(newname, mode="w", encoding="utf-8", newline="\n") as newf:
            newf.write(contents.read())

if __name__ == '__main__':
    try:
        start_datetime = datetime.datetime.strptime("2021-04-01 00:00:00", "%Y-%m-%d %H:%M:%S")
        end_datetime = datetime.datetime.strptime("2021-05-01 00:00:00", "%Y-%m-%d %H:%M:%S")
        
        while start_datetime != end_datetime:
            print("start donwload :", start_datetime)
            year = str(start_datetime.year)
            month = str(start_datetime.strftime('%m'))
            day = str(start_datetime.strftime('%d'))
            filename = year + month + day + '_BTC_JPY.csv.gz'
            url = 'https://api.coin.z.com/data/trades/BTC_JPY/{}/{}/{}'.format(year, month, filename)
            
            # 日毎の価格データをダウンロード
            urllib.request.urlretrieve(url, filename)
            
            # 価格データを解凍する
            unzip(filename)
            
            # 解凍前のファイルを削除
            os.remove(filename)
            
            # 1日加算
            start_datetime = start_datetime + datetime.timedelta(days=1)
    except KeyboardInterrupt:
        print("Stop with Keyboard Interrupt.")
    except Exception as e:
        print(traceback.format_exc())
    finally:
        print("All stopped.")
```

## おわりに
ダウンロードしたデータの集計コードは[こちら](https://qiita.com/RioAki/items/eb94492be56c8272e1a9)。
ActionView::SyntaxErrorInTemplateの解決

#作業内容#
新規登録、ログインのパスを記述していた

#構文エラー#
記述した後にリロードで確認をしたら

```
ActionView::SyntaxErrorInTemplate in FurimasController#index
```
https://gyazo.com/e2deabd5a357543bb01255a15d1fb144
となっていました

#解決#
構文エラーは単純なものが多いので構文があっている確認をしましょう！
今回はif文を使ったのに<% end %>の記述がなかったのでエラーになりました。
canvasが表示されない時にチェックすること

数年ぶりにフロントを触って色々ど忘れしてます…
初歩的なところでつまづいてしまったので、忘れないようにメモします

## canvasが表示されない時にチェックすること

```
const stage = document.querySelector("canvas");
const ctx = stage.getContext("2d");

this.stage.style.width = width + "px";
this.stage.style.height = height + "px";
this.stage.width = width;
this.stage.height = height;
```

- canvas要素にwidth,heightを指定するときはpxをつける。
- contextにwidth,heightを指定するときはpxをつけない。

自分の場合は↓のようにまとめてpxをつけてしまっていたのでcanvasが表示されなくなっていました。
```this.stage.style.width = this.stage.width = height + "px";
```

おふ…
macOS Catalina に Ruby 2.3.0 を rbenv でインストールする

## 手順
特に難しいことはありません。OpenSSLの1.0系をインストールして rbenv にそれを参照させます

```
brew install rbenv/tap/openssl@1.0
```

OpenSSL をインストールするとコンパイラーや pkg-config に参照させるべきパスを教えてくれるのでそれを環境変数にセットしながら ｒｂｅｎｖ でインストールします

```
LDFLAGS="-L/usr/local/opt/openssl@1.0/lib" CPPFLAGS="-I/usr/local/opt/openssl@1.0/include" PKG_CONFIG_PATH="/usr/local/opt/openssl@1.0/lib/pkgconfig" RUBY_CONFIGURE_OPTS="--with-openssl-dir=/usr/local/opt/openssl@1.0" rbenv install 2.3.0
```

Ruby 2.3.0 縛りの Rails プロダクトを手元で動かす必要があったのでインストールしました。
[2.3系はサポートが終了している](https://www.ruby-lang.org/ja/news/2019/03/31/support-of-ruby-2-3-has-ended/)ので特別な事情が無い限り使わない方が良いですね。
Golang単体テストでstruct中身をassertするファクション

単体テストを書いていますが、どうやってstructの全てのフィールドをassertionする方法をいくつか案考えていました。

struct全体を比較するは `==` と `reflect.DeepEqual`ができると思いますが
- `==`の場合、structにpointerが入るとfalseになる
- `DeepEqual`はtime.Timeの型が入るとnano秒までの同じじゃないとダメらしいです。
- `DeepEqual`の場合はどのフィールドが相違かどうかがわからないです。
- `DeepEqual`はカスタマイズがしにくいです。例えばあるフィールドをassertionがいらないケースもあるかもしれない。

=> `==` と `reflect.DeepEqual`があまりイケてないのでcustomファクションを作りました
まず、このpackageを使う
`github.com/stretchr/testify`

```

func AssertStruct(t *testing.T, expect, actual reflect.Value) {
	typeOfExpect := expect.Type()

	for i := 0; i < expect.NumField(); i++ {
		expectField := expect.Field(i)
		actualField := actual.FieldByName(typeOfExpect.Field(i).Name)

		if expectField.Type().String() == "time.Time" {
			assert.Equal(t, expectField.Interface().(time.Time).Unix(), actualField.Interface().(time.Time).Unix(), fmt.Sprintf("%s should be equal", typeOfExpect.Field(i).Name))
		} else if expectField.Type().String() == "*time.Time" && expectField.Interface().(*time.Time) != nil && actualField.Interface().(*time.Time) != nil {
			assert.Equal(t, expectField.Interface().(*time.Time).Unix(), actualField.Interface().(*time.Time).Unix(), fmt.Sprintf("%s should be equal", typeOfExpect.Field(i).Name))
		} else {
			assert.Equal(t, expectField.Interface(), actualField.Interface(), fmt.Sprintf("%s should be equal", typeOfExpect.Field(i).Name))
		}
	}
}
```
- 基本の処理をStructの全てのフィールドを回して、`expect`と`actual`を比較する。
- time.Timeの型はUnix()でsecondに変換して比較する
- 呼び出す側はこんな感じ: 
`AssertStruct(t, reflect.ValueOf(&expect).Elem(), reflect.ValueOf(&actual).Elem())`
リバーシの操作（縦横） 

https://paiza.jp/works/mondai/a_rank_level_up_problems/a_rank_pincerattack_step2

きちんとメモ取っていこうという構え。
こういうところで「まあ正解したからいいや」と理解をおざなりにすると後の問題で詰まるのだ。

まずは自己流。

```java:Main.java
import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int h, w, y, x;
        String[][] map;

        Scanner sc = new Scanner(System.in);

        h = sc.nextInt();
        w = sc.nextInt();
        y = sc.nextInt();
        x = sc.nextInt();

        map = new String[h][w];

        for(int i=0; i<h; i++){
            String temp = sc.next();
            for(int j=0; j<w; j++){
                map[i][j] = String.valueOf(temp.charAt(j));
            }
        }
        //_____ここまで初期化______

        map[y][x] = "*";

        //上
        for(int i=y-1; i>=0; i--){
            if(map[i][x].equals("*")){
                for(int j=y-1; j>i; j--){
                    map[j][x] = "*";
                }
                break;
            }
        }
        //下
        for(int i=y+1; i<h; i++){
            if(map[i][x].equals("*")){
                for(int j=y+1; j<i; j++){
                    map[j][x] = "*";
                }
                break;
            }
        }
        //右
        for(int i=x+1; i<w; i++){
            if(map[y][i].equals("*")){
                for(int j=x+1; j<i; j++){
                    map[y][j] = "*";
                }
                break;
            }
        }
        //左
        for(int i=x-1; i>=0; i--){
            if(map[y][i].equals("*")){
                for(int j=x-1; j>i; j--){
                    map[y][j] = "*";
                }
                break;
            }
        }

        //_____ここから表示_______
        for(int i=0; i<h; i++){
            for(int j=0; j<w; j++){
                System.out.print(map[i][j]);
            }
            System.out.println("");
        }
    }
}
```

基準点を見て、上→下→右→左、と処理を行っている。
基準点の「一つとなり」から一個ずつ「＊」のマスを探して、行き当たったらそこまでを埋める。
ここはメソッドにした方がよさそうかな？

もーちょっとスマートにできそうなもんだけど、解説（C++）を読み解く元気がないので一旦保留。
「バックエンドエンジニア」という職種を簡単にまとめてみた

　バックエンドエンジニアは「サーバーサイドエンジニア」とも呼ばれます。Webサービスのバックエンド、つまりサーバ側のコンピュータ上で動作するプログラムを作ることが主な業務になります。
　Web系エンジニアの中では最も人数が多く間口の広い職種であること、言語や技術の選択肢が幅広いこと、スキルの掛け算や他の職種との兼務がやりやすいこと、キャリアアップの選択肢が多いこと等が特徴です。
　また業務未経験からWeb系エンジニアにジョブチェンジする方は、最初はこのバックエンドエンジニアの見習い的なポジションからキャリアを開始するケースが多いようです。上記の通り間口が広いので、どの職種が自分に向いているかわからない方はバックエンドエンジニアとしてキャリアを開始するのが無難で良いでしょう。

<h3>仕事内容</h3>
①サーバ構築
 サーバ構築では、WebサーバやDBサーバなど、システムに必要なサーバの設計と構築をおこないます。例えば、Webサービスにおける会員登録や金額計算などのシステム構築が挙げられます。
　こうしたシステムは、ユーザがWebサービスを利用する際には、画面上に表示される指示にしたがって操作を進めていくだけなので、裏側の処理について考えることはほとんどないでしょう。バックエンドエンジニアは、サービスを利用する側からは見えづらいものの、このようなWebサービスには欠かせない非常に重要な仕組みの構築を担っています。

②プログラム開発
　バックエンドエンジニアは、GO、Python、C#、Javaなどのサーバサイドのプログラミング言語を使ってシステム開発をおこないます。プログラミング言語は、システム要件に合わせて変わります。例えば、Windowsサーバで動く場合はC#、AIを使用する場合Python、大人数で開発する場合Java、といった言語が選ばれます。

③保守・運用
　バックエンドエンジニアは、構築したサーバや、開発したプログラムなどの保守や運用を担当する場合もあります。
　完成したシステムは公開され、毎日多くの人に利用されます。利用が進むと、未知のバグが発生したり、仕様の追加、変更なども発生します。こうした要望に応えてシステムをより使いやすい状態に保つのも、バックエンドエンジニアの業務の一つです。

<h3>必要知識</h3>
バックエンドエンジニアには、データベース・Webサーバやアプリケーションサーバ、HTTPプロトコル、APIやクッキーの知識等、様々な知見が必要になります。その中で個人的に重要だと思う内容を3つ紹介します。

<h4>①Webフレームワーク</h4>
　アプリケーションを開発する際は全てのコードを自分たちで書くわけではなく、様々な汎用的な機能がまとめられた「ライブラリ」や「パッケージ」を使用することが一般的です。
　Webフレームワークもそういったライブラリの一種で、Webアプリケーションを開発する際に必要な様々な機能が「雛形」としてまとめられており、エンジニアはその雛形に従ってコードを書くことで効率よく開発作業を進めることができます。
　Webフレームワークには、言語ごとに様々な種類があります。RubyはRuby on Rails、PHPはLaravel、PythonはDjangom等の代表的なWebフレームワークとなります。
　一般的には「MVC」と呼ばれるアーキテクチャのWebフレームワークが多いです。何か一つのWebフレームワークの使い方を覚えれば、他の一つも比較的習得しやすくなります。

<h4>②Webサーバ/アプリケーションサーバ</h4>
　ブラウザやスマホアプリ等のクライアントアプリケーションからHTTPリクエストに対して、何らかの処理を行ってHTTPレスポンスを返すのがWebサーバの役割です。
　この際にクライアントから「CSSファイル/画像ファイル」等の「静的ファイル」をリクエストされた場合は、基本的にはWebサーバ自体がそれらのファイルを返す処理を行いますが、「データベースにアクセスして商品データを取得する」等の「動的な処理」が必要な場合には、「アプリケーションサーバ」に対して処理を依頼して、その処理結果をクライアントに返します。
　アプリケーションサーバは、Ruby on Rails等で作られたWebアプリケーションを実行して、Webサーバに対して実行結果を返すことが役割です。

<h4>③REST API</h4>
 「API」とは「アプリケーション・プログラミング・インターフェイス」の略です。「アプリケーション同士がコミュニケーションするための約束事や取り決め」のことです。
　Webアプリケーションのクライアントやサーバのやり取りのインターフェイスを定義したAPIは「Web API」と言い、その中でも「REST」という設計原則に従って作成されたAPIは「REST API」と言います。
　REST APIを用いることで、APIを利用するサービス開発者の生産性が上がる、サーバ、クライアント間では何も共有されないので負荷に応じたスケーラビリティが向上する、等のメリットが挙げられます。

<h3>参考文献、データ</h3>　
勝又健太著「Web系エンジニアになろう」　https://www.amazon.co.jp/dp/4408339334?tag=note0e2a-22&linkCode=ogi&th=1&psc=1

modis「バックエンジニアとは？」

https://www.modis.jp/staffing/insight/column_87/#:~:text=%E3%83%90%E3%83%83%E3%82%AF%E3%82%A8%E3%83%B3%E3%83%89%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E3%81%AF%E3%80%81%E3%82%B5%E3%83%BC%E3%83%90%E3%82%B5%E3%82%A4%E3%83%89%E5%85%A8%E8%88%AC%E3%82%92%E5%8F%96%E3%82%8A%E6%89%B1%E3%81%86,%E3%81%AA%E3%81%91%E3%82%8C%E3%81%B0%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%9B%E3%82%93%E3%80%82

Qiita「RESTful APIとは何なのか」　
https://qiita.com/NagaokaKenichi/items/0647c30ef596cedf4bf2
【Java】AtCoderのABC-201に参加しました（レート：264→272）。

こんばんは。

2021/5/15に、AtCoderのABC-201に参加しました。
レートは以下の通りとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/402487/2eb1b72d-177b-1890-4c33-e43cd9413938.png)

実は家の用事もあり、AB問題を速攻で解いて切り上げてしまいました。
が、C問題についてのミスが発生しなかった？ので、パフォーマンスは高めでした。
嬉しいようないまいちなような。。
順位は5631 / 8739でした。

###A問題

3つの数列A1、A2、A3が与えられる。
これを、並べ替えることでA3-A2=A2-A1になるか？
3つしか文字列がないので、2重ループにしてチェックするなり、きれいな書き方は色々あったと思うのですが、とりあえず思いついた実装で。
1,2,3だと、以下の組み合わせがあると考えました。

1
2
3

1 
3 
2 

2
3
1

2
1
3

3
1
2

3
2
1

改めて・・これはセンスないですね。

```java

import java.util.Scanner;

public class Main{
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
  int a1 = sc.nextInt();
  int a2 = sc.nextInt();
  int a3 = sc.nextInt();
  
    if((a3-a2)==(a2-a1)||(a2-a3)==(a3-a1)||(a1-a3)==(a3-a2)||(a3-a1)==(a1-a2)||(a2-a1)==(a1-a3)||(a1-a2)==(a2-a3)){
  System.out.println("Yes");
    }else{
  System.out.println("No");
    }
}
}

```

###B問題

N個の山があり、名前はSi、高さはTi。
2番目に高い山の名前を求める。

```java
import java.util.Scanner;

public class Main{
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
  int n = sc.nextInt();
  String s[] = new String[n];
  int t[] = new int[n];
  int max1 = 0;
  int maxno = 1001;
  int maxno2 = 1001;
  for(int i=0;i<n;i++){
  s[i] = sc.next();
  t[i] = sc.nextInt();
    if(max1<t[i]){
      max1 = t[i];
      maxno = i;
    }else{
    }
  }  

  max1 = 0;
  for(int i=0;i<n;i++){
    if(max1<t[i]&&i!=maxno){
      max1 = t[i];
      maxno2 = i;
    }else{
    }
  }  

  System.out.println(s[maxno2]);
}
}

```


###最後に

レート維持の目的だけでも、A・Bだけなら15分くらいで解けるようになってきたので、参加は必ずしようと思います。

今後もがんばります！
ホワイトボードワークショップのコツ

現在私が所属している企業では、転職や別の部署から異動で新しくチームに加わったメンバーは、実務に入る前にチームの旧メンバーや近しいメンバーに向けてホワイトボードを使って、担当するSolutionのポイントを説明することが文化になっています。私はこれまでに見込みのお客様とワークショップを開催した経験がありますが、これまでは事前にGoogle SlideやPower Pointで静的なドキュメントを作成して、作成したドキュメントをワークショップで説明しながら出席者の意見を引き起こすことが中心、ホワイトボードはあくまで補足の説明で利用する程度だったため、ホワイトボードのみでSolutionのポイントを説明することはまだまだ不慣れで日々勉強中です。この記事は、お客様や社内の他のメンバー向けにオンラインホワイトボードワークショップを開催する際のポイントをまとめています。

# 目的と前提条件を明確に
そのワークショップの目的とアジェンダ、前提条件を明確に定義して、ワークショップ開催前の数週間前から招待者全員に周知しておいて、当日になって"このワークショップって何やるんだっけ?"とならないように事前に共有しておきます。これはホワイトボードワークショップだけに限らず、全てのミーティングに共通することかもしれません。お客様から既にヒアリング済の課題や要件がある場合は、事前にホワイトボードに書き出しておいて、ワークショップ中にまたぎぎしないようにしておきます。
<img src="https://i.imgur.com/ONQw2Uy.jpg" width=70%>

# 最終的に描くことを意識する
ワークショップ出席者のタイトルやバックグラウンドに応じて、出席者にもっともスッキリ伝えて行動を引き起こすためにはどんなことを描くべきかを検討して、ワークショップ中に描く最終的なイメージを意識します。本番のワークショップの前に何回か自分だけで練習してみると、本番で慌てずにスムーズに描けると思います。
<img src="https://i.imgur.com/bGqy0l2.jpg" width=70%>

# お客様の課題に沿ったシナリオを設定する
ホワイトボードで説明するシナリオはお客様の課題に沿ったものにします。事前に書き出した課題や要件をポイントしながら、課題や要件をクリアするためのSolutionを順序立てて描いていきます。例えば、下記のホワイトボードには"Key requirements"の1つに"Secure access to all type of applications including TCP/UDP, SaaS apps."とあります。あらゆるタイプのApplicationに安全にアクセスする仕組みを頭の中に描きながら、最もスッキリ伝わる順序でホワイトボードに描いていきます。ポイントはSolutionが持つ全ての機能を事細かに説明しないことです。これはデモにも当てはまることかと思います。
<img src="https://i.imgur.com/ZdTgnhR.jpg" width=70%>

# 質問の回答は端的に
ワークショップの目的の1つに、参加者から質問を引き出して具体的な行動を引き起こすことがあるかと思います。少しでも多くの質問を引き出せたらワークショップは概ね成功と言っても良いかも知れません。質問には可能な限り端的に回答できることも重要です。Yes/Noを問うClosedな質問であれば先にYes/Noと答えて後から理由を説明します。Openな質問であればなるべく手短に答えて、あとから何故そのように考えるのかを付け足すと質問者もQAを聞いている参加者もスッキリするかと思います。

# おわりに
最後までお付き合い頂きありがとうございました。お客様の前でホワイトボードを使って自社のSolutionがお客様のどんな課題を克服してどんな価値を提供できるかをダイナミックに説明するためには、お客様の課題と自社のSolutionを深く理解しなければなりません。特に自社のSolutionについては、ワークショップ中に色々な質問があがるため、Solutionの構造を隈なく理解しておく必要があります。一朝一夕にできることではありませんが、日々意識しながら少しづつホワイトボードスキルを高めていきたいですね。
AMI復元サーバで libMagickCore.so.5: cannot open shared object エラーが出た時の対応

# サーバを一台増やそうと思ってAMIから復元してデプロイしたらエラー

```
LoadError: libMagickCore.so.5: cannot open shared object file: No such file or directory
```

`libMagickCore` がないと言われてしまいます。


## 解決策
これサーバによってインストールされる場所が微妙に異なるので、再インストールしてあげないといけません。

```
bundle exec gem uninstall rmagick
bundle install
```


自分で過去にSlackにエラー対応書いておきましたが、ネット上にもバックアップ。
Macでnode.js関連のものが動かなくなったときの対処

# 経緯
node.jsのツールを使っていたのだが、`brew install git`でgitのバージョンが新しくなるーみたいな情報でやった後、nodeコマンドが使えなくなった。

```sh
% swagger-merger xxxx
dyld: Library not loaded: /usr/local/opt/icu4c/lib/libicui18n.67.dylib
  Referenced from: /usr/local/bin/node
  Reason: image not found
zsh: abort      swagger-merger 
```

# 対応
とりあえずエラーメッセージでググると
https://qiita.com/SuguruOoki/items/3f4fb307861fcedda7a5
が出てきて解決。

以下のコマンドを実行すると直った。

```
% brew upgrade node 
% brew reinstall node
```

# 原因（多分）
macOSでは、libicucore.dylib というライブラリが提供されていて、icu4cをインストールする必要がなくなっているらしいのだが、brewでgitを再インストールしたときに色々ダウンロードしてたから、勢いでicu4cも入れちゃった？
知らんけど。

とりあえず、brewで再度node.jsをインストールすることで、正しいライブラリの参照が作り直されたんだろうな。
多分だけど。
Salesforce_Visual Studio Code環境構築

<P><font color="#0000ff" size="8" face="ＭＳ ゴシック">必要なツールのインストール</font></p>

•<a href="https://code.visualstudio.com/">Visual Studio Code</a>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/6db6d8dc-f9d6-2410-e99f-50628f5e56e5.png)

•<a href="https://www.oracle.com/java/technologies/javase/javase-jdk8-downloads.html">JDK</a>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/714a5f97-cc45-8b4e-0f87-0a2195193564.png)

•<a href="https://cs76.salesforce.com/home/home.jsp">Salesforce CLI</a>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/9bfb9070-17db-623f-b79c-425323dc6141.png)

•<a href="https://marketplace.visualstudio.com/items?itemName=VignaeshRamA.sfdx-package-xml-generator">Salesforce Package.xml Generator Extension for VS Code</a>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/1aabc61c-c86c-5143-07fe-176ce7a6537f.png)



<P><font color="#0000ff" size="8" face="ＭＳ ゴシック">Visual Studio Codeにpluginをインストール
</font></p>
•Salesforce Extension Pack
図例↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/734e6484-d147-24e9-9cb1-6748fd49b235.png)
チョッパーはインストール下のplugin
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/fec258f0-9a76-a687-3b39-39848136c6a5.png)


<P><font color="#0000ff" size="8" face="ＭＳ ゴシック">sfdxコマンド</font></p>
Node.jsをインストールすると同時にnpmもインストールされます。
https://nodejs.org/ja/download/
以下のコマンドをタイプする。

node.jsのバージョンを確認

node --version
ダウンロードしたNode.jsのバージョンと同じ数字が返ってくれば問題なくインストールされている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/35a867ed-d762-125f-a7a7-99d0842e0003.png)

node.jsのバージョン結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/c0182f9c-e1f8-ad3a-40eb-64e879bbd6df.png)


v12.14.1
Node.jsと一緒にnpmもインストールされているのでそちらも確認する。

npmのバージョンを確認
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/0582342e-dbf4-b0e6-bdc8-a77ca2240663.png)

npm --version
npmのバージョン結果
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/87ab2e0f-bfc7-4cb3-8230-5b995d2d5c0b.png)

6.13.4

<P><font color="#0000ff" size="8" face="ＭＳ ゴシック">必要なツールのインストール</font></p>
オブジェクト情報の補完機能
1．Visual Studio CodeのNEW Terminaiに「SFDX:Refresh SObject Definitions」コマンド実行
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/003a938b-59a6-3e26-cc4c-72db1d23d569.png)

2.管理ユーザー権限がありCMDに
1.「sfdx plugin:install @salesforce/plugin-auth@1.4.3」コマンド実行
2.「sfdx update」コマンド実行
3.sfdx plugins:install @salesforce/sfdx-diff
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1479808/9f0c9044-6f50-483a-0580-4f3f52252684.png)

<P><font color="#0000ff" size="8" face="ＭＳ ゴシック">Package.xml　サンプル
</font></p>
https://www.infallibletechie.com/2018/12/packagexml-to-get-all-metadata-using.html
2点間の距離を求める

2拠点間の距離を求める方法を備忘録として残りておきます。  

### 計算で算出する

```php
/** 
 * 変数は下記が入っているものとする。
 * $lat：現在地の緯度
 * $lng：現在地の経度
 * $comparisonLat：距離を比較する緯度
 * $comparisonLng：距離を比較する経度
*/

// 緯度、経度の移動量を計算
$latDistance = $lat - $comparisonLat;
if ($latDistance < 0) {
    $latDistance *= -1;
}
$lngDistance = $lng - $comparisonLng;
if ($lngDistance < 0) {
    $latDistance *= -1;
}
// 緯度位置における経度量を計算
$latitude = 30.9221438 * cos($lat / 180 * pi());
if ($latitude < 0) {
    $latitude *= -1;
}

/**
 * 緯度や赤道での経度の場合0.00027778度 = 30.9221438mになるので
 * 移動量÷0.00027778*30.9221438の値で三角関数を使う
 */
$distance = (int)(sqrt((abs($latDistance / 0.00027778 * 30.9221438) ** 2) + (abs($lngDistance / 0.00027778 * $latitude) ** 2)));
```


### SQLで求める

Laravel8, MySQL8を使用しています。
SQLで計算する場合は経度と緯度を`geometry`型にしておく必要があります。


```php
    /**
     * @return \Illuminate\Database\Eloquent\Builder
     */
    public function newQuery()
    {
        $raw = '';
        foreach ($this->geoFields as $column) {
            $raw .= ' ST_AsText(' . $column . ') as ' . $column . ' ';
        }
        return parent::newQuery()->addSelect('*', DB::raw($raw));
    }

    /**
     * 現在地から〇m以内のデータを返す
     * @param float $lat 緯度
     * @param float $lng 経度
     * @param int $distance 距離
     * @return mixed
     */
    public function getData(float $lat, float $lng, int $distance)
    {
        return $this
            ->query()
            ->addSelect(DB::raw("ROUND(
                ST_LENGTH(
                    ST_GeomFromText(
                        CONCAT(
                            'LineString( " . $lat . " " . $lng . " , ', ST_X(position), ' ', ST_Y(position), ')'))) * 111000) AS distance "))
            ->whereRaw("ROUND(
                ST_LENGTH(
                    ST_GeomFromText(
                        CONCAT(
                            'LineString( " . $lat . " " . $lng . " , ', ST_X(position), ' ', ST_Y(position), ')'))) * 111000) < " . $distance)
            ->orderBy('distance')
            ->get();
    }
```
検定・推定時に使用するpythonのコード

※随時更新

<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->

<!-- code_chunk_output -->

- [正規分布、標準正規分布](#正規分布-標準正規分布)
  - [scipy.stats.norm](#scipystatsnorm)
  - [scipy.stats.norm.ppf](#scipystatsnormppf)
  - [scipy.stats.norm.cdf](#scipystatsnormcdf)
- [T分布](#t分布)
  - [scipy.stats.t](#scipystatst)
  - [scipy.stats.t.ppf](#scipystatstppf)
  - [scipy.stats.t.cdf(vals,df=)](#scipystatstcdfvalsdf)
- [χ二乗分布](#χ二乗分布)
  - [scipy.stats.chi2(df)](#scipystatschi2df)
  - [scipy.stats.chi2(df).ppf(q, df, loc=0, scale=1)](#scipystatschi2dfppfq-df-loc0-scale1)
  - [scipy.stats.chi2.pdf（x、df、loc = 0、scale = 1）](#scipystatschi2pdfx-df-loc-0-scale-1)
- [F分布](#f分布)
  - [scipy.stats.f.pdf(x, dfn, dfd, loc=0, scale=1) # Probability density function.](#scipystatsfpdfx-dfn-dfd-loc0-scale1-probability-density-function)
  - [scipy.stats.f.cdf(x, dfn, dfd, loc=0, scale=1) # Cumulative distribution function.](#scipystatsfcdfx-dfn-dfd-loc0-scale1-cumulative-distribution-function)

<!-- /code_chunk_output -->

## 正規分布、標準正規分布
### scipy.stats.norm
### scipy.stats.norm.ppf
用途:100p%点を求め棄却域を調べるとき

ss.norm(0,1).ppf(0.95)
1.6448536269514722


### scipy.stats.norm.cdf
 Cumulative distribution function.

```
平均0、分散1と指定して標準正規分布を扱うことができる。
ss.norm(0,1).cdf(x=5.0)

1-ss.norm(0,1).cdf(x=5.0)でp値を求められる。
```
## T分布
### scipy.stats.t
### scipy.stats.t.ppf
用途：100p%点の確認
print(ss.t(9).ppf(0.95))

### scipy.stats.t.cdf(vals,df=)
用途：累積確率の確認

```
1 - ss.t.cdf(x=1.5811388300841895,df=9)
```

## χ二乗分布

### scipy.stats.chi2(df)

### scipy.stats.chi2(df).ppf(q, df, loc=0, scale=1)

#### 自由度nのχ二乗分布のパーセント点の出し方

```
1,2どっちの書き方でも同じ
1
ss.chi2(9).ppf(0.025) # 2.7003894999803584

2
from scipy.stats import chi2
df=1
# 下側から自由度１のχ二乗分布の累積確立95%点を求めた
chi2.ppf(0.95, df)

# 下側から自由度10のχ二乗分布の累積確立95%点を求めた
df=10
chi2.ppf(0.95, df)
>>> 18.307038053275146

```

### scipy.stats.chi2.pdf（x、df、loc = 0、scale = 1）
確率密度関数
np.linspace使ってパーセント点の配列を求めて、それらのパーセント点に対して確率関数を出す。ちょっとだけめんどくさい。

```
fig, ax = plt.subplots(1, 1)
df = 10
x = np.linspace(chi2.ppf(0.01, df),
                chi2.ppf(0.99, df), 100)
ax.plot(x, chi2.pdf(x, df),
       'r-', alpha=0.7, label='chi2 pdf') # alpha = 
```

## F分布

### scipy.stats.f.pdf(x, dfn, dfd, loc=0, scale=1) # Probability density function.
用途：確率密度関数を確認したい時など

```
import scipy.stats as ss

d1 = 3
d2 = 100

x = np.linspace(-1,5, 1000)

plt.plot(x, ss.f(d1,d2).pdf(x), color="black")

plt.show()

```
### scipy.stats.f.cdf(x, dfn, dfd, loc=0, scale=1) # Cumulative distribution function.
用途：自由度m,nのF分布に従う統計量F値のp値を確認したい時等

Cumulativeなので、F値以下が起こる確率の累積を計算する。なのでp値を求めたいときは
$$1-p(X≤F)$$


```
pval=1- ss.f.cdf(x = 10,  dfn=3, dfd=6) #x=p値,f値なのに引数がxなのが紛らわしいので注意
print(pval)
0.00947164803029854
```
画像アプリケーションに対するDatabricksリファレンスソリューション

[Reference solution for image applications \| Databricks on AWS](https://docs.databricks.com/applications/machine-learning/reference-solutions/images-etl-inference.html) [2022/5/23時点]の翻訳です。

> [Databricksクイックスタートガイド](https://qiita.com/taka_yayoi/items/125231c126a602693610)のコンテンツです。

本記事と関連ノートブックは、数多くの実世界の画像アプリケーションで用いられている一般的な設定に基づく分散画像推論モデルに対するリファレンスソリューションを説明するものです。ここでは、オブジェクトストレージに大量の画像を格納し、場合によっては継続的に新たな画像が登録されていくことを前提としています。あなたは、画像分類、物体検知のためのトレーニング済みのディープラーニング(DL)モデル、例えばプライバシー保護のためにユーザーがアップロードした画像から人間を検知するためのMobileNetV2をいくつか持っており、格納された画像に対してモデルを適用したいと考えています。

モデルを再トレーニングし、以前計算した予測結果をアップデートするかもしれません。しかし、多くの画像をロードし、DLモデルを適用することは、I/O、計算の負荷がかかるものです。幸運なことに、推論のワークロードは驚くほど並列化されたものであり、理論上は容易に処理を分散することができます。本ガイドにおいては、以下の二つのステージから構成される実践的なソリューションをウォークスルーします。

1. オートローダーによるDelta Lakeへの画像ETL
1. pandas UDF(ユーザー定義関数)による分散推論の実行

# オートローダーによるDelta Lakeへの画像ETL

トレーニング、推論タスクを含む画像アプリケーションにおいては、[オートローダー](https://qiita.com/taka_yayoi/items/df143647dcf5942b51c6)を使用して画像をDeltaテーブルにETLすることをお勧めします。オートローダーを用いることでデータ管理を容易にし、継続的に投入される画像を自動で処理することができます。

## 画像データセットをDeltaテーブルにETLするサンプルノートブック

[画像データセットをDeltaテーブルにETLするサンプルノートブック](https://docs.databricks.com/_static/notebooks/deep-learning/dist-img-infer-1-etl.html)

# pandas UDFによる分散推論の実行

以下のノートブックでは、リファレンスソリューションをデモするために、PyTorchとTensorFlow tf.Kerasを用いています。

## PyTorchとpandas UDFによる分散推論ノートブック

[PyTorchとpandas UDFによる分散推論ノートブック](https://docs.databricks.com/_static/notebooks/deep-learning/dist-img-infer-2-pandas-udf.html)

## Kerasとpandas UDFによる分散推論ノートブック

[Kerasとpandas UDFによる分散推論ノートブック](https://docs.databricks.com/_static/notebooks/deep-learning/dist-img-infer-3-keras-udf.html)

## 制限

大容量の画像ファイル(平均画像サイズが100MB以上)の場合は、Deltaテーブルにはメタデータ(ファイル名の一覧)のみを格納し、必要な際にはパスを用いてオブジェクトストレージ上の画像を読み込むことをお勧めします。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
TkinterでDB入出力アプリ

できる範囲で無駄を削った，入力をdbに出力するアプリケーション
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/412006/3b5e6feb-990d-f075-9efb-9592f58a645f.png)

ソースコードはこちら

https://github.com/Tshino118/ListMaker


#目的
Python上でのSQLへのデータ保存のやり方について学ぶために作成した．

#__init__.py
setpu.pyを呼び出している．これによってわざわざsetup.pyを走らせなくとも初期設定を行うことができるらしい．

#setup.py
sqlファイルの作成を行う．テーブル名はEnglish, 属性名はSentence，Descriptionを定義している．

#ListMaker.py
メインのアプリケーション．Tkinterのレイアウトが大半を占めている．setup.pyをインポートに記述することでsetup.pyを走らせることができる．

#db2csv.py
データベースをCSVとして出力する．ListMakerに組み込んでも良かったが，何度も使うわけではないし面倒だったのでそのままにしている．

#あとがき
新たな発見もあったので頃合いをみて検索機能等も追加していきたい．
【JavaScript】記述方法まとめ

# JavaScriptの記述方法
- HTML内外への記述方法
- コメントアウトの記述方法
- 変数の記述方法

##HTML内外への記述方法
###1.HTMLのbody内に記述
＜script＞＜/script＞で囲って記述する。

####メモ
短い記述や、動作確認の際に最適。
複数ファイルで同じJavaScriptを使いたい場合は非効率なので、2番の方法の方が良い。


例）

```html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>HTML内に記述</title>
</head>
<body>
<h1>テキスト</h1>

<!--ここから-->
<script>
  //JavaScript記述
</script>
<!--ここまで-->

</body>
</html>
```

###2.拡張子.jsの外部ファイルに記述
htmlのhead内に＜script src="リンク先とファイル名.js"＞＜/script＞で追加する。

####メモ
複数のJavaScriptファイルがある場合は、上から順番に実行される。順番を間違えると、思ったように動作しない場合があるので注意。

例）

```html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>拡張子.jsの外部ファイルに記述</title>

<!--ここから-->
  <script src="ファイル名.js"></script>
<!--ここまで-->

</head>
<body>
<h1>テキスト</h1>
</body>
</html>
```

##コメントアウトの記述方法
1行の時は先頭に//をつける
複数行の時は/**/で囲む

例）

```html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>コメントアウトの記述方法</title>
</head>
<body>
<h1>テキスト</h1>

<!--ここから-->
<script>
//　1行のコメントアウト

/*
複数行の
コメントアウト
*/
</script>
<!--ここまで-->

</body>
</html>
```

##変数の記述方法
###命名規則
・変数の役割を表す簡潔な英語名にする
・単語のつなぎ目は頭文字を大文字にすると見やすい
・予約語は利用できない

>予約語|MDN　https://developer.mozilla.org/ja/docs/conflicting/Web/JavaScript/Reference/Lexical_grammar

###1.constで記述
const 変数名 = 値（データ型）で記述する。

####メモ
変数の中身の変更（再代入）不可！再宣言不可！
→コードの途中で誤って値が変更されてしまうことを防げるので、基本はconstを使う。変数の中身を変更する可能性がある場合はletを使う。

※ブロック｛｝の内外では別の変数として扱われるので、再宣言、再代入が可能。

例）

```html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>constで記述</title>
</head>
<body>
<h1>テキスト</h1>

<!--ここから-->
<script>
const sample1 = 'テキスト';
const sample2 = 123;
const sample3 = true;

//下記のように再代入するとエラーになる
sample1='テキスト2';
</script>
<!--ここまで-->

</body>
</html>
```

###2.letで記述
let 変数名 = 値（データ型）で記述する。

####メモ
変数の中身の変更（再代入）が可能。再宣言は不可！
→変数の中身を変える可能性がある場合にのみ使う。

※ブロック｛｝の内外では別の変数として扱われるので、再宣言が可能。

例）

```html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>letで記述</title>
</head>
<body>
<h1>テキスト</h1>

<!--ここから-->
<script>
let sample1 = 'テキスト';
let sample2 = 123;
let sample3 = true;

//下記のように再代入が可能
sample1='テキスト2';

//下記のように再宣言は不可
let sample1 = 'テキスト2';
</script>
<!--ここまで-->

</body>
</html>
```

###3.varで記述
var 変数名 = 値（データ型）で記述する。

####メモ
変数の中身の変更（再代入）も再宣言も可能。
→変数の値を意図せず上書きしてバグが発生する可能性があるので、基本はconstまたはletを利用したほうがよい。

例）

```html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>varで記述</title>
</head>
<body>
<h1>テキスト</h1>

<!--ここから-->
<script>
var sample1 = 'テキスト';
var sample1 = 123;
sample1='テキスト2';
//再宣言も再代入も可能
</script>
<!--ここまで-->

</body>
</html>
```
sliceメソッドでマイナスを使って末尾から切り取る

#はじめに
超基本的なことですが、全然知らなかったことが恥ずかしいので、こちらに記載しておきます

#問題
以下のようなプログラムを書きなさいという問題において、sliceメソッドの新しい使い方を発見しました

「問題1」
任意の2つの文字列があります。
どちらかの文字列がもう一方の文字列の最後にある場合はTrueを、ない場合はFalseを出力するプログラムを作りましょう。大文字と小文字は区別されません。

例えば、'world'と'helloworld'を渡した場合はTrueとなります。左側の'world'が右側の文字列の最後にあるからです。一方、'world'と'worldhello'とした場合はFalseとなります。右側の文字列には'world'が含まれているものの、文字列の最後に無いためです。

#自身が書いたコード

```ruby
def end_other(a,b)
    a_down=a.downcase
    b_down=b.downcase
    a_len=a_down.length
    b_len=b_down.length
    
    if a_len >= b_len
        tmp=a_down.slice(a_len - b_len ..a_len )
        if tmp==b_down
            return true
        end
        return false
    else
        tmp=b_down.slice(b_len-a_len..b.len)
        if tmp==b_down
            return true
        end
        return false
    end
end

puts "#{end_other("abdcHSasd","asd")}"

```

かなり冗長です。今回、何が問題かと言うと、いちいちどちらの文字列が長いかを判定して、その上で末尾を切り取って、一致するかどうかを確認しています。これでは、かなりコード量が増えてしまいます

#sliceメソッドにマイナスを使って改善した場合

まずは改善した場合を見てみます。かなりスッキリしています。

```ruby
def end_other(a, b)
  a_down = a.downcase
  b_down = b.downcase
  a_len = a_down.length
  b_len = b_down.length
  if b_down.slice(-(a_len)..- 1) == a_down || a_down.slice(-(b_len)..- 1) == b_down
    puts "True"
  else
    puts "False"
  end
end
```

改善したパターンでは、sliceメソッドでマイナス表記を使ったこと、if文の工夫をしました。

sliceのマイナス表記は見慣れないと思いますが、とても簡単な仕組みです。
単純に末尾から数えているだけです。
**ただし、0からではないことに気をつけてください！**

```ruby
string.slice(-5,-1)#末尾から数えて1文字〜5文字目をカット
```
このメソッドを使うとif文もかなりスッキリします。

ちなみに余談ですが今回のようなif文を、AまたはBという覚え方をする方がいますがそれはお勧めしません。
以下のように覚えるとかなり見慣れない表記にもすんなり対応できます（ここの説明は割愛します）

```ruby
if ここの条件部がfalseならば　|| こちらの処理を返す
```
#他のメソッド
end_with?というメソッドもあるみたいです！！
勉強になりますね！
https://docs.ruby-lang.org/ja/3.0.0/method/String/i/end_with=3f.html

#終わりに

基礎の基礎をしっかり押さえることは本当に重要ですね。使えればいいではなく、使ってどんなことができるかや他にどんな使い方があるのかなど深ぼることが重要かと思います。
皆様も普段使われているメソッドを見直してみてはいかがでしょうか
pyenv install 3.4.Xでerror: implicit declaration of function 'getentropy' is invalid in C99

## 概要

表題の通りです。



```bash
$ pyenv install 3.4.3

python-build: use openssl from homebrew
python-build: use readline from homebrew
Downloading Python-3.4.3.tar.xz...
-> https://www.python.org/ftp/python/3.4.3/Python-3.4.3.tar.xz
Installing Python-3.4.3...
python-build: use readline from homebrew
python-build: use zlib from xcode sdk

〜略〜

Last 10 log lines:
Python/random.c:81:19: error: implicit declaration of function 'getentropy' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
        int res = getentropy(buffer, len);
                  ^
Python/random.c:81:19: note: did you mean 'py_getentropy'?
Python/random.c:77:1: note: 'py_getentropy' declared here
py_getentropy(unsigned char *buffer, Py_ssize_t size, int fatal)
^
1 error generated.
make: *** [Python/random.o] Error 1
make: *** Waiting for unfinished jobs....
```



`error: implicit declaration of function 'getentropy' is invalid in C99`というエラーが出ています。



## 解決方法

かなり前に同一のエラーに対してissueが立てられていました。

https://bugs.python.org/issue28676



1. [パッチ](https://gist.github.com/orip/00142a498cf6d0c536b5d38771ad6249)をダウンロード
2. `--patch`パッチを当てて`pyenv install`する

```bash
$ pyenv install 3.4.3 --patch < Python-3.4.3-macos.patch
```
ActiveSupport::Concernを簡単に解説！

# Consernとは何か
モデルやコントローラーの処理において、共通している処理を別ファイルにまとめることでDRYなコードを書くことが出来るものです。
これにより効果的なリファクタリングが可能です！

# 基本的な使い方
以下のようなモデルがあるとします。
同じ処理をしているので、こういった処理に対して`ActiveSupport::Concern`を利用してリファクタリングを行う。

```app/models/user.rb
...
scope :foo, -> {puts 'foo'}
scope :bar, -> {puts 'bar'}
...
```

```app/models/post.rb
...
scope :foo, -> {puts 'foo'}
scope :bar, -> {puts 'bar'}
...
```

sample_concern.rbのようなファイルを作成し、共通した処理を記述する。

```app/models/concerns/sample_concern.rb
module Sample
  extend ActiveSupport::Concern

  included do
    scope :foo, -> {puts 'foo'}
    scope :bar, -> {puts 'bar'}
  end
end
```

そうすると、先程のuser.rbとpost.rbは以下のように簡単に書けます。

```app/models/user.rb
class User < ApplicationRecord
  include Sample
...
```

```app/models/post.rb
class Post < ApplicationRecord
  include Sample
...
```

# 注意点

## ビジネスロジックはモデルに書く
コントローラーに定義されたメソッドを、Concernsにしてリファクタリングしようとした際に、このメソッドがビジネスロジックの場合、良くないとされています。
ビジネスロジックがコントローラ、モデルの両方に存在していると、特定の処理を追いかける際に、色んな場所に探しにいく事になるので、コードの見通しが悪くなります。

## rubocopのClassLength対策としてConcernsは利用しない
Concernsを利用すると、クラス自体の長さを短くすることが出来て、一見綺麗に見えます。
しかし、rubocopのClassLength警告は「該当クラスが責務を持ちすぎである」ということの指摘なので、実質的な責務を減らさないConcernsは意味がありません。
コードも追いづらくなるので可読性を下げる事になります。

## 複雑なビジネスロジックをConcernsにする
includeで手軽にメソッドを増やせるのと、コンテキストを分けることで実装をリファクタリングしやすくなる

# 終わりに
リファクタリングをすることでコードを綺麗にする事が出来るので、良いですよね。
しかし、クラスから単純にConcernsに切り出しても責務が減る事は無いので、責務を減らしたいのであればクラスとして切り出したほうが良いっぽいです。。
最初からConcernsとして切り出そうとするのではなく、まず別の方法も検討してみましょう！

# 参考
[我々はConcernsとどう向き合うか](https://blog.willnet.in/entry/2019/12/02/093000)
VirtualBox の仮想マシンに Tera Term で SSH 接続する手順 (ポートフォワーディング)

## 動作確認環境

- [VirtualBox](https://www.virtualbox.org/wiki/Downloads) 6.1.22
- [Tera Term](https://ja.osdn.net/projects/ttssh2/releases/) 4.105


## 前提

- 仮想マシンのネットワークアダプター 1 の割り当てが NAT に設定されていること。


## VirtualBox ポートフォワーディング設定

1. VirtualBox で設定対象の仮想マシンを選択し, **仮想マシン - 設定** をクリックする。
    - *設定* ウィンドウが開く。
1. 画面左のメニューより, **ネットワーク** をクリックする。
    - *アダプター 1* 設定が表示される。
1. **高度** をクリックし, **ポートフォワーディング** ボタンを押下する。
    - *ポートフォワーディング ルール* ウィンドウが開く。
1. 以下の通りに設定し, **OK** ボタンを押下する。
    - 名前: **ssh**
    - プロトコル: **TCP**
    - ホスト IP: (空欄)
    - ホストポート: **2222**
    - ゲスト IP: (空欄)
    - ゲストポート: **22**
    - ![WS000000.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124605/51c0315c-5ff2-8246-a0ea-046c2addb7fd.png)
1. *アダプター 1* 設定画面に戻るので, **OK** ボタンを押下する。
    - *設定* ウィンドウが閉じる。


## Tera Term による SSH 接続

1. Tera Term を開き, *Tera Term: 新しい接続* 画面で以下の通りに設定, **OK** ボタンを押下する。
    - **TCP/IP** を選択。
    - ホスト: **localhost**
    - ヒストリ: (問わない)
    - サービス: **SSH**
    - TCP ポート: **2222**
    - SSH バージョン: **SSH2**
    - IP バージョン: **AUTO**
    - ![WS000001.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/124605/1ceca45b-3314-2831-ff0f-aa4486fbf451.png)
1. *セキュリティ警告* 画面が表示された場合, **続行** ボタンを押下する。
    - *このホストを known hosts リストに追加する* チェックは問わない。
    - *SSH 認証* 画面が表示される。
1. 認証情報を入力し, **OK** ボタンを押下する。
1. 仮想マシンにログインできることを確認する。


どっとはらい。
サクラエディタ向け Markdown シンタックスハイライト設定

1. [Markdownもどき２](http://sakura.qp.land.to/?Customize%2F%C5%EA%B9%C6%2F77) より, **markdown2.rkw** と **Markdown2.col** をダウンロードする。
1. サクラエディタより, **設定 - タイプ別設定一覧** をクリックする。
1. **追加** ボタンで設定を追加し, **設定変更** ボタンを押下する。
1. [スクリーン] タブ: 設定の名前を **Markdown** とし, ファイル拡張子は **md** とする。
1. [カラー] タブ: **インポート** ボタンを押下し, 先ほどダウンロードした **Markdown2.col** を開く。
1. [ウィンドウ] タブ: 文字コードを **UTF-8** とする。
1. [正規表現キーワード] タブ: **正規表現キーワードを使用する** にチェックを入れ, **インポート** ボタンを押下, 先ほどダウンロードした **markdown2.rkw** を開く。
1. 最後に **OK** ボタンを押下する。


どっとはらい。
【SQL】SELECT文の文法は評価順序を暗記しておけば楽に理解できる

# はじめに
基本情報技術者試験の午後問題、ORACLE MASTER Bronze 12c SQL基礎、Silver DBA 2019、Silver SQL 2019、といった試験ではSQLの文法に関する問題が数多く出題されます。

`FROM`句、`WHERE`句、`GROUP BY`句、`HAVING`句では列別名を使用**できない**[^1]、`ORDER BY`句では列別名を使用**できる**、`WHERE`句や`FROM`句では集約関数を使用**できない**、`ORDER BY`句では一部の集約関数を使用**できる** etc...

といったSELECT文の細かい文法規則を覚えるの、面倒ですよね。
実は上記の文法規則は全て、`SELECT`文が評価される順序を覚えるだけで**暗記が不要**になります。

# SELECT文の評価順序
実際に見ていきましょう。

1. `FROM`
1. `WHERE`
1. `GROUP BY`
1. `HAVING`
1. **SELECT**
1. `ORDER BY`

一見複雑ですが、特に着目すべきは`SELECT`句の評価順です。
手続き型プログラミング言語等に慣れていると、初めに書かれる`SELECT`句が最初に評価されると誤解しがちですが、**実際にSELECT句が評価されるのは終盤**です。列別名を定義するのは`SELECT`句であるため、それ以前に評価される構文内では列別名が使用できません。これが（Oracle DBにおいて）`FROM` 句～`HAVING`句で列別名が使用できない理由です。
また、`WHERE`句が実行されるのは`GROUP BY`句より先なので、`WHERE`句では`SUM`といった集約関数を使うことはできないことがわかります。

その他にも、`SELECT`句で指定した列の全てを`GROUP BY`句で指定するルールや、`WHERE`と`HAVING`のどちらがパフォーマンスが良いか？ といった疑問にも、評価順序の観点から考えることができます。
前者のルールは実際には逆[^2]で、「`GROUP BY`句で集約していない列を`SELECT`句で指定できない」というのが正しいです。集約結果に存在していない列を参照できるわけがないので当然ですね。
また後者のケースでは`GROUP BY`で集約される前に条件分けができる、`WHERE`句のほうが`HAVING`句と比べてパフォーマンスが良いことがわかります。

このように、評価順序を覚えておくだけで多くの文法事項について説明できることがわかります。あとは`GROUP BY`句と`HAVING`句の構文（評価順序ではない）が**順不同**である、というような例外的な事項を抑えておけばよいでしょう。

# まとめ
`SELECT`句の評価順序を覚えておくことで、その場で考えるだけで様々な文法規則を導き出せます。試験では評価順について直接は聞かれないはずですが、コストパフォーマンスの良い学習なので覚えておいて損はないでしょう。

[^1]: Oracle Database 19cの場合。Oracle以外のDBMSには、`FROM`句や`GROUP BY`句で列別名を使用できるものも存在します。実装依存の事項であるため、情報処理技術者試験では問われません。
[^2]: 論理学的には逆というより対偶でしょうか。
(随時更新)母平均・母分散の推定・検定をpythonで行う


<!-- @import "[TOC]" {cmd="toc" depthFrom=1 depthTo=6 orderedList=false} -->

<!-- code_chunk_output -->

- [母分散既知:正規分布に従う統計量を使用した母平均の推定](#母分散既知正規分布に従う統計量を使用した母平均の推定)
  - [ex.問題引用：意味が分かる統計解析p171](#ex問題引用意味が分かる統計解析p171)
- [母分散未知:t分布に従う統計量を使用した母平均の推定](#母分散未知t分布に従う統計量を使用した母平均の推定)
  - [ex.問題引用：意味が分かる統計解析p171](#ex問題引用意味が分かる統計解析p171-1)
- [母分散未知:χ^2分布に従う統計量を使用した母分散の95%信頼区間を推定](#母分散未知χ2分布に従う統計量を使用した母分散の95信頼区間を推定)
  - [ex.問題引用：意味が分かる統計解析p147](#ex問題引用意味が分かる統計解析p147)

<!-- /code_chunk_output -->


#### 母分散既知:正規分布に従う統計量を使用した母平均の検定
##### ex.問題引用：意味が分かる統計解析p171

作成する統計量
$$
\frac{\bar{x}-\mu}{\sqrt{\frac{\sigma^{2}}{n}}}
$$

優位水準5%
母数:μ = 150,s^2 = 2^2 # 工場なら母分散既知でもおかしくない
標本:N = 100,Xbar = 151

帰無仮説：母平均は増加していない。
対立仮説：母平均は増加した。

```
mu = 150 
s2 = 2**2

N = 100
xbar = 151
```
```
x = (xbar - mu) / np.sqrt(s2/N) # 今回は母分散既知なので統計量が正規分布に従う

①xbarの棄却域を調べるアプローチ
mu + 1.96 * np.sqrt(s2/N) # xbarの棄却域、上側5％点
>>>150.392
xbar > 150.392 より帰無仮説は棄却され、対立仮説「母平均が増加した。」が採択される。

②統計量の棄却域を調べるアプローチ。こっちの方が式変形など不要なので、個人的には楽。

ss.norm(0,1).ppf(0.95)
1.6448536269514722

x = xbar - mu / np.sqrt(s2/N) # 今回は母分散既知なので統計量が正規分布に従う
x # 5.0、標準正規分布に従う統計量

これが1.64を超えているので、帰無仮説は棄却され、対立仮説「母平均が増加した。」が採択される。

③棄却域を調べ、統計量が生起するp値まで調べるアプローチ。こっちの方は正確にP(X>5)となる確率まで調べている。この場合棄却域を調べずに関数が出してくれるp値だけを見てもいいのだが、上側5％点を知りたいため結局棄却域を調べている。

ss.norm(0,1).ppf(0.95)
1.6448536269514722

x = xbar - mu / np.sqrt(s2/N) # 今回は母分散既知なので統計量が正規分布に従う
x # 5.0、標準正規分布に従う統計量

# P(X>5.0)(=p値)を調べる。

ss.norm(0,1).cdf(x=5.0)
0.9999997133484281 どうやらこれを1から引けばX>5.0が起こる確率が出てきそう

1 - ss.norm(0,1).cdf(x=5.0)
2.866515719235352e-07
p値が 0.05 より小さいので、帰無仮説は棄却され、対立仮説「母平均が増加した。」が採択される。

```


#### 母分散未知:t分布に従う統計量を使用した母平均の検定
##### ex.問題引用：意味が分かる統計解析p171
優位水準5%

母数:μ = 150,

標本:N = 100,Xbar = 151,s^2 = 2^2(不変分散であることに注意)

帰無仮説：母平均は増加していない。
対立仮説：母平均は増加した。


```
母数、標本について前提を確認
mu = 150

s2_h = 2**2 # こっちは不偏分散
N = 10
xbar = 151


import scipy.stats as ss

②統計量の上側％点と棄却域を調べるアプローチ

# t分布の上側5％点を確認 自由度はn-1
print('t(9)分布の上側5％点', ss.t(9).ppf(0.95))
1.8331129326536335

T=>1.8331129326536335で帰無仮説が棄却される

統計量Tを調べてみる。
T = (xbar - mu) / np.sqrt(s2_h/N) # 今回は母分散未知なので統計量がt分布に従う
T
1.5811388300841895

これは棄却域に入らないため、帰無仮説は受容され、母平均は増加していないことになる。

------------追記------------
P(T>1.5811388300841895)を確認してみる。
1 - ss.t.cdf(x=1.5811388300841895,df=9)
0.07415235368327966
統計量1.5811388300841895は100回標本をとったら7回は観測されるということ

```

#### 母分散未知:χ^2分布に従う統計量を使用した母分散の95%信頼区間の推定
##### ex.問題引用：意味が分かる統計解析p147

作る統計量は
$$
下側5％点\leq\chi^{2}=\frac{(n-1) s^{2}}{\sigma^{2}}\leq上側5％点
$$

だが、pythonは不等式を解けないので、式変形して以下の形に持っていって計算する。

$$
\frac{(n-1) s^{2}}{\chi_{0.975}^{2}(9)} \leq \sigma^{2} \leq \frac{(n-1) s^{2}}{\chi_{0.025}^{2}(9)}
$$


```
import scipy.stats as ss

sample = np.array([184.2,176.4,168.0,170.0,159.1,\
        177.7,176.0,165.3,164.6,174.4,])

s2 = sample.var(ddof=1)
degree_of_freedom = len(sample)-1 #9

# chi^2分布の5%点を調べる
print(ss.chi2(9).ppf(0.025)) # 2.7003894999803584
print(ss.chi2(9).ppf(0.975)) # 19.02276779864163

#上側
print(((len(sample)-1)*s2)/ss.chi2(9).ppf(0.025))
print(((len(sample)-1)*s2)/ss.chi2(9).ppf(0.975))
187.6251555576279
26.634452218681822
```

よって信頼区間は
$$
 26.6344...\leq \sigma^{2} < 187.6251...
$$