OmniAICreator/Qiita-1.07M huggingface dataset:
ExcelVBAでのパフォーマンスアップのため

#ツールの概要
色々なシートから対象のデータを各セルから読み込んで指定した箇所で好きなフォマードで書き込みツールです。

#問題になっている
各シートで利用者の各情報が記載されて
各利用者のため指定したフォマードの中に入れることですので、
１人の利用者の５シートから対象のデータを読み込んで
まだ指定のセルで書く処理をするとパフォーマンスが良くない状態になっている

#解決方法
各シートのデータを最初から読んでArrayとして保存し、
対象利用者の指定したフォマードの中に入れると１００人以上を１分以内で出力される
以前は１００人以上なら７分ぐらいでした。
tmux コマンドリスト

# はじめに
- tmuxの頻出コマンドリスト + 用語説明
- ()内に筆者の`イメージ`を書いてます。`厳密`には異なるのであくまで`参考程度`に

## 新規セッション作成

-  `セッション`とは言い換えると`作業エリア`(セッション)
- `セッション`の中では`画面分割`、`タブ切替`など`キーボード`のみで操作可能
- また複数の`セッション`を作成可能、`プロジェクト`ごとに`セッション`(作業エリア)を`切替`可能

```ruby
# セッション作成
$ tmux new -s セッション名(任意の名前)
# セッション名変更
$ prefixキー + $
```
## セッション削除
```ruby
# 指定して削除
$ tmux kill-session -t セッション名
# すべてのセッション削除
$ tumx kill-server
```
## アタッチ
-  作成した`セッション`に`アタッチ`する(接続する)

```ruby
# セッション一覧取得
$ tmux ls
# セッションにアタッチ(接続という表現がしっくりくる)
$ tmux attach -t 名前
# 上記と等価
$ tmux a -t 名前
```
## デタッチ
- `アタッチ`(接続)中の`セッション`(作業エリア)から`デタッチ`(ログアウト)する

```ruby
# セッションデタッチ(接続中のセッションからログアウトする)
# prefixキーは設定ファイルで変更可能(デフォルトは CTR+q)
$ prefixキー + d
```
## ウィンドウ
- セッション内でタブのような役割をする。
- タブごとに役割を分けるなど結構使う
[![Image from Gyazo](https://i.gyazo.com/817a23c78d3f88d1635fef2c0c983801.gif)](https://gyazo.com/817a23c78d3f88d1635fef2c0c983801)

```ruby
# 新規作成
$ prefixキー + c

# ウィンドウ名前変更
$ prefixキー + ,

# ウィンドウ切替
$ prefixキー + インデックス番号
# 次のウィンドウ 1→2 
$ prefixキー + n
# 戻る 2→1
$ prefixキー + p

# ウィンドウ削除
$ prefixキー + &

# ウィンドウリスト
$ prefixキー + w

# ウィンドウ検索
$ prefixキー + f
```
## ペイン
- 画面分割ができる
- ターミナル専用などにして使ったりする
- 筆者はvimで分割しがちなので正直あまり使わない...

[![Image from Gyazo](https://i.gyazo.com/b4a1e69a644865eb488cc6f77842d978.gif)](https://gyazo.com/b4a1e69a644865eb488cc6f77842d978)

```unix
# 画面分割(横)
$ prefixキー + "

# 画面分割（縦）
$ prefixキー + %

# 削除
$ prefixキー + x

# 画面切替
$ prefixキー + o

# 番号が表示されている間に押す
$ prefixキー + q 
```
## おわりに
- バッファと設定ファイルはまた別記事で書きます。
- 正直筆者自身上記の２つはほとんど使ってないので、使いこなしだしたら記事を書ます。
【メモ】Visual Studio CodeでのJavaScriptのデバッグ

# 毎度忘れるのでメモ

1. 事前に拡張機能の[Live Server](https://marketplace.visualstudio.com/items?itemName=ritwickdey.LiveServer)をインストールする。
1. index.htmlとscript.jsのHTML/JavaScriptのニコイチを用意する。
1. 
1. script.jsのコードのどこかにF9でブレークポイントを設置
1. index.htmlをF5でデバッグする
1. launch.jsonが起動するので、以下のように設定する。

```json
{
    "version": "0.2.0",
    "configurations": [
        {
            "type": "chrome",
            "request": "launch",
            "name": "Launch Chrome Local Debug",
            "url": "http://localhost:5500/index.html",
            "webRoot": "${workspaceFolder}"
        }
    ]
}
```

5500のポートはlive Serverのポート
3.Docker in WSL環境構築

# 概略
現在では、DevOpsのベスト・プラクティスを実現する重要な要素として、また、Infrastructure as Codeの観点からサービスをDockerで構築することがスタンダードとなっています。但し、今までは開発プラットフォームが主にWindowsだったため、中々コード化したインフラ構築の学習や開発が手元（ローカル環境）でできないのが現状でした。しかし、WSL2の登場によりWindwos上でもより本番環境に近いLinux環境でのサービスを試せるようになり、Dockerも試せるようになりました。
本章ではWSL2上に複数のDockerコンテナを起動し、動作を検証します。
環境イメージは下記の通りとなります。

![Docker on WSL環境俯瞰図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/96681/e72b8302-ebb8-4a2d-c453-3b9d699ef725.png)

- 本番環境に用意するべきサーバを全てローカルで起動する。
- DBのデータ等、コンテナがダウンしても保存しておきたいデータはDockerホストにマウントし、永続化する。
- 全てのサーバはDocker及び、docker-composeでコンテナとして管理し操作する。


---

# 使用した環境

Windows11 Pro Insider Preview
Intel Core i7-8650U
実装RAM 16.0 GB

---

# 目次
[アーキテクト技術者・構成管理者・リモート開発者のためのローカル開発環境構築ガイド](https://qiita.com/boss_ape/items/c33408df7557801d0183)
**3. Docker in WSL環境構築**
[3.1. Docker / docker compose インストール・初期設定](https://qiita.com/boss_ape/items/f35a1362fe56f755e44c)
[3.2. Docker環境構成検討]()
[3.3. DockerによるMySQL(RDBMS)サーバ構築]()
[3.4. DockerによるGo言語(AP)サーバ構築]()
[3.5. DockerによるNginx(Web)サーバ構築]()
[3.6. docker-composeによる簡易オーケストレーション]()

---

[2.2. gitインストール・設定](https://qiita.com/boss_ape/items/c9155659d8d474f3c8b6) < 前 **3. Docker in WSL環境構築**  次 > [3.1. Docker / docker compose インストール・初期設定](https://qiita.com/boss_ape/items/f35a1362fe56f755e44c)
【SQL】テーブルとレコード(登録処理用)

<h1>【SQL】employeesテーブル</h1>
<h3>テーブルカラム</h3>
id・年齢・生年月日・メールアドレス・住所・グループ名

```sql:CREATE_employees.sql
CREATE TABLE employees(
    id INT AUTO_INCREMENT NOT NULL,
    name VARCHAR(100) NOT NULL,
    age INT(3) NOT NULL,
    birthDay DATE NOT NULL,
    email VARCHAR(100),
    address VARCHAR(100),
    groupId VARCHAR(100),
    PRIMARY KEY (id)
);
```

<h3>レコードの追加(10件)</h3>

```sql:INSERT_employees.sql
INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`address`
   ,`groupId`
) VALUES (
    1
   ,'佐藤武'
   ,22
   ,'1999-05-06'
   ,'ta-satou@keru.com'
   ,'北海道札幌市北区北33条西1丁目1-1ヤマダレジデンス1101号室'
   ,'松'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`groupId`
) VALUES (
    2
   ,'山田恵子'
   ,25
   ,'1996-04-26'
   ,'da-yama@keiko.com'
   ,'竹'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`address`
   ,`groupId`
) VALUES (
    3
   ,'鈴木光太郎'
   ,40
   ,'1981-03-14'
   ,'suzuki-kou@tarou.co.jp'
   ,'東京都中央区南1条西1丁目'
   ,'松'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`address`
   ,`groupId`
) VALUES (
    4
   ,'高橋みか'
   ,67
   ,'1954-01-06'
   ,'mika.takahashi@hokkaido.co.jp'
   ,'北海道札幌市中央区北2条西1丁目1-1'
   ,'竹'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`address`
   ,`groupId`
) VALUES (
    5
   ,'秋本康'
   ,65
   ,'1956-02-02'
   ,'sapporo-akb@sapporo.city.jp'
   ,'北海道札幌市中央区'
   ,'竹'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`address`
   ,`groupId`
) VALUES (
    6
   ,'小池ゆり'
   ,68
   ,'1952-07-15'
   ,'tokyo-yuri@tokyo.jp'
   ,'東京都新宿区西新宿1丁目1-1'
   ,'梅'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`address`
   ,`groupId`
) VALUES (
    7
   ,'菅義男'
   ,72
   ,'1948-12-06'
   ,'ga-su@go.jp'
   ,'東京都千代田区永田町1-1-1'
   ,'梅'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`groupId`
) VALUES (
    8
   ,'麻生二郎'
   ,80
   ,'1940-09-20'
   ,'竹'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`email`
   ,`groupId`
) VALUES (
    9
   ,'安倍晋次'
   ,66
   ,'1954-09-21'
   ,'sakura-mirukai@go.jp'
   ,'梅'
);

INSERT INTO `employees` (
    `id`
   ,`name`
   ,`age`
   ,`birthDay`
   ,`groupId`
) VALUES (
    10
   ,'安部寛'
   ,56
   ,'1964-06-22'
   ,'竹'
);


```
Unity C# Invoke()について、

#
Unity Invokeでググると、MonoBehaviour.Invoke() がHITし過ぎる。 

しかし本当に知りたいのは

.NETのMethodBase.Invoke() だったのだ。

何という事でしょう、、、サンプルにあるInvoke()は指定時間後に実行されると思ったら、パラメータは違うし挙動も違うし、

大混乱という人が少なからずいるんじゃないかと思いまして、

私？私はググったから大丈夫でしたよ？

なんてね。
【TypeScript】typeとinterfaceの違い


TypeScriptの`type`と`interface`の違いをまとめています。

#結論

**type**エイリアスは、複数の場所で使い回す**型に名前をつける**。

**interface**は、オブジェクトや関数の**構造を定義**する。

<br>

具体的なtypeとinterfaceの違いは以下です。

```:①同名の宣言
typeは、同名のtypeを宣言するとエラー。
interfaceは、同名のinterfaceを宣言するとマージされる。
```

```:②継承
typeは、継承できない。
interfaceは、継承できる。
```


#①同名の宣言

typeは同名のtypeを宣言できません。（エラーになる。）

```ts
type Person = {
  name: string
  age: number
}

type Person = {
  hight: number
}
//エラー
```

interfaceは同名のinterfaceが宣言されるとマージされる。

```ts
interface Person {
  name: string
  age: number
}

interface Person {
  hight: number
}
//Personにhightというプロパティが付け足される。

const taro: Person = {
  name: "taro",
  age: 20,
  hight: 170
}
```

上記の場合、Person型を付けた`taro`オブジェクトには`name`、`age`、`hight`の３つのプロパティが必須になっています。

#②継承

typeは継承できません。

interfacemは、`extends`を使って継承できます。


```ts
interface Person {
  name: string
  age: number
}

interface Employee extends Person {
  occupation: string
}
//Personを継承したEmployee型を定義

const taro: Employee = {
  name: "taro",
  age: 20,
  occupation: "sales",
}
```

<br>

ちなみにtypeは継承はできませんが、交差型で新しい型を作ることはできます。

```ts
type Person = {
  name: string
  age: number
}

type Hobby = {
  hobby1: string
  hobby2: string
}

type Introduction = Person & Hobby
//交差型で新しい型を宣言

const taro: Introduction = {
  name: "taro",
  age: 20,
  hobby1: "tennis",
  hobby2: "shopping"
}
```

#まとめ

typeもinterfaceも実際ほとんど同じように使えますが、違いは以下。

```:①同名の宣言
typeは、同名のtypeを宣言するとエラー。
interfaceは、同名のinterfaceを宣言するとマージされる。
```

```:②継承
typeは、継承できない。
interfaceは、継承できる。
```

interfaceの方が柔軟に型を変化させることができるので、推奨されている様子です。

ただ、「柔軟に変化」できる分、思わぬバグを生みやすいとも言えそうなのでtypeが劣るというわけではない。

結論、違いを理解した上で、状況に応じて適切に使い分けていきましょう。

今回は以上です！
jsonでスニペットを書かなくて良いようにした

# はじめに

Nimの勉強に、ultisnipで使われている記法(を簡略化したもの)で定義したスニペットファイルを、LSP形式のjsonファイルに変換するプログラムを書きました。

[snip2json](https://github.com/uga-rosa/snip2json)

# 導入

一応binディレクトリにバイナリを置いていますが、linux以外では自前ビルドしてください。クロスコンパイル試したんですが上手くいかなかったので。。。
[公式](https://nim-lang.org/install.html)からインストールして

```sh
nim c -d:release snip2json.nim
```

でコンパイル出来ます。

# 使い方

非常にシンプルで、指定のディレクトリ以下にある全てのファイルを変換して出力します。デフォルトだと`snip/`以下のファイルを`json/`以下に出力します。

```
 .
└──  snip
   └──  test.snip
```

これが

```
 .
├──  json
│  └──  test.json
└──  snip
   └──  test.snip
```

こう。拡張子は見てないです。

中身はこんなふうに変換されます。

```test.snip
snippet test
hello! $1
endsnippet

snippet test2
hello! ${1:name}

by
endsnippet
```

```json:test.json
{
  "test": {
    "prefix": [
      "test"
    ],
    "body": [
      "hello! $1"
    ]
  },
  "test2": {
    "prefix": [
      "test2"
    ],
    "body": [
      "hello! ${1:name}",
      "",
      "by"
    ]
  }
}
```

# おわり

自分で使うには十分な機能になりました。json書きづらいんですよね。
【C++】1行で配列やvectorの和を取る決定版

多くの言語は一行で和がとれるのに、なぜC++はfor文を回さないといけないのか、、
そんな疑問が記事になりました。

この記事では、配列やvectorの和を1行で取る方法を紹介します。
また汎用性と安全性に配慮しているので、どんな型でも安心してご利用いただけます。
脱・安直なaccumulate()！

## C++17以上の場合

reduce()を使いましょう。 

```c++
#include <array>
#include <iostream>
#include <numeric>
#include <vector>
#include <set>
int main() {
  float v[] = {1.1, 1.2, 1.4};
  // std::vector<float> v = {1.1f, 1.2f, 1.4f};
  // std::set<float> v = {1.1f, 1.2f, 1.4f};
  // std::array v = {1.1f, 1.2f, 1.4f};
  float sum = std::reduce(std::begin(v), std::end(v)); // どの型でも無事3.7が出力される
  std::cout << sum << std::endl;
}
```
[サンプルコード](https://wandbox.org/permlink/B09OzfhxJhsIMFJd)


n要素までの和を取りたければ、`std::next(itr, n)`を使います。静的配列などで使えそうですね。

```c++
  float sum = std::reduce(std::begin(v), std::next(std::begin(v), 2)); // 2.3
```


## C++11以上の場合
reduce()の代わりに、accumulate()を使いましょう。

```c++
#include <array>
#include <iostream>
#include <numeric>
#include <vector>
#include <set>
int main() {
  float v[] = {1.1, 1.2, 1.4};
  // std::vector<float> v = {1.1f, 1.2f, 1.4f};
  // std::set<float> v = {1.1f, 1.2f, 1.4f};
  // std::array v = {1.1f, 1.2f, 1.4f};
  float sum = std::accumulate(
      std::begin(v), std::end(v),
      std::remove_reference<decltype(*std::begin(v))>::type{});
  std::cout << sum << std::endl;
}
```
[サンプルコード](https://wandbox.org/permlink/Jj9VW3HOtNlMxhDy)

C++17の例と同様にn要素までの和が計算できます。

## 汎用性と安全性
上記の方法は次の特徴を持ちます。

- 配列もvectorもarrayもsetも、みんな同じように和を計算できる(汎用性)
- 第三引数の罠にハマらない(安全性)

実はreduceもaccumulateも第三引数に愚直に`0`を入れると、暗黙的なダウンキャストが発生する可能性があります。注意しましょう。

```c++:✕悪い例
  std::vector<float> v = {1.1, 1.2, 1.4};
  float sum = std::accumulate(v.begin(), v.end(), 0); // 3.7を期待したはずが、3に!
```
詳しくは下の記事をご参照ください。

https://qiita.com/haruyama480/items/e777f2f65f0ab5ac9745


## おわりに
C++11未満の方は頑張ってfor文を書いてください。

thanks: @yumetodo
ライブラリなしでおしゃれなカラーピッカーを実装する【React】

## はじめに
`<input type="color" />`を使うことでカラーピッカー（ユーザーに色を選択させるUI）を簡単に実装できますが．見た目があまりかわいくない…

そう思い，色々試してデザインする方法を編み出したので残しておきます．

![スクリーンショット 2021-09-16 0.13.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840171/ddbbed41-f936-214a-7624-2db8f7bd46bc.png)

https://developer.mozilla.org/ja/docs/Web/HTML/Element/input/color


## 結論
inputタグに`opacity: 0;`を設定することで透明にし，divタグで囲ってデザインする．

## 実装例
React+TypeScript+TailwindCSSで今回は円形にデザインした実装例です
![スクリーンショット 2021-09-16 0.10.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840171/c77481d9-5369-ba9c-9146-7f6229b41fd9.png)


```React:color.tsx

const Color: React.VFC = () => {
  const [color, setColor] = useState<string>("#000000");
  
  return (
        <div
          className="w-8 h-8 rounded-full border border-gray-400"
          style={{ background: color }}
        >
          <input
            type="color"
            value={color}
            onChange={(e) => {
              setColor(e.target.value);
            }}
            className="w-full h-full opacity-0"
          />
        </div>
  );
};

```
MOUNT differences between z/OS UNIX & Linux

z/OS UNIX allows to mount a filesystem to directory(mount point) that contains any files or directories but Linux does not allow to mount a filesystem to non empty directory, mount point is must be empty.

You can configure NONEMPTYMOUNTPT(NOWARN|WARN|DENY) parameter in BPXPRMxx. You can recognize the mount command is being performed to empty directory or non empty directory.

https://www.ibm.com/docs/en/zos/2.5.0?topic=parameters-statements-bpxprmxx
Routifyでparamsに補完を効かせたい

# 結論

```ts:src/ambient.d.ts
declare module '@roxi/routify' {
  export const params: import('svelte/store').Readable<{
    userId: string
    postId: string
  }>
}
```

# 対象者
- Svelte + Routify + TypeScript構成の人
- `$params`の補完が効かなくて困っている人

# 概要
svelteでファイルベースのルーティング(Next.jsみたいなやつ)をしたい場合、Sapper, SvelteKit, Routifyあたりが選択肢としてあります。SapperはSPAモードがなく、SvelteKitは現時点(2021/09/16)ではSPAとしてビルドするときにSSGの挙動をしてしまう問題などがあるため、SPAを作りたい場合はRoutifyが選択肢として上がります。

# 困りごと
Routifyで`/users/:userId`のようなパスの`userId`を取り出したい場合、以下のコードでいけます

```ts
import { params } from '@roxi/routify'
$params.userId // <--
```
しかし、$paramsの型は`{[x: string]: any;}`であるため、全く補完が効きません。

# 解決方法
アンビエント宣言で型を上書きします。

```ts:src/ambient.d.ts
declare module '@roxi/routify' {
  export const params: import('svelte/store').Readable<{
    userId: string
    postId: string
  }>
}
```
基本的に、ライブラリのリポジトリから型定義を探せば、上書きする方法は何となく分かるはずです。
https://github.dev/roxiness/routify/blob/master/index.d.ts

なお、この方法だと、
- `/users/:userId`ではuserIdのみを補完にだし、
- `/users/:userId/posts/:postId`ではuserIdとpostIdを補完にだす

のようなことはできません。どのページでも共通の補完となってしまいます。
でも補完が効かないよりはマシなはず。
CCNA　RIP

##Part 1　RIPの特徴

RIP(Routing Information Protocol)はホップ数と言って、
経由するルーターの数を基準に最適経路を選択します。

**RIPの動作**

ルータはRIPが有効なインターフェイスから30秒毎にルーティングテーブルの情報を
送信する。これをレギュラーアップデートと言います。
・　受信情報が自身にない場合、その情報を登録します。
・　受信情報が自身にあり、送信元が同じである時、その情報で更新します。
・　受信情報が自身にあり、送信元が異なり、メトリックが小さい時、その情報で更新します。
これらをベルマンフォード法と言います。
全ての情報が行き渡った状態のことをコンバージェンスと言います。

RIPは様々なメーカーのルータで使用できます。
また、ディスタンスベクタ型で、ルータにかかる負担が小さいです。
30秒毎に定期更新をして、他のルーティングプロトコルよりも
ネットワークの負荷が大きいです。理由はルーティングテーブル全体を
送るので、トラフィックが多くなります。
コンバージェンスが遅いです。メトリックとして、ホップ数を使用します。

RIPv1はブロードキャストで、クラスフルなので、集約は自動です。
しかし、RIPv2はマルチキャストで、クラスレスなので
集約は手動です。

##Part 2　ルーティングループと無限カウント

あるネットワークが不具合が起きてしまった時、
そのルーティングテーブルから情報が削除されます。そして、別のルーティングテーブルが
レギュラーアップデートされて送られてきた時、新しい情報として追加されます。
その繰り返しを無限カウントと言います。
そして、パケットが送られてきた時、ルーティングテーブルでルータ間を
ループする状態が続きます。

##Part 3　ルーティングループの防止機能

**スプリットホライズン**

これはあるインターフェイスで受信したルート情報は、同じインターフェイスからは
アドバタイズしない。アドバタイズとは送ったり、広めたりすることです。

**ルートポイズニング**

障害が発生したルートのメトリックを16にして隣接ルータに送信します。
RIPではメトリック16が最大なので、これにすると機能していませんとなります。

**イベントトリガーアップデート**

ネットワークの変更や障害(イベント)があった場合、30秒毎のレギュラーアップデートを待たず、
即座に送信します。これはルートポイズニングと相性が良いです。
これを受け取ったルータはそのネットワークをpossibly downと判断します。

**ポイズンリバース**

メトリック16の経路情報を受け取ったルータは、送信元にそのルート情報を返す。
スプリットホライズンは適用されません。

**ホールドダウン**

possibly  downとなるとホールドダウンタイマーが作動します。
この経路がダウンしたことを全ルータが認識できるまで、経路情報の更新に制限をかけて
誤った情報の登録を防ぐ。
1, possibly downでもパケットのルーティングは行われる。
2, possibly downの状態では、以前と同じか以前よりも大きなメトリック値の経路情報は破棄します。
3,　以前よりも小さいメトリック値の経路情報を受信すれば適切な最適経路と判断し、ホールドダウンタイマーを停止し、ルーティングテーブルに登録します。

**RIPタイマー**

updateタイマーはレギュラーアップデートを送信する時間です。30秒
invalidタイマーはレギュラーアップデートが送信されて来なくなった際に
その経路を無効とみなすまでの時間。180秒
holddownタイマーはpossibly downになった経路に対してルーティングテーブルの
更新を保留する時間。180秒。

デフォルトルートを1台のコンピュータに設定して、
そこからRIPで他のルータに配布することができる。

**等コストバランシング**
メトリックが最小の経路が複数あったときに、通信を分散させる機能。

**パッシブインターフェイス**

パッシブインターフェイスが設定されたインターフェイスからは
ルーティングアップデートが送信されなくなる。
【デザインの基礎を学ぶ①】良いサービス開発のために「誰のためのデザイン」を読む

#はじめに
今回、自らのプロダクトを作るにあたって、ユーザーに最大限の価値を届けるデザインってなんだろう？ということで名著「誰のためのデザイン」を熟読することにしました。

もともと所属するコミュニティの朝活で発表するためにまとめたものですが、自らの思考の整理も兼ねてこちらにまとめていきたいと思います。

#誰のためのデザインとは？
アメリカの認知科学者で人間中心設計を世の中に提唱したD.A.ノーマン氏が書いたデザインの原理を記した名著。

[誰のためのデザイン](https://www.amazon.co.jp/%E8%AA%B0%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%EF%BC%9F-%E5%A2%97%E8%A3%9C%E3%83%BB%E6%94%B9%E8%A8%82%E7%89%88-%E2%80%95%E8%AA%8D%E7%9F%A5%E7%A7%91%E5%AD%A6%E8%80%85%E3%81%AE%E3%83%87%E3%82%B6%E3%82%A4%E3%83%B3%E5%8E%9F%E8%AB%96-D-%E3%83%8E%E3%83%BC%E3%83%9E%E3%83%B3/dp/4788514346)

#なぜこの本を選んだのか？
見た目を整えたり、人間心理を応用したデザインの方法論的な本はたくさんあるが、「そもそも人間とはどんな生き物か」という原理的な説明がわかりやすく書かれた本だと思ったからです。

#第1章のポイント
ここから実際に本を読んで心に残った点を簡単にまとめていきます。

##良いデザインの特徴は2つ
それは、`発見可能性`と`理解`である。

つまり、どれだけ見た目が美しく機能に優れたものであっても、そのものが持つ本来の目的に対して人がその用途を発見して理解できなければ何の意味もないということです。

著書ではこれを装飾の美しい開け方がわからないドアで説明しています。

## 誰もが間違えるという前提のもとデザインせよ
ものがどう動くか、どう制御されるか、さらには人とテクノロジーがどういう関係を持つかに着目することが重要。「きっとこう使ってくれるはず」という思い込みで作ったデザインは失敗する。

## ユーザーを観察せよ

人間中心設計はプロダクトやサービスが満足させようとする人々とそのニーズに対する理解からスタートする。この理解は観察することで得られる。

##アフォーダンスとシグニファイヤ
この本では、アフォーダンス、シグニファイヤ、制約、対応づけ、フィードバックの5つのキーワードと概念モデルという重要ワードが頻出する。

この章ではアフォーダンスとシグニファイヤに注目している。

`アフォーダンス`
そのモノやサービスの属性とそれをどのように使うことができるかを決定する主体の能力。アフォーダンスは不変のものではなく可変する（詳細は下記例で）。

`シグニファイヤ`
アフォーダンス（そのモノやサービスがもつ能力）を示す特性のこと。

## 脳で考えなくて良い設計をせよ
「わかりやすい」ではなく五感を通して直感的にわかるのが良い設計。

たとえ内部が複雑で理解不能な作りでもユーザーが一発で理解できるなら良い。ユーザーが容易にアウトプットを起こせるかどうかが体験設計では重要。

## フィードバックに気を配る
フィードバックがないと人は不安になる。適切なタイミングと0.1秒でも遅れると人は違和感を感じる。

##概念モデルを意識した設計をする

メンタルモデルに近い。ある人がパッと見たときに持つイメージのこと。人は良い概念モデルがあると自分の行為の結果を予測できる。馴染みのレイアウト、ゲームの最初で操作方法を反復練習させられる、など。

##ユーザーとデザイナーの概念モデルは大概ずれている

デザイナーの概念モデルで作られたイメージはユーザーのそれとずれていることが多い。だからユーザーに触ってもらって率直なフィードバックを得るほうがよい。

##良いデザインに必要なのはマネジメントスキル
サービスやプロダクトデザインとは、様々な要素が掛け合わさってできる。良いデザインを実現するには関係者全体で方針をあわせることが重要。

他人のものの見方を理解すること、自分の専門的な考えをときに捨て去ること、ユーザー視点から設計することを全体に理解させることなくして良いものは作れない。
Nuxt.jsにtailwindcssを導入する

参考にするサイトを間違えたり、勘違いして無駄に時間を浪費してしまったので
備忘録として記録を残す。

https://tailwindcss.nuxtjs.org/setup

基本は上記のサイトに記載してある順に行えば良いので、これ以降は見る必要はない。

## Nuxt.jsのアップデートをする

```
$ npm update nuxt
```
Please make sure to update your Nuxt version to be minimum v2.15.3.
お使いのNuxtのバージョンをv2.15.3以上にアップデートしてください。

と書いてあるので、念の為アップデートしておく。

## tailwindcssをインストール

```
npm install --save-dev @nuxtjs/tailwindcss
```

## nuxt.config.jsに追記する

下記は`create-nuxt-app`コマンドを実行した際に出てくる質問のなかで、tailwindcssを選んでいると、はじめから記載されている。

```nuxt.config.js
export default {
  buildModules: ['@nuxtjs/tailwindcss']
}
```

今回は、何を思ったのか上記をtailwind.config.jsに書くんだと勘違いしまってた。
この時点ではtailwind.config.jsはまだないので注意。

## tailwind.config.jsを作成

```
$ npx tailwindcss init
```
このコマンドを叩くと、tailwindcss.config.jsファイルがルート上に作られる。

ここまでやれば、tailwindcssが有効になっているはずなので、確認する。
ABC177 C - Sum of product of pairs から学んだ

https://atcoder.jp/contests/abc177/tasks/abc177_c

![abc177_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/294116be-3d21-5b21-0074-e64c5504c877.png)

無心になったが、とりあえず
サンプルも読む。

![abc177_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/61831574-8c1b-8eca-7aa2-67d822fa5bc1.png)

なるほど。
例えば** 1 2 3 4 **が与えられたとすると
**1x2+(1+2)x3+(1+2+3)x4**とならないか？

後は表現方法が問題だ。
だがしかし、tle & wa

```ans.py
N = int(input())
A = list(map(int,input().split()))
 
score = A[0]*A[1]
 
for i in range(2,N):          #計算量 O(N)
    score += sum(A[:i])*A[i]  #計算量 O(N)...合算してほぼ O(N^2)
    score %= 7+10**9
print(score)
```

配列の sum の計算量は配列長さに依存する。
なので最終的には、それだけで O(N) となりうる。
っということで書き換えたら、通った。

```ans_r1.py
N = int(input())
A = list(map(int,input().split()))
 
X = sum(A)
score = 0
 
for i in range(N-1,0,-1):
    score += (X-A[i])*A[i]
    score %= 7+10**9
    X -= A[i]
print(score)
```
プッシュスイッチ付きのロータリーエンコーダを分解する

# 1.はじめに
[久しぶりにロータリーエンコーダを使ってみた](https://qiita.com/airpocket/private/a5c4f43cb65d617e779c)けど、構造を明確に理解していなかったことに気付いたので分解して勉強。

# 2.分解してみた
今回分解したロータリーエンコーダは、回転軸がプッシュスイッチになっているものです。エンコーダー検出用の3pin(A,B,GND)の他に、スイッチ用の2pin(SW,GND)がついています。

![front.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/3f1f1575-a07f-bcdb-ec70-3d94ca06a641.jpeg)
![pins.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/84939036-5edc-e011-eb2e-2e776fd78d26.png)

分解すると3階建て構造になっていました。
1階層目はプッシュスイッチの接点。2階層目はロータリーエンコーダの接点、3階層目はクリック感を出すためのばねがしこまれていました。

# 2-1.1階層目
![sw.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/4af56f7c-dc07-6515-c289-21817aa5a479.png)
一階層目をばらすと、プッシュスイッチ接点を、上部から貫通してきているエンコーダ軸が押し込む構造になっていました。スイッチは接点が同時にばねになっている一般的なタクトスイッチと同じ構造でした。

# 2-2.2階層目
![state.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/b40461d3-87b6-51b6-f27d-76bca81deb01.png)
2階層目は、エンコーダーの接点があります。放射状に延びているのがAstateとBstateの接点です。扇状に配置されているのがGNDにつながる接点です。これらの接点を接続するのが上面に存在するコンタクトです。コンタクトは一枚のリングから4本の接点が伸びている構造で、A,B各接点とGNDを適宜スイッチする構造です。
AsteteとBstateは1/4周、GNDは1/2周の範囲にしか配置されていませんが、コンタクトの接点は4ヶ所（赤矢印部）存在するため、全周にわたって接点が存在しているのと同等の働きをします。

# 2-3.3階層目
![spring.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/496179/29e1ed42-9d3d-4f1a-d769-043672471fab.png)
3階層目には板ばねが仕込まれていて、回転する際にコンタクト裏面の溝と接触してクリック感を出しています。

# 3.まとめ
ロータリーエンコーダーの仕組みについては何となく知っていましたが、分解してより理解が深まりました。特に。AstateとBstateを同じ面に1/4周ずつ配置し、コンタクトの接点4個を使って各ステートが一周配置されているのと同等の処理を行うという構造には目からウロコの思いでした。
コンタクト自体は薄い鉄板状の端子の弾性を使って接点に押し付ける構造だったため、チャタリングは避けられない仕組みです。高級品はこのあたりの部品が良くなってチャタリングを防止しているのでしょうか。
[前回の記事](https://qiita.com/airpocket/private/a5c4f43cb65d617e779c)ではソフトでチャタリング対策を行いましたが、適当なコンデンサを端子間に挟んでハード面でのノイズ対策する方がスマートだなと思えたことに電子工作歴2年の成長を感じています。
配列処理スピード比較

##配列のループ処理の速さは？？
配列の要素に対して処理を行いたいことはよくある話だが何が一番早いのか検証してみた。

ちなみに配列

```php

$array = array();
for($i = 1; $i < 100000; $i++){
    $array[] = $i;
}
```
処理させる内容

```php
function hundredNumber($n){
    return $n * 100;
}
```
処理速度を測る関数はこちらを参考にさせていただきました。
>[PHPの処理速度の計測方法](https://qiita.com/HidakaRintaro/items/8893f1a36709eee3582f)


#foreach
定番の配列処理

```php
$start = hrtime(true);

$result_array = array();
foreach($array as $num){

    $result_array[] = hundredNumber($num);
}

$end = hrtime(true);

echo 'time : '.number_format($end - $start)."<br>"; 
//time : 19,387,398
```
#for
ループ処理といえばこれ

```php
$start = hrtime(true);

$result_array = array();
for($i = 1; $i < 100000; $i++){

    $result_array[] = hundredNumber($i);
}

$end = hrtime(true);

echo 'time : '.number_format($end - $start); 
//time : 17,017,476
```
#while
またまた定番、よく無限ループして焦ってる

```php
$start = hrtime(true);

$result_array = array();
$i = 1;
while($i < 100000){

    $result_array[] = hundredNumber($i);
    $i++;
}

$end = hrtime(true);
echo 'time : '.number_format($end - $start); 
//time : 17,280,002
```
#array_map
あんまり使ったことない

```php
$start = hrtime(true);

$result_array = array_map('hundredNumber', $array);

$end = hrtime(true);

echo 'time : '.number_format($end - $start); 
//time : 15,786,888
```

#結果発表
一番定番のforeachが遅い結果となってしまいました。
そして私の中ではダークホース的存在だったarray_mapが優勝！！

コードもスッキリするし、これからは積極的に使っていこうと思いました。
AtCoderログ：0113 - ABC 122 B

# 問題

https://atcoder.jp/contests/abc122/tasks/abc122_b

## 問題文
> 英大文字からなる文字列 $S$ が与えられます。$S$ の部分文字列 (注記を参照) であるような最も長い ACGT 文字列 の長さを求めてください。
> ここで、ACGT 文字列とは A, C, G, T 以外の文字を含まない文字列です。

## 制約
> ・$S$ は長さ $1$ 以上 $10$ 以下の文字列である。
> ・$S$ の各文字は英大文字である

## 収録されている問題セット
- [AtCoder Problems Boot camp for beginners Easy 100](https://kenkoooo.com/atcoder/#/training/Boot%20camp%20for%20Beginners/1) [#018]

# 回答
## 回答1 (AC)
文字列を1文字目から順番にチェックし、A,C,G,Tが続いていればその文字数を記録していけば良いでしょう。コードは以下のようになりました。

```C++:abc122b-1.cpp
#include <bits/stdc++.h>
using namespace std;
 
int main() {
  string s;
  cin >> s;

  int series = 0, smax = 0;
  for ( int i=0; i<(int)s.size(); i++ ) {
    if ( s.at(i)=='A' || s.at(i)=='C' || s.at(i)=='G' || s.at(i)=='T' ) {
      series += 1;
      smax = max(smax,series);
    } else {
      series = 0;
    }
  }

  cout << smax << endl;
}
```

# 調べたこと
## [AtCoder の解説](https://atcoder.jp/contests/abc122/tasks/abc122_c/editorial) → [ユーザ解説](https://blog.hamayanhamayan.com/entry/2019/03/25/230649)
回答1と同じ方針でした。

## [AtCoder の解説](https://atcoder.jp/contests/abc122/tasks/abc122_c/editorial) → [コンテスト全体の解説](https://blog.hamayanhamayan.com/entry/2019/03/25/230649)
文字列の全ての部分文字列を生成し、それがACGT文字列かをチェックしていました。

# リンク
## 前後の記事
- 前の記事 → [AtCoderログ：0112 - ABC 218 B](https://qiita.com/RoadLynton/items/5f8127d0fdaf8c135322)
- 前の記事 → [AtCoderログ：0114 - ABC 094 B](https://qiita.com/RoadLynton/items/184d563cdab62008feae)
【GitHub】静的サイトの公開

#はじめに
HTMLとCSSだけで静的サイトを作り、それをGitHub Pagesで公開する流れを説明します。

#公開手順
1) GitHub公式ページにアクセスし、RepositoriesのNewをクリックします。
2) Repository nameを入力し、Create repositoryをクリックします。
3) 画面遷移したら、Quick setupという項目のところに表示されているURLをコピーしておきます。
4) エディターに戻り、ターミナルもしくはコマンドプロンプトを使い、GitHubにプッシュしていきます。

```terminal:ターミナルorコマンドプロンプト
①cd 公開したいフォルダ名
②git init
③git add .
④git commit -m "メッセージ"
⑤git remote add 3)でコピーしたURL
⑥git push -u origin master
```

5) GitHub公式ページに戻り、作成したリポジトリのページからSettingsをクリックします。
6) 下の方にGitHub Pagesという項目があり、`Check it out here!`というリンクがあるのでそこをクリックします。
7) Sourceという項目の`None`となっている部分を`Branch:master`に変更し、saveをクリックします。
8) 画面遷移後、`Your site is ready to be published at https://アカウント名.github.io/リポジトリ名/`と表示されるので、そのリンクをクリックすればWebページが表示されます。

#おわりに
これはあくまで「静的サイト」の公開なので、その点にはご注意願います。
LeetCode344[Reverse String]-Recursion再帰で実現する。

タイトルの通り、LeetCode 344の解き方についてシェアしてきます。

問題文はそのままコピーします、

```md
Write a function that reverses a string. The input string is given as an array of characters s.

Example 1:

Input: s = ["h","e","l","l","o"]
Output: ["o","l","l","e","h"]
Example 2:

Input: s = ["H","a","n","n","a","h"]
Output: ["h","a","n","n","a","H"]
 

Constraints:

1 <= s.length <= 105
s[i] is a printable ascii character.

```
ま、簡単に言うと、string型の'hello'を'olleh'で変換することです。

各言語内の関数やモジュールを使えばええじゃんと思うかもしれないが、実はこれを実現するためにはいろいろな方法があります。

今回は2つの方法を紹介します、一つはタイトルの通り再帰で実現します。もう一つはTwo pointersで実現します。

# Recursion solution

Recursionの概念はわかると思いますが、ざっくりで言うと、
1. 関数内部にもう一度今所属している関数を呼び出す。
2．永遠に呼び出されたらキリがないので、必ずなにか終わりの条件を追加する。

実はこの問題に関して、Two pointersのやり方は多分理解しやすいが、Recursionで実現するのも面白いです。

では、大体のイメージ図からどのように再帰で実現したかをみてみましょう！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1729963/a0c8ae6e-34a7-4817-2154-0e3fe9b2d43e.png)

解説：

まず、1回目の再帰はhとoを同時に再帰します(多分理解にくいが、コード見ればわかると思います)。

2回目に入って、また再帰し、lのところで再帰が止まります。

止まったら、今回は元に戻します。

ここで、2回目の再帰の部分はeとlを交換し、1回目はhとoを交換します。

それで終了となります。

コード：

```python
def recursion(s, left, right):
        if left >= right:
            return
        recursion(s, left+1, right-1)
        s[left], s[right] = s[right], s[left]
```
left >= rightが再帰の終了条件。
4行目の部分は再帰の部分で、毎回の再帰は左側を右に1 step,　右側は左に1 stepの形ですすみます。
再帰が終了した後(left < rightの時)、各文字を交換します。


# Two pointers
```python
def recursion(s, left, right):
    while left < right:
            s[left], s[right] = s[right], s[left]
            left += 1
            right -= 1

    return s
```
考え方としては、再帰の解き方と似ていますが、実は違いますね。

# 参考
https://leetcode.com/problems/reverse-string/
sys.path.append()でモジュール探索パスを追加したがインポートができなかったのはpip installしたパッケージが原因だった

# 概要
自作モジュールを相対パスでimportしたく、`sys.path.append(os.path.dirname(__file__)`を入れたのに何故かimportができなかった。

# 結論
pipで入れていたパッケージと自作モジュールで利用していた名前が被っていたため、pipで入れたパッケージを読み込みにいってしまっていた。

# 環境
* Windows10
* miniconda

# 詳細
以下のような構成で自作モジュールを呼び出そうとしたところ、`libs.utils`が見つからないと`ModuleNotFoundError`が発生。

```
parent_dir/
  |- my_modules/
  |   |- libs/
  |      |- utils.py
  |   |- my_module.py
  |- controller.py
```

`controller.py` ⇒ `my_module.py` ⇒ `utils.py`と呼び出す流れ。

## 各モジュールのコード

```python:controller.py
from my_modules.my_module import *

module_func()
```

```python:my_modules\my_module.py
from libs.utils import *

def module_func():
    print("This is module_func")
    utils_func()
```

```python:my_modules\libs\utils.py
def utils_func():
    print("This is utils_func")
```

## やりたいこと
`parent_dir`にいる状態で`python controller.py`を実行
⇒以下のような結果が欲しい。

```powershell:AnacondaPrompt
[自分のフォルダ]\parent_dir>python controller.py
This is module_func
This is utils_func
```

しかし、結果は以下の通り。

```powershell:AnacondaPrompt
  File "[自分のフォルダ]\parent_dir\my_modules\my_module.py", line 1, in <module>
    from libs.utils import *
ModuleNotFoundError: No module named 'libs.utils'
```

## 原因と解決策
**原因**：コマンドから実行する場合、`controller.py`を実行している`parent_dir`が基準になるため、`parent_dir`から`libs.utils`を探しているが見つからない。
**解決策**：[こちらの記事](https://note.nkmk.me/python-relative-import/)を参考に「モジュール探索パスを追加して絶対インポート」する方法を実践。

つまり、`my_modules\my_module.py`に`sys.path.append(os.path.dirname(__file__)`を追加する。

```python:my_modules\my_module.py
# 追加分
import os
import sys
sys.path.append(os.path.dirname(__file__))
# 追加分ここまで
from libs.utils import *

def module_func():
    print("This is module_func")
    utils_func()
```

これにより、my_moduleフォルダもパスに追加されるため、相対パスとして読み込んでくれるはず！

**結果**

```powershell:AnacondaPrompt
  File "[自分のフォルダ]\parent_dir\my_modules\my_module.py", line 1, in <module>
    from libs.utils import *
ModuleNotFoundError: No module named 'libs.utils'
```

変わらない！なぜ！

## 現象の調査
いろいろ試してみると、自分が使っているminicondaの仮想環境でこの事象が発生することが判明。(新規作成したまっさらな仮想環境では事象が発生しない。)

### 試したこと
仮想環境にinstallした何かしらのパッケージが原因と考え、問題環境のinstallパッケージの一部を削除しながら原因のパッケージを特定することに。
おそらく他に効率が良いやり方があるのだろうが、知識のない私は地道な作業で調査。
※以下のコマンドは[こちら](https://qiita.com/ozaki_physics/items/13466d6d1954a0afeb3b)を参考にさせていただきました。


①仮想環境の情報をyamlファイルに書き出す。

```powershell:AnacondaPrompt
conda env export > ファイル名.yml
```
②yamlファイルのうちdependenciesを2分探索の要領で分割
③分割したyamlファイルを基に新規環境作成

```powershell:AnacondaPrompt
conda env create -n 新たな環境名 -f ファイル名.yml
```

### 特定
そしてついに突き止めた。

```yaml:env.yaml
dependencies:
  - pip=21.2.4=pyhd8ed1ab_0
  - pip:
    - libs==0.0.10
```
このlibsが存在していると問題が発生する。

ここまでくれば原因は明確。
`libs.utils`を見に行く際に、pipでinstallしているlibsを優先的に探していたということであった。

# 教訓
* 自作モジュールを使う場合は汎用的な命名を避ける。(my_libsのような名前にする。)
* [condaとpip：混ぜるな危険](https://onoz000.hatenablog.com/entry/2018/02/11/142347)←今回は直接関係なかったが、改めて確認すると`pip install`しているパッケージが多かったと反省。
スーパーキラキラカラフルクッキリディスプレイも最初と最後の文字さえあっていれば読める説


みなさんはタイポグリセミア(Typoglycemia)というものをご存知でしょうか？

wikiからの引用ですが

> 文章中のいくつかの単語で最初と最後の文字以外の順番が入れ替わっても正しく読めてしまう現象である

https://ja.wikipedia.org/wiki/%E3%82%BF%E3%82%A4%E3%83%9D%E3%82%B0%E3%83%AA%E3%82%BB%E3%83%9F%E3%82%A2

今まさに新作のiPhoneが発表され、「スーパーキラキラカラフルクッキリディスプレイ」という謎の単語がtwitter上で話題になりました。

それをみて**「最初と最後の文字以外の順番が入れ替わっても正しく読めてしまうんじゃね？」**と思い、検証プログラムを書いてみました。

とにかくすぐに確認したかったのでjsで書きました

```javascript
(str => str.slice(0, 1) + str.slice(1, -1).split('').sort(() => Math.random() - 0.5).join('') + str.slice(-1))('スーパーキラキラカラフルクッキリディスプレイ')
```

結果は、、、

```
スキークスデカキーキッィラプリラフパラレルイ
```

？

# 読めませんでした

よく考えたら「**文章中**のいくつかの単語で...」なのでそもそも文章じゃないとダメでした😇
ターミナルを見ながらvimで編集したい【初学者向け】

vimを使い始めたばかりの初学者です。
Macを使用しています。シェルはターミナルです。
vimのプラグインは導入していません。

### やりたいこと
シェルに表示されたコンパイルエラーの内容を見ながらvimで開いたソースコードを編集したい

###経緯
1. ターミナルから `vim 4-2.c`とコマンドを入力し、ファイル4-2.cを新規作成してvimを開いた
2. コーディング後に保存してvimを終了しターミナルに戻った
3. ターミナルで`gcc -o 4-2 4-2.c`を実行するとエラーメッセージが表示された
4. エラーを修正するために再度ターミナルから `vim 4-2.c`とコマンドを入力しvimを開いた
5. ターミナルがvimと置き換わったことで、先ほどターミナルに表示されていたエラーメッセージが参照できなくなってしまった

### 解決方法　その１
1. 予めターミナルウィンドウを2つ開く
2. 片方でソースコード編集、もう片方でコンパイルを行いエラーメッセージを見る

### 解決方法　その２
1. コーディング後、vimを閉じずにコマンドモードで`:vert terminal`を入力
2. vimウィンドウ内を垂直分割してターミナルが起動する
3. 起動したターミナル内でコンパイルを行う
4. エラーメッセージが表示された場合には、`Ctrl` + `w`を入力し、続けて`l`（vimがターミナルの左にある場合は`h`）を入力する
　※`Ctrl`と`⌘`を間違えないように注意
5. vimがアクティブになり編集ができるようになるので、ターミナルに表示されたエラーメッセージを参照しながらコード修正をする

### 参考
https://knowledge.sakura.ad.jp/23018/

### おわりに
基本的なことすぎるためか、「ターミナル　vim 同時に」や「ターミナル見ながら　vim」等ググっても中々知りたい情報が出てきませんでした。
私みたいな初学者の参考になれば嬉しいです。もっと効率の良い方法があればぜひコメントで教えて欲しいです。
ketosで音響解析その２

#はじめに
<a href='https://qiita.com/tetra9064/items/1a51787a3da0e70ed167'>前回の記事</a>でデータベースを作成したので今回はそれを基に検出器を作成していきます。

必要なデータは<a href='https://gitlab.meridian.cs.dal.ca/public_projects/ketos_tutorials/-/blob/master/tutorials/train_a_narw_classifier/train_a_narw_detector_part_1.zip'>ここに</a>あります。
前回作成したデータベースや今回のコードも入っています。

#分類器のトレーニング
まずはチュートリアルで使用されるランダムシードを定義する必要があるようです。

```py
import numpy as np
np.random.seed(1000)

import tensorflow as tf
tf.random.set_seed(2000)
```

##インポートする
今回使うものです。

```py
import ketos.data_handling.database_interface as dbi
from ketos.neural_networks.resnet import ResNetInterface
from ketos.data_handling.data_feeding import BatchGenerator
```

#トレーニング
まずはデータベースに接続します。

```py
db = dbi.open_file("database.h5", 'r')
```

次にdb内のテーブルを使えるようにしておきます。

```py
train_data = dbi.open_table(db, "/train/data")
val_data = dbi.open_table(db, "/val/data")
```

学習させるためのバッチサイズなどの指定をketosに沿って設定していきます。

```py
def transform_batch(X, Y):
    x = X.reshape(X.shape[0],X.shape[1],X.shape[2],1)
    y = tf.one_hot(Y['label'], depth=2, axis=1).numpy()
    return x, y
```


```py
train_generator = BatchGenerator(batch_size=128, data_table=train_data, 
                                  output_transform_func=ResNetInterface.transform_batch,
                                  shuffle=True, refresh_on_epoch_end=True)

val_generator = BatchGenerator(batch_size=128, data_table=val_data,
                                 output_transform_func=ResNetInterface.transform_batch,
                                 shuffle=True, refresh_on_epoch_end=False)
```

##ニューラルネットワークの作成とトレーニング

チュートリアルではResNetを使用します。
####下準備

```py
resnet = ResNetInterface.build_from_recipe_file("recipe.json")
```


```py
resnet.train_generator = train_generator
resnet.val_generator = val_generator
```

```py
resnet.checkpoint_dir = "checkpoints"
```

####学習開始

```py
resnet.train_loop(n_epochs=30, verbose=True)
```

学習が完了したらデータベースを閉じ、モデルを保存します。

```py
db.close()
```


```py
resnet.save_model('narw.kt',audio_repr_file='spec_config.json')
```

今回はこれで終了します。
ketosを使って音響解析。音響解析、機械学習用ライブラリ

#ketosとは
ketosとはpythonのライブラリで、音響データと機械学習を扱うことができる、音響解析に特化したライブラリです。
目的としては水中音響における難しい検出と分類を行う機械学習モデルの作成を支援することとなっています。
ketosという名前は古代ギリシャ語で大きな魚、クジラ、サメ、または海の怪物を表すらしい…かっこええ…

<a href='https://docs.meridian.cs.dal.ca/ketos/introduction.html'>公式ドキュメント</a>

#ketosのインストール

ketosの最新版はpython3.6以上,3.8未満で動作します。
pipでインストールできます。

```py
pip install ketos
```

#基本的なトレーニングデータベースの作成
公式ドキュメントのチュートリアルに沿って説明します。
チュートリアルでは北大西洋セミクジラの鳴き声を検出します。
手順としては音声データからスペクトログラムを作成し、機械学習を行い、検出器を構築します。

チュートリアルで使用するデータが欲しい方は<a href='https://gitlab.meridian.cs.dal.ca/public_projects/ketos_tutorials/-/blob/master/tutorials/create_database_simpler/database_creation_tutorial.zip'>こちらのリンク</a>からダウンロードできます。

##ライブラリをインポートします

```py
import pandas as pd
from ketos.data_handling import selection_table as sl
import ketos.data_handling.database_interface as dbi
from ketos.data_handling.parsing import load_audio_representation
from ketos.audio.spectrogram import MagSpectrogram
from ketos.data_handling.parsing import load_audio_representation
```

##ダウンロードしたデータを読み込みます
csvファイル名のところは自分のデータの保存先を指定してください。

```py
annot_train = pd.read_csv("annotations_train.csv")
annot_val = pd.read_csv("annotations_val.csv")
```

これらを表示すると音声ファイルの名前とクジラの鳴き声が含まれているか否かのラベルでできたデータフレームが出てくるはずです。

これらのデータフレームをketosで利用される形に変換する必要があるようです。

```py
map_to_ketos_annot_std ={'sound_file': 'filename'} 
std_annot_train = sl.standardize(table=annot_train, signal_labels=[1], backgr_labels=[0], mapper=map_to_ketos_annot_std, trim_table=True)
std_annot_val = sl.standardize(table=annot_val, signal_labels=[1], backgr_labels=[0], mapper=map_to_ketos_annot_std, trim_table=True)
```

これで完了です。

##スペクトログラムの設定を選択
サンプリングレートやウィンドウ幅、移動幅などを設定します。
これも公式の通りに設定しておきます。
jsonファイル名のところは自分のデータの保存先を指定してください。

```py
spec_cfg = load_audio_representation('spec_config.json', name="spectrogram")
```

spec_cfgの値は次のようにして変更することも可能です。

```py
#spec_cfg['step'] = 0.064
```

##データベースの作成
data dirで指定するところを自分の保存先へ変更してください。
trainのデータベース作成

```py
dbi.create_database(output_file='database.h5', data_dir='data/train',
                               dataset_name='train',selections=std_annot_train,
                               audio_repres=spec_cfg)
```


```py
dbi.create_database(output_file='database.h5', data_dir='data/val',
                               dataset_name='val',selections=std_annot_val,
                               audio_repres=spec_cfg)
```

これでデータベースが作成できたので開いてみましょう。

```py
db = dbi.open_file("database.h5", 'r')
```

データベースの作成は終了です。

長くなるので一旦記事を分けようと思います。
ポイントインタイムリカバリ とは？ RDSで実際にやってみた

## 勉強前イメージ

スナップショットみたいな感じで今のデータを取っておくみたいなやつだった気がする

## 調査

オンラインのバックアップを使用して、
バックアップの保持期間中ならどこの時点の状態にもデータベースを復元させる事ができる。
オペミスでデータの削除をしてしまった際も復元可能。
ポイントインタイムリカバリでDBを復旧させると、
既存のDBのデータが戻るのではなく、
新規にDBが構築され、そのDBのデータが指定した時点のものになります。

### ポイントインタイムリカバリ をやってみる

- 目次
	- 適当なDBを作成
	- データを削除
	- 復旧させる
	- もとに戻ってることを確認

- 適当なDBを作成

test-rds を作成しました

1RDS Management Console - Google Chrome 2021-09-15 

中身も適当なデータを入れてます

```
MySQL [name]> select * from name.user;
+------+------+
| id   | name |
+------+------+
|    1 | Bob  |
|    2 | Natu |
+------+------+
2 rows in set (0.01 sec)
```

- データを削除

テーブルを削除します

```
drop tables user;
```

検索もできなくなりました。

```
MySQL [name]> select * from user ;
ERROR 1146 (42S02): Table 'name.user' doesn't exist
```

- 復旧させる

test-rds を指定して、 アクション > 特定時点へ復元 を進めます。

![2RDS Management Console - Google Chrome 2021-09-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/a4e43f03-0c80-0f23-1428-6f7fd757087c.png)


復元時刻は復元可能な最新時刻にしています。
その他はデフォルトで作成しました。
DB名は test-rds-points にしています。

![3RDS Management Console - Google Chrome 2021-09-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/3a2ce965-b8f4-4fb7-c5da-a24673cbc27b.png)


test-rds-points が作成されました。
10分程度待ちます。

![4RDS Management Console - Google Chrome 2021-09-15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/129517/7972de05-4e1f-32b5-b628-186008b02d57.png)


- もとに戻ってることを確認

test-rds-pointのステータスが利用可能になったら接続を行い、
元の状態に戻ってることを確認します。

```
MySQL [name]> select * from name.user;
+------+------+
| id   | name |
+------+------+
|    1 | Bob  |
|    2 | Natu |
+------+------+
2 rows in set (0.01 sec)
```

データがもとに戻ってました！！！！

## 勉強後イメージ

やらかしたときとかにパッと出てきたら・・・

## 参考

- [Aurora MySQL 5.7 でポイントインタイムリカバリをやってみた](https://dev.classmethod.jp/articles/aurora-mysql-5-7-point-in-time-recovery/)
ABC193 C - Unexpressed から学んだ

https://atcoder.jp/contests/abc193/tasks/abc193_c

![abc193_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/b72e38ad-576b-ab64-f81b-df0d578f780c.png)

うーん。さっぱり分からん。

![abc193_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/737344/4715eb7b-40b8-50e0-9a78-125ed449db09.png)

20分悩んで降参。

https://www.youtube.com/watch?v=rZG8_snLX5o

なるほど。
**a^2 <= N となるから a <= (N)^(0.5)が言える**。。か。
想定される最大値 N と、想定される最小値 a^b(=a^2) の関係(不等式)から
a の条件を導き出している。 

```Unexpressed.py
N = int(input())
lis = []
for a in range(2,1+10**5):
    b = 2
    while True:
        if a**b <= N:
            lis.append(a**b)
            b += 1
        else:
            break
lis = set(lis) #二重の値を省く処理
print(N - len(lis))
```

勉強になりました。m(_ _)m
[Ruby] デザインパターンの簡潔サンプルコード集


# 概要

Ruby によるデザインパターンの簡潔なサンプルコード集.

Web でデザインパターンの使用例を探しているときに、
「複雑な例での説明は要らない. それよりも簡単な例を提示してくれ.」
という思いが強かったので書き残す.

|コンテンツ|掲載時期|
|:--|:--|
|[[Ruby] 簡単例: Singleton(モジュール)](https://qiita.com/robozushi10/items/90b091bca458e5d7a6c5)|2021/09|
|[[Ruby] 簡単例: Singleton(オブジェクト)](https://qiita.com/robozushi10/items/ab5e439b40b32c9e935d)|2021/09|
【Ruby】フォーマット文字列

rubyのフォーマット文字列をまとめておく。

```
フォーマット文字列	意味
%y	西暦の下2桁(00-99)
%Y	西暦を表す数(9999)
%m	月を表す数字(01-12)
%M	分(00-59)
%d	日(01-31)
%D	日付(%m/%d/%y)
```

%Y-%m-%d → 2021-09-09
これが一番よく使いそう。
[Ruby] 簡単例: Singleton(モジュール)


|本シリーズのトップページ|
|:--|
|[[Ruby] デザインパターンの簡潔サンプルコード集](https://qiita.com/robozushi10/items/b4a43ead438317578ec9)|

# 概要

既存コードへの機能追加の際に Singleton を追加したときの記録.

Singleton の概念などは省略.
単に Ruby でどう書くかだけを書き残す.

## ファイル構成

・モジュール mod.rb で定義したデータを Singleton にする
・下記 user1.rb と user2.rb は mod.rb を include する

```
.
|-- mod.rb .... モジュール.
|-- user1.rb .. 上記 mod.rb の使用者その1
`-- user2.rb .. 上記 mod.rb の使用者その2
```

## 実装

### mod.rb

「@a」を(同一プロセス上の) プログラム各所からアクセスできるようにする

```ruby
module M
  @a = '' # 保持したい値を持たせる

  class << self
    def a() # Getter
      @a
    end

    def a=(b) # Setter
      @a = b
    end
  end
end
```

## user1.rb

既存のユーザ側の冒頭処理.
前述の @a に値を設定する.

```diff
 #!/usr/bin/env ruby
 # -*- encoding: utf-8 -*-
+require_relative 'mod'
 略

 if __FILE__ == $0
+  include M
+  M.a = '/home/foo/.env' # ← プログラム全体から参照したいファイルを定義する
   略
 end
```

## user2.rb

既存のユーザ側のとある処理.
前段である user1.rb で設定された @a の値を取り出している.

```diff
+require_relative 'mod'
 略

 class MyClass
+  include M
   def foo
+    puts "M.a => #{M.a}"
   end
 end
```

# 参考情報

・https://buildersbox.corp-sansan.com/entry/2019/04/16/110000
・Rubyによるデザインパターン

以上
MySQL　group by句 が指定すべきカラムについて

#  MySQLでのGROUP BYの処理
問題演習を行っていた際に躓いた箇所があったため、備忘録として記録します。

以下のリンクの問題で私は

https://tech.pjin.jp/blog/2016/05/12/sql%e7%b7%b4%e7%bf%92%e5%95%8f%e9%a1%8c-%e5%95%8f7/

```SQL:私の回答
SELECT 
      p.name '名前', p.position 'ポジション', p.club '所属クラブ', count(g.id) 'ゴール数'
FROM
    players p
LEFT JOIN goals g ON g.player_id = p.id 
GROUP BY  p.name
ORDER BY 'ゴール数' DESC;
```
と上記のように回答しました。
しかし、正解は

```SQL:正解
SELECT 
     p.name AS '名前', p.position AS 'ポジション', p.club AS '所属クラブ', COUNT(g.id) AS 'ゴール数'
FROM 
     players p
LEFT JOIN goals g ON g.player_id = p.id
GROUP BY p.id, p.name, p.position, p.club
ORDER BY 'ゴール数' DESC
```
です。
私の回答と正解とで異なる点は「GROUP BY」が指定するカラムです。
私の回答では「p.name」だけであったのに対し、正解では「p.id, p.name, p.position, p.club」とplayersテーブルから抽出する全てのカラムを指定しています。

MySQL 5.6 リファレンスマニュアルによると、

>標準 SQL では、GROUP BY 句を含むクエリーは、GROUP BY 句で名前が指定されていない選択リスト内の非集約カラムを参照できません。たとえば、このクエリーは、選択リスト内の name カラムが GROUP BY に表示されていないため、標準 SQL では不正です。MySQL では、選択リストが GROUP BY 句で名前が指定されていない非集約カラムを参照できないように、GROUP BY の使用が拡張されています。つまり、上記のクエリーは MySQL では正当です。この機能を使用すると、不要なカラムのソートおよびグループ化が回避されるため、パフォーマンスを改善できます。ただし、これは主に、GROUP BY で名前が指定されていない各非集約カラム内のすべての値がグループごとに同じである場合に役立ちます。サーバーは各グループから任意の値を自由に選択できるため、同じ値でなければ、選択した値は不確定です。さらに、ORDER BY 句を追加しても、各グループからの値の選択が影響を受ける可能性はありません。値が選択されたあとに結果セットのソートが発生しますが、ORDER BY によって、サーバーで選択された各グループ内の値は影響を受けません。

とのように記述があります。
つまり、私の回答はMySQLにおいては不備にはならないけれども、GROUP BY で名前が指定されていないカラム内の値がグループごとに異なる場合はエラーとなるので気を付けましょうってことです。今回はたまたま、値がおんなじであったためエラーとはならずに出力できました。

##まとめ
今後「GROUP BY」を使用する際は、クエリ内の「FROM」で指定したテーブルの全てのカラムを指定することを誓います。


##リンク
MySQL 5.6 リファレンスマニュアル：https://dev.mysql.com/doc/refman/5.6/ja/group-by-handling.html

https://tech.pjin.jp/blog/2016/05/12/sql%e7%b7%b4%e7%bf%92%e5%95%8f%e9%a1%8c-%e5%95%8f7/
MavenプロジェクトをGradleプロジェクトに変換

# 環境

* OS: Windows 10 Home
* Gradle 7.0.2

# 前提

* Gradleがセットアップ済みであること
 * https://qiita.com/yiwa81/items/ccfd6f397a949a0fbe95

# MavenプロジェクトをGradleプロジェクトに変換

* コマンドプロンプトを開き、Mavenプロジェクトのフォルダに移動

* `gradle init` を実行
 * 実行例    

```
gradle init

Found a Maven build. Generate a Gradle build from this? (default: yes) [yes, no]

Select build script DSL:
  1: Groovy
  2: Kotlin
Enter selection (default: Groovy) [1..2]


> Task :init
Maven to Gradle conversion is an incubating feature.
Get more help with your project: https://docs.gradle.org/7.0.2/userguide/migrating_from_maven.html

BUILD SUCCESSFUL in 51s
2 actionable tasks: 2 executed
```

# 変換後の後処理

* `.gitignore` にGradle用の設定を追加

```
.gradle
bin/
build/
```

* Maven用の不要なファイルを削除
 * pom.xml
「ニュートン法」を参考に√7をVBAソルバーでやってみた。

オリジナル

https://qiita.com/roadto93ds/items/476d84c94410edfe5b10

#VBAソルバーで　

"GRG Nonlinear","Simplex LP","Evolutionary"の3通りです。
ソルバー実行するために以下の参考の設定が必要です。

参考　

https://docs.microsoft.com/ja-jp/office/vba/excel/concepts/functions/using-the-solver-vba-functions

```vb
Const myMethod = "GRG Nonlinear"
'Const myMethod = "Simplex LP"
'Const myMethod = "Evolutionary"
Sub aaa_main()
    Range("A1") = ""
    Range("A2") = ""
    Range("A3") = ""
    Range("B1") = ""
    Range("C1") = ""
MsgBox "√7を" & myMethod & "で計算します。"
    Range("B1") = "√7="
    Range("C1").Formula = "=sqrt(7)"
    Range("A2").Formula = "=A1^2"
    Range("A3").Formula = "=A1^2-7"
    Dim ws As Worksheet: Set ws = ActiveSheet
    SolverReset
    SolverOk setCell:=ws.Range("A3"), _
                   MaxMinVal:=3, _
                   ByChange:=ws.Range("A1"), _
                   EngineDesc:=myMethod
    SolverSolve UserFinish:=True
    Cells(1, 1).Select
End Sub
'結果
'                √7=2.64575131106459
'"GRG Nonlinear" で 2.64575130933988
'"Simplex LP"　　で 0
'"Evolutionary"　で 0
```


#手計算もありましたね？
おすすめのサイトを教えて下さい。
Gradleのセットアップ（Windows）

## 環境

* OS: Windows 10 Home

## 対象のGradleバージョン

* Gradle 8.0.1

## インストール

* 以下からアーカイブをダウンロードする
 * https://services.gradle.org/distributions/gradle-8.0.1-bin.zip

* アーカイブを展開し、適当なフォルダに配置する
 * 例: `C:\Gradle\gradle-8.0.1`

* GRADLE_HOME環境変数としてインストールしたフォルダを設定する
 * 例: `GRADLE_HOME=C:\Gradle\gradle-8.0.1`

* Path環境変数に `%GRADLE_HOME%\bin` を追加する

## 動作確認

* コマンドプロンプトを開き、以下のコマンドが実行できることを確認  
 `gradle -version`
Zybo Z7用のmicroSDカード

## Zybo Z7用のmicroSDカードについて

### Zybo Z7 Reference Manual

まず[Zybo Z7 Reference Manual](https://digilent.com/reference/programmable-logic/zybo-z7/reference-manual?redirect=1)で調べてみる。

下記のように書かれていた。

> Format the microSD card with a FAT32 file system.

google翻訳

> microSDカードをFAT32ファイルシステムでフォーマットします。



---

### SDカードの規格

#### ファイルシステム

SanDiskのHPに記載されている[SD / SDHC / SDXCカードの仕様と互換性](https://kb-jp.sandisk.com/app/answers/detail/a_id/5342/~/sd-%2F-sdhc-%2F-sdxc%E3%82%AB%E3%83%BC%E3%83%89%E3%81%AE%E4%BB%95%E6%A7%98%E3%81%A8%E4%BA%92%E6%8F%9B%E6%80%A7)を参考にしてみる。

FAT32は4GBから32GBまでの範囲らしい。

ただし、以下[wiki](https://ja.wikipedia.org/wiki/SD%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%BC%E3%82%AB%E3%83%BC%E3%83%89#SDXC)からの引用のとおり、FAT32でフォーマットすれば、32GB以上のSDカードでも使用できるかもしれない。

> 旧来のSDHC対応機器でSDXCメモリーカードをFAT32でフォーマットし使用することも可能である。ただし、Windows標準のフォーマッタを使用した場合、実装上の問題から64 GB以上のSDXCメモリーカードであっても利用できる上限容量は32 GBとなる（サードパーティー製のフォーマッタを使用することで、1ファイルあたりの容量は4 GBまでに制約されるものの回避可能である）。

#### スピードクラス

「[FPGAの部屋](https://marsee101.blog.fc2.com/blog-entry-2929.html)」様で書かれているように、スピードクラスはClass 10を使うのが良いようだ。



#### 容量

[FPGAの部屋様](https://marsee101.blog.fc2.com/blog-entry-2929.html)や[@kazuyamashi様の記事](https://qiita.com/kazuyamashi/items/756dec099ed202a3b08e)、[@Rohira様の記事](https://qiita.com/Rohira/items/f3500520bb2cbdbb15b5)で書かれているように、8GB以上が推奨っぽい。



---

### 参考

Xilinxのサポートでは[Zynq UltraScale+ MPSoC: テスト済み SD カードのリスト](https://japan.xilinx.com/support/answers/66779.html)が公開されている。

[ここ](https://japan.xilinx.com/support/answers/66779.html)で合格となっているSDカードなら、Zynq-7010やZynq-7020でもより安心して使えるかもしれない。



---

### まとめ

以上をふまえて、AmazonでmicroSDを探してみた。

以下辺りが良さそうだ。

* [サンディスク microSD 32GB UHS-I Class10 Nintendo Switch メーカー動作確認済 SanDisk Ultra SDSQUA4-032G-EPK エコパッケージ](https://www.amazon.co.jp/microSD-Nintendo-%E3%83%A1%E3%83%BC%E3%82%AB%E3%83%BC%E5%8B%95%E4%BD%9C%E7%A2%BA%E8%AA%8D%E6%B8%88-SanDisk-SDSQUA4-032G-EPK/dp/B08K4214KB/ref=sr_1_3?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=microsd&qid=1631710263&refinements=p_n_feature_sixteen_browse-bin%3A2286403051%2Cp_89%3ASanDisk&rnid=2321255051&s=computers&sr=1-3)
* [Verbatim バーベイタム microSDHCカード 32GB UHS-1 U1 Class10 MHCN32GJVZ2](https://www.amazon.co.jp/%E4%B8%89%E8%8F%B1%E3%82%B1%E3%83%9F%E3%82%AB%E3%83%AB%E3%83%A1%E3%83%87%E3%82%A3%E3%82%A2-Verbatim-microSDHC%E3%82%AB%E3%83%BC%E3%83%89-32GB-Class10-MHCN32GJVZ2/dp/B002NP88BI/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=microsd+32g+Verbatim&qid=1631709833&sr=8-4)
* [シリコンパワー microSD カード 32GB class10 UHS-1対応 最大読込85MB/s full HD SP032GBSTHBV1V20JA](https://www.amazon.co.jp/%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%91%E3%83%AF%E3%83%BC-microSD-%E6%9C%80%E5%A4%A7%E8%AA%AD%E8%BE%BC85MB-%E3%80%90Amazon-co-jp%E9%99%90%E5%AE%9A%E3%80%91-SP032GBSTHBV1V20JA/dp/B0813M9M1F/ref=sr_1_1?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&dchild=1&keywords=microsd&qid=1631710193&refinements=p_n_feature_sixteen_browse-bin%3A2286403051%2Cp_n_feature_eighteen_browse-bin%3A4693360051%2Cp_89%3A%E3%82%B7%E3%83%AA%E3%82%B3%E3%83%B3%E3%83%91%E3%83%AF%E3%83%BC&rnid=2321255051&s=computers&sr=1-1)
スコアの平均点を出す方法！

◼️ スコアの平均点を出すにはどうしたらよいのか？
　
そんな時はaverage_scoreを使うとスコアの平均点を簡単に算出できる！

書き方：　average_score = {・・・　+ ・・・ + ・・・ }

上記の様に書けばOK！
・・・　の所には平均点を出すための各スコアを記述すれば良い:point_up:

今日の投稿は以上です。

wagaでした！
Webシステムのセキュリティについてのまとめ -サイバー攻撃編-

# はじめに
近年、多様化しているサイバー攻撃を耳に挟みます。こういった脅威に備えるためには、サイバー攻撃がどういったものであるのかを理解する必要性があると思い、記事にまとめて行きたいと思います。

#サイバー攻撃の目的
代表例として、金銭の要求。他にも、不満を持つ企業や組織が運営するシステムにダメージを与えて、損害を発生させることを目的としたサイバー攻撃もある。

#DDoS攻撃
DDoSとは「Distributed Denial of Service attack」の略で短時間にサーバーが処理できないような大量のアクセスを行うことで、サービスを妨害する攻撃。

# SQLインジェクション
悪意のある第三者が、セキュリティの甘いWebサイトのフォームに、DBが解釈できるコマンドを実施。それにより不正な命令文を「インジェクション（注入）」するサイバー攻撃を、SQLインジェクションと呼ぶ。その結果、データベースの情報が漏えいしたり、改ざん・消去されたりする場合があります。

#ウイルス
ウイルスは、コンピュータに侵入する不正プログラムで、利用者がメールの添付ファイルを開くことやWebサイトを閲覧することで感染します。

#クロスサイトスクリプティング
SNSや掲示板等）に対して、自身が制作した不正なスクリプトを挿入することにより起こすサイバー攻撃。

#トロイの木馬
一般的に、アプリケーションやスクリーンセーバ、文書ファイルなど、害のなさそうなプログラムを装い、利用者にダウンロードさせることでコンピュータに侵入します。コンピュータに長期間侵入し続け、個人情報を盗んだり外部サイトを攻撃したり、勝手に大量のスパムメールを送信したりと、不正な動作を繰り返す。

#パスワードクラッキング
個人情報を狙い、IDとパスワードによる認証を行う会員制Webサイトからユーザーのパスワードを抜き出そうとする攻撃。

#ランサムウェア
「身代金要求型不正ウイルス」「身代金要求型不正プログラム」。データを暗号化するなどをした後、制限や暗号化を解除することと引き換えに身代金を要求。

# 最後に
学習している中で、サイバー攻撃の種類も多岐にわたることがわかりました。サイバー攻撃の仕組みを知ることで、具体的な取り組みが必要となるということで次回、Webセキュリティと対策について学習して行きたいと考えております。
vim viコマンド（簡単メモ）

起動

```:ターミナル
$ vi ファイル名
```
モード

```
i 　　　　インサートモード(編集開始）
ｖ　　　　　　ビジュアルモード（範囲選択）
esc コマンドモードに戻る
```
カーソル移動

```
[→] 右　
[←]　　左
[↑]　　上
[↓]　　下
[^] 現在行の先頭位置へ
[$]　　現在行の末端位置へ
[G]　　最終行の先頭位置へ
```

画面スクロール(移動）

```
H　　　画面先頭へ
M　　　画面中央へ
L　　　画面最終部へ
```

削除

```
x 　　　削除 
dd 　カーソルの１行を削除
D  　カーソルから行の終端まで削除
```
取り消し

```
u  取り消し（直前の操作）
```
コピー&ペースト
 
```
yy　　　カーソル位置の行をコピー
p　　　　　ペースト
```

終了　

```
:q 　　　　　終了（quit)
:q!　　　　　保存せず終了
:wq　　　　　保存して終了(w = write)
:wq! 　保存して強制終了
```