OmniAICreator/Qiita-1.07M huggingface dataset:
Redfishを使ってサーバーの状態監視

#Redfishを使ってサーバーの状態監視

Redfish、何それ美味しいの？

従来サーバー監視はIPMIToolやベンダー固有の管理ツールを使うのが定番でしたが、
最近APIを通して共通化しようという試みも出てきているようです。
サーバー屋さん的にはどうなのかね？という感じもありますが、まずはお試し。

今回は2つの方法で基本情報の取得。
1,Postmanを使う
2,Curlを使う

#1,Postmanを使う
PostmanをノートPCにインストール
https://www.postman.com/downloads/

デスクトップのアイコンをクリックしてPostmanを開き、
アドレスバーにIPアドレスと/redfish/v1/Systems/1/くらいまで入れて
authorizationをBasic AuthにしてIPMIのユーザーとパスワードを入れるとサーバーと繋がります。

GET IPアドレス/redfish/v1/Systems/1/
![postman02.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/a001cb07-4ee2-4865-3334-d86d6a3399e1.jpeg)

Body内になるリンク/redfish/v1/System/1をクリックすると、下の画像のようなサーバーのFRU項目が出てきます。
![postman03.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/d6cc53db-45d4-bef9-1d83-0fe01628fe64.jpeg)


IPMIではなかなか取れないNICの情報も取れる。
GET IPアドレス/redfish/v1/Systems/1/EthernetInterfaces/1
![postman04.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/de1870e8-9a50-573b-7288-4197bdbb18a2.jpeg)

Memoryのスピードや型番、状態も取得可能。
GET IPアドレス/redfish/v1/Systems/1/Memory/1
![postman05.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/8ce15d56-347d-013f-8702-46e8c7dabdd3.jpeg)

各項目ごとに掘り下げていくと情報が色々と確認出来、JSONだけでなく色々な形式で出力できるので
独自に作成した管理ツールがある人にはに便利かも。知らんけど。

#2,Curlを使う
ノートPCではなく、管理用のLinux端末からRedfish経由で情報を見たい場合は
curlを使用するとコマンドラインでできるのでスクリプト化してもいいかも。

curlは色々できるようですが、とりあえず監視だけなら
curl -u ユーザー：パスワード　－X GET　'https\://IPアドレス/redfish/v1/Systems/1/項目'
で情報取得は可能。
![curl00.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/ec0d799c-99f4-4a16-10ce-7aa77c308ca1.jpeg)

ただ、これだと非常に見辛いので、|（パイプ）とjqを使ってJSON形式で見やすく変換した方が良さげです。
jqのインストールはいたって簡単。
$sudo yum -y install epel-release
$sudo yum -y install jq

jqで必要な情報だけ.ドット＋項目を,で羅列すると見やすくなりました。(前後はシングルクォーテーション)

ネットワークの常態とMACアドレス調べ
curl -k -u ADMIN:ADMIN -X GET 'https\://IPアドレス/redfish/v1/Systems/1/EthernetInterfaces/1' |jq '.Description, .Status, .MACAddress' 

Memoryのスロットごとの容量と状態調べ
curl -k -u ADMIN:ADMIN -X GET 'https\://IPアドレス/redfish/v1/Systems/1/Memory/1' |jq '.Name, .CapacityMiB, .Status'
![curl01.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478729/6d709984-a7a6-a7b6-d079-08253aded958.jpeg)


---
掘り下げれば色々出来そうな感じはありますが、まずはRedfishで情報を取る方法はこれで良しとする！
『コピペOK』NodeでS3へ画像アップロード【2020】

まずは、[ここ](https://qiita.com/rh_/items/24ed1cebbdc3a731aabb)からs3へのアクセスキーと、シークレットきーを取得してください。

## S3 Bucketを作る

```
$ npm i --save aws-sdk
```

```create-bucket.js

const AWS = require('aws-sdk');

// Enter copied or downloaded access ID and secret key here
const ID = '';
const SECRET = '';

// The name of the bucket that you have created
const BUCKET_NAME = 'test-bucket'; //同じバケット名は作れない ユニーク必須

const s3 = new AWS.S3({
    accessKeyId: ID,
    secretAccessKey: SECRET
});

const params = {
    Bucket: BUCKET_NAME,
    CreateBucketConfiguration: {
        // アジアパシフィック (東京)
        LocationConstraint: "ap-northeast-1"
    }
};

s3.createBucket(params, function(err, data) {
    if (err) console.log(err, err.stack);
    else console.log('Bucket Created Successfully', data.Location);
});

```

こんな感じ。で、実行

```
$ node create-bucket.js
```

## S3で画像をアップする

```uplode-bucket.js

const fs = require('fs');
const AWS = require('aws-sdk');

// Enter copied or downloaded access ID and secret key here
const ID = '';
const SECRET = '';

const s3 = new AWS.S3({
    accessKeyId: ID,
    secretAccessKey: SECRET
});

const uploadFile = (fileName) => {
    // Read content from the file
    const fileContent = fs.readFileSync(fileName);

    // Setting up S3 upload parameters
    const params = {
        Bucket: "test-bucket",
        Key: 'uniquename.jpg', // s3へ保存される名前 ユニーク必須
        Body: fileContent
    };

    // Uploading files to the bucket
    s3.upload(params, function(err, data) {
        if (err) {
            throw err;
        }
        console.log(`File uploaded successfully. ${data.Location}`);
    });
};

uploadFile('/Users/user-name/Desktop/test.png'); //ここにファイルの実体を入れる
```

こんな感じ。で、実行

```js
$ node uplode-bucket.js
```

## 参考

https://stackabuse.com/uploading-files-to-aws-s3-with-node-js/
【図解まるわかり セキュリティのしくみ】本の感想を書く

# 本当に図解まるわかりだった

![alt](https://images-na.ssl-images-amazon.com/images/I/518I5iF9Z1L._SX348_BO1,204,203,200_.jpg)
[図解まるわかり セキュリティのしくみ](https://www.amazon.co.jp/%E5%9B%B3%E8%A7%A3%E3%81%BE%E3%82%8B%E3%82%8F%E3%81%8B%E3%82%8A-%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF-%E5%A2%97%E4%BA%95-%E6%95%8F%E5%85%8B/dp/4798157201/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=VGO8U97HV60Q&dchild=1&keywords=%E5%9B%B3%E8%A7%A3%E3%81%BE%E3%82%8B%E3%82%8F%E3%81%8B%E3%82%8A+%E3%82%BB%E3%82%AD%E3%83%A5%E3%83%AA%E3%83%86%E3%82%A3%E3%81%AE%E3%81%97%E3%81%8F%E3%81%BF&qid=1586219870&sprefix=%E5%9B%B3%E8%A7%A3%E3%81%BE%E3%82%8B%E3%82%8F%E3%81%8B%E3%82%8A%2Caps%2C342&sr=8-1)

##◇ 感想
「セキュリティの基礎をを付けたいな～」と過去にも同じような本を読んだのですが、もう１冊くらい読んで基礎を固めたいと思い本書を購入しました。やはり初学者として「図解」の部分に大変惹かれてしまいます…

結論から言うとかなり分かりやすかったです。なぜなら全ページに図解が掲載されており、言葉だけでは分かりにくい部分も視覚的にイメージできたからです。要所要所に図解が挟まっている感じだろうと思っていたらまさかの全ページで驚きました。以前から攻撃手法の XSS や CSRF をよく混同しがちだったのですが、おかげで今後混同することはなさそうです。また、視覚的に理解できるという点からエンジニア以外の方でも十分理解できる内容となっています。第6章と第7章では組織における個人情報の取り扱いなどの話が展開されており、組織のセキュリティ管理を担当している人にとっても押さえておくべき内容が記載されていました。

セキュリティの基礎を学んでみたいエンジニア、セキュリティを学んでみたいけどなんだか難しそうと思っている非エンジニアの方、そんな方々におすすめの一冊です。
Storyboardが複数の場合の画面遷移

# はじめに
`Storyboard:ViewController=1:1`で開発する時に画面遷移ってどうするんだろう、と思ったのでやってみました。
そこら中に記事があるので、自分用の備忘録として残しておきます。
想定は「Main.storybard」→「Sub.storyboard」の画面遷移です。

# 手順
1.`Main.storyboard`を開いて画面遷移する用のボタンを用意する。
  <img width="431" alt="main.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605119/95c56620-41f3-1aec-34b2-f83e86ed552f.png">

  ~~~swift:MainViewController.swift
import UIKit

class MainViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }

    @IBAction func tapBtn(_ sender: Any) {
        // Storyboardのインスタンスを名前指定で取得する
        let storyboard = UIStoryboard(name: "Sub", bundle: nil)
        // Storyboard内で'is initial'に指定されているViewControllerを取得する
        let nextVC = storyboard.instantiateInitialViewController() as! SubViewController
        // FullScreenにする
        nextVC.modalPresentationStyle = .fullScreen
        // Subへ渡す値
        nextVC.text = "hello" // <--- SubViewControllerのプロパティ`text`
        // presentする
        self.present(nextVC, animated: true, completion: nil)
    }
}
  ~~~

2.`Sub.storyboard`と`SubViewController.swift`を作成する
  <img width="349" alt="sub.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605119/49744059-5882-7cab-98ef-6625434c3d8f.png">

この時、`Is Initial ViewController`に**チェックを入れることを忘れないように！**
<img width="261" alt="スクリーンショット 2020-04-07 10.17.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/605119/a5e191ed-8729-8bd0-8748-213f68c81a03.png">

3.起動すれば動くはず

# 参考
- [多人数でのiOS開発におけるStoryboardとの向き合い方（１画面１Storyboard）](https://blog.machio.me/entry/2017/08/31/190528)
- [モーダルビューをフルスクリーンで表示させる（iOS13以降）](https://qiita.com/hiroyuki7/items/acaa51cbb85328dc7657)
- [【Swift/iOS】画面遷移時の値渡し](https://capibara1969.com/1060/)
ReactNative-Expo内で展開したWebViewのchromeDevToolでの確認の方法

# 出来ること
- Expoで展開したWebViewのlogなんかをChromeDevToolで見られる
- WebView生成後の確認

# 出来ないこと
- 実機での確認

# 手順
- AndroidStudioからAndroidエミュレーターの起動
- `expo start` でexpoの起動
- `expo start`で開かれたwebサイト上の `Run on Android device/emulator`をクリックしてエミュレーターでApp起動
  - この時、PCに複数のエミュレーターや実機が刺さっていると怒られる
- `chrome://inspect/#devices` をchromeで開くと対象のWebViewが出ているので確認できる
  - 出てない場合はエミュレーターが開発者モードになってないのかも(build番号何回かTapするやつ 

# おまけ
- 下記みたいなの見つけて絶望したけど出来た
```
https://expo.canny.io/feature-requests/p/support-running-debugger-against-webview-without-native-changes
https://github.com/expo/expo/issues/485
```
- modules内の`kt`ファイルいじったり色々したけど無駄だった
Docker初心者がdocker-compose.ymlについて説明する

## はじめに
`docker-compose.yml`は一見意味がわからないですが、一つ一つ調べると理解できたので説明していきます。

## docker-compose.yml

```yml:docker-compose.yml
version: '3'
services:
  web:
    build: .
    ports:
      - "3000:3000"
    depends_on:
      - db
    volumes:
      - .:/API_sample
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
  db:
    image: mysql:5.7
    volumes:
      - mysql_data:/var/lib/mysql/
    environment:
      MYSQL_ROOT_PASSWORD: password
    ports:
      - "3306:3306"
volumes:
  mysql_data:
```

### version
docker-composeのバージョンを指定します。</br>
現時点では、version3が最新版のようです。

リファレンスは[こちら](https://docs.docker.com/compose/compose-file/#compose-and-docker-compatibility-matrix)

### services
アプリケーションを動かすための要素です。</br>
ネストされた`web`と`db`は各要素で、自分で好きな名前をつけることができます。

### build
`docker-compose build`のときにビルドするためのDockerfileのパスを指定しています。</br>
ここでは、Dockerfileもdocker-compose.ymlもプロジェクト直下にあるのでこのような書き方をしています。

### ports
各serviceのポート番号を指定しています。</br>
`ホストOS(local)のポート番号:dockerコンテナ内のポート番号`という書き方ができます。
ここでは、railsのポート番号が`3000`なので、`3000:3000`という書き方をしています。

1台のPCでDockerを使った複数のプロジェクトを扱うときに、ポート番号が重複するのを防ぐことができます。</br>
たとえば`3001:3001`という書き方をすると、`localhost:3001`でサーバーに接続できます。

### depends_on
コンテナの依存関係を設定します。</br>
今回は`db`に依存関係があることを明記しています。

こうすることで、`docker-compose up`のときにDBを先に起動してくれます。

### volumes
dockerの中でデータを永続化する設定です。</br>
この設定をすることで、コンテナ内のデータは消えずに残ってくれます。


上記の例だと、`web`では相対パスのすべてのソース(API_sample)をコンテナのAPI_sampleにマウントしています。</br>
そして、`db`ではdbコンテナ内の/var/lib/mysqlをmysql_dataという名前でマウントしています。</br>
このmysql_dataは最後の2行でvolumesとして設定されています。

volumeは下記コマンドで一覧を見ることができます。

```zsh
$ docker volume ls
```

### command
`docker-compose up`で実行されるコマンドです。</br>
upと同時に、`bundle exec rails s -p 3000 -b '0.0.0.0'`が実行されてサーバーに接続できるようになります。

### image
コンテナ作成に必要なイメージを指定しています。</br>
ここでは、dbのコンテナ作成に、mysql5.7を使用すると設定しています。

### environment
環境変数を設定します。
database.ymlに書かれているパスワードを環境変数として設定し、mysqlに接続できるようにします。
Nuxt.jsでhead要素・404ページの設定を行う

# 前提
`$ npx create-nuxt-app プロジェクト名` でモジュールをインストールして開始すると、`nuxt.config.js`ファイルが生成されます。
このファイルで行う設定内容まとめです。

# nuxt.config.js ファイル
- `export default { ...` 以下をJSON形式で記述します。
- アプリケーション共通設定を行う事ができます。

## head要素の記述
```js
export default {
  ...
  head: {
    title: "タイトル",
    meta: [
      { charset: 'utf-8' },
      { name: 'viewport', content: 'width=device-width, initial-scale=1' },
      { hid: 'description', name: 'description', content: process.env.npm_package_description || '' },
      /* OGP設定も可能です */
      { property: 'og:title', content: 'OGPタイトル'},
      { property: 'og:type', content: 'website'},
      { property: 'og:url', content: 'OGP URL'},
      { property: 'og:image', content: 'OGP image'},
    ],
    link: [
      { rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' },
      /* CDN等 */
      { rel: 'stylesheet', type: '', href: 'https://fonts.googleapis.com/css?family=Sen&display=swap' }
    ]
  },
  ...
}
```

## ローディングカラーの変更
- Nuxt.jsでは、初期状態でローディングアニメーションが設定されています。
- 好みのカラーへ変更が可能です。

```js
export default {
    ...
    loading: { color: '#カラーコード' },
    ...
}
```

## 404ページの設置
- Nuxt.jsでは、`/pages`配下で自動的にルーティングが行えます。
- 存在しないURLへのアクセスが行われた場合の404リクエストで表示するページ設定を行う事ができます。

```js
export default {
    ...
    router: {
    extendRoutes (routes, resolve) {
      routes.push({
        name: 'custom',
        path: '*',
        component: resolve(__dirname, './components/404.vue')
      })
    }
  },
  ...
}
```
CAD・形状モデリング　１

本シリーズでは、プログラミングというよりもその裏側に焦点をあてます。主にMATLABを使いますが、基本は他言語でも同じだと思いますので、そこは適時読み替えてください。

主目的は、CAD→STLにしたのに、読み込めない！エラーが出る！という事象に対して何が起きているかというのを解説し、打開策を検討できるようになってもらうこととします。しますが、適時脱線すると思いますが、そこはご了承ください。

なお、ここにでてくる技術の解説をしていく流れでいこうと思います。
https://www.jstage.jst.go.jp/article/jjspe/79/2/79_144/_pdf
https://www.jstage.jst.go.jp/article/jjspe/79/3/79_223/_pdf
https://www.jstage.jst.go.jp/article/jjspe/79/4/79_309/_pdf

※教科書の類が職場で、昨今のこの状況もあって職場にいけないので、記憶などを頼りに書いています。間違いがあれば、ご指摘ください。
PythonでCSVファイルを読み込んでそのままDataFrameに変換する

# はじめに
- CSVで取得したデータをPythonで分析するために読み込んでPandasのDatafarame型で保持する方法をまとめる。


#事前準備
- 分析したいCSVファイルをカレントディレクトリに用意しておく
- CSVファイルは成形済前提

#コード
```python
import csv, os
import pandas as pd
import numpy as np

#対象のファイルのパス文字列を指定
file_path = os.path.join(".","maerge_Machine11_trd.csv")
print("file name:" + file_path)

#CSVファイルからdfへ変換
df = pd.read_csv(file_path)

#読み込んだデータの表示
df.head()

#TODO:dfからの目的のデータの取得
#TODO:統計解析・可視化

```

# 解説
- os.path.jpin()で環境依存せずにファイルの場所を指定する
- pd.read_csv()でファイルを開きdataframe型へ変換
- この後は、dfから必要な行・列を取得して統計解析や可視化を行えばよい。
plunkerでtensorflow.js その28

#概要

plunkerでtensorflow.jsやってみた。
関数フィッティングやってみた。

#写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/247e0df2-d863-0c80-806e-ab70df21c8ff.png)


#サンプルコード


```
 
function predict(x) {
  return tf.tidy(() => {
    return tf.div(tf.exp(tf.mul(tf.mul(x.sub(a), x.sub(a)), tf.neg(b))), c)
  });
}
function loss(pred, label) {
  return tf.losses.meanSquaredError(pred, label).mean();
}
function train(xs, ys, numIterations) {
  for (let iter = 0; iter < numIterations; iter++) 
  {
    optimizer.minimize(() => {
      const pred = predict(xs);
      return loss(pred, ys);
    });
  }
}
const a = tf.variable(tf.scalar(Math.random() + 70));
const b = tf.variable(tf.scalar(Math.random()));
const c = tf.variable(tf.scalar(Math.random()));
const learningRate = 0.005;
const optimizer = tf.train.adamax(learningRate);
const numIterations = 300;
const yy =  [2, 0, 0, 0, 2, 0, 3, 0, 4, 4, 5, 0, 0, 2, 0, 0, 3, 0, 1, 0, 0, 2, 0, 1, 14, 16, 7, 8, 10, 10, 11, 17, 25, 12, 11, 19, 25, 14, 13, 15, 18, 19, 38, 29, 60, 41, 41, 9, 70, 58, 0, 62, 72, 66, 0, 39, 11, 35, 39, 44, 94, 27, 65, 114, 80, 81, 225, 173, 0, 87, 225, 317, 122, 522]
const xs = tf.tensor2d([[1], [2], [3], [4], [5], [6], [7], [8], [9], [10], [11], [12], [13], [14], [15], [16], [17], [18], [19], [20], [21], [22], [23], [24], [25], [26], [27], [28], [29], [30], [31], [32], [33], [34], [35], [36], [37], [38], [39], [40], [41], [42], [43], [44], [45], [46], [47], [48], [49], [50], [51], [52], [53], [54], [55], [56], [57], [58], [59], [60], [61], [62], [63], [64], [65], [66], [67], [68], [69], [70], [71], [72], [73], [74]], [74, 1]);
const ys = tf.tensor2d([[2], [0], [0], [0], [2], [0], [3], [0], [4], [4], [5], [0], [0], [2], [0], [0], [3], [0], [1], [0], [0], [2], [0], [1], [14], [16], [7], [8], [10], [10], [11], [17], [25], [12], [11], [19], [25], [14], [13], [15], [18], [19], [38], [29], [60], [41], [41], [9], [70], [58], [0], [62], [72], [66], [0], [39], [11], [35], [39], [44], [94], [27], [65], [114], [80], [81], [225], [173], [0], [87], [225], [317], [122], [522]], [74, 1]);
train(xs, ys, numIterations);
const aa = Number(a.dataSync());
const bb = Number(b.dataSync());
const cc = Number(c.dataSync());
//alert(aa + ", " + bb + ", " + cc);
var values = [];
for (var i = 0; i < 74; i++)
{
  values.push({
    x: i, 
    y: yy[i],
    pred: Math.exp((i - aa) * (i - aa) * - bb) / cc
  });
}
const spec = {
  '$schema': 'https://vega.github.io/schema/vega-lite/v2.json',
  'width': 300,
  'height': 300,
  'data': {
    'values': values
  },
  'layer': [{
    'mark': 'point',
    'encoding': {
      'x': {
        'field': 'x', 
        'type': 'quantitative'
      },
      'y': {
        'field': 'y', 
        'type': 'quantitative'
      }
    }
  }, {
    'mark': 'line',
    'encoding': {
      'x': {
        'field': 'x', 
        'type': 'quantitative'
      },
      'y': {
        'field': 'pred', 
        'type': 'quantitative'
      },
      'color': {
        'value': 'tomato'
      }
    }
  }]
};
vegaEmbed('#vis', spec);




```

#成果物

https://embed.plnkr.co/plunk/0VP8tiZXJRJbjyU5

以上。
Slackの過去ログを消す (slack_cleaner2)

## 参考

* https://github.com/sgratzl/slack_cleaner2

## 手順

* ubuntu 20.04 にて確認
* `Too Many Requests for url:`と表示される場合、数分待つ

```sh
pip3 install slack_cleaner2
```

* Slackの[TOKEN](https://api.slack.com/legacy/custom-integrations/legacy-tokens)を取得し、以下の`SECRET TOKEN`箇所に記述

![スクリーンショット_2020-04-07_09-15-24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/25728/09534cc3-6f91-e722-72e2-838ffa476440.png)


```py:delete.py
from slack_cleaner2 import *
s = SlackCleaner('SECRET TOKEN')

# *bot ユーザーのメッセージを全削除
for msg in s.msgs(filter(match('.*bot'), s.conversations)):
  msg.delete()
```

```sh
python3 delete.py
```


### ユーザー一覧

```py:users.py
from slack_cleaner2 import *
s = SlackCleaner('SECRET TOKEN')

for user in s.users:
    print(user)
```


### 会話一覧

```py:conversations.py
from slack_cleaner2 import *
s = SlackCleaner('SECRET TOKEN')

for conversation in s.conversations:
    print(conversation)
```

### general ルームの会話を全削除

```py:
from slack_cleaner2 import *
s = SlackCleaner('SECRET TOKEN')

# for msg in s.c.general.msgs():
#   msg.delete()
```



### 10件削除したら終了する

```py:sys.exit
import sys

from slack_cleaner2 import *
s = SlackCleaner('SECRET TOKEN')

i = 0
for msg in s.c.general.msgs():
    i = i + 1
    msg.delete()
    if i > 10:
        sys.exit()
```

```py:forを抜ける
from slack_cleaner2 import *
s = SlackCleaner('SECRET TOKEN')

i = 0
for msg in s.c.general.msgs():
    i = i + 1
    msg.delete()
    if i > 10:
        break
```
【Mac】Selenium/jupyter notebook/Chromedriver install方法

# Selenium install方法

## 作業するフォルダへパスを通す。
例： desktopのworkフォルダにパスを通すなら
1. Terminalを開き　`cd ~/Desktop/work`
2. Terminalに`pwd` を入力しパスが正しいか確認

## pipを使用する場合
`pip3 install Selenium`

##Anacondaを使用する場合
`conda install Selenium`

# jupyter notebook install方法
##pip使用する場合
`pip install jupyter`
##Anacondaを使用する場合
`conda install jupyter`

-----

下記URLが表示されるか確認
http://localhost:8888/tree

表示されているのならば、下記画像の「NEW」をクリックし新たなnotebookを作成。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68847/e6b0eb1f-90fb-604f-5145-c1c57965819a.png)

#chromedriver install方法

`brew install chromedriver`

しかし、自分の環境では、下記のエラーが出たため

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68847/c1047e25-9140-afae-aa76-a700d9bbf0ce.png)

エラーメッセージに従い下記コマンドを入力
`brew cask install chromedriver`

しかし、下記のように警告がでたため
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68847/7b10510b-6ced-02d6-a0bc-3de2ea1461f1.png)

警告に従い下記コマンドを入力
`brew cask reinstall chromedriver`

どうやら、前にchromedriverがインストールされていたよう。
とにかく、chromedriverをreinstall。

## chromedriverインストール確認
jupyternotebookに下記を入力

`from selenium import webdriver`
`browser = webdriver.Chrome()`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/68847/3a0e8535-1f05-0abc-9247-ecb6b858cf06.png)


これを実行し、Chromeブラウザが立ち上がったらインストール成功
htmlのタグ(超初心者向け一覧)

##前置き
大学でなんとなく習ったはいいものの、いちいち調べるの面倒だなあ。英語苦手だし……スペルミスがよく起きる(;^ω^)
例のごとく自分が使いそうなやつをまとめますか！

##ここから本編
###絶対忘れてはいけない編###
#####`<!DOCTYPE html> `
一番最初に絶対必要なやつ。
使うHTMLのバージョンをここで指定するぽい。
HTML5ならこれでオッケー。それ以前のバージョンなら、<!DOCTYPE　…　の後が変わってくる。

#####`<HTML>　</HTML>`
`<!DOCTYPE html>` の後に絶対に必要なやつ。`<!DOCTYPE html>` 以外をこれで囲む。
こっからここまで全部HTMLですよーって意味かしら？

###忘れたら意味ない編###
#####`<HEAD>　</HEAD>`
タイトルとかの情報をここで決める。
`<HTML>`の中には入るけど、`<BODY>`の中には入らないぽい。

#####`<BODY>　</BODY>`
本編情報をここで決める。
`<HTML>`の中には入るけど、`<HEAD>`の中には入らないぽい。
二つはライバルポジなのかもしれない。

#####`<title>　</title>`
タイトルを決める。`<HEAD>`の中に入れる。
なかったらどうなるんだろ。多分、タイトルがないから検索欄にも引っかからないものができるんじゃないかな。

###あったらいいね編###
#####`<h1>　</h1>`
この中には本編の見出しが入る。`<h2>`や`<h3>`にしたら、その数字の分だけ見出しが小さくなる。
`<BODY>`の中にある。

#####`<p>　</p>`
この中に一つの段落の文章を書く。`<BODY>`の中にある。
論文とかの長文を書くときには必須。つまり、これを使わない人生を送れたらいいなーってことだ。

```html:perfect.html
<!DOCTYPE html> 
<HTML>　
  <HEAD>　
    <title>これこそタイトル</title>
  </HEAD>
  <BODY>
    <h1>素晴らしい見出し</h1>
    <p>完璧な文章</p>
    <p>すごい文章</p>
  </BODY>
</HTML>
```
構造をまとめるとこんな感じ。(^^)/


##補足
ここからさらに拘りたい場合はここ見ると分かりやすい。
[HTMLタグリファレンス(目的別)](http://www.htmq.com/html/indexm.shtml)
【Day45】積み上げ日記

##予定
■SQL

##完了
■SQL

##学習時間
３h

##学習ポイント
■重複したデータを削除する
SELECT DISTINCT (カラム名)

■四則演算
例、カラムに消費税をかける

■平均を求める
AVG(カラム名)

■データが何個あるか数える
COUNT(カラム名)

■最大数
MAX(カラム名)

■最小数
MIN(カラム名)

■グループ化
GROUP BY カラム名

■データの改名
カラム名 AS “名前”

#疑問点
■サブクエリ

##計画通り進んだか？
進んだ。サブクエリがいまいち理解できなかったが、要するに一回小さい箱を整理してから、大きい箱でまとめるような感覚で理解できた。
【Day46】積み上げ日記

##予定
■SQL基礎
##完了
■SQL基礎
##学習時間
４h
##学習ポイント
■複数のテーブルを1つにしたい時
FROM テーブルA
JOIN テーブルB
ON テーブルA.カラム名＝テーブルB.カラム名
※JOINは何回でも使える

■複数テーブルでのカラムの指定
SELECT テーブル名.カラム名 , テーブル名.カラム名
※WHEREでも使える

■NULLも含めてデータを取得したい時
LEFT JOIN
※通常NULLは除外される

##疑問点
■HAVINGとWHEREの違い
−実行順序の違い
→実行順序の表をまとめて、見ながら処理していく。

##計画通り進んだか？
進んでいない。SQLを一区切りにしてRubyに取り掛かろうとしたが、あまり理解ができていなかったため少し時間をかけて理解進捗に注力した。結果、７０％くらいの理解度にはなったと思うが、ここに時間を費やしても仕方ないので、明日で一区切りする！
Pure Dataでサウンドプログラミングに挑戦してみよう①

#Pure Dataって何？:thinking:
音声、ビデオ、映像処理のためのリアルタイムなグラフィカルプログラミング環境である
そもそも、先ほども出したMax/MSPとは双子のような関係でもある（そもそも開発者はMaxを開発したMiller Puckette）
フリーソフトであり、対応OSはMac/Windows/Linuxとなる

プログラミング言語の一つでもあるが、他の言語と違い、**オブジェクト**と言う箱を**パッチコード**と言う線で繋いていく方法でプログラムを組む

[本家サイト](http://puredata.info/)
[日本のサイト](https://puredatajapan.info/)

#Pure Data Vanilla？ あれ、Pd-extendedが主流じゃなかったの？
自分がPure Dataのことを知ったのは7年前とか、そのくらい前のことでした
元々Pure Data VanillaとPd-extendedの二つがあることは知っていました
当時は、Pd-extended版を基本的にダウンロードする形が主流だった記憶があります

##VanillaとPd-extendedの違い
###Pure Data vanilla
- Miller Pucketteが開発を続けているオリジナルバージョン
- MIDIコントロールやDSP（デジタルシグナルプロセッシング）のための開発環境
- インターフェイスは太めの線やフォントで描かれており、昔風
- 音の処理をするための基本的なオブジェクトが揃っている

###Pd-extended
- Pure Data Vanillaを土台にして、世界中の有志達によって開発された様々なオブジェクトやライブラリ（エキスターナル）が加えられた拡張バージョン
- 映像や画像情報を扱うGEMなどはこちらのバージョンに含まれていた
- 2014年以降アップデートが止まってしまっている様子

今ではPd-extendedのアップデートが止まったため、[Pure Data Japan](https://puredatajapan.info/)でもVanillaの最新版をダウンロードするように言っているそう

#ダウンロード
[Pure Data ダウンロードページ](http://puredata.info/downloads/pure-data)

#さて、どうしよう？
とは言ったものの、具体的に「こんなのが作りたい」と言ったアイデアが今あるわけではないので、[Pure Data Japanのチュートリアル](http://puredatajapan.info/?page_id=10)や数少ない(尚且つ、Pd-extendedを使う前提で書かれた)専門書を使い、それに沿って作っていく方針
その後、応用を利かせて作り続けることが出来るのか不安ではあるが、取り合えずチュートリアルを使って学んでいく予定

##使用する書籍
[「PureData」ではじめるサウンド・プログラミング  「音」「映像」のための「ビジュアル・プログラミング](https://books.rakuten.co.jp/rb/13149548/)
[Pure Data チュートリアル＆リファレンス](https://books.rakuten.co.jp/rb/12193340/)
[Pd Recipe Book Pure Dataではじめるサウンドプログラミング](https://books.rakuten.co.jp/rb/11555291/)
Ubuntu16.04でCisco Packet Tracerを使う

今回はネットワーク学習に最適なCisco Packet TracerをUbuntuで使おうと思います!

#インストール方法
まず[cisco.com](https://identity.cisco.com/index.html)でアカウントを作成。
サインインする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/edfcf0fe-5bb2-85f9-fbf2-c3580faa0caf.png)
アカウント作成。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/10a86058-1070-aaa7-3e6b-72c0096084cc.png)
その後、[Introduction to Packet Tracer](https://www.netacad.com/ja/courses/packet-tracer/introduction-packet-tracer)の「Sign up today!」から、もう一度プロフィールを登録。
登録が完了したら、以下の画面になるので、「Packet Tracerのダウンロード」を選択。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/2095ae9f-b345-5546-13d4-1b36bea12013.png)
Linuxの最新版をダウンロード(7.3.0)して、インストールしようとしたが失敗。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/2fa663fe-7ad0-40de-60d5-dae18931105d.png)

~~~:インストール失敗
$ sudo apt install ./PacketTracer_730_amd64.deb
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
注意、'./PacketTracer_730_amd64.deb' の代わりに 'packettracer' を選択します
インストールすることができないパッケージがありました。おそらく、あり得
ない状況を要求したか、(不安定版ディストリビューションを使用しているの
であれば) 必要なパッケージがまだ作成されていなかったり Incoming から移
動されていないことが考えられます。
以下の情報がこの問題を解決するために役立つかもしれません:

以下のパッケージには満たせない依存関係があります:
 packettracer : 依存: libdouble-conversion1 しかし、インストールすることができません
~~~

一つ古いバージョンをダウンロード(7.2.2)して、インストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/1466ebd8-6e78-f393-663b-9ca1c44bb5c4.png)
実行権限を付与して実行。

~~~
$ chmod 775 PacketTracer-7.2.2-ubuntu-setup.run
$ sudo ./PacketTracer-7.2.2-ubuntu-setup.run
~~~

以下の画面が出たら、起動できているので設定ウィザードに従ってインストールする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/31abb7dc-dbb5-0e06-282e-2b4e3ab88f1e.png)

ubuntuのコンピューター検索でPacket Tracer-7.2.2を起動。
再度ログインを求められるのでログイン情報を入力すると使えるようになる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/558865/2b3285f8-b2a9-3c75-da9f-56fbf5393771.png)

#終わりに
次回はパケットトレーサーでネットワーク構築の練習をして、CCNA取得に役立てたい！！
Microsoft Teams | 10分でできる Microsoft Teams を使った授業 | 課題の作成

関連記事は[**「Microsoft Teams の授業での活用」**](https://qiita.com/hisaho/items/12837a169bd6f1d90d5c)をご参照ください。

# はじめに

本記事では、Microsoft Teams を活用して授業を実施するための方法を解説いたします。今回は **「課題の作成」**について説明します。


# 課題を作成する

- クラスのチームに移動し、**[課題]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/727af0e2-d5ab-20e9-d8a7-0cfc812db650.png)
- **[開始する]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/b84729d1-fce5-f456-d793-b81347b56d54.png)
- **[作成]→[課題]** をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/8e38afea-d809-8977-6882-ffca3a748950.png)
- **「新しい課題」**の画面が開きますので、必要な情報を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/714d8b23-dc3c-5422-f829-e74add0c9f72.png)
- ここでは課題は、[**埼玉県が公開している学力向上ワークシート**](https://www.pref.saitama.lg.jp/g2204/gakuryokukoujou/worksheet/h27wa-kushi-to-suugaku.html)を使用したいと思います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/7fc365e0-aa5f-5399-0448-32b7acfb090b.png)
- 課題として使用するワークシートをあらかじめ手元の PC もしくは OneDrive にダウンロードしておきます。
- [**埼玉県が公開している学力向上ワークシート**](https://www.pref.saitama.lg.jp/g2204/gakuryokukoujou/worksheet/h27wa-kushi-to-suugaku.html)は **Microsoft Word** 形式です。学生が Microsoft Word を所有しているとはかぎりませんので、ここでは**PDF形式**に変換しアップロードします。
- **[手順]**にファイルを添付できますので、先ほどダウンロードしたワークシートファイルを添付します。点数、割り当てるユーザー、提出期限などを設定したら、**[割り当てる]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/b3dfb6f9-7f05-6848-d1fb-bf07adbbafb1.png)
- これで課題が割り当てられました。あたらに課題を作成する場合には、**[作成]**をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/78535/41332b19-960b-5d0f-2a33-641da8ee087a.png)
VSCodeのRemote Development機能を使用してWindowsからMacに接続する

## はじめに

Macでプログラムを書く必要ができたときにMacBookのキーボードだとつらかったのでVSCodeの**Remote Development機能**を使用することにしました。
とても簡単に導入でき、遅延なども感じず、ターミナルも使用できるためとても便利です。

## Mac側設定

`システム環境設定 > 共有`を開きます。

サービスの中の`リモートログイン`をオンにします。
画面にsshで接続するためのコマンドが表示されるのでメモします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/37299e47-3b6f-e265-eadc-8a890faa4118.png)

これでMac側設定は完了です。

## Windows側設定

VSCodeを開き`Remote - SSH`をインストールします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/eb210db4-ca3e-df7c-e400-d231cf5399e0.png)

`Remote - WSL`や`Remote - Containers`は違うので注意してください。

その後左側のタブから`リモート エクスプローラー`タブを選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/e16b6cfa-827f-0ba7-2502-5cb0ea1487af.png)


上部のコンボボックスで`SSH Targets`が選択されていることを確認してください。
`SSH Targets`が選択可能な項目に存在しない場合は違う拡張をインストールしています。
`Remote - SSH`が正しくインストールされているかどうか確認してください。

`SSH Targets`と書かれた部分の+ボタンをクリックすると接続先を追加することができます。
Mac側で設定したときに出てきたコマンドを入力すればMacに接続できます。
接続が完了するとリストに接続したマシンが表示されます。
横にあるフォルダボタンを押すと新しいVSCodeのウィンドウが開き、パスワード入力を求められます。
パスワードを入力すると準備完了です。
あとはフォルダーを開くを選択するとMac内のどのフォルダーを開くか聞かれるので好きなフォルダを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/0c4ac660-ece0-8d00-68c6-8548ad75f51b.png)

VSCodeの拡張機能はローカルとリモートで別々になっているのでリモートでも使用する場合はリモートにもインストールする必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/42193/9b0539ec-b32d-f930-c1d7-6066a249cfc9.png)

## 最後に

VSCodeさえあれば始められてWindowsに繋いでるキーボードをそのまま使用できて感動しました。
Remote Developmentを使いましょう。
ERROR in The target entry-point "@angular/fire" has missing dependencies: [ng]  - firebase/appが発生した時の対処

# エラー

```
 ERROR in The target entry-point "@angular/fire" has missing dependencies:
[ng]  - firebase/app
```

#解決

```
npm uninstall angularfire2
npm i @angular/fire
npm i firebase
```
#####環境
MacOS catalina
ionic5
Angular
シェル（shell）を使ってプログラミングしてみる！

みなさんこんにちわ！

みなさんはシェル（shell）って聞いたことありますか？

[こちら](http://www.cc.kyoto-su.ac.jp/~hirai/text/shell.html)のサイトを参考にさせてただくと、

> シェルとは、UNIX / Linux でターミナルソフト (kterm など）を利用する場合、ユーザはプロンプトで操作目的のコマンドを入力し、そこで表示される結果を見てまた次のコマンド入力を行う、というサイクルで対話的な作業を行います。本当は UNIX / Linux の中核（kernel: カーネル）が管理している機能を用いて、ユーザは様々な処理を行っているのですが、カーネル自身はユーザと直接対話する能力を持っていません。そこで、ユーザと対話する能力を持ち、カーネルに対して操作のお伺いを立てる仲介役のプログラムが、ユーザとカーネルの間に存在してユーザは操作を行います。この仲介役プログラムは、ユーザから見てカーネルの周りをすっぽり覆っている「殻」(shell) のように見えることからシェルと呼ばれます（図1参照）。簡単に言えば、シェルは、ユーザが入力したコマンドを解釈してカーネルに処理を依頼し、その結果やメッセージなどを画面に表示する機能を持っているのです。

だそうです！

つまり、我々がターミナルからカーネルに指示を出す際、カーネルとの間に割って入り、カーネルがわかるように翻訳してくれる通訳のような存在のようです！

シェルについてさらっと理解したところで、早速ターミナルを使ってシェルプログラミングを行っていきましょう！

シェルにも色々種類があるようですが、最近のLinuxやMac OSなどではbashがシェルの標準環境となっていることから、bashを使います！

# シェルを使ったプログラミング

シェルで実行するコマンドをまとめて一つのファイルにしたものをシェルスクリプトと言います。

利用するコマンドについては

- [初心者向け！基本的なLinuxコマンドと使い方！](https://qiita.com/nokonoko_1203/private/499ac9f9938e94e7b02a)

- [初心者向けシェルスクリプトの基本コマンドの紹介](https://qiita.com/zayarwinttun/items/0dae4cb66d8f4bd2a337)

- [シェルスクリプト入門 書き方のまとめ](http://motw.mods.jp/shellscript/tutorial.html)


など自分の使いたい機能を考えて調べてみてください！










シェルスクリプトの拡張子は「.sh」

サンプルシェルスクリプト（lsコマンドを実行したあとに、dateコマンドを実行、echoコマンドで文字列を出力して、readコマンドで入力結果を受け取って変数に入れて出力するスクリプト）

```
#!/bin/bash
ls
date
echo メッセージを入力して下さい。
read message
echo 入力されたメッセージ: $message
```

※最初の`#!/bin/bash`は「シバン」といい、このシェルスクリプトを /bin/bash にある bash シェルで実行する、という意味

- ファイル権限
Linux の全てのファイルには、

・ファイルの所有ユーザー
・所属グループ
・その他のユーザー
の 3 つのアカウントの集団に対して、

・読み込み可能
・書き込み可能
・実行可能

という3つの権限を管理している

`chmod a+x my-first.sh`で`my-first.sh`は全てのユーザーが実行可能なようにファイル権限を変更

- シェルスクリプトの実行
必ず`./`をつけた相対パスで実行する必要がある→つけないとエラー`my-first.sh: command not found`が発生
↓
相対パスを指定しないとコマンドだと認識されるから、「そんなコマンドは存在しないよ！」と怒られる

実行結果

```
$ ./my-first.sh

my-first.sh
2018年  3月 29日 木曜日 08:13:52 UTC
メッセージを入力して下さい。
入力されたメッセージ: hoge
```

readコマンドで第一引数の変数に対して、入力された文字列を代入し、echoコマンドで`$`をつけて変数を指定することで、入力内容を表示

- シェルスクリプトでのif文

```
#!/bin/bash
read -p "日本で二番目に高い山は槍ヶ岳でしょうか？ [y/n]" yn
if [ $yn = "n" ]; then
    echo 正解です。日本で二番目に高い山は北岳です。
else
    echo 不正解です。日本で二番目に高い山は北岳です。
fi
```

readコマンドは、-p"表示したい文字列"というオプションをつけることで、 文字を表示しながら入力を変数に受け取ることができる

if文は`if [ $yn = "n" ]; then`のように、条件は[]内に記入してスペースをつけて、最後はコロンと`then`をつける。またif文の終わりには`fi`の記載が必要

- シェルスクリプトでのwhile句

`while :; do`から`done`までを、終了メッセージを受け取るまでループ

例：`while :; do (echo "Thank you for your access!") | nc -l 8000 ; done`

→8000というポートを使ってサーバーとして起動し、アクセスがあったら、標準出力の内容を返して終了する

echoコマンドでの標準出力を`|`（パイプ）を使ってncコマンドに渡している

ncコマンド：NetCatの略。 TCPやUDPの読み書きを行うコマンドで、Webサーバーからの情報の取得や、簡易Webサーバーの設置、メールの送信などさまざまな機能がある

ポート：TCPやUDP の通信の取り決めのひとつ。0番から65535番のいずれかの数値を設定して通信を行う。通信をするためには、必ず何かしらのポートを利用しなくてはならず、プロトコルやソフトウェアによって、このポートが決まっているものもたくさんある
react-scrollを実装してみた

最近の勉強で学んだ事を、ノート代わりにまとめていきます。
主に自分の学習の流れを振り返りで残す形なので色々、省いてます。
Webエンジニアの諸先輩方からアドバイスやご指摘を頂けたらありがたいです！

#smoothなスクロールを実装したい！
まずはreact-scrolをインストール

```
$ npm install react-scroll
```

Linkタグを使用します！Linkの後にオプションをつけます。これはgithubにある公式のドキュメントからコピペできます。
to=には移遷したい先のIdを指定しましょう。

>smoothスクロールを実装するため、smoothはtrueにしておきます。offsetはpadding-topのようなもので、移遷する位置を指定できます。durationにはスクロールする秒数を指定しましょう。

⬇️Props/Optionsを見てください
[react-scroll](https://github.com/fisshy/react-scroll/)

```TopPage/index.js 
import React from 'react';
import { Link } from 'react-scroll'

省略

<nav>
   <ul className="navi">
    　<li>
     　　<Link activeClass="active" to="Home" spy={true} smooth={true} offset={50} duration={500}>
             Home
         </Link>
      </li>

      <li>
         <Link activeClass="active" to="about" spy={true} smooth={true} offset={50} duration={500}>
            about
         </Link>
      </li>
   </ul>
</nav>

省略

 <section className="Home" name="Home">
 </section>

 <section className="about" name="about">
 </section>
```

上記のようにto=には移遷したい先のIdはname="Home"の様に指定する必要があります。
これでsmoothなスクロールを実現できました！

#参考記事
・[react-scroll](https://github.com/fisshy/react-scroll/)
・[Implementing Smooth Scrolling in React](https://scotch.io/tutorials/implementing-smooth-scrolling-in-react/)
・[React-Scrollでsmoothなスクロールを実装してみた。](https://qiita.com/takk0715/items/6b82d7b4d13134d717eb#react-scroll%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB/)
【GCP】GAEをコンソールから操作する

「バージョン」という項目が複数の異なるコードをデプロイしてることを確認できる
IDをクリックするとそのアプリをブラウザで見た時の内容が確認できる

https://cloud.google.com/appengine/docs/standard?hl=ja
ここに書いてあるのをみるとGAEは一つしか作成できなさそう。
その上に複数のアプリをデプロイしていれば削除はできそうな気がする。

複数のアプリを作成はできそう
https://www.serversus.work/topics/vyly8dwer5uql5ra5xdg/
【GCP】GAEを使ってみる　2回目

【目的】
「【GCP】GAEを使ってみる　1回目」で操作はできたけど、Paasのことをわかっていないのもあり、イメージができなかったので、再度PJを作りなおしてGAEを作ってみた。

【操作】
チュートリアルで作っても、操作をすべて覚えてないので、自分のブログに書き起こして、わからないことは調べたほうがいいと思った。

もう一度プロジェクト作成。
Pythonで作ってチュートリアルとおりでデプロイまで行ける。

PJ作成⇛GAEを構築
このときPythonを選択。
スタンダードかどうかも選択できる。

cloud shelから構築。

1.git clone \ https://github.com/GoogleCloudPlatform/
をやろうとしたら、すでにインストールされていると表示された。
アカウントがt-suzukiなので、PJを変えてもその配下に以前ダウンロードしたものとかが残っているみたい。

2.なので、gitコマンドは無視して勧める。
cd \ python-docs-samples/appengine/standard_python37/hello_world
githubからクローンはできてるので、ディレクトリを移動する。

3.アプリをテストするために以下のコマンドをうつ。
virtualenv --python python3 \ ~/envs/hello_world
virtualenvコマンドはpython開発で使う、仮想環境作成ツール。
アプリをテストするには、まず分離された仮想環境を作成します。
これにより、アプリがシステム上の他の Python アプリケーションと干渉することを防ぎます。


4.新しく作成した仮想環境を有効にします。
source \ ~/envs/hello_world/bin/activate
仮想環境は作成しただけでは有効にならないので、sourceコマンドで有効にする。

5.pip を使用してプロジェクトの依存関係をインストールします。この「Hello World」アプリは Flask のマイクロフレームワークに依存します。
pip install -r requirements.txt

6.最後に、Flask 開発サーバーを使用して Cloud Shell でアプリを実行します。
python main.py

ここまでの作業でCloud Shell 上でテスト画面がみれるようになる。

7.App Engine へのデプロイをするときは、以下をうつ。
gcloud app create
リージョン内にアプリを作成する。
アプリをデプロイするコマンドですが、app.yamlないしappengine-web.xmlがある場所で叩かないと怒られます。

8.以下のコマンドでアプリをデプロイできます
gcloud app deploy app.yaml \ --project \ testclouddatastore-mune

9.サブドメインにアクセスすると起動が確認できる。

プロジェクトを無効にしたいときは、設定から。
プロジェクトを削除するときは、
コンソールの左上にあるナビゲーション メニューで [IAM と管理] に移動します。
IAM と管理者　＞　[リソースの管理] ＞[削除]

＝＝＝＝

Do you want to continue (Y/n)?  y
Beginning deployment of service [default]...
╔════════════════════════════════════════════════════════════╗
╠═ Uploading 2 files to Google Cloud Storage                ═╣
╚════════════════════════════════════════════════════════════╝
File upload done.

↑ここの2 filesが変更したファイルがあがっていることになる、

＝＝＝

【疑問点1】
多分、おれは無料枠で使ってるので、スタンダード
確認は以下の手順で可能　
コンソール画面　＞　GAE　＞　バージョン　＞環境
ここに「標準」とあった。だからローカルからは接続できない。

【疑問点2】
GAEの削除、追加作成とかやってみたかったのだけど、できない。
仕組みがわかってないので以下を実施。
https://dev.classmethod.jp/articles/gae-webapp/

GAE作成のところから
gcloud app create --project=***********

つくろうとしたら以下のエラーが出た

ERROR: (gcloud.app.create) The project [***********] already contains an App Engine application in region [us-central].  You can deploy your application using `
gcloud app deploy`.

エラーの詳細がぐぐってもでてこない。
おそらくもうGAEは立ち上がっててアプリもつくれますよってこと
gcloud app deployを使ってといってる。
Paasの仕組みとしてGoogleの開発環境を使ってて、自分のアカウントですでにGAEを構築したことがあるからこういうことになってるのかと思う。

【疑問点3】
お恥ずかしながら、yamlが何かがよくわからない。


ということで一段落したので、調査の続き。
確かにyamlは以下の中身になっている。

$ sudo find /home/***/python-docs-samples/appengine/ -name "*.yaml" -print
runtime: python27
api_version: 1
threadsafe: true
handlers:
- url: /.*
  script: main.app

YAML　YAML Ain’t Markup Language 
YAMLのルールに従って書かれた、テキストファイル（中身が文字だけのファイル）のこと
用途はXMLのような汎用のマークアップ言語に近いが、文法はプログラミング言語に近く、プログラムが内部で扱うオブジェクトなどを保存や送受信などのためにデータ化する「シリアライズ」（serialize）のための形式として特に有名である。

これがYamlの公式ドキュメント
https://cloud.google.com/appengine/docs/standard/python/config/appref?hl=ja
App Engine アプリの設定は app.yaml ファイルで構成します。

【感じたこと】
・https://qiita.com/rshibasa/items/6ea3eff7f210153772da
ここもやりたい。削除方法やファイルの編集について書いてある。
・鍵を作成したりしなくてもコンソールからすべていじれるのは楽
・Python以外でも構築をしてみたい。
【GCP】DataStoreを使ってみる

【目的サイト】
https://cloud.google.com/datastore/docs/quickstart?hl=ja
・ネットでいろいろ探したが、チュートリアルが一番良さそうだった。

エンティティを直接作成するパターンを学ぶ。

https://www.topgate.co.jp/gcp06-how-to-use-cloud-datastore-gae
ここはコンソールから直接操作はしないパターン。
DataStoreはデフォルトで使えるようになっているらしく、コンソールから操作する必要はないらしい。

・datastoreについて
https://qiita.com/kazutomo/items/bcaf55d3d0fc23885766

~~~~~~~~~~~~~~~~~~~

エンティティの作成中に以下のエラーが発生。

このエンティティを保存できませんでした。もう一度お試しください。
The project testclouddatastore-mune does not exist or it does not contain an active Cloud Datastore or Cloud Firestore database. Please visit http://console.cloud.google.com to create a project or https://console.cloud.google.com/datastore/setup?project=testclouddatastore-mune to add a Cloud Datastore or Cloud Firestore database. Note that Cloud Datastore or Cloud Firestore always have an associated App Engine app and this app must not be disabled.
追跡番号: c1648598569413667
↓
このエラーはGAEが無効になっていると表示されるみたい。
GAEを有効にしたらなおった。
ということはGAEを使わないとdatastoreは使えないということ？

＝＝＝
「種類別クエリ」タブから確認すると、CLIではなく、GLIでデータの中身を簡単に見ることができる。
＝＝＝
「GQL クエリ」　画面をクリックすると入力できないように見えるが、そのままキーボードを押すと入力できる。
大文字小文字は区別されるので注意。
結果は画面下部に表示される。
実際にクエリをテストすることができる感じ。

【思ったこと】
サーバからどうやってdatasotoreにアクセスして処理するかも調べたい
include つきの Mapbox Style を HOCON で

地理院地図 Vector のタイルである experimental-bvmap 向けに、速くて管理しやすいスタイルを開発しています。

[![](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102082/ab90a908-2a1d-3f35-ddf0-1b410be48e1a.png)](https://optgeo.github.io/toki/static.html#10.82/35.631/139.8223/-37.7)

experimental-bvmap をスタイルするにあたっては、 `text-offset` の記述など、繰り返される記述をうまく切り離して `include` することが有効です。

>DRY (Don't Repeat Yourself) 原則重要

ということです。

これを実現するために、[toki](https://github.com/optgeo/toki) では HOCON (Human-Optimized Config Object Notation) を使っています。

具体的には、次のような書き方をしています。

### hocon/label.conf
```
id: label
type: symbol
source: v
source-layer: label
layout: {
  text-field: [
    get
    knj
  ]
  text-font: include _text-font
  text-offset: include _text-offset
}
paint: {
  text-color: [
    rgb
    0
    0
    0
  ]
  text-halo-color: [
    rgb
    255
    255
    255
  ]
  text-halo-width: 1
}
```

### hocon/_text-offset.conf

```
[
  match
  [
    get
    dspPos
  ]
  [
    LT
    LC
    LB
  ]
  [
    literal
    [
      0.5
      0
    ]
  ]
  [
    RT
    RC
    RB
  ]
  [
    literal
    [
      -0.5
      0
    ]
  ]
  [
    CT
  ]
  [
    literal
    [
      0
      0.5
    ]
  ]
  [
    CB
  ]
  [
    literal
    [
      0
      -0.5
    ]
  ]
  [
    literal
    [
      0
      0
    ]
  ]
]
```

### hocon/_text-font.conf

```
[
  NotoSansCJKjp-Regular
]
```

# 分析
私は、結局のところ、開発者の正論を導入することで、**開発者が幸せになれる**ベクトルタイルツールキットを作ることを狙っているように思います。[Programmer Happiness](https://rubyonrails.org/doctrine/#optimize-for-programmer-happiness) 重要、ということですね。

そういったアプローチに興味を抱き熱意を持った人間が少しくらいいないことには―あまりいっぱいいる必要もないだろうけれど―それは困ったことになってしまうでしょう。

expression を始め、 Mapbox Style には Lisp の素養が役に立ちそうなところがたくさんあります。プログラマーをハッピーにする方向で Mapbox Style を掘り下げる、ということを進めたいと思います。
[Swift] Unity as a LibraryをSwiftから呼ぶ

基本的なところはここを見ながら進める。
https://qiita.com/tkyaji/items/7dbd56b41b6ac3e72635

SwiftでUnityクラスを作る。上の記事ならこんなかんじ。

```swift
class Unity: NSObject, UnityFrameworkListener, NativeCallsProtocol {
    static let shared = Unity()
    private let unityFramework: UnityFramework
    
    override init() {
        let bundlePath = Bundle.main.bundlePath
        let frameworkPath = bundlePath + "/Frameworks/UnityFramework.framework"
        let bundle = Bundle(path: frameworkPath)!
        if !bundle.isLoaded {
            bundle.load()
        }
        let frameworkClass = bundle.principalClass as! UnityFramework.Type
        let framework = frameworkClass.getInstance()!
        if framework.appController() == nil {
            var header = _mh_execute_header
            framework.setExecuteHeader(&header)
        }
        unityFramework = framework
        super.init()
    }
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) {
        unityFramework.register(self)
        FrameworkLibAPI.registerAPIforNativeCalls(self)
        unityFramework.setDataBundleId("com.unity3d.framework")
        unityFramework.runEmbedded(withArgc: CommandLine.argc, argv: CommandLine.unsafeArgv, appLaunchOpts: launchOptions)
    }
    
    var view: UIView {
        unityFramework.appController()!.rootView!
    }
    
    func showHostMainWindow(_ color: String!) {
        
    }
}

```

ViewControllerを作る。

```swift

class LaunchViewController: UIViewController {}

class ViewController: UIViewController {
    private let unityView = Unity.shared.view
    
    override func loadView() {
        super.loadView()
        view.addSubview(unityView)
        NSLayoutConstraint.activate([
            unityView.topAnchor.constraint(equalTo: view.topAnchor),
            unityView.leftAnchor.constraint(equalTo: view.leftAnchor),
            unityView.rightAnchor.constraint(equalTo: view.rightAnchor),
            unityView.bottomAnchor.constraint(equalTo: view.bottomAnchor),
        ])
    }
}

```

後述するが、`LaunchViewController`なるものを作っておく。

```swift:AppDelegate.swift
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
    lazy var window: UIWindow? = .init(frame: UIScreen.main.bounds)
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        
        window?.rootViewController = LaunchViewController()
        window?.makeKeyAndVisible()
        Unity.shared.application(application, didFinishLaunchingWithOptions: launchOptions)
        window?.rootViewController = ViewController()
        
        return true
    }
}

```

起動時にUnityクラスを初期化しておく。
`runEmbedded`はwindowが無いと上手く動かないので、先ほど作った`LaunchViewController`でwindowを作り、そのあとでメインのViewControllerに差し替える。
起動直後にUnityを出さないのであれば、適当にwindowが出来てから呼べばOK
Windowsコマンドプロンプトからec2にsshする

Windowsで開発環境整えるのって難しいですよね…。
Linuxに比べて資源少ないし…。
今回はEC2デビューしたので、WindowsのCMDからEC2にSSHする方法を説明します。

##環境
- Windows10 Command Prompt　（ローカル）
- EC2 Linux（リモート）


###EC2の設定
EC2側でインスタンスを立ち上げ、**SSH**接続を有効にします。
私はLinuxにしましたが、お好きなOSで大丈夫だと思います。

立ち上げの際作成されるSSHキーの.pemファイルは**C:\User\$User\\.ssh**に保存してください。
WindowsでのSSHのデフォルトフォルダーです。

＊EC2インスタンス立ち上げの詳細は省きます。

###SSHをインストール
Windows10で　設定→アプリ→オプション機能→機能の追加　から
**OpenSSHクライアント**と**OpenSSHサーバー**をインストールします。

![スクリーンショット (69).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541119/12415c28-f787-1c5e-932d-0d1991d5a5be.png)
![スクリーンショット (70).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541119/cdee55cd-61da-a2e3-b4f4-095431d70fed.png)
![スクリーンショット (71).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541119/6d6f5fc6-af58-550e-46d5-6cd76a5edd07.png)


###.pemファイルの権限を修正
**PowerShell**を起動し、以下のコマンドを打ちます。
こうすることで、PC上の他のユーザーがこのSSHキーを使うことを防ぐことができます。

```powershell
$path = ".ssh\SSH鍵名.pem"
icacls.exe $path /reset
icacls.exe $path /GRANT:R "$($env:USERNAME):(R)"
icacls.exe $path /inheritance:r
```
SSHキーのプロパティ→セキュリティで今使っているWindowsユーザーのみ表示されていればOKです。
![スクリーンショット (73).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/541119/3f802573-40a4-1df1-0526-ce3cdde27da6.png)


###cmdからSSHする
以上でWindowsの設定は完了しました！
EC2のインスタンス一覧から接続ボタンを押してSSHコマンドを取得します。
コマンドプロンプトで、.sshフォルダに移動し、上記のコマンドを打てばEC2に入れます。

```
C:\User\$User>cd .ssh
C:\User\$User\.ssh>ssh -i "鍵名.pem" ec2-user@ec#-#-##-###-###.region.compute.amazonaws.com
```
(#は数字、regionはインスタンスの地域コード、パスはEC2コンソールから取得）


##おまけ　SSHのコマンドが長すぎ！
EC2のSSHコマンドって結構長いですよね。
それを開発のたびに打つのは面倒くさい…
そんな時は、SSHに**あだ名**をつけちゃいます。

まずはコマンドプロンプトから

```
C:\User\$User\.ssh> notepad config
```
でconfigファイルを開き、以下を入力します。

```
Host ec2nickname (あだ名)
HostName #-#-##-###-###.region.compute.amazonaws.com (インスタンスのURL）
User ec2-user (インスタンスのユーザー名）
IdentityFile ~/.ssh/鍵名.pem
```

次に、dirコマンドでconfigファイルがあることを確認します。
config.txtになっていた場合、moveコマンドでconfigに直してください。

そしたら、**ssh <新しい名前>**だけでEC2に入れるようになります！

```
C:\User\$User\.ssh>move config.txt config
C:\User\$User\.ssh>ssh ec2nickname
```


##参考資料
https://www.youtube.com/watch?v=gpQOiln8Q4k
https://www.youtube.com/watch?v=GEA4t1Z1OP4
初心者によるプログラミング学習ログ 283日目

#100日チャレンジの283日目
twitterの100日チャレンジ#タグ、#100DaysOfCode実施中です。
すでに100日超えましたが、継続。
100日チャレンジは、ぱぺまぺの中ではプログラミングに限らず継続学習のために使っています。
283日目は、
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">おはようございます<br>283日目　2h<br>・xdデザインカンプからのサイト模写<br>・ヘッダーとフッターのブラウザ幅いっぱい表示<a href="https://twitter.com/hashtag/%E6%97%A9%E8%B5%B7%E3%81%8D%E3%83%81%E3%83%A3%E3%83%AC%E3%83%B3%E3%82%B8?src=hash&amp;ref_src=twsrc%5Etfw">#早起きチャレンジ</a><a href="https://twitter.com/hashtag/%E9%A7%86%E3%81%91%E5%87%BA%E3%81%97%E3%82%A8%E3%83%B3%E3%82%B8%E3%83%8B%E3%82%A2%E3%81%A8%E7%B9%8B%E3%81%8C%E3%82%8A%E3%81%9F%E3%81%84?src=hash&amp;ref_src=twsrc%5Etfw">#駆け出しエンジニアと繋がりたい</a><a href="https://twitter.com/hashtag/100DaysOfCode?src=hash&amp;ref_src=twsrc%5Etfw">#100DaysOfCode</a></p>&mdash; ぱぺまぺ@webエンジニアを目指したい社畜 (@yudapinokio) <a href="https://twitter.com/yudapinokio/status/1247252295919648768?ref_src=twsrc%5Etfw">April 6, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
Pythonでアルゴリズム（二分探索）

#はじめに
　コロナウイルスの影響で暇になったので...（以下略）
　前回のセグ木は重かったので今回は割と簡単に実装できる二分探索を適当にまとめてみます。
#考え方
　どこかの境界で条件を満たすものと満たさないものが分かれている場合に、その境界を**O(logN)**で探索することができます。
　例えば、条件を満たさないものを**x**、満たすものを**o**として、以下のようなリストが与えられたとします。
　　　　　　　　　　　**xxxxxxoooooo**
 
　0-indexで考えると、5番目や、6番目(境界の左右どちらか)を求めたいというときに二分探索が有効です。
　探索する範囲の左を**left**、右を**right**という変数に代入します。これらを足して、2で割ったもの（切り捨て）を**mid**として、indexが**mid**の要素が条件を満たすかどうかを判定します。
　満たすなら、それよりも右には境界はないので**right**の値を**mid**に更新して右側を切り捨てます。逆に、満たさないならそれよりも左に境界はないので**left**の値を**mid**に更新します。
　このようにして毎回半分ずつ区間が狭くなり、最終的には**right**と**left**が隣り合ったら探索終了です。このとき、**right**は常に条件を満たす要素のインデックス、**left**は満たさないもののインデックスを持たせていたので、上の例でいうと**left**は5、**right**は6という値を持ちます。
#例題1
　**[2, 5, 7, 9, 10, 18, 29]**で、9以上となる最小のインデックスを考える。これは、条件を9以上とすれば満たすか満たさないかが**xxxoooo**となるため最終的に**right**が持つ値が答え。　
##コード
```py
a = [2, 5, 7, 9, 10, 18, 29]

left = 0
right = len(a) - 1

while right - left > 1:
    mid = (right + left) // 2
    if a[mid] >= 9:
        right = mid
    else:
        left = mid

print(right) # 3
```
#例題2
　せっかくなのでatcoderの過去問から、[ABC146-C](https://atcoder.jp/contests/abc146/tasks/abc146_c)の**Buy an integer**を解きます。これも、候補である1~10^9についてどこかより左は買えて、右は買えないという境界が存在するため二分探索していけばよい。今回はインデックスでなく直接整数を探索します。(リスト作ってたらTLEです)
　注意として、1つも買えない場合とすべて買える場合には境界が存在しないため場合分けした方がよさそうです。
##コード
```py
import sys

a, b, x = [int(x) for x in input().split()]

left = 1
right = 10**9

if a*right + b*len(str(right)) <= x:
    print(right)
    sys.exit()

if a*left + b*len(str(left)) > x:
    print(0)
    sys.exit()

while right - left > 1:
    mid = (right + left) // 2
    if a*mid + b*len(str(mid)) <= x:
        left = mid
    else:
        right = mid

print(left)
```
#標準ライブラリbisect
　リストの中に含まれるか判定する二分探索、挿入したい要素の入るインデックスを求める際に使えます。
　これは、昔[自作したもの](https://qiita.com/takayg1/items/7bd88aa4994362bc5a70)もあるので自作してもよいですが、標準ライブラリの**bisect**を使うのが普通だと思います。(使い方は練習必要な気がします)
std::any::AnyとBoxで何でも受け入れる構造体を作成する

# はじめに
ソースコードは[gist](https://gist.github.com/morimolymoly/49bd3ae25237e8a56d5fe4c9d7519a39)を参照してください。

# やりたいこと
様々な型を受け入れる構造体をつくりたい

# 問題
様々な型に対応するにはジェネリクスを使うのがよいですが、以下のようなコードはコンパイル不可能です。
`b_vec`の型は1つ目のアイテムを解釈した瞬間から、`Vec<B<i32>>`となってしまい、`B<String>`を格納することはできません。

```rs
struct B<T> {
    value: T
}

fn main() {
    let b_vec = vec![
        B {
            value: 10 as i32,
        },
        B {
            value: String::from("hi"),
        }
    ];
}
```

# 解決
`std::any::Any`トレイトと`Box`を組み合わせたメンバを構造体に定義することで解決できます。
`std::any::Any`トレイトは非`'static`参照を含む型には実装できませんが、逆に言うとほとんどの型で使用することができます。(実装されています)

そのため、`std::any::Any`トレイトオブジェクトにより様々な型を指定することが可能となります。

以下のようにして、`Box`の中に`std::any::Any`トレイトオブジェクトを入れた型のメンバを構造体`A`に定義します。すると、あらゆる型をもったAで`Vector`を生成しても`Vec<Box<dyn Any>>`となり、多様な型を受け入れられるようになります。

また、`std::any::Any`トレイトには`downcast_ref`メソッドがあり、これで元の型を取り戻すことができます。それも`Option`型で取り出すことができるので大変便利です。

```rs
use std::any::Any;

struct A {
    value: Box<dyn Any>
}

fn main() {
    let a_vec = vec![
        A {
            value: Box::new(10),
        },
        A {
            value: Box::new(String::from("hi")),
        },
    ];
    for v in a_vec.iter() {
        if let Some(a) = v.value.downcast_ref::<i32>() {
            println!("i32 {}", a);
        } else if let Some(a) = v.value.downcast_ref::<String>() {
            println!("string {}", a)
        }
    }
}
```

# まとめ
`std::any::Any`トレイトと`Box`を組み合わせることにより、まるで動的型付けのようなコードを書くことができるようになりました。

# 参考
https://doc.rust-lang.org/std/any/trait.Any.html