OmniAICreator/Qiita-1.07M huggingface dataset:
Vue.jsまとめ⑦　コンポーネントの高度な機能

下書きが上限に達しているので仮の状態で投稿しています

子コンポーネントにhtmlを渡す
親、コンポーネントタグ内にhtmlを記述
子、表示したいところにslotタグを記述

slotのスコープはstyleは親子共に、それ以外は親のみ

フォールバックコンテンツ（slotのデフォルトを設定）
slotの中に記述

名前付きスロット（複数のデータを渡せる）
親、<temprate v-slot:名前>
子、<slot name="名前">

templateで囲っていないところは名無し（default）のslotにまとめて渡される

スロットプロパティで子コンポーネントのデータにアクセスする（基本的には$emitを使う）
子 slotタグ内で
name="名前"　v-bind:自由 = "データ"
親　コンポーネントタグ内で
v-slot:名前="変数"　#変数はslotPropsを仮に使いがち
#変数にデータが入る、変数は{{ 変数 }}などで使える

v-slot:[名前]で動的なスロット名にできる

v-slot:名前は#名前に省略できる（デフォルトは#defoltとする）

○動的に複数のコンポーネントを切り替える
<component :is="動的なコンポーネント名"></component>

切り替えたらデストロイされる（内容は保存されない）
デストロイしないためにはkeep-aliveタグの中にcomponentタグを入れる
Vue.jsまとめ⑥　コンポーネント間でデータを受け渡す方法

下書きが上限に達しているので仮の状態で投稿しています

○親から子に
子でexport内で
props:["名前"]　もしくは　
props:{
　名前:値の型　#バリデーションをしている、値の型をオブジェクトにすればさらにバリデーションできる
}
親でコンポーネントタグ内で
v-bind:名前 = "渡したい値"

propsの名前はキャメルケース(likeNumber)かケバブケース
propsは配列かオブジェクトにすることで複数にできる
propsは配列とオブジェクトは参照渡しだから注意が必要

○子から親（データを変えるわけではない）
子の関数内で
this.$emit("名前", 処理内容)
親のコンポーネントタグ内で
v-on:名前="変数 = $event"　など　
#関数に渡した場合
関数(引数){
　this.number = 引数; #v-onで引数がなくても引数に値が渡される
}

$emitはカスタムイベントを作ることができる
ケバブケースで書く
Vue.jsまとめ⑤　コンポーネント

下書きが上限に達しているので仮の状態で投稿しています

Vueインスタンスを再利用するため
Vue.component('コンポーネントの名前', {コンポーネントの情報})
コンポーネントを使用するときは<コンポーネントの名前></コンポーネントの名前>
コンポーネントの情報はVueインスタンスのelプロパティ以外
ただし、dataは関数として書く（別のコンポーネントとも共有してしまうから）

グローバル登録
main.jsに
import 名前 from 場所
Vue.component('コンポーネントの名前', {コンポーネントの情報})

ローカル登録
変数 = コンポーネントの情報 #Vueファイルはそのままexport
続けてVueインスタンス内で(使いたいファイルのscriptタグ内で)
import 名前 from 場所
components:{ 
　'コンポーネントの名前': 変数　#同じなら省略可能
}

単一ファイルコンポーネントはインポートしたらオブジェクトになる

○単一ファイルコンポーネントの使い方
scriptタグはexport defaultで囲ってdataやmethodsなどを書く
templateタグは一つの要素にまとめる（divなど）

ケバブケース（like-number）かパスカルケース(LikeNumber)

styleタグ
CSSを記述
scopedで自身のコンポーネント内だけに限定する
Vue.jsまとめ④ Vue CLI

下書きが上限に達しているので仮の状態で投稿しています

○メリット
ファイル分割
コード軽量化
プラグインの使用
HMR
その他機能の使用

○フォルダ構造
node_modules 
パッケージが入っている

babel.config.js
babelの初期設定

package.json
バージョンなどの情報のまとめ

public
webパックによっていじられないフォルダ（ファビコンやindex.htmlの根幹などのみ、あまり触らない）

src
asets　イメージフォルダやCSSファイル
components 次回

main.js　src全体をまとめる
Linuxの新しいコマンド！！　その２

# 勉強の記録
- Linuxコマンドを覚えよう　2020/12/20

## 勉強した内容
- Linuxで使う便利なコマンドを覚える

## 何をベースに勉強してるか
- [N予備校 プログラミング入門](https://www.nnn.ed.nico/courses/668/chapters/9514)

## 内容の詳細
- cat : ファイルの結合する。　Excelのセルの結合をイメージしてるけどいいのかな…？
- less : ファイルの中身を見やすく表示！
- grep : ファイルの中から単語を指定して検索。（写真などであれば日付検索など！）

### わかったことについて
grepコマンドが一番わかりやすく、利便性があるように感じました。
今後エラーチャックなどでも役に立つそうなので期待値も高い！


### むずかしかったよ
- 授業内容に関しては特別難しいということは無いのですが、まぁとりあえず覚えなきゃって程度なので実際に使っていくまで脳に留めておけるかが分からない…＞＜

## 次回やる予定のこと
- 次回もまだこういうのが続くぽい！
TOPPERS SafeG-MでASP3カーネルとMicropythonを同時に実行する

# 概要
TOPPERS SafeG-Mを利用してASP3カーネルを保護しながらMicropythonを実行する方法を説明します。
SafeG-MについてはTOPPERS公式のページをご覧ください。
[https://www.toppers.jp/safeg-m.html](https://www.toppers.jp/safeg-m.html)
### 対応ハードウェア
STM32L552
評価ボード：NUCLEO-L552ZE-Q ([https://www.st.com/en/evaluation-tools/nucleo-l552ze-q.html](https://www.st.com/en/evaluation-tools/nucleo-l552ze-q.html))
このほか、PCとボードのシリアルポートを接続する手段が必要です（USB-シリアル変換器等）。
### 必要なソフトウェア
- STM32CubeIDE ([https://www.st.com/ja/development-tools/stm32cubeide.html](https://www.st.com/ja/development-tools/stm32cubeide.html))
- STM32CubeProgrammer ([https://www.st.com/ja/development-tools/stm32cubeprog.html](https://www.st.com/ja/development-tools/stm32cubeprog.html))
- ネイティブホストのツールチェーンまたはmpy-cross ([https://pypi.org/project/mpy-cross/](https://pypi.org/project/mpy-cross/))

# ビルドの手順

1. リポジトリをクローンし、submoduleを更新します。

    ```
$ git clone https://github.com/mtkrtk/micropython
$ cd micropython
$ git submodule init
$ git submodule update lib/stm32lib/
    ```

2. ネイティブホストのツールチェインがある場合は、mpy-crossをビルドします。

    ```
$ make -C mpy-cross
    ```

3. STM32CubeIDEを起動し、safeg-m/target/stm32l552/をワークスペースとして設定します。
4. メニューから"File" → "Import..." → "General" → "Existing Projects into Workspace"と選択し、"Select root directory:"にワークスペースのディレクトリを指定して全てのプロジェクトをインポートします。
5. sample/sample_Secure/configure.launchを右クリックして"Run As" → "configure"を実行し、Makefileを作成します。
6. Secureプロジェクト、NonSecureプロジェクトの順でビルドします。

# ハードウェアの設定
1. STM32CubeProgrammerを利用し、オプションバイトを以下のように設定します。
  - DBANK = 1
  - TZEN = 1
  - SECWM1_PSTRT = 0x00
  - SECWM1_PEND = 0x51
  - SECWM2_PSTRT = 0x7F
  - SECWM2_PEND = 0x00

2. PD_8とPD_9にUSB-シリアル変換器を接続します。

# 実行
ST-LinkをPCに接続し、STM32CubeIDEからsample/sample_Secure/sample.launchを右クリック、"Debug As" → "sample"を選択することで実行が開始されます。
ST-Linkのシリアルモニタを開くことで、ASP3のサンプルプログラムの出力を確認したり、コマンドを入力できます。
またASP3の全てのタスクが実行状態でなくなるとMicropythonが起動します。
MicropythonとはPD_8とPD_9のシリアルで通信できます。

Micropythonのタスクに対して、ASP3のタスクと同様にST-Linkのシリアルからコマンドを入力できます。
例えば4番のタスクに"t"コマンドを送信することでMicropythonを終了させられます。
"e"や"d"等のコマンドは、以下のPythonスクリプトを実行することで受信できます。

```py
import safegm
safegm.call_asp3()
```
dockerを使っている人docker-composeを使ってみる

#はじめに

なお、本記事は以下のUdemy講座を元にした覚書です。
[米国AI開発者がゼロから教えるDocker講座](https://www.udemy.com/share/103aTRAEASdltXRH0F/)


#docker-composeを使うと良い時
- docker run コマンドが長くなるとき
- 複数のコンテナをまとめて起動するとき

#準備
docker-composeが入っているか確認します。（Dockerインストール時に一緒に入っていますが、念のため）

```bash
$ $ docker-compose --version
docker-compose version 1.27.4, build 40524192
```
バージョン情報が出なかった場合、インストールしてください。
[Docker Compose のインストール](https://docs.docker.jp/compose/install.html)

build contextを用意します。今回の構成は以下の通り。

```:biuldcontext
project-name
　∟　docker-compose.yml
　∟　Dockerfile
　∟　その他
```

#docker runコマンドをdocker-copose.ymlに書いてみる

```bash:dockerコマンドの例
$ docker build .
$ docker run -d -it -v /Users/yukokanai/work/docker/project-name:/project-name -p 8888:8888 {image} bash
$ docker exec -it {コンテナ名}
```
これをdocker-compose.ymlに書いてみる

```yml:docker-compose.yml
version: '3'

services:
  web:
    build: .           #buildから実施
    ports:             #-p ポートフォワーディング
      - '8888:8888'
    volumes:           #-v hostディレクトリ(.)をコンテナディレクトリ(/project-name)にマウント
      - '.:/project-name'
    tty: true          #-t ttyを割り当てます。
    stdin_open: true   #-i STDINを開きます。
```
実行

```bash
#buildcontextに移動
$ cd project-name

#imageがなければbuildとrunを行う(webサーバーとして使いたいので-d)
$ docker-compose up -d
#キャッシュimageを使いたくない場合は以下の様にする
#$ docker-compose up --build -d

# コンテナの中に入る(webはymlに書いたサービス名）
$ docker-compose exec web bash
```
終了

```bash
$ docker-compose down
```

#複数コンテナを作る場合
サンプル

```yaml:docker-compose.yml

version: '3'

volumes:
  db-data:

services:
  web:
    build: .
    ports:
      - '3000:3000'
    volumes:
      - '.:/my_product-register'
    environment:
      - 'POSTGRES_PASSWORD=postgres'
    tty: true
    stdin_open: true
    depends_on:
      - db
    links:
      - db

  db:
    image: postgres
    volumes:
      - 'db-data:/var/lib/postgresql/data'
    environment:
      - 'POSTGRES_PASSWORD=postgres'
```
[MySQL] 昨日の特定時間の指定

最近SQLクエリを書くことが増え、つまづいた部分のメモ。

## 結論

```sql

CONCAT(CAST(DATE_FORMAT(DATE_SUB(CURDATE(), INTERVAL 1 DAY), "%Y-%m-%d") AS CHAR), "16:00:00")
```

やりたかったのは、あるレコードの登録日カラムの値が現在日時を基準に”昨日の16時以降”であるかどうかの判定

ただ、マイナス○時間やマイナス○日とかは出来るものの、時間の指定ができず、、
→[MySQLで「おととい」「昨日」「明日」「あさって」](https://qiita.com/redpanda/items/85c3f83ba95add333b5d)

そこで使用したのが、以下の関数
- [CONCAT関数](https://www.dbonline.jp/mysql/function/index35.html)
- [DATE_FORMAT関数](https://www.dbonline.jp/mysql/function/index49.html) 

## CONCAT関数
→日付と時刻を結合
日付はDATE_SUB関数を使用して今日からマイナス1日
時刻は定時を記載

## DATE_FORMAT関数
→DATE_SUB関数で変換した日時を年月日で指定

CAST関数を使用しているのは、日時（型：TIMESTAMP）をCHAR型にキャストするため
Live Share でペアプログラミングを行う。

#動作環境

この記事は

+ Windows 10
+ Visual Studio Code ver.1.51.1
+ LiveShare ver.1.0.3375

で書かれています。

LiveShare のログインに関しては別の記事を参考にして下さい。

# 手順

## ログイン

1. あらかじめ Live Share にログインします。

## セッションを開始する

1. 左下のアカウントのアイコンをクリックします。
2. テキストボックスに現れたリストから [Start Collaboration Session] をクリックします。

![liveshare006.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540529/9a0b2c61-dc14-593d-10b1-1ea60db956cd.png)

## 相手を招待する
1. 左上に [セッションの詳細] というツリーが出来るため、その後、左下の自分のアカウントをもう一度クリックします。
2. 右上のテキストボックスから現れたリストから [Invite Others(Copy Link)] をクリックすると、クリップボードにリンクがコピーされます。
3. Skype や Google のチャットなど、VSCode を使えるパソコンから開けるツールにクリップボードにコピーされたリンクをペーストして相手を招待します。

図2
![liveshare005.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540529/ec2cdead-f17a-f801-1d9a-4260fea47e30.png)

## 連絡先に相手が表示される

図3
![liveshare007.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/540529/604456c7-4d2e-dd72-b6fe-a18f93c53ccb.png)

注意)サーバーを Share しなくても、今開いているファイルを共有できます。
もしかしたら PyLint をインストール（更新）しないと Python で Live Share できないかも知れません。そこら辺は良く分かりません。すいません。
EC2インスタンスのターミナルでの初回起動時の設定

#概要
AWSでEC2インスタンスを作成後、インスタンスの初回起動時の設定について、ターミナルでインスタンスにSSH接続し、セキュリティ対策を行うまでを簡単にまとめます。この記事はEC2インスタンスが作成してあることが前提となっています。

#手順
##ターミナルでインスタンスに接続
ターミナルからSSH接続します。"my-key.pem"が保存されているディレクトリへ移動し、次のコマンドを実行します。"ec2-user@0.0.0.0"は接続するユーザー名とIPアドレスです。IPアドレス部は自分のインスタンスのパブリックIPに合わせてください。


```
例
ssh -i "my-key.pem" ec2-user@0.0.0.0
```
必要に応じて、次のコマンドを実行して、キーが公開されていないことを確認します。400の"4"は自分だけしか読み込めないようにするための属性です。

```
 chmod 400 my-key.pem
```
セキュリティ警告が出たら"yes"と入力してください。初回の接続時のみに尋ねられます。問題なければメッセージが表示され、接続が完了します。

##セキュリティ対策
セキュリティ対策として、"ec2-user"の変更およびSSH待ち受けポート番号の変更を行います。少し違いはありますが、ほとんど[ココ](https://avinton.com/academy/amazonec2-initial-setting/)と[ココ](https://avinton.com/academy/amazon-ec2-vpc/)を参考にさせていただき、簡単にまとめた記事となるので、詳細はurl先で確認していただいた方がわかりやすいです。

###ec2-user の変更
デフォルトのユーザーが"ec2-user"となっており、セキュリティ対策する必要があります。新しいユーザーを作成し、"ec2-user"をSSHができなくなるよう制限をかけます。

```
1. "test"には好きな名前を入力してください。
sudo useradd test

2. 作成したユーザーを/home ディレクトリで確認してください。
ls /home

3. ユーザーのパスワードの設定してください。"test"には好きな名前を入力してください。
sudo passwd test

4. 追加したユーザーでsudoコマンドを実行するには、ユーザーをwheel(root権限をもつグループ)というグループに登録する必要があります。
次のコマンドでユーザーをwheelグループに加えましょう。
sudo usermod -aG wheel test

5. wheelに所属しているユーザーは、次のコマンドで確認できます。
less /etc/group | grep wheel
```

###公開鍵のコピーとパーミッション設定
新規ユーザーでインスタンスへ接続するために、EC2に登録した公開鍵をユーザーのホームディレクトリ配下に登録する必要があります。

```
1. ec2-userのディレクトリにある公開鍵を、新規ユーザーディレクトリにコピーしてください。
sudo cp -R ~/.ssh/ /home/test/.ssh

2. コピーした .ssh ディレクトリとその配下にあるキーの所有者をec2-userから新規ユーザーへ変更します。
sudo chmod -R go-rwx ~test/.ssh

3. .ssh ディレクトリとファイルのパーミッションを制限します。
sudo chown -R test:test ~test/.ssh

4. 一度インスタンスからログアウトし、新規ユーザーでSSH接続後、rootになれるか確認してください。
ssh -i "my-key.pem" test@0.0.0.0
sudo su -

5. ec2-userでSSH接続ができなくなるようにするため、SSH設定ファイルに追記してください。
echo "DenyUsers ec2-user" >> /etc/ssh/sshd_config

6. 設定後、sshdを再起動します。
systemctl restart sshd
systemctl status sshd

```

###待ち受けポート変更
SSH接続のデフォルトの待ち受けポートは22番です。セキュリティ対策として別のポート番号に変更することを行います。

```
1. sshdのコンフィグファイルを開き、1024～49151の範囲内でポート番号を変更します。
sudo vi /etc/ssh/sshd_config

2. 下記を入力し、ポート番号を変更します。
例
Port 11111

3. 変更後、指定したポートをAWSのセキュリティグループで開けてください。
EC2 > セキュリティグループ > 対象のセキュリティグループ選択 > アクション >
インバウンドルールを編集 > ポート範囲に先ほど変更したポート番号(11111)を入力 > ソースをマイIPに変更 > 保存

4. 次回以降、sshする際は次のようにオプション（-p）をつけ、ポート番号を指定する必要があります。
ssh -i "my-key.pem" -p 11111 test@0.0.0.0
```

以上、インスタンスの初回起動時の設定として、デフォルトユーザーであるec2-userの変更とSSH接続時のポート番号の変更について簡単にまとめました。わかりづらい箇所については、下記の参考を確認していただければ詳細が載っています。

#参考
[参考] 大澤 文孝; 玉川 憲; 片山 暁雄; 今井 雄太. Amazon Web Services 基礎からのネットワーク＆サーバー構築　改訂3版. 日経BP. Kindle 版. 
[参考] https://avinton.com/academy/amazon-ec2-vpc/
[参考] https://avinton.com/academy/amazonec2-initial-setting/
機能の一部だけを使えるJavaScriptフレームワークを作る




# JavaScriptフレームワーク自作の試み
SPAと一部の入力バリデーション機能を作りました
名前を fframe とし github でプロジェクトを公開ています https://github.com/ikuo0/00013-fframe
変数名は ff です、fframeの機能を使う際は ff.ApplyRouter("./source", $("body"), {"ajax-cache": false}); のように変数 ffからアクセスします。

## 動作例
![全部１.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104691/d20d0082-fa65-bc3d-8450-effca01b735a.png)


## 自作する理由とか
フォーム全体を包括するのではなくピンポイントで使いたい所にだけ機能を提供するフレームワークが欲しいと思って自作することにしました
とりあえず今回使いたかった機能はSPAとバリデーション機能なのでその2つだけです。
HTMLテンプレートに関してはスタイルシートで display: none; としてテンプレートを作成する昔ながらの手法？で充分だと思っていますので作る必要は無いと考えています

## ソース本体
https://github.com/ikuo0/00013-fframe/blob/master/js/fframe.js
これをコピペして読み込んで下さい、JQuery必須です。

## SPAの使い方（router機能？の使い方）
### index.htmlへの記述

``` javascript
        <script type="text/javascript">
            delay(1) // bodyの描画完了を待つ // delay はfframe.js 内で宣言されている関数です
            .then(function() {
                // HTML, JSファイルのディレクトリを指定、SPAする要素を指定、キャッシュを使うかどうかの指定
                ff.ApplyRouter("./source", $("body"), {"ajax-cache": false});
                return true;
            })
            .then(function() {
                // 初回アクセス等、ハッシュ指定が無い場合の対処
                if(!ff.PathInfo.pageKey) {// ff.PathInfoにURL、ハッシュ等の情報がまとめられている
                    window.location = "#!input-form";
                }
                return true;
            });
        </script>
```

### ハッシュ名＝ファイル名という規則
例えば以下の場合

```
https://????.com/index.html#!hoge
```

hoge.html hoge.js の順番にファイルを読み込み body タグの中身を hoge.html に置き換えます、プログラム的にファイルの有無チェックや整合性を取る事はできないため事前にファイル名を合わせて準備しておく必要があります。
この場合は hoge.html hoge.js の２ファイルを予め作っておく必要があります。

### JSファイルで関数を即時呼び出す実装とする
hoge.js の実装は以下のように作成し、JSファイル読み込みと同時に実行されるように仕込みます。

``` javascript
// hoge.js の実装
// 日本語
(new function() {
    console.log("start");
    var self = this;
    self.start = function() {
        console.log("a#start");
        var me = this;
        // 処理
    }
    self.start();
}());

```
routerの起動
https://github.com/ikuo0/00013-fframe/blob/master/index.html

router対応のJSファイルの書き方
https://github.com/ikuo0/00013-fframe/blob/master/source/a.js


## 変数同期、自動バリデーションの使い方
HTML

``` html
<input id="input-text" type="text">
```

Javascript

``` javascript
var obj = {
    "OnChange": function(id, val) {
        var obj = this;
        print("obj[" + id + "]=" + obj[id] + "");
    }
};
ff.AddSyncroAndValid_Text(obj, "#input-text", {"value": "HOGE", "min": 3, "max": 15});
```

フォーム例
https://github.com/ikuo0/00013-fframe/blob/master/source/input-form.html

フォームに変数同期とバリデーションを追加する例
https://github.com/ikuo0/00013-fframe/blob/master/source/input-form.js

以上です
UiPathでC#コードを呼び出す

* UiPathでC#コードを呼び出しをする方法

# 手順

#### １．「コードを呼び出し」アクティビティを使用する 

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184967/e3d4e0e7-2426-d6ba-4f3c-4fac4d358d4c.png)


#### ２．コードを記入
* 言語は「CSharp」にすること。
* コードはコードを書いたファイルを呼び出すのではなく直接記入する。

![11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184967/08a69926-6c86-79ad-8353-51cb0fa9390a.png)


【コード全文】

``` CSharp
string name = argInput;
string result = String.Concat( "Hello," , name);

argOutput = result;
```

引数の設定によりデータの受け渡しをする。

![10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184967/dee0ad10-33b5-4d9d-91ec-094c32d711f5.png)


#### ３．実行フロー＆実行結果

【実行フロー】
![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184967/0016376c-c898-0afc-9b57-7502704c2ede.png)

【実行結果】
![12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184967/74dc1971-72d9-a3dc-3ea0-3bf584b10d27.png)
CloudFront 

<H2>CloudFrontとは</H2>
・CDN(Contents Delivery Network）
・静的コンテンツの配信を高速化するサービス

<H2>CloudFrontの仕組み</h2>
・オリジンサーバーの静的コンテンツをキャッシュしておくことで、クライアントへの応答を高速化する。
　※キャッシュにない場合は、オリジンサーバーから取得する。
・エッジサーバーは世界各地に存在している。
　クライアントの位置情報をもとに、一番近いエッジサーバーからコンテンツを配信することで、距離によるレイテンシを低減する。
・オリジンサーバーへのコンテンツのリクエストを減らすことで、オリジンサーバーへの負荷を軽減させる。
Node.jsでデータベース検索

データベースから必要な情報を検索する。
データベースはsqlite3を使用。

```hello.js
router.post('/find',(req,res,next) => {
    var find = req.body.find;
    db.serialize(() => {
        var q = "select * from データベース名 where";
        db.all(q + find,[],(err,rows) => {
            if(!err){
               var data = {
                   title: 'Hello/find',
                   find:find,
                   content:'検索条件' + find,
                   mydata: rows
               }
               res.render('hello/find',data);
            }
        });
    });
});
```
後はhtmlに以下のコードをbodyに入力して完成させる。

```find.ejs
<div role="main">
        <p><%= content %></p>
        <form method="post" action="/hello/find">
            <div  class="form-group">
                <label for="find">FIND</label>
                <input type="text" name="find" id="find"
                class="form-control" value="<%=find %>">
            </div>
            <input type="submit" value="更新"
            class="btn btn-primary">
        </form>

        <table class="table mt-4">
            <% for(var i in "データベース名") { %>
            <tr>
                <% var obj = "データベース名"[i]; %>
                <th><%= obj.id %></th>
                <td><%= obj.name %></td>
                <td><%= obj.mail %></td>
                <td><%= obj.age %></td>
            </tr>
            <% } %>
        </table>
    </div>
```
結果
(検索前)
![検索前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942694/53cb49e9-c59b-3b7b-0da3-79caaff2660d.png)
(検索後)
![検索結果.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/942694/4875717b-47d6-f276-e844-f125f94b9ab1.png)
検索条件を変えることで必要なデータを得られる。
FaceBookAPIで、広告キャンペーンを作成


## 概要
FaceBookAPIを使用して広告キャンペーンを作成する際のコードにちょっとハマったので備忘録的に書き留めておきます。


##キャンペーン作成コード
Laravel用に書いてます。

```
　　public function createCampain(Request $request)
    {
        $url = 'https://graph.facebook.com/v9.0/act_' . '広告アカウントID' . '/campaigns';

        $data = [
            'name'                  => 'キャンペーン名',
            'objective'             => 'LINK_CLICKS',
            'status'                => 'PAUSED',
            'special_ad_categories' => '[]',
            'access_token'          => 'アクセストークン',
        ];

        $data = http_build_query($data, "", "&");

        $header = [
            "Content-Type: application/x-www-form-urlencoded",
            "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)",
        ];

        $options = [
            'http' => [
                    'method'  => 'POST',
                    'header'  => implode("\r\n", $header), 
                    'content' => $data
                ]
        ];

        $json   = file_get_contents($url, false, stream_context_create($options));
        $json   = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
        $result = json_decode($json, true);
    }
```

###ちなみにキャンペーン取得コード

```
    public function getCampain(Request $request)
    {
        $url = 'https://graph.facebook.com/v9.0/act_' . '広告アカウントID' . '/campaigns';

        $data = http_build_query(
            [
                'fields'            => "name",
                'access_token'      => "アクセストークン",
            ]
        );

        $header = [
            "Content-Type: application/x-www-form-urlencoded",
            "User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"
        ];

        $options = [
            'http' => [
                    'method' => 'GET',
                    'header' => implode("\r\n", $header), 
                ]
        ];

        $json   = file_get_contents($url . '?' . $data, false, stream_context_create($options));
        $json   = mb_convert_encoding($json, 'UTF8', 'ASCII,JIS,UTF-8,EUC-JP,SJIS-WIN');
        $result = json_decode($json, true);
    }

```

##あとがき
広告や広告セットもURLの最後を/campaigns→/adsに変えるくらいで動くと思います。
Raspberry Piのデフォルトシェルを大好きなscorphish (fish)にする

### scorphishの魅力
　あれは確か2017年だったか，新しいMacbookを購入した際，友人にMacbookを貸し出して諸々の全てのセットアップをお願いしました。するとターミナルのシェルがfishテーマの[scorphish - Github](https://github.com/oh-my-fish/theme-scorphish)を更にカスタマイズしたものになって帰ってきました。fishが便利なのは言わずもがなですが，このscorphishテーマはgitのstaging状況やcommit，push状況をコンパクトに表現してくれるので大のお気に入りになりました。
　リッチみが足りないbashを使えない身体になってしまったので，手元のRaspberry Piにもfishを入れたいと思います。
### fishの導入
　何か特別な操作をする訳ではありません。公式ページ (https://fishshell.com) より，[Go fish] > [Linux]タブ > [debian]の「Subscribe or Download」をクリックすると，[opensuseのfish導入ページ](https://software.opensuse.org/download.html?project=shells%3Afish%3Arelease%3A3&package=fish) が開くので，ページの指示に従ってLXTerminalにコマンドをコピペします。

```terminal:LXTerminal
$ echo 'deb http://download.opensuse.org/repositories/shells:/fish:/release:/3/Debian_{バージョン}/ /' | sudo tee -a /etc/apt/sources.list
$ curl -fsSL https://download.opensuse.org/repositories/shells:fish:release:3/Debian_{バージョン}/Release.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/shells_fish_release_3.gpg > /dev/null
$ sudo apt update
$ sudo apt install fish
```

{バージョン}のところには，Debianのバージョンを入れてください．バージョンはターミナルで次のように確認できます．

```terminal:LXTerminal
$ cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
```

VERSION_ID="10"なので，私は{バージョン}に10と入れて導入しました．次にfishをデフォルトシェルに変更します．

```terminal:LXTerminal
$ sudo chsh --shell $(which fish)
```

ターミナルを再起動すると，リッチなfishが立ち上がるはずです。

### scorphishの導入

　fishを入れたところで，大好きなscorphishテーマに変更したいと思います。パッケージマネージャであるfisherをインストールした後，scorphishをインストールします。

```terminal:LXTerminal
$ curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs https://git.io/fisher
$ fisher install oh-my-fish/theme-scorphish
```

ターミナルを再起動すると，見た目がコンパクトでリッチなシェルが起動します．
![スクリーンショット 2020-12-20 15.23.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699329/96a9349a-8fb5-cefd-bbad-c027831aa21b.png)

　なお，fishの設定ファイルは全て**~/.config/fish/**にあるので，fishシェルでパスを通したりする際はこの配下に**config.fish**を作ってそこに環境変数を記述してください (参考: https://qiita.com/ledsun/items/8ca1a450b21c8ebc9670) 。お疲れ様でした。
エンタープライズ向けAzure App Service

# Azure App Serviceとは
Azure App ServiceはMicrosoft社が提供しているPaaS（Platform as a Service）で、
企業が.netやjavaで開発したWEBアプリケーションをセキュアで運用できるクラウドプラットフォームである。
[App Service の概要](https://docs.microsoft.com/ja-jp/azure/app-service/overview)
##魅力的な機能
**<font color='blue'>1. 伸縮自在</font>**
昔のWEBホスティングプラットフォームと違って、どんなストレスにも堪えられるように自動的にスケールアップ（CPU、メモリの増設）やスケールアウト（実行環境のインスタンス数）を上げることができる。
また、負荷が無い時にスケールダウンやスケールインにして**伸縮自在**を実現できる。

**<font color='blue'>2. 災害時のBCP（事業継続計画）対応</font>**
Azureが提供している数多くの地域（リージョン）から２つ以上の地域に（例：東日本と西日本）にアプリケーションをデプロイすれば
企業が自然災害、大火災などの緊急事態に遭遇できて、企業の経済的価値だけでなく社会的価値の向上に繋げることができる。
[Azure地域の概要](https://azure.microsoft.com/ja-jp/global-infrastructure/geographies/)

**<font color='blue'>３. セキュリティー</font>**
開発者がいくら技術力に優れていてもアプリケーションの脆弱性やセキュリティーを全て考慮して開発するとは限らない。
よくあるのはセキュリティーガイドラインやチェックシートを作成して、そのガイドラインやチェックシートに沿ってレビューを行う。
しかし、レビュイーとレビュアーも最近どのような脅威があって、本当に対応できているか分からないケースもよくある。
Azure App Serivceプラットフォーム自体のセキュリティーをマイクロソフト社が保護するので、
開発者はアプリケーション層のセキュリティーに集中して開発できる。
また、WAF（WEBアプリケーションファイアウォール）を提供しているAzure Front DoorやAzure Application Gatewayを使用すれば、追加構成を必要とすることなく、新たな脆弱性の対応が自動的に適用される。

##プランの種類
| プラン | 概要 |
|:-:|:-:|
|無料   | 1日約60分使える、無料である、デモ環境やテスト環境に向いている |
|共有   | 1日約 240 分使える、共有環境である、開発/テスト環境に向いている  |
|BASIC   | 時間制限のない格安プランである、 開発/テスト環境に向いている |
|STANDARD   | 自動スケールに対応した専用環境、運用環境に向いている  |
|PREMIUM   |  スタンダードよりパフォーマンスが強化された環境であり、運用環境に向いている |
|ISOLATED   |  ネットワークが分離され、パフォーマンスが優れている環境であり、ハイパフォーマンスを要とする運用環境に向いている |
[App Service の価格](https://azure.microsoft.com/ja-jp/pricing/details/app-service/windows/)
[App Service プランに関する詳細を表示する](https://docs.microsoft.com/ja-jp/azure/azure-resource-manager/management/azure-subscription-service-limits#app-service-limits)

##無料でAzure App Serviceを試す
Azure の無料アカウントを作成すれば、 １２ヶ月間無料サービス利用できます。
[Azure の無料アカウントの作成](https://azure.microsoft.com/ja-jp/free/)
プログラミングを学習し始めて人工知能エンジニアとして転職するまでの学習軌跡

2020年は人工知能エンジニアとして転職することができました。プログラミングを学び始めたのはここ１年半程度です。年末というこの機会に、この１年半でやってきたことを振り返っていきます。
これから、エンジニアを目指す方々の一助になるようであれば幸いです。

#目次
[1. 自己紹介](#1-自己紹介)
[2. プログラミングを学び始めるきっかけ](#2-プログラミングを学び始めるきっかけ)
[3. 2019年8月〜11月：Python学習開始](#3-2019年8月〜11月：Python学習開始)
[4. 2019年12月〜2020年5月：AI勉強&転職活動](#4-2019年12月〜2020年5月：AI勉強&転職活動)
[5. 2020年5月〜8月：DockerやAWSを学ぶ](#5-2020年5月〜8月：DockerやAWSを学ぶ)
[6. 2020年9月〜現在](#6-2020年9月〜現在)

#1. 自己紹介
初めまして。スイミンと申します。私のスペックとしては以下の通りです。
> 出身地：関東
> 学歴：国立大学 理系大学院卒（プログラミング関係なし）
> 職業歴：新卒で銀行系SIerに入社→2020年5月より転職し人工知能エンジニアとして採用される
> プログラミング経験：学生時代に授業の過程でFortranを少しだけ。SIer時代はコードに触れる機会なし

#2. プログラミングを学び始めるきっかけ
大学院を卒業し就職したSIer企業では、銀行勘定系システムの担当としてプロジェクトを推進していました。この時はコードに触れる機会はなく、設計やスケジュール管理などがメインのタスクでした。

きっかけは`2019年8月`。上司からプログラミング学習を薦められて、学習し始めました。学習を進めるに従って自分がシステムの仕組みについて無知さや、SIer企業にこのまま働き続けることへに不安を覚える機会が増え、転職を考えるようになりました。

#3. 2019年8月〜11月：Python学習開始
## 3-1. オンライン学習サイト
オンライン学習サイト(PyQ)でPythonの学習開始。
Pythonの基礎はこの学習サイトで学んだ。

![スクリーンショット 2020-12-19 19.02.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530363/f7a19f48-82ba-6fe2-4f37-1b31c3860782.png)
[PyQ(パイキュー)](https://pyq.jp/)

<良かった点>
・ステップに則って課題をこなしていけば、プログラミングのスキルが身に付く
・自分のペースでガンガン進めるので、やる気があれば短期間でスキル向上
<課題点>
・オンライン学習サイトのため、進捗がやる気に比例する。
　やる気が下がると進捗が顕著に下がってしまう。

## 3-2. 個人開発
3-1でPythonの基礎を学び、簡単なアプリを作ってみた。使うパッケージはtkinterやopenpyxlなどを使用。リストや辞書の考え方に悪戦苦闘しながら作成。

勉強していた頃の記事：[【Python】tkinterでファイル&フォルダパス指定画面を作成する](https://qiita.com/dgkmtu/items/2367a73f7e2d498e6075)

<良かった点>
・実践することでPythonの理解が一歩進んだ
・技術系の記事の書いてあることがなんとなく分かり始める
<課題点>
・何度も立ち止まって調べないといけないので、根気が必要
・仕事も別にやりながらのため、時間確保の課題がある

#4. 2019年12月〜2020年5月：AI勉強&転職活動
## 4-1. AI学習のため勉強開始
「Pythonできるようになったら、AI勉強しないとだろ！！」といった若干の勢いでAIの勉強開始。
それなりにお金がかかるので迷ったけど、勢いのまま下記の学習サイトで勉強した。

![スクリーンショット 2020-12-19 19.40.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530363/6bb7fd95-f5b6-ab45-6d3b-930d6b504984.png)

[TechAcademy(テックアカデミー)](https://techacademy.jp/)

<良かった点>
・メンター制度で課題に思ったことを先輩エンジニアに質問できる
・テキストが受講後も閲覧可能なため、復習に活用できる
<課題点>
・PyQと同様、個人のモチベーションに進捗が左右される
・料金はそれなりにするので、払った分を回収できるかどうかは自分次第

## 4-2. 転職活動
2019年12月末〜2020年2月にかけて転職活動をした。
当時はSESとweb系企業の区別がついてなく、なんとなくイメージしやすいSESを選択。
(当時を振り返るとweb系企業も選択肢に入れとくべきだったかな)

転職活動は順調に進み、2月で転職先が決定。

#5. 2020年5月〜8月：DockerやAWSを学ぶ

##5-1. Udemy講座で学習
Pythonが動く環境の構築に向けて、DockerやAWSを勉強。 
AWSのEC2を使ってDockerで環境構築し、GPUを繋げるまでを習得。

![スクリーンショット 2020-12-20 14.51.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530363/239b0bce-4802-7ac4-b9cb-e76627e2c180.png)

1, [ゼロからはじめる Dockerによるアプリケーション実行環境構築](https://www.udemy.com/course/docker-k/)
2, [米国AI開発者がゼロから教えるDocker講座](https://www.udemy.com/course/aidocker/)

##5-2. 自作の画像認識アプリを作成
AI+Django+Dockerを使って画像認識アプリを自作。
CDジャケット画像から音楽ジャンル判定する。
この頃になるとPythonのプログラミングには自信がついてきたかな。

![ImageRecognition.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530363/2fdc0702-911c-12cd-ca75-33c39d74e374.png)

#6. 2020年9月〜現在
現在はkaggle([https://www.kaggle.com/](https://www.kaggle.com/))に挑戦中。
まだまだ、プログラミングのスキルは足らないことばかりなので、
より技術を高めていきたい。
python requestsを使ってpostリクエストをretryする

しょーもないハマり方をしてしまったので供養のためメモ

pythonのrequestsモジュールを使う際、リトライの処理を実装したいときはurllib3.utilのRetryが使えます。

今回postでステータスコード500が帰ってきた時に一定時間待ってからリトライする処理をさせたかったので、Retryを使ったのですが500番が返ってきてもリトライしてくれず...
結論を言うとpostでリトライさせたいときは引数のallowed_methos渡してをPOSTリクエストに関して明示的に許可してやる必要がありました。

```python:test.py

import requests
from requests.packages.urllib3.util.retry import Retry
from requests.adapters import HTTPAdapter
import logging

logging.basicConfig(level=logging.DEBUG)

session = requests.Session()

retries = Retry(total=5,backoff_factor=1,allowed_methods=['POST'],status_forcelist = [500])
retries_default = Retry(total=5,backoff_factor=1,status_forcelist = [500])
logging.debug(repr(retries.__dict__))
logging.debug(repr(retries_default.__dict__)) #指定しないとallowed_methosにPOSTがない
session.mount('https://',HTTPAdapter(max_retries=retries))

session.post('https://httpbin.org/status/500')

```
(修正中)SSHの解説と鍵生成方法(Mac向け)

# この記事は修正中です。

この記事は指摘が入り、修正中です。
詳しくは、 @angel_p_57 様のコメントをご覧下さい。

>> SSHでは公開鍵と秘密鍵という鍵のペアを使用して、共通鍵の交換を行います。

> この記述そのもの、文面だけなら間違いではないんですが、その後の記述はもろもろ完全に間違いなので、そもそも技術内容を把握されてないと思います。書くならちゃんとウラを取りましょう。
※ただし、世の中解説を書いてる人のほぼ全てがウラを取らず想像・伝聞でしか書いてないので、検索してもマトモな記事はまず見つかりません。現実のソフトの動きを追うなり、公式の技術ドキュメントを読み込む必要があるので、注意が必要です。
通信の流れの概要は「SSHの公開鍵認証における良くある誤解の話」の「[妥当な説明](https://qiita.com/angel_p_57/items/2e3f3f8661de32a0d432#妥当な説明)」の章に挙げてますが、予備知識なしで把握するのは難しいかも知れません。
最低限「[SSHの公開鍵ってなに?](https://qiita.com/angel_p_57/items/19eda15576b3dceb7608)」の内容が把握できていれば十分ではないかと思います。


# SSHとは

SSH(Secure Shell)とはざっくり言うと、高度なパスワード認証を使って暗号化した通信を行う仕組みのことです。
暗号化することにより、安全にネットワーク越しに通信することができます。

まずはSSHでの通信の仕組みを軽く説明します。

## SSHで使用する3つの鍵

SSHでは公開鍵と秘密鍵という鍵のペアを使用して、共通鍵の交換を行います。
とりあえずこの3つの鍵を説明します。

### 公開鍵とは

公開鍵とは相手に公開する鍵のことです。
この鍵はもしインターネット上に公開しても問題はありません。

この公開鍵を使うと、文字を暗号化することができます。
（鍵を掛けるイメージ）

### 秘密鍵とは

秘密鍵は言葉の通り自分だけが持っている秘密の鍵のことです。
名前の通り、絶対に自分以外の人に公開してはいけません。

この秘密鍵を使うと、公開鍵によって暗号化された文字を複合する（元の文字列に戻す）ことができます。
（鍵を開けるイメージ）

### 共通鍵とは

自分と通信相手だけにしか知られてはいけない鍵のことです。
（共通で使用するパスワードみたいなもの）

## 実際のSSHでの通信の流れ

登場人物
Aさん：通信を持ちかける人（クライアント）
Bさん：通信する人（ホスト）

A「Bさん、私と秘密の通信をしませんか？」

AがBに鍵（公開鍵）を渡す。

B「わかりました。ではこのパスワード（共通鍵）で通信しましょう」

BがAに共通鍵（公開鍵で共通鍵自体を暗号化する）を渡す。
その後Aは共通鍵を秘密鍵で複合する。

A「ふむふむ。このパスワードですね。わかりました」

以降、共通鍵で通信する。

### SSHのメリット

秘密鍵を間違えて公開してしまわない限り、ほぼ、盗聴されることがないこと。
これが一番大きいです。

パスワード認証だと、相手のサーバーにIDとパスワードを送信することになります。
もし、これが盗聴されていたら、終わりです。
また、サーバー側からパスワードが漏洩する可能性もあります。

しかし、SSHでは自分が秘密鍵を間違えて漏洩させてしまわない限り、安全です。

# SSHの鍵生成方法

これまでに説明した鍵ペアというものは簡単に作ることができます。

まずはターミナルアプリを開きます。
HOMEの下にSSH用のフォルダを作成し、そこに移動します。
以前に作成した鍵がないかも確認します。
lsコマンド（フォルダの中身を見るコマンド）で入力後に何も表示されなければ大丈夫です。

```
$ mkdir ~/.ssh
$ cd ~/.ssh
$ ls
```

次にRSAと呼ばれる方式の鍵のペアを作成します。
何点か聞かれますが、こだわりがなければEnter連打で大丈夫です。

```
$ ssh-keygen -t rsa
```

そしてlsコマンドで生成したファイルを確認します。
以下の二つがあれば大丈夫です。
.pubがついている方が公開鍵です。

```terminal
$ ls
id_rsa          id_rsa.pub
```

ここまでくれば、あとはサーバーに.pubを送信すればいいだけです。

ね、簡単でしょ。

# 参照
https://qiita.com/hanlio/items/689d796ec51fcf4c05aa
https://www.sejuku.net/blog/74220
【Rails】Herokuデプロイ時　you can't define an already defined column '   '　対処方法

ローカル環境での開発時は気づかなかったのでが、herokuデプロイ時に色々問題が起きたので、備忘録として書いておきます。
#事の発端
こんなエラーがでて、マイグレートできませんでした。

```
rails aborted!
StandardError: An error has occurred, this and all later migrations canceled:
you can't define an already defined column 'name'.
```

#一度データベースをリセットしてみる
一度データベースをリセットしてマイグレートもし直します。
※データベースの中身は全て消えますので注意！データが消えて困る方は実行しない事！

```
$ rails db:migrate:reset
```
で、もう一度マイグレート

```
$ rails db:migrate
```

すると、こんなエラーがでました。

```
StandardError: An error has occurred, this and all later migrations canceled:

PG::UndefinedColumn: ERROR:  column "user_id" of relation "scores" does not exist
```
タイムスタンプ順にマイグレートされていくのですが、あるマイグレートファイルのところでエラーがでました。色々問題はあったのですが、大きな問題としては存在しないカラムをreomoveしようとするマイグレーションファイルが存在していました。それを削除してもう一度マイグレーションを実行すると問題なくマイグレーションできました。
初心者（私）におすすめしたい便利アプリ

##初心者(私)は今すぐ入れた方がいい！
ネットサーフィンをしていたところ、(Qiita)で面白い記事を見つけました
その中の記事に書かれていた内容の二つを今、私が使っていてすごく便利だなと思ったので、
本記事を書いております。


##Deepl
###Deeplとは翻訳アプリである。
何が便利なの？？

ずばり、

####一瞬で翻訳してくれる。(⌘CC)ですぐに画面遷移し、翻訳を開始してくれる
![tannbo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825677/9fdd1825-901d-cefd-59ec-f60a837e2ce6.png)
(翻訳内容は適当です。。すいません。)

railsでよくブラウザでエラー文が出たときは、いちいちコピペしてっていう作業を短縮することができる。かなりおすすめのアプリです。


##Wappalyzer
Wappalyzerとは、Chromeの拡張機能である。

どんな拡張機能か？？

ずばり、

WEBサイトに飛んで、Wappalyzerを見ると、どんな構成でアプリが作られているか、
どんな言語で作られているか、どんなフレームワークで作られているか、

参考にしたいWebサイトの詳細を簡単に見ることができる。


###Qiitaの場合

![RRRR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/825677/09393446-ab2a-38e8-50e8-04f1b72de6b2.png)


このように、使用言語や、ライブラリ、フレームワーク、アナリティクスまで、
気になるアプリケーションの構成などを簡単にみることができる超便利な拡張機能。

Chromeの場合、拡張機能で簡単にインストールできるので、初心者で、まだ業界において知識が浅い方などは、興味本位でいろんなアプリケーションで試してみるといいかもしれません！！！
C# 入門 【基本文法】

# 【C# 入門】

来年からC#を使った業務に従事することになりました。
そのため、休日を使ってC#を簡単に学習してみました。

Microsoftの[C# 関連のドキュメント](https://docs.microsoft.com/ja-jp/dotnet/csharp/)を参考にしました。

## オブジェクト指向

C# は、オブジェクト指向、"コンポーネント指向"のプログラミング言語である。
堅牢で永続的なアプリケーションの構築を支援するさまざまな機能が用意されている。
Javaと似たようなところが多いとされている。

## Hello, World

```C#
using System;

class Hello
{
    static void Main()
    {
        Console.WriteLine("Hello, World");
    }
}

//出力結果
//Hello, World
```
・using System
→System 名前空間を参照する using ディレクティブで始まる。
 (名前空間は、プログラムとライブラリを階層的に整理するための手段）

・class Hello
→class名は、Hello（Java : public class Hello）

・static void Main( )
→基本的な構文（Java : public static void main(String[] args)）

・Console.WriteLine("Hello, World");
→出力（Java : System.out.println("Hello, World");）

## 型と変数

・値型と参照型の2種類の型がある。
値型の変数が直接データを格納するのに対して、参照型の変数はデータへの参照を格納する。

```C#
string sample = "Hello";
Console.WriteLine(sample);
string sample2 = "World";
Console.WriteLine(sample2);

//出力結果
//Hello
//World

string sample = "Hello";
Console.Write(sample);
string sample2 = "World";
Console.Write(sample2);

//出力結果
//HelloWorld
```

出力時、Console.WriteLine(　);だと改行される。
Console.Write(　);だと改行されずに引き続き出力される。

## 文字列の処理

・string
→文字列を定義する。（Java : String）

```C#
string firstSample = "Taro";
string secondSample = "Hanako";
Console.WriteLine($"My friends are {firstSample} and {secondSample}");

//出力結果
//My friends are Taro and Hanako
```

## 整数の演算

・int型は、整数を表す。
　+ : 加算
　- : 減算
　* : 乗算
　/ : 除算

```C#
int a = 5;
int b = 15;
int c = a + b;
Console.WriteLine(c);

//出力結果
//20
```
## 整数の有効桁数と制限

・int型には最小値と最大値の制限がある。
これらの制限を超える値が作られると、オーバーフローの状態になる。

```C#
int max = int.MaxValue;
int min = int.MinValue;
Console.WriteLine($"The range of integers is {min} to {max}");

//出力結果
//The range of integers is -2147483648 to 2147483647
```

## 条件判断

・ifステートメントを使用した条件判断

```C#
int a = 5;
int b = 6;
if (a + b > 10)
    Console.WriteLine("The answer is greater than 10.");

//出力結果
//The answer is greater than 10.
```

・if と else を組み合わせ

```C#
int a = 5;
int b = 3;
if (a + b > 10)
    Console.WriteLine("The answer is greater than 10");
else
    Console.WriteLine("The answer is not greater than 10");

//出力結果
//The answer is not greater than 10
```

・ループを使用した処理の繰り返し
whileステートメントは、条件が false になるまで、条件の確認と実行を繰り返す。

```C#
int counter = 0;
while (counter < 3)
{
  Console.WriteLine($"The counter is {counter}");
  counter++;
}

//出力結果
//The counter is 0
//The counter is 1
//The counter is 2
```

・for ループの処理

```C#
for(int counter = 0; counter < 3; counter++)
{
  Console.WriteLine($"The counter is {counter}");
}

//出力結果
//The counter is 0
//The counter is 1
//The counter is 2
```

# これから。

簡単にまとめはしましたが、ほとんどJavaと同じような感じになりました。
来年からの業務は主に保守ですが、ソースコードを読めないといけないです。
今後も、この記事に追加していこうと思います。
製造業向けにPower BI活用を提案しての振り返り

# 概要
この1年、中小規模工場を操業している製造業企業に対して、
生産性向上の一環としてIT/IoTシステムを提案するとともに、
そのデータの利活用手段としてPower BIを提案してきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/01b3afe3-a8f2-4260-b2a4-c74b74876f6b.png)

その取り組みを簡単にまとめ、振り返りをしたいと思います。


# 中小工場の現状
ざっくり簡単に説明していきますが、工場の生産ラインにどのような工程があって、
それらにどのような作業があって、そして作業にどれくらい時間がかかっているかを把握していきます。
また、合わせて誰が何をどのくらいの時間しているかも把握していきます。
※実際は

ということで、たいてい生産ラインに対して指示書等で作業指示が行われて、
それを日報として報告したりするのですが、
　・手書きで日報をつけていたり、つけていなかったり・・・
　・手書き日報は、事務員や生産管理担当の方が、Excelに入力しなおしたり・・・
　・Excelをゴニョゴニョして、原価や作業時間を計算したり・・・
という現状だったりします。

# 導入したこと
・工場の作業員が、スマホアプリでリアルタイムに作業記録（やること、開始日時、終了日時）をつけれるようにする
・スマホアプリで入力された作業記録は社内のDBに自動で保存。作業時間も自動計算。
・Power BI Desktopでデータを見える化

# 振り返り
### 導入しやすさについて
中小工業では大きな予算を取ることが難しいです。
また、改善効果が見えない段階で費用をかける許可が下りにくい場合もあります。
その点を見越し、無料で使えるPower BI Desktopを使用することにしました。

分析ツールなんて言うと、敷居が高く感じられるようでしたが、
こちらで簡単な画面を作成してデモした結果、
職員さんが、「自分でもできそう！」と思えたとのこと。
ドラッグ＆ドロップで画面を作っていける点が好評でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/8dc245f6-b7cf-ddb0-215d-43805f0010d1.png)


現場の生産性データだけじゃなくて、販売管理システムのデータをCSV出力してPower BI Desktopに取込み、
受発注データなども自分で可視化し始めるツワモノさんが現れたりしました。


### ビジュアルについて
生産計画等では、ガントチャートを作成することが多いのですが、
Excelで作成するのは結構手間ですよね。

Power BIで簡単にガントチャートを表示できることを伝えると、相当喜ばれました。
ガントチャートのビジュアルの使い方は、過去記事で紹介していますので
参考にされてください。
⇒ [Power BI Tips - ガントチャートを表示する](https://qiita.com/yossihard/items/17ab837374de66a9804f)

生産性の分析では、これまではExcelで円グラフや棒グラフを作成されていましたが、
もちろんPower BIでもそれらが作れます。

ちょっと問題なのは、パソコンがインターネットに接続されていないと、
ガントチャートが表示されない点です。
もしかして、App Sourceから取得したビジュアルは、全てそうなのかな？


### データの取り込みについて
企業内にはデータベースだけでなく、Excelファイルや他のシステムのデータ等、
分析に使用するデータが点在するのが実際です。

Power BI Desktopで、それらが簡単に取り込めるのもかなり好評でした。
元データが更新されても、更新ボタンを押せば取り込めるのも嬉しいですね！

ただ、データベースからのデータの取り込みと、
取り込んだ各種データの紐づけ（リレーションシップの管理）が難しいようでした。
⇒一対多／多対多といった用語が取っつきにくいようです。


### 共有方法
レポートを安全に共有する方法として、Power BI サービスを使用することも考えたのですが、
分析画面の作成と閲覧でツールが変わることを避けるため、
生産管理の方がpbixファイルを作成し、それをファイルサーバー等で共有してもらうようにしています。

Power BIの操作に慣れていない方の方が多いので、表示タブの「オブジェクトをロック」を有効にして、
レポート上のグラフ等のオブジェクトがずれないようにしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146789/e788d7e1-b09c-f2cd-3516-47b4169d0a52.png)

# まとめ？
今は一つの部署での運用だったりですが、
運用する部署が増えたり、長期間運用していく中で、
また課題が出てくると思っています。
そこでのノウハウなんかも共有しきたいと思います。
[Node.js] リアルタイムワードクラウドWebアプリ(D3.js+Socket.io+Twitter)で苦労したこと

# はじめに

組み込みエンジニア2年目のすいばりです。

今回、**リアルタイムにTwitterのワードクラウドをWebブラウザ上に表示するアプリ**を作りました。

[NPB-LiveCloud!（NPBライブクラウド）](https://npb-livecloud.herokuapp.com/)
![npb_livecloud_logo.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/110901/cc5b43fc-48c1-44ae-b8a1-d3dbea699f7d.png)

当然開発で色々詰まりました。
同じこと目指している方に情報共有したいなと思って記事書きました。
読んで&使っていただけたら嬉しいです！

# 成果物の説明

アプリのシステム構成は以下の通りです。
![npb_livecloud](https://user-images.githubusercontent.com/61776220/90955213-9ac4f000-e4b6-11ea-80a3-a5ab3a0c1945.png)

流れは大体以下です。
1. Twitter filter streamでツイート収集
2. MeCabで形態素解析
3. 単語頻出数集計
4. ブラウザでワードクラウド作る！

コード&機能詳細は、[GitHub](https://github.com/suibari/NPB_LiveCloud)をご覧ください！

# 詰まったことリスト

1. D3のバインディング設定が難しい
2. heroku free planのslug sizeが限界
3. MeCab辞書のherokuデプロイ方法が複雑

それぞれ説明します。

## D3のバインディング設定

D3.jsはJavaScriptのグラフ描画用ライブラリです。
NPBライブクラウドではこのD3.jsと、D3-cloud.jsというD3.jsの機能を使ってワードクラウドを描画するラッパーライブラリを使用してます。

D3.jsにはバインディングという概念があります。
バインディングとは、**DOM要素に対してデータを紐づける**ことです。
バインディングはDOM要素が存在しなくてもできます(XXX is not definedにならない！)。
この考え方がよくわからなくて詰まりました。

例えば以下のコード。

```js
class wordCloud {

_draw(words) {
    let cloud = d3.select('svg').select('g').selectAll('text').data(words); //wordsをtext要素に対してバインディングする
    //中略

cloud.merge(cloud) // 全text要素(その時点でのあるなし問わない)に対しての操作
    .style('fill', (d) => { return d.color }) 
    //中略
}
```

_draw関数が最初に呼び出されるとき、まだtext要素は存在していません。
普通にDOM操作する感覚だと、not definedとか怒られるので違和感あると思います。

D3.jsは便利な分くせが強いので、そこに詰まりました。

## heroku free planのslug size

herokuは無料から使えるレンタルサーバー(PaaS)です。
herokuの無料プランはデプロイできるサイズが**500MBまで**という制限があります。

NPBライブクラウドでは形態素解析ソフトのMeCabを使っているためサイズが大きいです。
最初、大体こんな感じでslug sizeオーバーしました。

|モジュール|サイズ|
|:-------:|:---:|
|アプリ本体|10MB|
|Linuxbrew|400MB|
|MeCab|10MB|
|MeCab-ipadic|50MB|
|MeCab新語辞書|400MB|
|計|800MB↑|

対策としては、[MeCab新語辞書](https://github.com/neologd/mecab-ipadic-neologd/blob/master/README.ja.md)をやめて自作辞書を使用しました。
自作辞書は[自分の過去記事](https://qiita.com/Suibari_cha/items/aeeb3fb07b94207c1ff3)を参考にWebスクレイピングで作成しました。（方法は下記の章）
それでもかつかつです。(確か490MBくらい)

## MeCab辞書のherokuデプロイ

git経由して.MeCab設定ファイルmecabrcをherokuにデプロイします。
配置場所は ~/app/.mecabrc です。

注意点として、herokuのユーザhomeディレクトリのProcfileを使った方法は現在は使えません。
理由は[こちら](http://shigechi-64.hatenablog.com/entry/2018/01/08/195232)。
なのでこうして辞書ファイルを予めコンパイルしておいて一緒にデプロイするしかないみたいです。

# おわりに

heroku上にwebアプリを作りました。そこで詰まった点をまとめたという話でした。

感想ですが、一番むずいのってモチベーションの維持かもしれないです。
このアプリは完全一方通行なので、誰がどのくらい見てくれてるとか、何が求められているとか、開発者の自分では把握できません…。
モチベーション維持やフィードバックの仕組みを考えておくのは趣味開発では大切かもって思いました。

ふわっとした記事になりましたが、以上です。
よいお年を！
ag-Gridに入門

JavaScriptで高機能でエクセルライクなUI/UXを実現できるライブラリ、**ag-Grid**を発見した。日本語の情報が少ないので、自分のためと誰かのために、使えそうな機能やapiの使い方をのせておく。

# **Grid API**

gridOptions.api.メソッド名で使用

### すべての行を取得

```javascript
//forEachNode(callback)を使う場合
gridOptions.api.forEachNode( function(rowNode, index) {
    console.log(rowNode.data);
})
```

# **行の追加・更新・削除**

api.updateRowData(transaction)でデータの更新や削除ができる。transactionにわたすパラメータは、[公式サイト](https://www.ag-grid.com/javascript-grid-data-update/)参照。

```javascript
//追加の場合
let newData = {};
for (let key in columnDefs) {
  newData[columnDefs[key]['headerName']] = "";
}
gridOptions.api.updateRowData({add: [newData]});
```

# **終わりに**

ag-Gridをもっと使いこなせるようになったらさらに情報を追加していく。
全自動スリットアニメーション表示機

#スリットアニメーションとは
スリットアニメーション（スキャニメーションともいうらしい）とは、ギザギザの絵の上にスリットの入ったシートを被せて横にスライドさせることで、下の絵が動いているように見える、という目の錯覚を利用した遊びです。
以下のページに詳しく書いてあるので、そちらをどうぞ。私もここのページを参考にさせてもらいました。
[https://scanimation-meijinkai.info/whatis/](https://scanimation-meijinkai.info/whatis/)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/f0c1abe6-bb57-b9f2-7b79-131905f67d61.png)

#作りたいもの
スリットアニメーションでアニメーションさせるには、スリットのシートをスライドさせる必要があります。
手でスライドすればいいのですが、面倒なので、モータを使って自動でスライドさせてみることにします。

#作ってみた
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/504156/a40980b0-7212-3aa2-9f0a-9fad3e8ffd60.png)

タミヤのモーターとこれまたタミヤの「楽しい工作シリーズ」を駆使して作ってみました。
「楽しい工作シリーズ」を初めて使ってみましたが、とても便利ですね。

クランクとアームでモーターの円運動をスライドの往復運動に変えています。

以下は動かしてみた動画です。途中、PWMのduty比を変えて速度を変えています。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">M5stackで全自動スライドアニメーション <a href="https://t.co/ayu5zbqJwi">pic.twitter.com/ayu5zbqJwi</a></p>&mdash; なまやつはし (@5xssUFaTa9UqFJx) <a href="https://twitter.com/5xssUFaTa9UqFJx/status/1340534941826760704?ref_src=twsrc%5Etfw">December 20, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

#ソースコード
M5Stackのソースコードです。

```.cpp
#include <M5Stack.h>

const double PWM_Hz = 2000;   // PWM周波数
const uint8_t PWM_level = 8; // PWM分解能 16bit(0～255)
const uint8_t PWM_CH = 1;  // チャンネル

uint32_t duty = 64;

void setup() {
  // put your setup code here, to run once:
  M5.begin();
  M5.Power.begin();

  pinMode(26, OUTPUT); 

  // チャンネルと周波数の分解能を設定
  ledcSetup(PWM_CH, PWM_Hz, PWM_level);
  //モータのピンとチャンネルの設定
  ledcAttachPin(26, PWM_CH);
  //duty比を0に設定
  ledcWrite(PWM_CH,0);
}

void loop() {
  M5.update();

  // 現在のdutyを表示
  M5.Lcd.setCursor(0,0);
  M5.Lcd.setTextColor(WHITE,BLACK);
  M5.Lcd.setTextSize(3);
  M5.Lcd.printf("duty: %03d",duty);
  
  // dutyをプラス（Max255）
  if (M5.BtnA.wasPressed())
  {
    if (duty < 255)
    {
      duty += 1;
    }

    ledcWrite(PWM_CH,duty);
  }
  // dutyをマイナス（Max0）
  else if (M5.BtnB.wasPressed())
  {
    if (duty > 0)
    {
      duty -= 1;
    }

    ledcWrite(PWM_CH,duty);
  }
  // dutyを0に（モーターを止める）
  else if (M5.BtnC.wasPressed())
  {
    ledcWrite(PWM_CH,0);
  }

  delay(10); 
}
```

以上です！！
GitHubからアプリをクローンして複製する（初期化）

自作のアプリをポートフォリオとして転職活動を行っています。

個人情報がふんだんに含まれていたため、そのあたりを一掃して、アプリの機能のみ維持した状態で公開用のアプリを再作成するための、**複製**と**初期化**手順です。

# 流れ
- 複製したいアプリをclone
- 必要によっては、cloneしたディレクトリ名を変更（app_v2としました）
- 個人情報関連を編集（ここはコミット履歴に残したくない）
- ディレクトリのgitの情報を削除
- 新規のリモートリポジトリを作成
- 初期化し、作成したリモートリポジトリにプッシュ

という感じです。

# コマンド

```shell
# GitHub上で複製したいアプリのclone する際のURLをコピー
git clone コピーしたURL

# ファイルを編集し、一旦.gitを削除
rm -rf .git

# リポジトリを作成し、新規作成時の指示に従う
# 初期化し、再度pushまで
git init
git add .
git commit -m 'コミットメッセージ'
git branch -M main
git remote add origin 作成したリモートリポジトリのURL
git push origin HEAD
```

完了。

余談ですが、 `git push origin HEAD`とすると、現在のブランチ名でpushしてくれて便利！
HDD容量監視スクリプト

複数対象を監視する想定
監視対象が増減する際に変更が容易
監視パーティション使用率が80％以上になるとメールで通知
複数対象が閾値を超えてもメールは一通
メール本文に容量、使用率、対象パーティション記載
#ファイル作成
```
$ touch chkdisk.sh
$ chmod 755 chkdisk.sh
```

#スクリプト内容
```
#!/bin/bash

# 送信元アドレス
from="任意のアドレス"

# 送信先アドレス
to="任意のアドレス"

# メール件名
SUB="任意の件名"

# 閾値
LIMIT=80

# 監視対象
par=(par1 par2 par3)

# script
for i in ${par[@]}; do

# 閾値チェック
       chk=` df -h | grep $i | awk '{ print $5 }' | sed -e '$s/.$//' `
   if [[ $chk -ge $LIMIT ]]; then
       body+=("$(df -h | grep $i)\n")
   fi
done

# メール送信処理
echo -e "{$body[@]}" | awk '{ print $2,$5,$6 }' | mail -s "$sub" -r "$from" @to
```
cronの設定を任意の時間帯、曜日にして完了
プロダクトに貢献するユーザーサポート


こんにちは！[株式会社ACCESS Advent Calendar 2020](https://qiita.com/advent-calendar/2020/access) 20日目の記事です！

昨日は @ikeyasu さんでした！[ドローン](https://qiita.com/ikeyasu/items/5c6c7d5951e6144fa274)ってたくさん種類があっておもしろいですね！


今回はユーザーサポートについて書きたいと思います！
突然ユーザーサポートすることになってしまった、ユーザーとやりとりするの怖い…っていうみなさんのおまもり記事となればうれしいです。


## ユーザーサポートどんなことやるの？

### サポートのチャネルは以下
* アプリ内のお問い合わせフォーム（Googleフォームつかってる）
* Google Playの開発元へ問い合わせるところ

基本的にはメールでのみ対応しています。稀に電話でも来るけど正規ルートじゃないので除きます。

### サポートツール
サポートツールは [Zendesk](https://www.zendesk.co.jp) を使っています。
[Freshdesk](https://freshdesk.com/jp/) も使ってみたことがありますが、検索をよく使うので個人的には Zendesk のほうが使いやすかったです。
前どんな感じで回答してたっけ…となったときに検索機能が優秀だとうれしいです。


### 普段のサポートの流れ
* まずはざっくりチェック
    * 新着メールを確認する
        * 緊急度高そうなものはないか、優先度チェックもしておく
    * ぱっと見て、テンプレで返せるものはさっと返す
    * ちょっと考えないといけないものはとりあえず寝かせる( ˘ω˘ ) ｽﾔｧ…
* じっくり返信
    * 緊急度高そうなものから返していく
    * 一人で考えても難しいものはチームに相談

こんな感じで対応しています。


### その他やっていること
* Bugっぽかったら再現確認してチケット化する
* 要望系で多いものや気になるものはチームへFeedbackする

再現確認の時に、ユーザー利用率の高い機種を用意しておくと良いです。
シェアの高い機種や、Androidバージョンは Firebase を使って調べています。

## サポートが楽になる！必須アイテムベスト3🎉
### 1. 選択形式のお問い合わせフォーム
以前は自由入力でしたが、必要な情報が足りず問題の把握に時間がかかっていました。そこで選択形式のフォームに変更してみましたが、効果は抜群です！
きっとユーザーも負担が減ったのではないでしょうか？
また、機種情報などは自動入力されるようにしてます。

* 項目例
    * 問い合わせ種別（質問・要望 or 不具合報告）
    * 不具合の種別（受信できない、通知が遅れる、など問い合わせの多いものを選択肢にいれてます）

### 2. 返信用テンプレート
よくある問い合わせに対する返信文や、汎用的な文章はテンプレート化してぽちぽち選んで返信できるようにしてます。テンプレートないともう生きていけない…。
ユーザーが見れるFAQページに追加していくのもGood！


### 3. 「こんな問い合わせきてつらかった…」って言える人
人なのでアイテムじゃないんですが、Mustなので入れました。
いろんな問い合わせがくるので、中には心にうっ…とくるものもたまにあります。
サービスを運用する上で、必要な仕事なので対応するのですが、辛いものは辛い…。人間だもの…。
ということで、そういう時はチームの人に労ってもらっています。
対応方法を一緒に考えてくれていつもありがとう！


## サポート対応のコツ
### 困ったらスクリーンショットをもらうのだ！
文章だと限界があるので、どこの画面で発生しているどういう問題なのか？どんなエラーが出ているのか？が一発でわかるスクリーンショットを送ってもらいましょう。
（前にまったく違うアプリのスクリーンショットが送られてきたことがありました）

### いろんな角度から考える
まるまる鵜呑みにしないで、こう言っているけど本当だろうか？と立ち止まりましょう。
たとえば、メールアプリで「通知がこないです」と問い合わせがきたとします。

通知がこないのか…。ふむふむ、新着通知がこないのかな？通知はONになっているか聞いてみよう！！

となる前に、ちょっと立ち止まって通知が来ないってどういうこと？と考えてみましょう。
メールは受信してるけど通知がこないとか、メール自体受信できないとか、着信通知音が鳴動しないとか…いろいろありますよね！
思い込んでないかな？と自身に問いつつ、事実を探るサポート担当者たらんことを！


### ユーザーの気持ちに寄り添う
これで大変な思いをしたんだろう、すごい困っただろうなと気持ちに寄り添うことも大切です。感情移入するとか、同調するということではなく、ただ寄り添う。

せっかく使おうとしたのに思うように使えなかったら悲しいですよね。

たとえ端末の問題だったとしても、ユーザーからしてみれば使えないことには変わりないんですよね。賛否両論あると思いますが、これうち関係ないな…と思っても、できる限りベストを尽くすようにしています。

サポート対応も1つのユーザー体験なので、この時の対応でまたうちのアプリを使おうかなって思ってもらえるといいなぁと思っています。
ちなみに、わたしは3代目のサポート担当なのですが、前任担当者が丁寧に対応していたおかげで長年使ってくれているファンの方がいるので大事にしなければという思いもあります。



## さいごに
サポートもサービスの一部です。そしてユーザーと一番近い場所でもあります。
サポートを通してユーザー理解を深めたり、生の声を聞いてプロダクト開発に活かしていくことができます。
カスタマーサポートはこれからもユーザーに価値を届けていく上で大切な仕事の1つだと思うので、頑張っていこうと思っています！



---

明日は @Momijinn さんです！素敵な月曜日を☆彡
Line風のアイコンを作る方法

今回はcssを使ってlineのトーク画面風を作ってみたいと思います。
lineと言えばアイコンがありますよね。そちらの方をまた作って行こうと思います。今回はアイコンの代わりに名前を使います。


```line.html.erb
  <p class = "lineheader">ユーザーネーム</p>
  <p class = "linetext">テキスト</p>

```



```line_header.css
.lineheader{
  color: white;
  background-color: balck;
  text-align: center;
  font-weight: bold;
  border-radius: 20vh;
}
```
これでアイコンについては完成です。

次にテキストに移ります。ここからが本番ですね!頑張って行きましょう!!!


```line_text.css
.linetext{
  position: relative;
  ここからしたはお好みに合わせて
  color: balck;
  font-weight: bold;
  text-decoration: none;
  padding: 17px 13px 15px 18px;
  border-radius: 12px;
  background-color: red;
}
```

多分これで四角ができたと思います。さあ、次からです。でっぱりを作りましょう。



今回必要となるのが擬似要素という単語です.擬似要素とは一部だけにクラスを与えることです。例えば

```line_textdemo1
  <h2>私<span class = "line_textdemo1">は</span>トムだ</h2>


```
こうすることで文字の一部にクラスを与えることができました。
今回使用している下のコードにあるafterは要素の右隣にまた同じ要素を出すことだ可能になります。

```line_afterdemo1.html.erb
   <p class = "afterdemo1">私はトムだ</p>
```

```line_afterdemo1.css
   .afterdemo1:after{
   color: red;
   }
```
実行結果
私はトムだ。　私はトムだ。←赤文字　　このようになります。


```line_text.css
   linetext:after{
   content: "" ;
   position: absolute;
   border: 10px solid transparent;
   left: -26px;
   border-right: 22px solid red;
   }
```


border: 10px solid transparent;と
border-right: 22px solid red;
の解説をしていきたいと思います。

borderとはとは三角形を作るcssです。border-topで逆三角形、border-downで三角形を作ることができます。
border-rightでyoutubeの再生ボタン逆の三角形が作れます。border-leftではyoutubeの再生ボタンを作ることができます。border〜〜とかで三角形の底辺を指定することができます。



border-right 22pxで三角形を指定することができます。例えば1pxの場合とても鈍角な三角形ができますが、
33pxだととても鋭角な三角形が完成します。

borderを指定することでそれ以外の三角形を指定することができます。今回は一つの三角形しか使わないのでtransparent（透明）を使います。


これで完成したと思います。
意外と簡単にできましたね。これで以上です!
AWS SSHログイン

ssh -i "xxx.pem" root@10.0.0.0
だと、ログインできなかった。

原因は何か→@前のrootがダメだったぽい

→初期設定ではsshコマンドでいきなりrootとしてログインすることはできない。sshでrootによるログインを許可するには、/etc/ssh/sshd_configに設定必要。
rootでのログインを許可するのはセキュリティ上問題があるので基本あんまりやらない方がいいぽい
現状、私のレベルだとそんな大したことはしてないし、rootはないって思っとけばええんやない。



ec2-userにしたらいけた。
ssh -i "xxx.pem" ec2-user@10.0.0.0ね。