OmniAICreator/Qiita-1.07M huggingface dataset:
Hasuraのリレーションシップ（1対1）

## はじめに

以下のゴールを達成するため、本日は Hasuraの リレーションシップを学んでいきます。

今回はHasuraを使って1対1のリレーションを作る方法を見ていきます。

## 最終的なゴール

以下のような構成のアプリを作ることです。

![スクリーンショット 2021-10-18 17.27.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/e8a9a2e1-2723-4fec-77ef-be3b9eefdd81.png)

### 目的

- 仕事で使っている技術のキャッチアップと復習
- 使う可能性がある技術の理解度向上

## Hasuraのリレーションシップ（1対1）

今回説明するHasuraのリレーションシップ（1対1）の概念図です。

![スクリーンショット 2021-10-23 20.42.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/99f00985-49f5-b00b-ead7-9bcda200aa06.png)

これを実際に、テーブルや関連づけやデータを追加することで実現していきます。

やり方の概要を先に伝えておくと

前回やった、1対多の関係をForeign Key で作成して関係の設定を unique 制限をかければ1対1のリレーションシップはできます。

前回👇
https://qiita.com/ryosuketter/items/59a05d4eb5c715287ded

### テーブルの作成とデータの追加

`users`テーブル以外に、`profiles`テーブルを作成します。

![Add_Table_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/5d878d8f-0e72-2eb7-699a-e54835268e19.png)

続いて、データを追加します。

いつものように、「Insert Rows」で2つ作成して、「Browse Rows」で確認します。

![Browse_-_profiles_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/3b059468-b0c7-a350-10fd-feba0913c111.png)

では、次は、`profiles`テーブルと`users`テーブルを1対1で連携させていきます。

### テーブル同士の関連づけ

`profiles`テーブルと`users`テーブルを1対多の関係で関連づけます。

`users`テーブルに行って、Modifyを選んで、新しいカラムを作成します。

![Modify_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/6a3865be-253b-ea6e-4038-36396b7167d2.png)

#### Foreign Keyの設定

Add Foreign Keysしてください。

![Modify_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/c89a5a80-0608-da82-b3a6-f970784aaab3.png)

#### Relationshipsタブにいきます

**users**

![Relationships_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/239d9a1f-860c-865f-0924-1c08d1a0aead.png)

Nameは`profile`のまま、Saveします。

**profiles**

![Relationships_-_profiles_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/6120791c-8bbf-99c0-d625-b181749f7a53.png)

Nameは`user`のまま、Saveします。

これで、`profiles`テーブルと`users`テーブルを1対1で連携できました。

データを追加していきましょう。

#### データの追加

### usersテーブルから見ると

![Browse_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/f2637cf6-5eae-9a2b-35a5-e50f527f905e.png)

- `users.name` = john の `profile_id` に `profiles.nickname` = Jon の `profiles.id` を
- `users.name` = bob の `profile_id` に `profiles.nickname` = bobby の `profiles.id` を

割り当てていきましょう

![Browse_-_users_-_Data___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/30f6843d-d69c-835e-0d7d-4a9412aa010c.png)

関連づけました。

### クエリで確認しましょう

#### usersから見る

![API_Explorer___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/96e7986b-d18e-0796-a44b-fc4c64fa3fe6.png)

#### profilesから見る

![API_Explorer___Hasura.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14191/88875df7-b5c1-d998-69e3-d272c218091f.png)

本日は以上です。

次回以降で、また別のHasuraのリレーションシップ（多対多を）見ていきます！

## 参考

https://hasura.io/learn/ja/graphql/hasura/relationships/

## アウトプット100本ノック実施中

https://qiita.com/ryosuketter/items/713474dbd009870e4103
OpenCVのinpaintは32-bit floatを入れても動く

OpenCVのinpaintは便利ですがuint8の画像でしか動かないと思っていました。
しかしエラーメッセージをよく読むと……

```
    inpainted = cv2.inpaint(src, mask, 3, cv2.INPAINT_TELEA)
cv2.error: OpenCV(4.0.1) C:\ci\opencv-suite_1573470242804\work\modules\photo\src\inpaint.cpp:756: error: (-210:Unsupported format or combination of formats) 8-bit, 16-bit unsigned or 32-bit float 1-channel and 8-bit 3-channel input/output images are supported in function 'icvInpaint'
```

実は16-bit unsigned shortや32-bit floatを入れても動くらしいです。ただし1チャンネル限定。

issueによると2017年にはこの仕様になっていたらしい。知らなかった。
https://github.com/opencv/opencv/pull/8776

issueによるとinpaintはあんま使われてない＆テンプレートで書かれているのでバイナリが肥大化することを避けたい、という判断で限定された型とチャンネル数の組み合わせしかサポートされていないらしい。
いやinpaintはよく使うので全部の型をサポートしてほしいんですが……

チャンネル毎にループを回せば複数チャンネルの画像も扱えます。pythonで書くとこんな感じ。

```python
# cv2.INPAINT_TELEA: image should be 0.0-255.0 range
# https://github.com/opencv/opencv/blob/9267536feefa0e0c5ca6f1113b6e22debe438ddf/modules/photo/src/inpaint.cpp#L403
# cv2.INPAINT_NS: accept float range
# https://github.com/opencv/opencv/blob/9267536feefa0e0c5ca6f1113b6e22debe438ddf/modules/photo/src/inpaint.cpp#L514
def inpaint_float32(image, mask, radius=3, method=cv2.INPAINT_NS):
    image = image.astype(np.float32)
    inpainted = np.zeros(image.shape, dtype=np.float32)
    if len(image.shape) == 2:
        inpainted = cv2.inpaint(image, mask, radius, method)
    elif len(image.shape) == 3:
        _, _, ch = image.shape
        # apply inpaint per channel
        # because only 1 channel input is supported for float 
        for i in range(ch):
            inpainted[..., i] = cv2.inpaint(
                image[..., i], mask, radius, method)
    else:
        raise Exception('image shape is not supported')
    return inpainted
```

gistにも載せました。
https://gist.github.com/unclearness/2397f8b893d46aef76dbee203b2bbbd1

OpenCVに実装されている手法はチャンネル毎に独立にinpaintするのでアルゴリズム的にはおそらく問題ないです。

`INPAINT_TELEA`はインペイント処理の最後でuint8にキャストしているので入力が[0.0 255.0]のレンジでないと結果がおかしくなるようです。普通にfloatにキャストすればいい気がするのですがアルゴリズム的に問題があるのかもしれない。
https://github.com/opencv/opencv/blob/9267536feefa0e0c5ca6f1113b6e22debe438ddf/modules/photo/src/inpaint.cpp#L403

`INPAINT_NS`はfloatの範囲なら問題なく動きそうです。未確認ですが入力が負でも扱えると思います。
https://github.com/opencv/opencv/blob/9267536feefa0e0c5ca6f1113b6e22debe438ddf/modules/photo/src/inpaint.cpp#L514
野球の勝敗おみくじ

#きっかけ
投稿主は野球が好きです。
特にヤクルトスワローズが好きです。

セリーグのペナントレースでヤクルトか、阪神タイガースが優勝争いを繰り広げられています。
※2021年10月23日の時点

ヤクルトが残り5試合で首位、マジックナンバー３。
タイガースが残り3試合で2位、ゲーム差0.5。

ここ数試合、運の悪い負け方をするヤクルト、そして勢いのあるタイガース。
正直気が気ではない状態なので、神頼み状態です。

そこでなんとなく気を紛らわす(？)ために、
簡単なコードでおみくじで今日の勝敗でも占ってみようと考えました。


#コード
```C#:test.py
# -*- coding: utf-8 -*-

//GUIを使うためにtkinterをインポート
import tkinter
import random

//勝敗をランダムで決める
def click_btn():
    label["text"]=random.choice(["勝つ","負け","引き分け"])
    label.update()

//ウインドウオブジェクト
root = tkinter.Tk()
//タイトル
root.title("勝敗占い") 
//ウィンドウサイズの固定
root.resizable(False,False)
//キャンバスの部分作成
canvas = tkinter.Canvas(root,width=800,height=600)
//キャンバスの配置
canvas.pack()
//背景画
gazou = tkinter.PhotoImage(file="tsubakuro.png")
//画像の表示設定
canvas.create_image(400,300,image = gazou)

//勝敗の表示
label = tkinter.Label(root,text="？？",font=("Times New Roman",60),bg="white")
label.place(x=380,y=60)

//ボタンの配置と文字の文字の表示
button = tkinter.Button(root,text="今日の勝敗は？",font=("Times New Roman",36),command=click_btn,fg="red")
button.place(x=360,y=400)

//ウインドウの表示
root.mainloop()
```

#結果
スタート前
<img width="400" alt="gazou1.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/c40725af-354f-bb34-ca50-0e8f8f552fd1.jpeg">
勝ち
<img width="400" alt="gazou2.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/7e47fd43-b59c-c601-acfb-67201d8251e3.jpeg">
負け
<img width="400" alt="gazou3.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/b44bde9e-8503-9d5c-dca1-af8c0ad6a010.jpeg">
引き分け
<img width="400" alt="gazou4.JPG" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/273331/fb949e4c-7047-3679-d9d8-ddb2e2609725.jpeg">

#まとめ
自分でボタン押して思ったのことは、少し負けが多いんですけど…。

あとマスコットキャラクターはかわいい。
スポーツは見ていて楽しい。

画像を変えたらどのスポーツでも利用できますね。

###参考文献
Pythonでつくるゲーム開発入門編
https://www.amazon.co.jp/dp/B07VD7BTRN/ref=cm_sw_r_tw_dp_58F9BJ8SQ7756E4WDD2T
[PHP]標準入力する

#➀1行だけの場合
##入力値
```
1 2
```
##コード
```php
$num = trim(fgets(STDIN));
echo $num;
```
##結果
```
1 2
```

#➁複数行の場合
##入力値
```
1 2
3 4
5 6
```

##コード
```php
while($num = trim(fgets(STDIN))){ 
    echo $num,PHP_EOL;            
    #PHP_EOLで改行
}
```

##結果
```
1 2
3 4
5 6
```

#➂半角スペース等で区切られた文字列が複数行ある場合

##入力値
```
0 1 2 3 4
5 6 7 8 9
```

##コード
```php
while($num = trim(fgets(STDIN))){ 
    $array[] = explode(" ", $num);
}

#出力
var_dump($array);
```
1．explode関数を使用して、入力値を半角スペースで分割する
2．分割した入力値を配列に入れていく
##結果
```
array(2) {
  [0]=>
  array(5) {
    [0]=>
    string(1) "0"
    [1]=>
    string(1) "1"
    [2]=>
    string(1) "2"
    [3]=>
    string(1) "3"
    [4]=>
    string(1) "4"
  }
  [1]=>
  array(5) {
    [0]=>
    string(1) "5"
    [1]=>
    string(1) "6"
    [2]=>
    string(1) "7"
    [3]=>
    string(1) "8"
    [4]=>
    string(1) "9"
  }
}
```
【Vue.js】算出プロパティとメソッドの比較

#はじめに
こんにちは！
今回は【Vue.js】算出プロパティとメソッドの違いについてアウトプットしていきます！

#算出プロパティとメソッドの違いとは
**算出プロパティとメソッドの違いは３点あります。**
①算出プロパティ　cpmputed　・・・ （）不要
　        　　　   メソッド　methods・・・　（）必要

②getter,setter
・cpmputed・・・getter,setterが必要
・methods・・・getterのみ必要

③キャッシュ
・cpmputed・・・される
・methods・・・されない


#書き方・解説
##①プロパティとメソッド

```HTML:HTML
  <p>
  {{ reversedMessage }}
  <!-- プロパティ -->
  </p>
  <p>
  {{ reversedMessageMethod() }}
  <!-- メソッド -->
  </p>
```
```Vue.js
  data: {
    message: 'Hello Vue.js!'
  },
  computed: {
    reversedMessage: function() {
      return this.message.split('').reverse().join('')
    }
  },
  methods: {
    reversedMessageMethod: function() {
      return this.message.split('').reverse().join('')
    }
  }
```





#まとめ
上記のようにプロパティには（）不要、メソッドには（）必要というふうになります。
②getter,setter、③キャッシュについては別記事で解説します。

#最後に
今回は算出プロパティとメソッドの違いについてアウトプットしました。
今回の記事を読んで質問、間違い等あればコメント等頂けると幸いです。

今後ともQiitaにてアウトプットしていきます！

最後までご愛読ありがとうございました！
MacからDockerのMySQLにgzip圧縮のダンプを流すコマンド

## なぜこの記事を書いたか
Macだとzcatじゃなくてgzcatだよっていう話と、
mysqlのpオプションをパイプで使うと怒られるよっていうのを忘れないため。

## 前提
- ディレクトリなどの名称は仮称

## コマンド

流す対象のDBやユーザをまだ作ってなければ作成する

```sh
$ mysql -p -h 127.0.0.1
> CREATE DATABASE sample CHARACTER SET utf8mb4;
> GRANT ALL ON *.* TO 'admin'@'%' WITH GRANT OPTION;
> CREATE USER 'admin'@'localhost' IDENTIFIED BY 'admin';
> CREATE USER 'admin'@'127.0.0.1' IDENTIFIED BY 'admin';
> FLUSH PRIVILEGES;
```


ダンプを流し込む

```sh
$ export MYSQL_PWD=admin
$ gzcat ./infra/mysql/dump/sample.dump.gz | mysql -u admin -h 127.0.0.1 sample
```

### ちなみにS3から流す場合

S3にあるのが生データならこう

```sh
$ export MYSQL_PWD=admin
$ aws s3 cp s3://バケット名/dump/20211023/sample.sql - | mysql -u admin -h 127.0.0.1 sample
```

S3にあるのがgzipならたぶんこう

```sh
$ export MYSQL_PWD=admin
$ aws s3 cp s3://バケット名/dump/20211023/sample.sql.gz - | gzcat | mysql -u admin -h 127.0.0.1 sample
```
STM32CubeMXで生成したコードのDMAがうまく機能しなかった時の確認と対処

UART、ADC諸々のDMAがうまく動かない時の対処法メモ

# 結論

**CubeMX v6.2.1現在の生成コードが間違ってる場合がある。**

MCUや使用するペリフェラルによって、イニシャライズの順序が変わる場合があります。
この時DMAのInitの順番が変わると、DMAの動作が正常にならない場合があります。

生成されるダメなInitコードの例

```
  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_DAC1_Init();
  MX_FDCAN1_Init();
  MX_SPI2_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();

  //DMA初期化がペリフェラル初期化の前にいたり後ろにいたりする
  MX_DMA_Init();

  MX_I2C2_Init();
  MX_USART2_UART_Init();
```

`MX_DMA_Init();`がDMAを使いたいペリフェラルの初期化よりも後に実行されると**その前に初期化が実行されたペリフェラルでDMAが正常に機能しない**。
上の場合だとADC～USART1までのDMAが正常に機能しない可能性があります。

# 修正する

DMAの初期化を、ペリフェラルの前に移動します。

```
  /* Initialize all configured peripherals */  
  MX_GPIO_Init();

 //DMAを使いたいペリフェラル初期化よりも前に持ってくる
  MX_DMA_Init();

  MX_ADC1_Init();
  MX_DAC1_Init();
  MX_FDCAN1_Init();
  MX_SPI2_Init();
  MX_TIM2_Init();
  MX_TIM3_Init();
  MX_USART1_UART_Init();
  MX_I2C2_Init();
  MX_USART2_UART_Init();
```

#何が起きてるのか

## コードの話

DMA_Initの中には、クロックの設定とNVIC割り込みに関する初期化が入っています。

```
  /* DMA controller clock enable */
  __HAL_RCC_DMA1_CLK_ENABLE();

  /* DMA1_Channel1_IRQn interrupt configuration */
  HAL_NVIC_SetPriority(DMA1_Channel1_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ(DMA1_Channel1_IRQn);
```

そのためペリフェラル初期化→DMA初期化の順に行ってしまうと、DMAの各種設定が反映されません。

## レジスタの状態

例としてUARTのDMA(DMA1 Ch5)を、サーキュラモード、メモリインクリメントで設定します。

### 正しい順序で初期化を行った場合

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995651/f6a46fc3-4763-5f36-e24d-d586b117e7f5.png" width="400">

CIRC(Circular)とMINC(Momery increment)の設定が反映されています。

### 逆の順序で初期化を行った場合

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1995651/4600fefc-6ad4-a1bc-26df-6879d57e1def.png" width="400">
この2つの設定が反映されていないのが見て取れます。
コマンドラインツール「mpx-cli」を利用してPDFファイルをMarkdownやDocxファイルへ変換する方法

# コマンドラインツール「mpx-cli」を利用してPDFファイルをMarkdownやDocxファイルへ変換する方法

### 概要
Mathpix Snipの機能をターミナルから実行できるコマンドラインツール「mpx-cli」を利用することで、編集に手間のかかるPDFファイルを簡単に編集可能なMarkdownやDocxファイルへ変換する方法を書いていきます。

### 目次
- 実行環境
- `HomeBrew`のインストール
- `npm`のインストール
- `mpx-cli`のインストール
- Mathpix Snipのアカウント登録とログイン
- 使い方
- 終わりに

### 実行環境
- MacBook Air (M1, 2020)
- シェル: zsh

### HomeBrewのインストール
:::note info
Homebrewを既にインストールしている方は飛ばしてください。
:::

[HomeBrew公式サイト](https://brew.sh/)の`Install Hombrew`下のコマンドをターミナル上で実行。

```
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```

途中Enterを押してインストールが進むと追加のコマンドが求められます。
ターミナルに表示されているコマンドを打ち、パスを通しましょう。

```
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/ユーザ名/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
```

最後にHomebrewが正常にインストール及びパスの追加ができているか確認します。

```
brew help
```


:::note warn
コマンドは必ず公式サイトからコピーしましょう。
:::


### npmのインストール

:::note info
npmを既にインストールしている方は飛ばしてください。
:::

Homebrewでnodebrewをインストールするため、以下のコマンドを実行します。

```
brew install nodebrew
```


nodebrewでnpmをNode.js(LTS版)と一緒にインストールするため、以下のコマンドを実行します。

```
nodebrew install stable
```

最新版をインストールしたい場合は`nodebrew install latest`と実行しましょう。

続いて使いたいNode.jsのバージョンを指定する必要があります。
[Node.js公式サイト](https://nodejs.org/en/)からLTS版のバージョンを指定しましょう。

```
nodebrew use v14.18.1
```

下記コマンドを実行すると、currentに使いたいNode.jsのバージョンが表示されているかと思います。

```
nodebrew ls
```

最後にパスを通します。

```
export PATH=$HOME/.nodebrew/current/bin:$PATH
source ~/.zsh_profile
```

下記コマンドを実行し、バージョンが表示されればインストールは完了です。

```
node -v
npm -v
```


### mpx-cliのインストール
npmを使ってmpx-cliをインストールするため、下記コマンドを実行します。

```
npm install -g @mathpix/mpx-cli
```

### Mathpix Snipのアカウント登録とログイン
[Mathpixの登録ページ](https://accounts.mathpix.com/signup)からアカウントを登録しましょう。
メールボックスにMathpixからのメールが届いているのでメールを認証し、ログインしましょう。

:::note info
学生の方はac.jpドメインで登録しましょう。月間無料利用回数が2倍になります。
:::

最後に下記コマンドを実行します。

```
mpx login
```

アカウント登録に利用したメールアドレスとパスワードを要求されるので入力します。パスワード入力中は画面に変更はありませんがそのまま入力しましょう。


### 使い方

詳細な使い方は[README.md](https://github.com/Mathpix/mpx-cli/blob/master/README.md)を参考にしてください。

<iframe width="560" height="400" src="https://www.youtube.com/embed/OTaPlA2-XPo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

PDFファイルを編集可能なファイルへ変換したい場合は下記コマンドを実行すると変換後のファイルがダウンロードされます。

```
mpx convert input-file.pdf output-file.docx
```

ホームディレクトリ以外で実行する場合、上記動画のようにファイルのパスも書きましょう。


### 終わりに

Qiitaへの初めての投稿なので色々と至らぬ点があったと思いますが、最後まで本記事を見てくださりありがとうございました。
Mac BigSurでM5Stamp C3(ESP32 C3)にArduino IDEで書き込みたい

Macbook Air M1(BigSur)

M5Stamp C3に書き込む方法のアナウンスが見つからないのでメモ。

~~ボードマネージャでESP32の「開発版」2.0.0をインストールする。
( https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_dev_index.json )~~
最新版ボードプロファイルではそのままM5Stamp C3が選べるようです。(2021.10.30追記）
![スクリーンショット 2021-10-23 19.10.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521584/38785ede-10f6-8b43-ea37-15cac7fad256.png)


USBシリアルがM5シリーズで今まで使われていたCP2102ではなくCH9102なのでドライバインストールが必要。
https://github.com/Xinyuan-LilyGO/LilyGo-T-Call-SIM800/files/7037260/CH9102_Mac_Driver.zip
をダウンロードする。

中国語のダイアログがでてセキュリティブロックが働くが勇気を振り絞ってセキュリティを解除してインストール

ボードはESP32C3 Dev Module
ポートはwchusbserial****

で書き込みできる。

サンプルコード
https://github.com/necobit/M5StampC3-LEDRandomFade
M5Stamp C3搭載のシリアルLEDをランダムでフェードさせるコード

![B5571D37-D51F-4BB8-867F-97AB692EF462.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521584/4a61c8be-dc62-9752-3d73-30af81cc1a11.jpeg)
![BD7C3462-DB73-4703-B578-2F71119121D3.jpeg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/521584/a55836dd-d51c-f5c2-ea92-a7eedc43c14d.jpeg)
GROVEコネクタをそのままつけると部品やケースの爪部分と
干渉するため後ろ足の部分をニッパーで切り取った。
付けた後にやろうとするとSMD部品を吹き飛ばすので（吹き飛ばした）
先に加工してから取り付けた方が良い。
pythonで天気情報のスクレイピング

#天気予報のスクレイピング
気象情報のデータが必要になったので、「tenki.jp」さんから1時間ごとの温度や湿度やらのデータを取ってきた。

##注意
・スクレイピングを行うためには、法律やWebサイト利用規約を守る。
　公式に提供されているAPIがあるなら、それを利用する方がよい。
・スクレイピングスキル向上を目的でコードを書いたが、
　不正に利用しない、攻撃実験をしないを守っています。
・一部(取ってくるデータの地域など)は〇など記載して伏せます。

##環境
pythonで仮想環境内、beautifulsoup4をインストール(pip、anaconda両方で試しました)。
両方とも仮想環境を作成して行うのがオススメです。
```
pip install beautifulsoup4
```
```
pip install requests
```
または
```
conda install beautifulsoup4
```
```
conda install requests
```

##htmlのクラス
chromeで調べたら下記のようになっていた

時間：hour
気温：temperature
降水確率：prob-precip
降水量：precipitation
湿度：humidity
風速：wind-speed

##コード
```c#:test.py
#-*- coding: utf-8 -*-

import requests
from bs4 import BeautifulSoup

//tenki.jpの1時間ごとの天気予報のURL(〇は伏せています)
url = "https://tenki.jp/forecast/〇/〇/〇/〇/1hour.html"

r = requests.get(url)

bsobject = BeautifulSoup(r.content,"html.parser")
town_1h = bsobject.find(class_="forecast-point-1h")

//時間
hour = town_1h.find(class_="hour")
h_span = hour.find_all("span")
h = [int(h_span[x].string) for x in range(len(h_span))]
print("時間(h)")
print("{}\n".format(h))

//気温
temp = town_1h.find(class_="temperature")
t_span = temp.find_all("span")
t = [float(t_span[x].string) for x in range(len(t_span))]
print("気温(度)")
print("{}\n".format(t))

//降水確率
rainy_p = town_1h.find(class_="prob-precip")
p_span = rainy_p.find_all("span")
p = [p_span[x].string for x in range(len(p_span))]
print("降水確率(%)")
print("{}\n".format(p))

//降水量
rainy_a = town_1h.find(class_="precipitation")
a_span = rainy_a.find_all("span")
a = [a_span[x].string for x in range(len(a_span))]
print("降水量(mm/h)")
print("{}\n".format(a))

//湿度
humidity = town_1h.find(class_="humidity")
h_span = humidity.find_all("span")
y = [h_span[x].string for x in range(len(h_span))]
print("湿度(%)")
print("{}\n".format(y))

//風速
wind_speed = town_1h.find(class_="wind-speed")
w_span = wind_speed.find_all("span")
w = [int(w_span[x].string) for x in range(len(w_span))]
print("風速(m/s)")
print("{}\n".format(w))

//下記のコードは得たデータをテキストに書き込むため

all_list = [h,t,p,a,y,w]

filename = "weather_town.txt"

with open(filename,"wt",encoding="utf-8") as f:
        f.write(str(all_list))
f.close()

```

##出力結果
例：〇〇市のデータ

```
時間(h)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24]

気温(度)
[10.0, 9.5, 9.5, 9.0, 8.5, 7.5, 9.5, 12.0, 15.0, 16.5, 18.0, 19.0, 19.0, 18.5, 18.5, 17.5, 15.9, 14.7, 13.6, 12.8, 12.0, 11.6, 11.2, 10.8]

降水確率(%)
['(%)', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '---', '10', '0', '0', '0', '0', '0']

降水量(mm/h)
['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']    

湿度(%)
['(%)', '78', '80', '80', '82', '84', '80', '76', '58', '46', '40', '34', '34', '32', '34', '36', '38', '42', '44', '46', '48', '48', '50', '52', '54']

風速(m/s)
[2, 2, 1, 2, 1, 0, 1, 1, 1, 4, 2, 3, 3, 4, 4, 4, 3, 3, 3, 3, 2, 2, 2, 2]
```


テキストデータは今回は乗せませんが、同じディレクトリには作成されています。

##参考
Pythonによるスクレイピング&機械学習 開発テクニック
https://www.amazon.co.jp/dp/4802611927/ref=cm_sw_r_tw_dp_61JA9G18RWK957HW4P92

スクレイピング・ハッキング・ラボ
miraihack 著
SQLの副問合せ（サブクエリ）について

#副問合せ（サブクエリ）とは
SQL文の内部に別のSELECT文を記述し、１つのSQL文で２つ以上の処理をするこSQLを作成することができます。

例えばサブクエリなしで最も大きな出金額を条件に費目と金額を取得したいとしましょう。

```sql:sql
SELECT MAX(出金額) FROM 家計簿  --=>(1)
SELECT 費目, 出金額 FROM 家計簿 WHERE 出金額 = (1)で得た結果　　--=>(2)
```
このクエリを書くときの思考回路は
１．　最終的に知りたい結果は費目、出金額なのでSELECT 費目, 出金額 FROM 家計簿 WHERE 出金額 =までを書くことを考える。
２．　出金額=の右辺にくる値を取得するために（１）のクエリを考える。
３．　（１）を書いてから(2)を書く。

結果的に２つの文が出来上がってしまいます。
サブクエリを利用し書き換えてみましょう。

```sql:sql
 SELECT 費目, 出金額 FROM 家計簿 WHERE 出金額 = （SELECT MAX(出金額) FROM 家計簿）
```

構造は単純で、先程の（１）のクエリを出金額の右辺に（）をつけて記述するだけです。またサブクエリの中にサブクエリを記述することも可能です。

![スクリーンショット 2021-10-23 17.00.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265227/715a0b87-de33-b3b0-d3e4-4a8547141ea7.png)

副問合せの処理の順番としては内包されたクエリから順に実行されていきます。

ここで副問合せのパターンについて考えてみましょう。副問合せの中身はSELECT文になるので得られる結果としては下記の３パターンが考えられます。

1.単一の値に化ける副問合せ
２．　列挙された複数値に化ける副問合せ
３．　表形式の複数値に化ける副問合せ

それぞれを具体的に確認しましょう。

###単一の値に化ける副問合せ
これは最初の例で挙げたクエリの形になります。副問合せの検索結果が一行一列の値となるものです。
![スクリーンショット 2021-10-23 17.14.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265227/3d8cb435-5ee2-2524-a7fb-8bfa47a8b4d5.png)

イラストの例ですとサブクエリの結果が10000という値になりそれを元に紫のクエリを実行します。

###列挙された複数値に化ける副問合せ
副問合せの検索結果が単一列（１行ｎ列）の値となる副問合せになります。
![スクリーンショット 2021-10-23 17.23.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265227/be1dde1e-154f-e6e2-c1ed-cb493708a76d.png)

このように複数の行を列挙する場合にその代わりとして利用できます。IN、ANY、ALL演算子などを用いた条件式が代表例になります。（IN、ANY、ALL演算子については[過去の記事](https://qiita.com/tomoki12/items/fd0bd3f73f4917f0830b）)）

複数行になるサブクエリでは単なる等号、不等号では比較できません。IN、ANY、ALLなどの複数行との比較で用いる演算子でないとエラーを生むことに注意しましょう。


###表形式の複数値に化ける副問合せ
副問合せの検索結果が表形式（n行m列）の値となる副問合せになります。
![スクリーンショット 2021-10-23 18.00.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1265227/ffdc0f9a-9aa9-eb31-457c-da9b8ceb18ed.png)

このサブクエリのパターンはINSERT文などで活用できます。
INSERT分では基本的に１回の呼び出しで１行の追加となります。したがってサブクエリを利用しない場合は１００行分の追加は１００回クエリをなげなくてはなりません。しかしｎ行m列の形でのサブクエリを利用すると１回のINSERT文で複数行のデータを登録することができます。


##参考
書籍： スッキリわかるSQL入門 第2版 ドリル222問付き！　
　　　 中山 清喬　著/飯田 理恵子　著
ラビットチャレンジレポート #4 統計学

# 統計学
### 記述統計
* 集団の性質を要約して記述する

### 推測統計
* 集団から一部を取り出し元の集団（母集団）の性質を推測する
    * 集団から一部を取り出すことを **抽出**という
    * 集団から取り出された一部を **標本**という
* 母集団を特徴づけるパラメータ（平均など）を統計学的に推測することを **推定**という
* **点推定** : 平均値などを1つの値に推定すること
* **区間推定** : 平均値などが存在する範囲を推定すること

## 確率変数と確率分布
* **確率変数**
    * 事象と結びつけられた数値（さいころの目、コインの表がでた数など）
* **確率分布**
    * 事象の発生する確率の分布
    * 離散値であれば表に示すことができる

* 下記の表はコインを4回投げる行為を複数回行った時の結果をまとめた表である
    * 確率変数は表がでた回数を表す
    * 事象が発生した回数はコインを4回投げる行為を1200セット行ったときに、1セットで何回表がでたか表している
    * 事象と対応する確率は1200セットのうち何セットで対応する事象が起きたを示している
        * 表が4回のときは75回事象が発生しているので、75/1200 → 1/16となる

|事象|裏が0回,表が4回|裏が1回,表が3回|裏が2回,表が2回|裏が3回,表が1回|裏が4回,表が0回|
|----|---------------|---------------|----------------|--------------|----------------|
確率変数|4|3|2|1|0|
事象が発生した回数|75|300|450|300|75|
事象と対応する確率|1/16|4/16|6/16|4/16|1/16|

## 期待値
* ざっくりいうと平均
* 平均との違い
    * 平均はすべての値を足し合わせてその個数で割る
    * 個数がきれに定まらない時のありえそうな値が期待値

|事象$X$|$X_1$|$X_2$   |....| $X_n$ |
|-|-|-|-|-|
|確率変数 $f(x)$ |$f(X_1)$| $f(X_2)$ | .... | $f(X_n)$ |
|確率 $P(X)$ |$P(X_1)$ &emsp; &emsp; &nbsp; &nbsp;|$P(X_2)$ &emsp; &emsp; &nbsp; &nbsp;| .... | $P(X_n)$ &emsp; &emsp; &nbsp; &nbsp;| 

* 期待値は下記のように求める
    * ざっくりいうと確率変数と確率をそれぞれかけたものをすべて足す

```math
E(f)=\sum_{k=1}^{n} P(X=x_k)f(X=x_k)
```

* 連続する値である場合は下記を使う

```math
E(f) = \int P(X=x)f(X=x)dx
```

## 分散と共分散
### 分散
* データの散らばり具合
* 出たの各々の値が期待値からどれだけずれているのか平均したもの
* 平均値とデータの値の差を2乗したものの平均

```math
分散Var(f) = E \bigl((f_{(X-x)})^2 \bigr)\\
= E(f^2_{(X=x)})-(E_{(f)})^2
```

* 例）3人の数学のテストの点数が下記の様であるとき
    * 平均値は $ \frac{90+100+80}{3}$より90が平均となる
    * 分散は $\frac{(90-90)^2+(90-100)^2+(80-100)^2}{3}$を計算して166.7となる

鳥谷さん|能見さん|藤浪さん
-|-|-
90|100|80


### 共分散
* 2つのデータ系列の傾向の違い
* 正の値をとれば似た傾向
* 負の値をとれば逆の傾向
* ゼロをとれば関係性の乏しい

```math
共分散Cov(f,g) = E \bigl((f_{(X=x)}-E(f))(g_{(Y=y)}-E(g)) \bigr)\\
=E(fg)-E(f)E(g)
```

* 例）3人の数学と国語のテストの点数が下記の様であるとき
    * 数学の平均値は $ \frac{90+100+80}{3}$より90が平均となる
    * 国語の平均値は $ \frac{60+50+70}{3}$より60が平均となる
    * 共分散は $\frac{(90-90)(60-60)+(90-100)(60-50)+(80-100)(60-70)}{3}$を計算して33.3となる

-|鳥谷さん|能見さん|藤浪さん
-|-|-|-
数学|90|100|80
国語|60|50|70



## 分散と標準偏差
* 分散は2乗をとっているので単位が変わってしまう！
    * 求めたのが長さの分散の場合、2乗することで面積になる
* 2乗することの逆演算をすれば元の単位に戻る→ **標準偏差**

```math
\sigma = \sqrt{Var(f)}\\
= \sqrt{E \bigl( (f_{(X=x)-E_{(f)}})^2 \bigr)}
```

* 標準偏差の値が小さいということは分散も小さいということになる
* 散らばり具合を元の単位で考えることができる


## 様々な確率分布
### ベルヌーイ分布
* コイントスのイメージ
* 表と裏で出る割合が等しくとも扱える
* xには裏か表か（0 or 1）が入る

```math
P(X| \mu) = \mu^x(1- \mu)^{1-x}
```

### マルチヌーイ分布（カテゴリカル分布）
* さいころを転がすイメージ
* 各面の出る割合が等しくなくとも扱える

### 二項分布
* ベルヌーイ分布の多試行版

```math
P(x| \lambda, n) = \frac{n!}{x!(n-x)!} \lambda^n(1-\lambda)^{n-x}
```

### ガウス分布
* 釣鐘型の連続分布
* 真の分布がわからなくてもサンプルが大きければ正規分布に近づく

```math
N(x; \mu, \sigma^2) = \sqrt {\frac{1}{2 \pi \sigma^2}} exp \Bigl(- \frac{1}{2 \sigma^2}(x- \mu)^2 \Bigr)
```

## 推定量と推定値
#### 推定量
* パラメータを推定する雨に利用する数値の計算方法や計算式のこと
* 推定関数ともいう

#### 推定値
* 実際に施行を行った結果から計算した値

##　標本平均
* 点推定の1つ
* 母集団から取り出した標本の平均値
* サンプル数が大きくなれば母集団の値に近づく→ **一致性**
* サンプル宇数がいくらであっても、その期待値は母集団の値と同様→ **不偏性**

```math
E(\hat{\theta})= \theta
```

## 標本分散

```math
\hat{\sigma}^2=\frac{1}{n}\sum_{i=1}^{n}(x_{i}-\bar{x})^2
```
* 一致性は満たすが不偏性は満たさない
MySQL 「WHERE」 と 「HAVING」 の違い

WHERE : 行の絞り込み → グループ化 → 集計
HAVING : 集計 → 行の絞り込み

MySQLでは以下の順でコマンドが実行される。
①FROM
②WHERE
③GROUP BY
④HAVING
⑤SELECT
⑥ORDER BY

そのため、GROUP BY のあとでWHEREを使うとエラーになる。
GROUP BYを呼び出した上で条件を絞り込む場合はHAVINGを使用する。
STM32L010で節電の為に4MHzにする。(内部電圧1.5V)　HAL



目的
節電化

![o_con68.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7d07ef6b-2913-9c12-62be-9ce6387e2749.jpeg)



```c++


#include "mbed.h"

void s_clk4();

DigitalOut myled(PA_4); RawSerial pc(PA_2, PA_3); //010 tx, rx 

int main()
{

    //__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);//4Mhz 1.8
    __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE2);//4Mhz 1.5 560uA
    //__HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE3);//4Mhz 1.2 460uA W_Not_Flash

    s_clk4();
    pc.baud(9600); //16mz
    //printf("%d Hz\r\n", SystemCoreClock);

    while(1) {
        myled = 1;
        wait(0.2);
        myled = 0;
        wait(0.2);

        printf("%d Hz\r\n", SystemCoreClock);

    }//while

}//main


void s_clk4()
{
  /*4mz*/

  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_NONE;
  HAL_RCC_OscConfig(&RCC_OscInitStruct);

  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_HSI;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV4;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_0);

 }//s_clk4


```
ジニ係数を知りたくなったら

統計を普通にしていればそこまで当たることもないのですが、統計検定で「ジニ係数」が出てきたため学びました。

用語として知っているよ！って方でも実際にどのような計算が行われているのか？という方（=私）のために簡単にまとめました。

※普通に機械学習とかでマストで知っておかなければいけないとは現時点では思ってないですし、
統計検定のような問題をとく状況にない限り、出てきたときに調べるスタンスで十分と素人の私は考えております。

# 用語の意味
ざっくりと意味を言えば、「理想とする状態からどのくらい乖離しているのか？」ということ。
経済学で所得格差の広がり具合をジニ係数で表現したりします（1が激ヤバの状態→0はみんなhappy）

ちゃんとした定義を野村証券のサイトから引用すると、
<B>「ジニ係数は、イタリアの統計学者コラド・ジニにより考案された所得などの分布の均等度合を示す指標で、国民経済計算等に用いられる。」</B>
引用元: [ジニ係数（じにけいすう）](https://www.nomura.co.jp/terms/japan/si/A02571.html)
です。

# 時に係数の算出する過程
必要な準備として、五分位数（全体を5等分し、20%, 40%, 60%, 80%, 100%の区間に分ける）と、ローレンツ曲線・完全平等線が必要です。
※かならずしも五分位数でなくても良いです。今回は例として五分位数を使うため、五分位数を使っているものを想定して話を進めます。

- x軸には累積度数として、0.2, 0.4, 0.6, 0.8, 1と設定し、y軸は対象としたいデータの累積度数とし、プロットしていきます。（ローレンツ曲線）
- 完全平等線として、y = xの直線を引きます。
- 完全平等線とデータ点をつなぎ合わせた線で囲まれた面積の2倍したものがジニ係数

さすがにこれをいつもの雑なグラフを作るのは
面倒
大変なので、引用させていただきます。
![スクリーンショット 2021-10-23 18.13.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865635/cc1139fb-ca70-3554-5122-a00df70967ba.png)
引用元: [2-5. ジニ係数](https://bellcurve.jp/statistics/course/3798.html)

ちなみに、通常の見方はx軸に対して、プロットされている点を参照し、そこからy軸方向に向かったときにぶつかる完全平等線との乖離が実際の感覚となります。
![スクリーンショット 2021-10-23 18.16.14.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865635/e6973e29-1222-c9f5-fc52-7d48a43c28b8.png)
引用元: [2-5. ジニ係数](https://bellcurve.jp/statistics/course/3798.html)
上記の例で言えば、x = 0.8のときプロットは0.47くらいですが、完全平等線が0.47を通るのはそのままx=0.47であるため、
本来47%くらいのデータ点でとるはずのものを約80%くらいのデータで取り合い、残りの約5割のものを残りの20%でぬくぬくと分け合っていると捉えることができます。

噛み砕いて言えば、
100人でパンを分けるときに、下から80人で47%のパンを分け合い、残りの20人で53%のパンを分け合うため、いかに裕福な人がパンを食べれているか？が伺えます
# 参考にさせていただいた記事
[ジニ係数（じにけいすう）](https://www.nomura.co.jp/terms/japan/si/A02571.html)
[2-5. ジニ係数](https://bellcurve.jp/statistics/course/3798.html)

## 余談
せっかくなので、2018年の所得格差のジニ係数ランキングを調べてみました。

ジニ係数が一番大きい（=格差やばい）のは南アフリカの0.62で、日本は0.33くらいでした（ファクトチェックなどはしてないので、興味ある方はぜひご自身でも調べてみると面白いと思います！）
参考文献: [世界のジニ係数 国別ランキング・推移](https://www.globalnote.jp/post-12038.html)
Game not found: Adventure-Atari2600. Did you make sure to import the ROM? の解決法

## 状況
[深層強化学習のチュートリアル](https://contest.openai.com/2018-1/details/)を勉強中、
```Game not found: Adventure-Atari2600. Did you make sure to import the ROM?```
のエラーが発生した。

## 実行環境
- Mac OSX BigSur 11.6
- pyenv
- python 3.7.7
- jupyter notebook

## 対処した方法(失敗)
https://github.com/openai/retro/issues/60 を参考に

```
python -m retro.import.sega_classics
```
上記コードを実行し、インポート成功との実行結果が出ているのにも関わらず、エラーが解決しない

## 原因
jupyter notebookでインポートしている`retro`とROMをインポートした`retro`が異なっていた。
### 確認方法
```
import retro
retro?

実行結果
Type:        module
String form: <module 'retro' from '/usr/local/lib/python3.7/site-packages/retro/__init__.py'>
File:        /usr/local/lib/python3.7/site-packages/retro/__init__.py
Docstring:   <no docstring>
```
で場所を確認する。
・pyenv 環境でインストールしているはずにも関わらず、pyenvのパッケージを使用していない。

## 解決方法（成功）
### jupyter notebookにpyenv環境を追加する
[Jupyter の kernel に pyenv 環境を追加する](https://qiita.com/yuki-shark/items/fba874a109f04004158b)を参考に

```
python -m ipykernel install --user --name=pyenv --display-name=pyenv
```
を実行。
その後、実行ファイルを開き、画面上部バーのkernelボタンから
・カーネルの変更 --> pyenv
を選択する。

```
import retro
retro?

実行結果
Type:        module
String form: <module 'retro' from '/Users/ryoryo/.pyenv/versions/3.7.7/Python.framework/Versions/3.7/lib/python3.7/site-packages/retro/__init__.py'>
File:        ~/.pyenv/versions/3.7.7/Python.framework/Versions/3.7/lib/python3.7/site-packages/retro/__init__.py
Docstring:   <no docstring>
```
から`retro`の場所を確認し、

```
cd /Users/ryoryo/.pyenv/versions/3.7.7/Python.framework/Versions/3.7/lib/python3.7/site-packages/retro
cd data
cd stable
cd SonicTheHedgehog-Genesis
ls
```
を実行。`rom.md`が見つかれば成功

## 参考
- [Jupyter の kernel に pyenv 環境を追加する](https://qiita.com/yuki-shark/items/fba874a109f04004158b)
エックスサーバーの「メール転送(エイリアス)確認ツール」を作ってみました

## 制作のきっかけ
エックスサーバーのメール転送機能でメンバー同報メールを運用していますが、
このメールの転送先が誰だったかな？とわからなくなった時に、
わざわざエックスサーバーの管理ログインから確認するのが面倒であったため。
※そもそもその運用では利用者に簡単に使ってくださいとは開放できないですしね。
※エックスサーバーに転送メールメンバーを返信してくれるAPIなどは無いですよね？
・・・もしありますよ？ということでしたら是非お教えください。。
## エックスサーバーのメール転送設定はどこにあるか？
エックスサーバーへFTPで接続して眺めてみるのと、[エックスサーバー公式のCron設定](https://www.xserver.ne.jp/manual/man_program_cron.php)にサーバ上のローカル位置が記載されているので、それらを参考にしつつ、メール転送の設定は「.alias」ファイルに記載されることが分かりました。
```/home/[エックスサーバID]/[エックスサーバ契約ドメイン(メールドメイン)]/mail/[メールドメイン]/[メールアカウント]/.alias```
## さっそく制作
テスト用のメールアカウントや転送をいくつか作って、それらが正しく表示できるか？を確認しました。
以下が作成した「index.php」です。
※まったくWebデザインもしていません。・・・ただ表示できるようにしただけです。。

```php
<title>エックスサーバー メール転送(エイリアス)確認ツール</title>
<h2>エックスサーバー メール転送(エイリアス)確認ツール</h2>
<br>
【このツールについて】<br>
このメーリングリスト（転送メール/メールエイリアス）のメンバー誰だっけかな？という時に調べられます。<br>
<br>
転送先メンバーを確認したいメーリングリスト（転送メール/メールエイリアス）を入力してください。<br>
<form method="post" action="" id="inputmail">
	<input type="text" name="pref[]" value="" size="30">@

	<select name="pref[]" size="1" from="inputmail">
	<option value="--ドメイン選択--">--ドメイン選択--</option>
	<option value="[メールドメイン1]">[メールドメイン1]</option>
	<option value="[メールドメイン2]">[メールドメイン2]</option>
	</select>

	<input type="submit" value="送信">

</form>
<br>
※このツールは社内アクセスのみ利用できます。社外からはVPN接続をしてください。<br>
---------------------------------------------------------------------------------------------------<br>
<br>

<?php

//h() 関数の定義(クロスサイトスクリプティング対策)
function h($str) {
  return htmlspecialchars($str, ENT_QUOTES, 'UTF-8');
}

//IPアドレス規制
$nowip = $_SERVER['REMOTE_ADDR'];
// 許可されたIPアドレスのリスト
$authip = array(
  "[利用許可するグローバルIPアドレス1]",
  "[利用許可するグローバルIPアドレス2]",
  "[利用許可するグローバルIPアドレス3]"
);
if(!in_array($nowip, $authip)){
    // 許可されているIPアドレスではない場合の処理
    $noip_alert = "<script type='text/javascript'>alert('IPアドレスが社内アクセスではありません。確認結果は表示できません。');</script>";
    echo $noip_alert;
    exit;
}else{
    // 許可されているIPアドレスであった場合の処理


if(isset($_POST['pref'][0])) {

//メールサーバのあるエックスサーバのパスを指定
$path = '/home/[エックスサーバID]/' . h($_POST['pref'][1]) . '/mail/';

$path = $path . h($_POST['pref'][1]);
//echo($path);

$mailpath = $path . '/' . h($_POST['pref'][0]) . '@' . h($_POST['pref'][1]);
//echo($mailpath);

$mailalias = $mailpath . '/' . '.alias';
//echo($mailalias);


foreach (glob($mailpath) as $maillists) {
//  echo($maillists . "<br/>");

echo('【対象メールアカウント】<br/>');
echo(h($_POST['pref'][0]) . '@' . h($_POST['pref'][1]). "<br/>");
echo("<br/>");
echo('【転送先登録メンバー】<br/>');
  $content = file_get_contents($mailalias);
  $rows = explode("\n", $content);
  foreach ($rows as $row){
   echo($row . "<br/>");
  }
}

}

}

?>
```
以上です。
## 参考にさせていただいたサイトなど
(Web Design Leaves)PHPフォーム
https://www.webdesignleaves.com/pr/php/php_basic_06.php?name=%E3%83%9E%E3%82%A4%E3%82%B1%E3%83%AB&age=33

(WEB制作の解決策FAQブログ)phpでIPアドレスを取得して制限を掛ける方法
http://keylopment.com/faq/1888/

(Public Constructor)【PHP】file_get_contentsでファイルを一行ずつ読み込む
https://public-constructor.com/php-file-each-row/
プログラミング学習　Day5（リスト、タプル、ディクショナリー）

# リスト
- 複数の要素を箱の中に入れれる。
- .append()で最後に要素を追加できる
- .pop()で最後の要素を取り出せる（利用しないなら削除と同じ）できる

入力

```Python
fruit = ["apple", "orange", "grape"]
print(fruit)
fruit.append("banana") # これで"banana"が追加される
print(fruit)
fruit.pop() # これで"banana"が消える
print(fruit)
print(fruit[1])
```

出力

```
['apple', 'orange', 'grape']
['apple', 'orange', 'grape', 'banana']
['apple', 'orange', 'grape']
orange
```

# タプル
- リストと似ているが内容を変更できない
- あまり使わない
- [] ではなくて ()で囲う
入力

```Python
fruit = ("apple", "orange", "grape")
print(fruit)
fruit.append("banana") # 変更できないのでエラーが出る
```

# ディクショナリー
- キーとバリューで要素を管理する
- キーによってバリューを管理できるので順番を気にしなくてよい（リストは先頭からの順番で値を管理しているがディクショナリーでは順番は気にしなくてよい）

入力（"fruit"や"color"がキー、"apple"や"red"がバリュー）

```Python
data = {"fruit":"apple","color":"red"}
print(data["fruit"])
```

出力

```
apple
```
- ディクショナリーの中のバリューにリストを入れることもできる

例

```Python
data = {"fruit":["apple", "orange", "grape"]}
print(data["fruit"])
```

出力

```
['apple', 'orange', 'grape']
```

- ディクショナリーのバリューを変数に代入する場合はコピーでなく参照になる。
- 参照先の変数を変更すれば参照元を変更できる。

入力

```Python
data = {"fruit":["apple", "orange", "grape"]}
a = data["fruit"]
a.append("banana")
print(data)
```

出力

```
{'fruit': ['apple', 'orange', 'grape', 'banana']}
```


# 疑問
- 何故ディクショナリーのバリューを何かの変数に代入する時は参照代入になるのか？
【Rails】acts-as-taggable-onで作成したタグ機能をseedデータに取り入れる

##目的
自作のアプリにダミーユーザーを作成。
その際acts-as-taggable-onで作成したタグの挙動や見栄えの確認をしていきます。


参考：
[Railsにタグ機能をつける。acts-as-taggable-on使用](https://qiita.com/nakamura999/items/56c6426fc5dd640617ce)
[rails acts-as-taggable-on でタグ付け後、タグを使って検索](https://qiita.com/take1457a/items/90465189140ec77b14be)


##環境
windows10 home
Ubuntu 20.04.1 on WSL2
rails 6.0.3
ruby 2.6.6

##seedデータ作成(失敗)
まずはタグ表示無しでデータが作れるか試してみる。

```seeds.rb
50.times do 
  user = User.create!( 
    name: Faker::Games::Pokemon.unique.name, 
    email: Faker::Internet.email, 
    password: "password", 
    password_confirmation: "password" 
  ) 
end 
15.times do |n| 
  User.each do |user| 
    user.microposts.create!( 
      photo: open("./db/fixtures/#{n + 1}.jpeg"), 
      detail: Faker::Hacker.say_something_smart 
    ) 
  end 
end
```

無事データが投入されたので、タグ付きのデータが投入できるか試してみる。

```seeds.rb(失敗例)
User.limit(5).each do |user|  # 5人のユーザーを選んで各々をuserに代入 
  15.times do |n|             # user1人につき15回投稿作成する 
    user.microposts.create!( 
      photo: open("./db/fixtures/#{n + 1}.jpeg"), 
      detail: Faker::Hacker.say_something_smart 
    ) 
    array = Faker::Food.dish.split("") 
    array.each{ |tag| 
      tag_list = ActsAsTaggableOn::Tag.new 
      tag_list.name = tag 
      tag_list.save 
    } 
  end 
end
```

これならFakerの中にある単語を空白（""）で区切って配列にし、一つ一つをtag_listに代入してくれるんじゃないかと思ってました。

![404f1c11f641a097431acbcf656affaf](https://user-images.githubusercontent.com/69103382/138555248-b40768c6-e0c1-449b-8b67-7de8433187b9.png)

結果、データを投入することはできたが各投稿にタグがついていないということに...。
調べたところ、どうやら文字列の配列化はできないっぽい。

参考：[配列っぽい文字列をうまく配列に変換する](https://qiita.com/_miyachik/items/addf3766f0e0dd20f154)

##seedデータ作成(成功)
どうやってmicropostインスタンスとtag_listを結びつけるのかがわからない。
そう思いながら[この記事](https://stackoverflow.com/questions/6413681/how-to-dbseed-my-acts-as-taggable-on-tags)を見ていたら次の引用部分で突然ひらめいた。

>... 
>  product = Product.create( 
>... 
>  ) 
>  product.tag_list.add "tag1", "tag2" 
>  product.save 
>...

そうか、micropostインスタンスを作るときに同時にmicropostを定義すればいいんだ！
その後tag_listも定義すればmicropost.tag_listでmicropostとtag_listを結び付けられる。

```seeds.rb
User.limit(5).each do |user|  # 5人のユーザーを選んで各々をuserに代入 
  15.times do |n|             # user1人につき15回投稿作成する 
    micropost = user.microposts.create!( 
      photo: open("./db/fixtures/#{n + 1}.jpeg"), 
      detail: Faker::Hacker.say_something_smart 
    ) 
    tag_list = ActsAsTaggableOn::Tag.new # tag_listを定義
    micropost.tag_list = Faker::Food.dish # micropostとtag_listを結びつける
    micropost.save 
  end 
end
```

![](https://user-images.githubusercontent.com/69103382/138555226-03e55d99-97c4-4be3-a10b-326c25e47411.png)
無事タグ付きの投稿データを作成することができました。
コマンドを打つとチャンネルを作ってくれるdiscordbotをPythonで作ろう

#Botとは

一般的なBotはいい印象はないそうです。
（[総務省HP](https://www.soumu.go.jp/main_sosiki/joho_tsusin/security_previous/kiso/k04_bot.htm#:~:text=%E3%83%9C%E3%83%83%E3%83%88%EF%BC%88BOT%EF%BC%89%E3%81%A8%E3%81%AF%E3%80%81,%E3%81%9F%E3%82%81%E3%81%AE%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%82%BF%E3%82%A6%E3%82%A4%E3%83%AB%E3%82%B9%E3%81%A7%E3%81%99%E3%80%82&text=%E5%A4%96%E9%83%A8%E3%81%8B%E3%82%89%E8%87%AA%E7%94%B1%E3%81%AB%E6%93%8D%E3%82%8B,%E3%81%A8%E5%91%BC%E3%82%93%E3%81%A7%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)より。）

しかし、ゲームでよく使われるBotとは、ユーザーの特定のアクションに対して決まったリアクションを返すロボット(ro **BOT**)です。今ではSiriやAlexaなどもユーザーの声に反応して検索してくれるという立派なBOTです。


#botを作るためのセットアップ
まずは自分のPCにdiscordパッケージをインストールする必要があります。
自分はVSCodeで書いたプログラムをLinux環境で動かしていますが、一応VSCodeでも動かせます。

Linux(自分はUbuntu20.04 LTS)でのインストール方法(4つ必要です。)

```
sudo apt install libffi-dev libnacl-dev python3-dev

sudo apt update

sudo apt upgrade

sudo python3 -m pip install -U discord.py

# 音声も必要な場合(なくても構いません)
sudo python3 -m pip install -U discord.py[voice]
```
---
Windowsでのインストール方法(管理者権限でコマンドプロンプト。Python3がインストールされていること前提)

```
python3 -m pip install -U discord.py


# 音声も必要な場合(なくても構いません)
python3 -m pip install -U discord.py[voice]
```

次に、BotのTOKENを所得する必要がありますが、webサイトにたくさん転がっているので特に詳しい説明はしません。
[参考](https://dot-blog.jp/news/discord-bot-token/)

最後に、エディタ(コードを書くためのメモ帳みたいなもの)をセットします。

普通のメモ帳でもできなくはないですが、エラーなどを発見してくれる専用の機能を持った方がわかりやすいので、そちらを使います。
[VSCode](https://code.visualstudio.com/Download)
自分の環境に合ったものをインストールしてください。

#早速作ってみる
## ログインした時のアクション

1行目に、

```python
import discord
```
と書きます。これは、discordというモジュールをここで使う、という表記です。

```python
client = discord.Client()

@client.event
async def on_ready():
    print(f'Logged in as: {client.user.name}')
    print(f'With ID: {client.user.id}')
```

#### 解説
説明していきます。

`client = discord.Client()` は実行するクライアントを変数に代入しています。

`@client.event` は、上で指定したclientが起こす行動について以下に書かれています。というものを示す目印です。

`async def` についてですが、`async` はコルーチン関数を理解しないといけないので、パスします。discotdbotを作るときには基本的にこれを使う、と理解してしまってもいいかもしれません。 (個人的には基本これ以外は使わないと思います。)


```python
@client.event
async def on_ready():
    print(f'Logged in as: {client.user.name}')
    print(f'With ID: {client.user.id}')

client.run('TOKEN')
```
`on_ready()` はdiscord.pyで定められている関数で、botを動かせる状態になったら、以下のプログラムを実行します。という意味です。この関数を`on_start`とかに変えたら動きません。
`print()`文は、コンソール (VSCodeでいうターミナルです。標準だと下の方に存在しています。) に出力されます。

`client.run('TOKEN')` : TOKEN は Discord Developer Portalからコピーします。


>動かしたBotの名前(Discord Developer Portalで決めたBotの名前です。)

>動かしたBotのユーザーID(下の赤い四角で囲んだところに書かれている18桁の数字)
の順で書かれます。
![d370cb32c917f319c3396ef5f07e1815.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1581903/915863cc-0e05-8e2f-902d-8ad70a78d78c.png)


---

次回は、書かれたメッセージに対しての反応を書いていきます
【SASS】はじめてのSASS

これから自分が学んだことをアウトプットするためこれから記事にしようと思います。
よろしくお願いいたします
【SASSの内容】
SASSとは？
css をより効率的に書けるようにした言語。webページがどんどん複雑になっていくとcssがカオスになっていくため、使いにくい
→コードの再利用、変数、条件分岐ができるようになったのがSASS。特にbootstrapをカスタマイズするときは便利なので使ってみることにした。

【準備①bootstrapのダウンロード】
以下の公式サイトからダウンロード
https://getbootstrap.jp/docs/4.5/getting-started/download/
今回はcomposerからダウンロードすることに

```composer.bash
composer require twbs/bootstrap:4.5.0
```
自分の場合はdockerコンテナを利用してタウンロードしたので

```composer-docker.bash
docker-compose up exec app composer require twbs/bootstrap:4.5.0
```

すると以下vender/twbs以下にbootstrapのファイルがダウンロードされます

![スクリーンショット 2021-10-23 6.47.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661879/83011dfa-f0c9-5133-c9c2-85af1dabeb3c.png)

適用したいHTMLに「bootstrap.css」を読み込みます。（bootstrap.min.cssは圧縮されたファイルで本番環境にアップロードする際にはいいけどコードが見にくいので開発環境ではこちらを使用）

【準備② SASSのインストール〜試しにコンパイル】
・SASSのインストール
https://sass-lang.com/install（公式ドキュメント）
私はcomposerでダウンロードしたいので以下のサイトからダウンロード
https://github.com/scssphp/scssphp（GitHubから以下のサイトに飛びます）
https://scssphp.github.io/scssphp/

```scssphp.bash
docker-compose exec app composer require scssphp/scssphp
```
一旦scssファイルを作成してそこにbootstrapのscssファイルをインポート

```app.scss
@import '/var/www/html/vendor/twbs/bootstrap/scss/bootstrap.scss';
```

コンパイル先のcssファイル（app.css）を作成、先ほどcomposerでダウンロードしたコンパイラーを使ってapp.scssをコンパイル
（endor/scssphp/scssphp/bin/pscss < companies/stylesheets/scss/app.scssでapp.scssを読み込み、> companies/stylesheets/css/app.cssでファイルを出力している）

```scss.bash
root:/var/www/html# vendor/scssphp/scssphp/bin/pscss < companies/stylesheets/scss/app.scss > companies/stylesheets/css/app.css
```
するとapp.cssファイルに以下のようにscssの記述をもとにcssが記述
![スクリーンショット 2021-10-23 8.43.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661879/05d4ee01-10e3-fd80-f60f-027ca055ba16.png)

あとは適当にscssファイルをカスタマイズ

コンパイルで生成したapp.cssをHTMLに読み込んでbootstrapのcssファイルを読み込ませた時と同じように反映されるか確認

```new.php
<!DOCTYPE html>
<html lang="ja">

<head>
	<meta charset="UTF-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<link rel="stylesheet" href="/var/html/companies/stylesheets/css/app.css">
	<title>会社登録</title>
</head>

<body>
	<h1>会社マスタ登録ページです</h1>
	<form action="create.php" method="POST">
		<?php if (count($errors)) : ?>
			<ul>
				<?php foreach ($errors as $error) : ?>
					<li><?php echo $error; ?></li>
				<?php endforeach; ?>
			</ul>
		<?php endif; ?>
		<div>
			<label for="name">会社名</label>
			<input type="text" id="name" placeholder="例：google" name="name" value="<?php echo $company['name'] ?>">
		</div>
		<div>
			<label for="establishment_date">著者名</label>
			<input type="date" id="establishment_date" name="establishment_date" value="<?php echo $company['establishment_date'] ?>">
		</div>
		<div>
			<label for="founder">代表者</label>
			<input type="text" name="founder" id="founder" value="<?php echo $company['founder'] ?>">
		</div>
		<div>
			<input type="submit" value="登録">
		</div>
	</form>
</body>

</html>
```
TOMCATインストール方法（１時間シリーズ第１弾）

#１時間でTOMCATをインストールする#

**用意するものはこちら**
・Eclipse

1. ヘルプのEclipseマーケットプレイスを開く

1. 「Tomcat」で検索をする!

1. EclipseTomcatPluginをインストール
 この画面で言うところの一番上にいる猫ちゃんの欄にあるPluginをインストールボタンを押す![rapture_20211023161215.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626652/21f44c63-a131-6961-225e-8a8729dd62d1.jpeg)

1. ごちゃごちゃ書かれているライセンスのレビュー画面にある「使用条件の条項に同意します」を選択して完了のボタンを押す![rapture_20211023161544.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626652/5560e8e1-a204-7c3e-5cf9-5250bb4d35e4.jpeg)

1. ソフトウェア更新画面に映るので、「今すぐ再起動」ボタンを押す（Pluginをインストールするときはおそらくこの画面は毎回出るので覚えておこう！！）![rapture_20211023161751.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626652/e1737bab-f5f1-903c-3067-018312a1e509.jpeg)

1. 待つ。ひたすら待つ。
1. ツールボックスに猫ちゃんのマークが付いていたらインストールできたということです。![rapture_20211023162337.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626652/d5a2404f-6d00-713d-7343-39bf2d0c2ee9.jpeg)

1. 一番左にある猫ちゃんのボタンを押して、TomCatを起動する。
1. 以下の３つで起動されていることが分かる。
 * コンソールに「 Server startup 」という文字が出ること
 * 「http://localhost:8080」にアクセスできること
 * そのアクセスした画面に「If you're seeing this, you've successfully installed Tomcat. Congratulations!」という文字が表示されていること![rapture_20211023162931.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626652/82977f54-0582-a9ff-f475-45f1b16b7ef0.jpeg)

ここまで30分くらいかかった。

#まだ時間があるので「TomCatプロジェクト」を作ってみる#
1. ファイル⇒新規⇒その他⇒「TomCatプロジェクト」（Javaカテゴリーの中にあるはず）を選択
1. プロジェクト名を入力する
1. コンテキスト名を入力する<br>
   コンテキスト名とは何かというと、WEBアプリケーションの名前みたいなもんかな。
　 「http://localhost:8080/コンテキスト名/パス名」てあるときのコンテキスト名のこと。
1. 待つ。がんばれEclipse!!（待ってばかりだな）
1. ファイルを新規作成する。
1. HTMLを書く（単純に「WELCOME!!」と表示される画面を作る）

```
<html>
<head>
<title>WELCOME</title>
</head>
<body>
WELCOME!!
</body>
</html>
```

1. 「http://localhost:8080/コンテキスト名/パス名」で作成した画面を表示する
![rapture_20211023165346.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/626652/35c6abe3-d63e-8f18-a4b8-2a6270bb8119.jpeg)


終り！！簡単ですね。
次期POSIX(Issue 8)で標準化されるawkの機能は delete array, nextfile, fflush()

## はじめに

次期 POSIX (Issue 8、2022 年後期予定)で標準化される awk の機能は `delete array`、`nextfile` ステートメント、`fflush()` 関数の 3 つです。

あれ？今まで使えなかったの？と思う人も多いと思います。はい、いずれも**ほとんどの環境ですでに使える機能**なのであえて新機能とは呼びません。というよりすでに多くの実装で使えるから POSIX で標準化されるわけです。（POSIX は仕様ができてから実装されるという流れではなく、多くの実装が登場して移植性があると認められたものを標準化するという流れなのでお間違えなきよう）

ついでにどのバージョンから使えるようになっているのかを確認しました。見出しのカッコの中の日付は、これらの変更が提案された日付です。

補足 Solaris 10/11 の `/bin/awk` は歴史的な awk なので関数すら使えません。`original-awk` は `nawk` (BWK awk , One True awk) のことで、macOS の `/usr/bin/awk` も `nawk` です。Debian 2.2 より前の環境は調査していないのでそれよりも古いバージョンから使える可能性が高いです。

## delete array (2012-02-18)

https://austingroupbugs.net/view.php?id=544

> At least gawk, mawk, BWK awk, Solaris /usr/xpg4/bin/awk, and BusyBox awk

私の調査

- gawk 3.0.4 (Debian 2.2) ・・・ YES
- mawk 1.3.3 (Debian 2.2) ・・・ YES
- origian-awk 20000525 (Debian 2.2) ・・・ YES
- Busybox awk 1.1.3 (Debian 4.0) ・・・ YES
- /usr/xpg4/bin/awk (Solaris 10/11) ・・・ YES

## nextfile (2012-09-14)

https://austingroupbugs.net/view.php?id=607

> The nextfile statement is supported by the vast majority of current awk implementations, specifically:
> 
> * BWK awk 20070501
> * gawk 3.1.7
> * mawk 1.3.4
> * BusyBox awk 1.15.1
> * awka 0.7.5
> * QSE awk 0.5.6
> 
> Support is notably absent from:
> * Solaris 10 /usr/xpg4/bin/awk
> * jawk 1.02

私の調査

- gawk 3.0.4 (Debian 2.2) ・・・ YES
- mawk 1.3.3 (Debian 2.2 - 10) ・・・ NO
- mawk 1.3.4 20200120 (Debian 11) ・・・ YES
- origian-awk 20000525 (Debian 2.2) ・・・ YES
- Busybox awk 1.1.3 (Debian 4.0) ・・・ YES
- /usr/xpg4/bin/awk (Solaris 10/11) ・・・ NO

## fflush (2012-12-04)

https://austingroupbugs.net/view.php?id=634

> fflush() is a useful extension that has long been available in the most versions of awk, and is implemented in at least the following modern versions:
> 
> * gawk 4.0.1
> * mawk 1.3.4-20121129
> * BWK awk 20110810
> * BusyBox 1.20.2 awk
> * awka 0.7.5
> 
> It is absent from:
> 
> * jawk 1.02
> * AIX 7.1 /usr/bin/awk
> * HP-UX 11i v2 /usr/bin/awk
> * Solaris 10 /usr/xpg4/bin/awk

私の調査

- gawk 3.0.4 (Debian 2.2) ・・・ YES
- mawk 1.3.3 (Debian 2.2) ・・・ YES
- origian-awk 20000525 (Debian 2.2) ・・・ YES
- Busybox awk 1.1.3 (Debian 4.0) ・・・ YES
- /usr/xpg4/bin/awk (Solaris 10/11) ・・・ NO

## まとめ

- `delete array` はほとんどの環境で問題なく使えそうです。
- `nextfile` は mawk が新しい環境でないと使えないかもしれません。UNIX (macOS は除く）は使えない可能性があります。
- `fflush()` は UNIX (macOS を除く）は使えない可能性があります。

`nextfile` は mawk の場合に少し注意が必要そうですけど、それ以外はほぼ問題なく使えそうです（macOS 以外の UNIX を除く）。mawk の `nextfile` も Debian に搭載されるのが遅かっただけで [CHANGES](https://invisible-island.net/mawk/CHANGES.html) を見る限り [1.3.4 20120627](https://invisible-island.net/mawk/CHANGES.html#index-t20120627) には実装されてるようです（`delete array` と `fflush()` は 1996 年の 1.2 の時点ですでに対応済み）。
Salesforce いつも忘れちゃうことをまとめとく vol.3 ～ 基礎知識（標準とカスタム）

# はじめに
- Salesforce は便利ですが、一度設定しても「あれ？どう設定したっけ？」と、覚えていたのに忘れてしまう…　そんな内容をまとめておきましょう。
- まずは、Salesforce の基礎的な部分を押さえておきたいと思います。


# 標準とカスタム
- Salesforce の基本的な用語の一つに「__標準__」と「__カスタム__」という言葉があります。
- __標準__ は、Salesforce の組織に __【標準で用意されている】__ 機能、権限セット、プロファイル、オブジェクトなどのことを指します。
- __カスタム__  は、Salesforce の組織に対して、__【使用者がカスタマイズ】__した機能、権限セット、プロファイル、オブジェクトなどのことを指します。

<font color="red">赤枠</font>の権限セットが標準、<font color="blue">青枠</font>の権限セットがカスタムです。削除リンクがあるのがカスタム、という点から確認ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/52922b16-1347-8f2b-c26b-aef12e601245.png)

<font color="red">赤枠</font>のプロファイルが標準、<font color="blue">青枠</font>のプロファイルがカスタムです。カスタム列があるので判りやすいですね。こちらも削除リンクがあります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/309141/ee0e608e-deed-42a5-c007-853aca266c0b.png)


# 過去の記事
- Salesforce いつも忘れちゃうことをまとめとく vol.2 ～ 基礎知識（Lightning と Classic）
    - https://qiita.com/xx_mana/items/bff9651220c3d628bf07
- Salesforce いつも忘れちゃうことをまとめとく vol.1 ～ 基礎知識（組織 と エディション と インスタンス）
    - https://qiita.com/xx_mana/items/a6546d425e748fc5743b

# ご了承ください
- まだまだ勉強中の部分もあります。間違っている箇所もあるかもしれません。
- Salesforceは、この時点のバージョン(2021年10月頃) での内容になります。今後、仕様変更が変わることによって、内容の通りにならない可能性もあります。ご了承ください。
 - また、URLなども変更になっている可能性もあります。