OmniAICreator/Qiita-1.07M huggingface dataset:
Flexbox入門

Flexboxを使うと`float`で実現していたような縦並びや横並びのレイアウト、または折り返しのレイアウトを簡単に組むことができます。

#横並びにする `display: flex`
`display: flex`は指定した要素の子要素を横並びにします。

##使い方
横並びにしたい要素の親要素に`display: flex`を指定します。

```index.html
<ul class="flex-list">
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
</ul>
```

```style.css
.flex-list {
  display: flex;
}
```

#子要素の幅を親要素に合わせて伸縮させる `flex: auto`
`flex: auto`は指定した要素の幅を親要素に合わせて伸縮させることができます。

```index.html
<ul class="flex-list">
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
</ul>
```

```style.css
.flex-list {
  display: flex;
}

.flex-list li {
  flex: auto; /* 調整したい要素に適用する */
}
```

#子要素のサイズに応じて折り返す `flex-wrap: wrap`
`flex-wrap: wrap`を指定すると、子要素のサイズに応じて折り返すことができます。
PC、タブレット、スマホで一列の表示個数を変えたいというのがよくあるユースケースだと思うので、
[メディアクエリ](https://qiita.com/shtwangy/items/7df6df215cf766714943)と合わせて使いましょう。

##使い方
折り返したい要素の親要素に`flex-wrap: wrap`を指定します。
折り返したい要素自身には列数に応じた`width`を指定します。

```index.html
<ul class="flex-list">
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
</ul>
```

```style.css
.flex-list {
  display: flex;
  flex-wrap: wrap;
}

.flex-list li {
  flex: auto;
  width: 50%; /* 一列に2つ表示する */
}
```

#子要素を上から下に並べる `flex-direction: column`
`flex-direction: column`は子要素を上から下へ並べます。

##使い方
縦に並べたい要素の親要素に`flex-direction: column`を指定します。

```index.html
<ul class="flex-list">
  <li>item1</li>
  <li>item2</li>
  <li>item3</li>
</ul>
```

```style.css
.flex-list {
  flex-direction: column;
}
```
"RC Car End-to-end ML Model Development"記事に記載のフィールドをGAZEBOシミュレータ環境に表示させる手順

以下記事に記載のフィールドをGAZEBOシミュレータ環境に表示させる手順
[RC Car End-to-end ML Model Development](https://www.wilselby.com/2019/12/rc-car-end-to-end-ml-model-development/)

```
Lastly, we will use the Conde world file developed by Valter Costa for his paper, “Autonomous Driving Simulator for Educational Purposes” as the simulated environment to operate the system and serve as a test track for training. 
```

step1.modelファイルをダウンロードして、~/.gazebo/models/.に配置

```
wget https://s3-us-west-2.amazonaws.com/selbystorage/wp-content/uploads/2017/July/conde_world.zip
unzip conde_world.zip
mv conde_world ~/.gazebo/models/.
```

step2.GAZEBO_MODEL_PATHを通す

```
$ export GAZEBO_MODEL_PATH=$GAZEBO_MODEL_PATH:~/.gazebo/models
```

step3.gazebo起動し、modelを選択（Insert->Conde worldを選択）してmodelが表示されればOK

```
$ gazebo
```

![Screenshot_field3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/344880/55e12f1c-0501-31c4-99ba-ea97c17902b5.png)


# 参考
[RC Car End-to-end ML Model Development](https://www.wilselby.com/2019/12/rc-car-end-to-end-ml-model-development/)
FlutterでAndroidビルドのみ失敗するようになる場合の対処法

# 現象

Androidでデバッグビルドしてデバッグ実行していたのに、突然ビルドが出来なくなることがある。
エラーは私の場合、firebase_analytics:webの依存関係が解決できない的なメッセージ。

```console
FAILURE: Build failed with an exception.

* What went wrong:
Could not determine the dependencies of task ':firebase_analytics:compileDebugAidl'.
> Could not resolve all task dependencies for configuration ':firebase_analytics:debugCompileClasspath'.
   > Could not resolve project :firebase_analytics_web.
     Required by:
         project :firebase_analytics
      > Unable to find a matching configuration of project :firebase_analytics_web:
          - None of the consumable configurations have attributes.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.

* Get more help at https://help.gradle.org

BUILD FAILED in 25s
Finished with error: Gradle task assembleDebug failed with exit code 1

```

# 環境など

|ツールなど|バージョンなど|
|:--|:--|
| MacBook Air Early2015|macOS Mojave 10.14.6|
|Android Studio |3.6.1|
|Java |1.8.0_131|
|Flutter|1.12.13+hotfix.9|
|Dart |2.7.2|
|Xcode |11.3.1|

# 対処法

https://github.com/FirebaseExtended/flutterfire/issues/1615
こちらにある、`flutter pub cache repair`を実行して解消しました。

必ず解決できるとは限らないようですが、今のところ私は現象が発生した2回中2回とも、この方法で解消しました。
ubuntu18.04LTS上でコマンドラインから画像サイズを変換する

convertで以下のように%指定、サイズ指定するとよい

```
$ convert -geometry "30%" src.png dst.png 
```

```
$ convert -resize 540x320 src.png dst.png
```

# 参考
[imagemagickのやさしい使い方](https://imagemagick.biz/)
PyPIデビューする際に参考になった書籍とリンク

PyPIに初めてパッケージを配布しました。  
基本的には[Python実践入門](https://gihyo.jp/book/2020/978-4-297-11111-3)を写経しました。
その際に細かな設定を調べたり、知識を補完するのに役立ったリンクを紹介していきます。

# Python実践入門 に関して
11章にパッケージ管理に関して紹介されています。
パッケージ配布に必要な設定と配布方法が書いてあるので、そちらを写経してPyPIパッケージを配布までできました。

# 参考になったリンク

- setup.py の記述に関して
   - https://docs.python.org/ja/3/distutils/setupscript.html
     - 設定するメタデータの内容を調べるのに役立ちました
   - https://packaging.python.org/guides/making-a-pypi-friendly-readme/
     - `long_description`を README.md から取ってくるコードをちょうだいしました
   - https://autopilot-docs.readthedocs.io/en/latest/license_list.html
     - ライセンスの記載の選択肢を確認しました
   - https://medium.com/@chezou/1%E8%A1%8C%E4%BF%AE%E6%AD%A3%E3%81%A7%E6%96%B0%E3%81%97%E3%81%84pypi%E3%81%A7markdown%E3%81%AE%E3%83%89%E3%82%AD%E3%83%A5%E3%83%A1%E3%83%B3%E3%83%88%E3%81%8C%E4%BD%BF%E3%81%88%E3%81%9F-14e40d90ff3f
      - `long_description`を書く際にかつてはreSTを使っていたということを知りました
- MANIFEST.in
   - https://docs.python.org/ja/3/distutils/sourcedist.html
      - MANIFESTに関して情報の補完に
- pypirc
   - https://docs.python.org/ja/3.6/distutils/packageindex.html#the-pypirc-file
       - オプションをさらっと読みました
- ライセンスに関して
   - ソフトウェアライセンスに関しておさらいしました
      - https://www.sbbit.jp/article/cont1/34811
      - https://qiita.com/fate_shelled/items/a928709d7610cee5aa66
      - https://qiita.com/syamaoka/items/ac9ceda558e03378a658
     
# 配布結果

無事配布ができました :+1:

```
$ twine upload -r testpypi dist/*
Enter your username: nassy
Enter your password: 
Uploading distributions to https://test.pypi.org/legacy/
Uploading py37nashiki-1.0.0-py3-none-any.whl
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6.73k/6.73k [00:02<00:00, 2.54kB/s]
Uploading py37nashiki-1.0.0.tar.gz
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6.93k/6.93k [00:01<00:00, 3.89kB/s]

View at:
https://test.pypi.org/project/py37nashiki/1.0.0/
(venv) 
```

```
$ twine upload -r pypi dist/*
Enter your username: nassy
Enter your password: 
Uploading distributions to https://upload.pypi.org/legacy/
Uploading py37nashiki-1.0.0-py3-none-any.whl
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6.83k/6.83k [00:05<00:00, 1.18kB/s]
Uploading py37nashiki-1.0.0.tar.gz
100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 7.04k/7.04k [00:00<00:00, 7.24kB/s]

View at:
https://pypi.org/project/py37nashiki/1.0.0/
(newenv) 
 ~/.ghq/github.com/nnashiki/play_py37_package 
```
子要素が全てfloatでも、親要素が子要素を含む高さを持つように設定する

親要素の高さは子要素を包む高さとなりますが、
子要素が全て`float`の時、親要素の高さは`0`となってしまいます。
これは、`float`が「浮いている」という意味で、親要素から見ると`float`の子要素は存在しないように見えるためです。

#`float`の解除
子要素が全て`float`でも、親要素が高さを持つように設定してみます。
`float`は`clear: left;`で「浮いている」状態を解除できます。
`clear: left;`を適用するためだけの空のタグを用意します。
空タグと`clear`で`float`を解除するのはよく使うテクニックらしいです。

```index.html
<div>
  <div class="float">
    ...
  </div>
  <div class="float">
    ...
  </div>
  <div class="clear"></div> <!-- `clear: left;`を設定するための空タグ -->
</div>
```

```style.css
.float {
  float: left;
}

.clear {
    clear: left;
}
```
高専キャリアとマイクロソフトがコラボしたクラウドAI開発講座進捗報告[6]

# クラウドAI開発講座進捗報告- 6週目

[これ](https://qiita.com/teruto725/items/222b011a8dd63bf76158)の続き


作りたいものに向けてひたすらコーディング。


## やったこと
やったことといってもひたすらコーディングなので今回は主に詰まったところについて各
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573723/e8d6ee27-cb41-f4c7-3aae-02776586b7f0.png)



### 1. BotHandler一回ごとに新しいインスタンスで処理されていた件
これ全然気づかなくてうーんってなってた。
サンプルのBotHandlerクラスの一つのインスタンスの各メソッドがActivityごとに呼び出されていると思ってた。
でも実際はイベントが発生するたびに新しいインスタンスが生成されそのインスタンス内のメソッドが呼び出されていた。つまり何が困るかというと下のようなコードがあったとき、

```c#
public class BotHandler : ActivityHandler
{
  public int count =0;
  protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
  {
     count += 1;//messageを受け取ったときにcountを1増やす
     Debug.WriteLine(count);//カウントを表示する
  }
}
```
出力は

```console
1
1
1
1
```

というように何度メッセージを受け取っても1から変化しない。
この原因は SampleのBotHandlerクラスが実はメッセージが読み込まれるたびに新しいインスタンスを生成していたからなのです（これ気付くまでめっちゃ時間かかった）

たぶん正しい解決法はDBにデータを保管しておくことだと思うんだけど絶対に面倒くさくてやりたくない、、、、

というわけでstaticパワーで力押しする作戦をとる。


クラスをstaticにするとインスタンスを作らなくても、値を呼び出したり更新したりできるのでBotHandlerが毎回新しいインスタンスで作られたとしても関係なく情報を保持できる。
コードで書くならまずcounterクラスみたいなクラスを適当に作って、


```c#
public static class Counter
{
  private static int count = 0;
  public static void addCountOne()
  {
    count += 1;
  }
　public static int getCount()
  {
    return count;
  }
}
```


BotHandlerではstaticメソッドを呼び出すだけ

```c#
public class BotHandler : ActivityHandler
{
protected override async Task OnMessageActivityAsync(ITurnContext<IMessageActivity> turnContext, CancellationToken cancellationToken)
{
     Counter.addCountOne(); //messageを受け取ったときにcountを1増やす
     Debug.WriteLine(count);//コンソールにprint
}
```

出力は

```console
1
2
3
4
```

みたいな感じなるはず！（実際に実行して確かめたわけじゃないので確かめてみてください）


それもめんどくさかったら一つ目のコードの
public int count =0;の部分をpublic static int count = 0にすればたぶん正しくカウントされる。これでもいいなって後で思いついたので追記。


### 2.ちょくちょく公式ドキュメント間違っている件
前から気になってたんですけどちょくちょく公式ドキュメント間違ってません？
例えば[Translatorの記事](https://docs.microsoft.com/ja-jp/azure/cognitive-services/translator/quickstart-dictionary?pivots=programming-language-csharp)のこの部分。![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/573723/b6ee5778-8048-f074-4138-e0918a0a039f.png)
あと何個かあったけどメモし忘れてた。
うーんという感じ。




## 感想
　1. Teamsへのアップロードで面倒な工程はすべて終わったはずなので、あとはコーディングを進めるだけ！のはずなんだけど、teamsで画像アップできるのか若干怪しい
  
## 来週の予定
ひたすらコーディング、ある程度かけてきたらコード解説記事を書きたい。
【最低限知っておきたいIT基礎知識】改行コード

SEなら最低限知っておきたい基礎知識の１つ、改行コードについてざっくりまとめています。

##目次
- １．改行コードとは？
- ２．改行コードの種類


##１．改行コードとは？
PCは文字を文字コードという数値データに変換して処理しますが、**文字コードの中でも改行を表すコードが改行コードです**。
改行コードを使用することで、文章の途中で文字を改行させることができます。
メールを打っている時などに出てくる "↲" といった記号が、そこで改行コードが使われていることを表す記号です。

改行コードは**制御文字（control character）**の１つです。
制御文字は、「あ」「ア」「A」「a」などといった文字と異なり、PCの周辺機器（例：プリンター）などに対して、動作の指示を表現することができます。制御文字の多くは、一般的な文字と異なり利用者がキーボードから入力したり画面に表示させたりすることはできません。
制御文字には、改行コードの他にスペース（空白文字）など様々な種類があります。

##２．改行コードの種類

改行コードには以下の３種類があります。
３つのうちどの改行コードを使用するかは、PCの機種やOS、使用するソフトによって異なります。
一般的にWindowsでは、CRLFが使われます。

- CR （Carriage Return キャリッジ・リターン）
- LF （Line Feed ラインフィード）
- CR + LF （Carriage Return キャリッジ・リターン + Line Feed ラインフィード）

改行コード一覧（引用元：[★](https://cprogram.net/line-feed-code/)）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/498362/74c6d0a0-b926-f540-e740-192c5842eb5b.png)
railsで複数model、複数レコードを投稿、編集する際の設計

# この記事の概要

- rails6で複数model、複数レコードを一括で保存する
- また編集も行う

# 要件

- 下記を一括登録
    - 複数レコード：max4つ
    - 複数model
- 表示する際にはその数によって表示数も変わる
- 投稿した内容をあとで編集できる

- 必須ではないができたら嬉しい要件
- レコードの数は可変
- edit時にレコードの数が変わるのもありえる（削除、追加ともにある）

# パターンは二つある

共通項：最初投稿する際はform数を4に固定し、全て表示する。2レコード投稿したい場合は2つformを空の状態で渡す。

- パターン1：nilのものは弾く。値のあるもののみをレコード追加する。
    - メリット：form数の変更に強い。無駄なレコードが入らない。
    - デメリット：editやレコード追加時に個別の処理を書く必要があるし、結構大変。
- パターン２：nilのものもレコードに入れる。edit表示の際にはそのまま出す
    - メリット：edit時に4つそのままひっぱり編集、削除もただそれをupdateするだけでいいので実装コストが低い。
    - デメリット：formの数が上下した際に変更が面倒

# パターン１

![パターン１.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193389/e26cfc37-b972-4ada-7c39-cbc56d53fc8a.jpeg)


パターン1はちゃんと必要なもののみレコードに追加し、editなども別々にちゃんと処理を各パターン。基本こっちでやるべきな気がする。。。nilのものは弾き、値のあるもののみをレコード追加する。

## 仕様

- create
    - formはmaxの4つをviewで表示
    - 値が空の場合はcontrollerで弾く。modelでvalidateするのと迷ったけどmodelで弾くとerror処理とややこしくなるので今回controllerで。
    - トランザクションにて一括で保存
- edit
    - formの表示数は可変で値の入っているもののみを表示
    - 値が入っているもののみ元からvalueに入れておく
    - レコードの追加はformの追加ページ、追加ボタンを押して行う
- レコード追加
    - 別メソッドを作って1レコードずつ保存するformを作る。

```ruby
  def create
    ActiveRecord::Base.transaction do
      @post = Post.new(name: params[:name],user_id: params[:user_id])
      @event1 = @post.events.new(date: params[:event][:date1],name: params[:event][:event_name1],url: params[:event][:url1],post_id: @post.id)
      if params[:event][:event_name2].present?
        @event2 = @post.events.new(date: params[:event][:date2],name: params[:event][:event_name2],url: params[:event][:url2],post_id: @post.id)
      end
    end
  end
```

# パターン２

![パターン２.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/193389/1c7721ca-e333-da3d-e98b-97088378f57a.jpeg)


パターン２は１と比べて雑な実装で4つ固定でレコードをもう確保してしまい、edit時もそれをそのまま出す。空だったら未入力だし、レコードを追加したい場合は空formに追加する。削除したい場合はformの中身を空にする。

## 仕様

- create
    - nilでも追加
- edit
    - 4つとも全部表示してupdate
【Linux】hostnameコマンド以外でのホスト名確認方法とは？

# はじめに
一昨日、このような記事を投稿したところ、有難いことに反響が大きかったです。
[【Linux】インフラエンジニアの僕が「hostname」コマンドを使わない理由とは？](https://qiita.com/satton6987/items/f50ad3df302290d1f544)

今回の記事では、Linuxでの`hostname`コマンド以外のホスト名確認方法について紹介していきたいと思います。

# hostnameコマンド以外のホスト名確認方法

## uname -n

`uname`とはシステム情報を表示するコマンドになります。

こちらのコマンドに、`-n`のオプションを付けると、ホスト名を表示させることができます。

```bash:コマンド
uname -n
```

```bash:実行結果
[root@tspdev01 ~]# uname -n
tspdev01
[root@tspdev01 ~]#
```

## hostnamectl status

Linux7系(RHEL/CentOS)にて使用できるホスト名確認コマンドになります。

```bash:コマンド
hostnamectl status
```

```bash:実行結果
[root@tspdev01 ~]# hostnamectl status
   Static hostname: tspdev01
         Icon name: computer-vm
           Chassis: vm
        Machine ID: 4ac15a471f30914187be09916857cdb9
           Boot ID: bedcdc6861c34bc5881a2ddb91c7955c
    Virtualization: kvm
  Operating System: CentOS Linux 7 (Core)
       CPE OS Name: cpe:/o:centos:centos:7
            Kernel: Linux 3.10.0-1127.13.1.el7.x86_64
      Architecture: x86-64
[root@tspdev01 ~]#
```

## echo $HOSTNAME

変数HOSTNAMEの値を確認することによって、ホスト名を確認することができます。

```bash:コマンド
echo $HOSTNAME
```

```bash:実行結果
[root@tspdev01 ~]# echo $HOSTNAME
tspdev01
[root@tspdev01 ~]#
```

# 【番外編】テストユーザーを作成して「hostname i」と実行してみる。

ホスト名が`i`になるのか検証してみます。

OSはこちらになります。

```bash:OSバージョン
[dev@tspdev01 ~]$ cat /etc/redhat-release
CentOS Linux release 7.8.2003 (Core)
[dev@tspdev01 ~]$
```

## 1.ユーザー作成

devユーザーを作成する。

```bash:コマンド
useradd -m dev
```

```bash:実行例
[root@tspdev01 ~]# useradd -m dev
[root@tspdev01 ~]#
```

## 2.作成したユーザーにパスワードを設定

devユーザーにパスワードを設定する。

```bash:コマンド
passwd dev
```

```bash:実行例
[root@tspdev01 ~]# passwd dev
ユーザー dev のパスワードを変更。
新しいパスワード:
新しいパスワードを再入力してください:
passwd: すべての認証トークンが正しく更新できました。
[root@tspdev01 ~]#
```

## 3.devユーザーにスイッチ

rootユーザーからdevユーザーにスイッチします。

```bash:コマンド
su - dev
```

```bash:実行例
[root@tspdev01 ~]# su - dev
[dev@tspdev01 ~]$
```

## 4.`hostname i`と実行する。

```bash:実行結果
[dev@tspdev01 ~]$ hostname i
hostname: you must be root to change the host name
[dev@tspdev01 ~]$
```

**結果的に、rootユーザーが求められて変更できませんでした。**

# まとめ

**○`hostname`コマンド以外のホスト名確認コマンド**

- uname -n
- hostnamectl status
- echo $HOSTNAME

**○一般ユーザーで`hostname i`を入力するとどうなる？**

root権限が求められ、ホスト名が変更できなかった。

# 参考記事
[変数　HOSTNAME](http://fujiyama443.blog102.fc2.com/blog-entry-43.html)
[6.3. HOSTNAMECTL を使用したホスト名の設定](https://access.redhat.com/documentation/ja-jp/red_hat_enterprise_linux/7/html/networking_guide/sec_configuring_host_names_using_hostnamectl)
[実は簡単！Linuxユーザの作成方法と追加方法](https://eng-entrance.com/linux-user-add#Linux)
MATLABのginputに対する不満解消メモ

# ginput関数とは
MATLABにはginputという関数があり、座標軸上でクリックした点の座標を取得してくれる関数です。

[ginputのドキュメント](https://jp.mathworks.com/help/matlab/ref/ginput.html)

# 不満点
すごく直感的に座標を取得できるので便利なのだが、ginputで複数の点をぽちぽちした時、一体どの点をクリックしたのか表示されないのです。ぽちぽちした点を表示するには一旦ginputを抜け出し、plotやscatterで表示しなければいけません。

# これの方がいいのでは？
というわけで、ぽちぽちした点の履歴を表示するようにアレンジしてみました。ざっと作ったのでもっといい書き方はあると思います。あと僕はMacを使っているのですが、returnキーのキーコードがわからなかったため、buttonの値をとってみていたら、returnの時にbutton = []が帰って来ました。とりあえずそのままreturnキー押下の判定に使いましたが、多分マズい。

```MATLAB
f = figure;
p = plot(0,0);
xlim([0,1])
ylim([0,1])
R = [];

while 1
    [x,y,button] = ginput(1);
    if isempty(button)
        close(f)
        break;
    elseif button == 1
        R = [R; [x,y]];
        p.XData = R(:,1);
        p.YData = R(:,2);
    end
end
```

これを関数として保存しておくと、こういう動作をします。
<img width="520" alt="スクリーンショット 2020-08-10 14.14.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/530192/437bb839-0e64-15a6-2981-27eefa960344.png">

これでどこをクリックしたか一目瞭然。
AzureでWebアプリを稼働させる「App Service」とGo

Azureには、Webアプリを稼働させるPaaSとして「App Service」が用意されています。

通常は、WebアプリをWindows上でネイティブに稼働させる「App Service（App Service on Windows）」となります。

- [App Service | Microsoft Azure](https://azure.microsoft.com/ja-jp/services/app-service/)

WebアプリをDocker化してLinuxコンテナーとして稼働させる「Web App for Containers（App Service on Linux）」も用意されています。

- [App Service - Web App for Containers | Microsoft Azure](https://azure.microsoft.com/ja-jp/services/app-service/containers/)

当初、Goは「App Service」にて実験サポートされていたのですが、2017年12月に対象外となりました(T_T)

- [End of life support for Go tooling on Azure App Service (on Windows) · Issue #45 · Azure/app-service-announcements · GitHub](https://github.com/Azure/app-service-announcements/issues/45)

そのため、現在Goで作成したWebアプリは「Web App for Containers」で稼働させることになっています。

- [クイック スタート:カスタム Linux コンテナーを実行する - Azure App Service | Microsoft Docs](https://docs.microsoft.com/ja-jp/azure/app-service/containers/quickstart-docker)

これでDockerを学ぶ理由ができたので、よしとしま、しょうか、ねぇ...q@w@p
Google Books APIの使い方~その１~

Google Books APIを使う機会があり、いろいろ調べていましたが、
詳細な情報が少なかったので、まとめてみました。

本記事はGoogle Books APIの[開発者向けサイト](https://developers.google.com/books)を翻訳して簡潔にまとめたものです。

内容もボリューミーなので、記事は何回かに分けて掲載します。

今回は「Google Books APIの概要」と「Googleブックスの基礎」についてです。

#Google Books APIの概要
Google Books APIを利用することで、
Googleブックスの機能をサイトまたはアプリケーションに組み込むことができます。

ただし、APIを使用して取得したデータの配布などは禁止されており、
商用サービスとしてAPIを利用することもできないようです。

[利用規約](https：//developer.google.com/books/terms.html)に違反した場合はAPIへのアクセスが一時停止されます。

Google Books APIには「Books API v1」と「Embedded Viewer API」の２種類があります。
## Books API v1
Googleブックスに対して以下の操作を実行できます。

- 特定のクエリに一致する書籍のリストを検索して閲覧する
- メタデータ、在庫状況、価格、プレビューページへのリンクなど、書籍に関する情報を表示する
- 自分の本棚を管理する

## Embedded Viewer API
Googleブックスの書籍をWebページに直接埋め込むことができます。

#Google Books APIを利用するには
基本的にはGoogleアカウントが必要です。

"基本的に"と書いたのは、アカウントがなくても一部のデータは取得可能だからです。

# Google ブックスの基礎
## コンセプト
Googleブックスには、次の4つのコンセプトがあります。

***Volume***
・本や雑誌に関するデータ。

***Bookshelf***
・Volumeのコレクション。
・ユーザーごとにあらかじめ用意されている本棚と、ユーザーが手動で追加した本棚があります。
・ユーザーは自由にVolumeを追加・変更・削除ができますが、
　おすすめの書籍などの一部の本棚は自動でVolumeが追加されます。
・本棚はプライベート（非公開）とパブリック（公開）のどちらかに設定できます。

***Review***
・Volumeに対するレビュー。
・ユーザーはVolumeごとに1つのレビューを設定できます。
・外部のソースからも利用できます。

***Reading Position***
・ユーザーのVolume内の最後の読み取り位置。
・ユーザーはVolumeごとに1つの読み取り位置しか持つことができません。
・ユーザーがそのVolumeを以前に開いていない場合、読み取り位置は存在しません。
・単語の解像度まで詳細な位置情報を保存されています。
・ユーザーに公開されません。

## データモデル
### リソース
一意の識別子を持つ個別のデータエンティティのことを指します。

***Volume resource***
　ボリューム

***Bookshelf resource***
　特定のユーザーの単一の本棚

### コレクション
リソースの集まりのことを指します。

***Volume collection***
・Googleブックスが管理するすべてのVolume resourceのコレクション。
・すべてのVolume resourceをリストにすることはできませんが、
　検索条件に一致するVolume resourceをリストにすることはできます。

***Bookshelf collection***
・Googleブックスが管理するすべてのBookshelf resourceのコレクション。


####＊あらかじめ用意されている本棚

| 本棚 | 説明 |
|:-----------------|:------------------|
| Favorites| 手動での追加・削除が可能です。 |
| Purchased| 購入した書籍が入ります。手動での追加・削除ができません。 |
| To Read| 手動での追加・削除が可能です。|
| Reading Now| 手動での追加・削除が可能です。|
| Have Read| 手動での追加・削除が可能です。|
| Reviewed| レビューをつけた書籍が入ります。手動での追加・削除ができません。  |
| Recently Viewed  | 最近Webリーダーで開いた書籍が入ります。手動での追加・削除ができません。 |
| My eBooks        | 購入した書籍が自動的に追加されますが、手動で削除が可能です。|
| Books For You    | おすすめと判定された書籍が入ります。おすすめがない場合、この本棚は存在しません。|

## オペレーション
コレクションとリソースに対して以下の5つのメソッドを使用できます。

| メソッド | 説明 | REST HTTP マッピング |
|:-----------------|:------------------|:------------------|
| list | コレクション内のリソースの指定されたサブセットをリスト | コレクションURIに対するGET |
| insert | 新しいリソースを追加 |新しいリソースのデータを渡すコレクションURIに対するPOST |
| get | 特定のリソースを取得 |リソースURIに対するGET |
| update | 特定のリソースを更新 |更新されたリソースのデータを渡すリソースURIのPUT |
| delete | 特定のリソースを削除 |削除するリソースのデータを渡すリソースURIでのDELETE |

各リソースに対して許可されているメソッドは以下の通りです。

| リソース | list   | insert | get | update | delete |
|:---------------|:------:|:------:|:---:|:------:|:------:|
| Volumes |△|×|○|×|×| 
| Bookshelves |△|◎|△|◎|◎|
| Reading Positions |×|◎|◎|◎|◎|
×：利用不可
○：認証なしで利用可
△：認証なしで利用できるが、プライベートデータに対しては認証が必要。
◎：認証により利用可

#最後に
以上、「Google Books APIの概要」と「Googleブックスの基礎」でした。

次回は「[Google Books APIの呼び出し方](https://qiita.com/stella0270/items/7a19dea8a4f47d97570b)」です。
Githubにアップデートできないことにムカつく

また起こりました。
Githubに新しいPGを載せようとしたら、
弾かれました。

そして、

hint: Updates were rejected because the remote contains work that you do
hint: not have locally. This is usually caused by another repository pushing
hint: to the same ref. You may want to first integrate the remote changes
hint: (e.g., 'git pull ...') before pushing again.
hint: See the 'Note about fast-forwards' in 'git push --help' for details.

とお馴染みの文章。
役に立ったことがありません。

こっちは変更するべき個所を変更して、
それをレビューのためにプッシュしたいだけなのに、
こういう事になってしまう。
頻繁にこういう事が起きるので嫌になります。

とは言うものの、
こちらのプッシュの準備が悪かったことから
起こった事実は変わりありません。
もっとケアする部分を増やして、
この事態が起こらないようにするしかありません。
例えば、Github内での編集は一切せずに、
毎回プッシュする方に完全シフトするのを身体に沁みつかせるとか。
VScodeのterminal操作をキーボードで　~設定は手間だが役に立つ~

# Is this  何の記事？

VScodeを使ってるけど、
**「ターミナルを開いたり、閉じたりするためにマウスやトラックパッドを使いたくない！！」**
というあなた。気が合います。一緒に設定をしましょう。

## ターミナルを開く

これはデフォルトで設定されているようです。

``controll + shift + ` ``

[参考記事](https://qiita.com/luccafort/items/b721d03dfb9630b33d89)の
『どうでもいいけどmacの `^` とか全然覚えられんから〜』っていう気持ち、
ほんまそれって感じ。
ちなみに僕は自分で `alt + p` を割り当てました。
割り当て方は下の『ターミナルを切り替える』をご覧ください。
![スクリーンショット 2020-08-10 13.51.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285307/713d718f-7b81-89c8-2cc6-75fc18243aa5.png)


## ターミナルを切り替える

これはデフォルトの設定はないようなので、各自で設定しましょう！

まず、`cmd + shift +p`を押して
『基本設定　キーボードショートカット を開く(preferences: open keybord shortcuts)』
を検索してクリックして開く！
![スクリーンショット 2020-08-10 11.41.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285307/301e9640-0317-0e7e-9e02-7f00c39efb03.png)

『入力してキーバインド内を検索』に

`focus next terminal` を入力すれば「次のターミナル」への設定を変更できる
![スクリーンショット 2020-08-10 12.08.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285307/4c1842ef-edfc-276a-f228-1d7f5b9e9dc3.png)

ダブルクリックして『任意の〜』って画面がでてから好きなキーを割当ましょう！

ちなみに僕はエセvimmerなので `alt + h`, `alt + l` を割り当てました。


## 不要なターミナルを閉じる

上記と同じように自分で設定することになります。

`cmd + shift +　p` で『基本設定』を開いたら `kill terminal` とかで検索して

カスタマイズしましょう。

ちなみに僕は `alt + w` を割当ました。
![スクリーンショット 2020-08-10 13.50.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/285307/0bad7eff-40af-babe-6d5b-fa14d1b116bb.png)


## まとめ
「キーボードだけで作業を終わらせたいんや」という気持ちを持ちながら
上手く扱えていなかったvscodeのターミナルに関して、ショートカットの設定方法を整理しました。

自分がPC変えたときのために残しておきましたが、同じ気持ちを持っていた方の参考になれば幸いです。
ちなみに、ショートカットキーについては
[エンジニアになって僕はマウスを捨てた](https://qiita.com/taekari/items/2d7d6a009937fb927810)
という記事にも書いていますので良かったらご覧ください！！

他にも「こんな便利なショートカットあるよ」や「自分こんな設定してるけどどう？」など
ありましたらコメントをいただけると嬉しいです！！

また、言語に関係のない~~つまらない~~記事を残してしまった…
次こそ！

## 参考記事
[Visual Studio Code上でターミナル起動](https://qiita.com/luccafort/items/b721d03dfb9630b33d89)
[vscodeの統合ターミナルタブ切り替えのやり方](https://teratail.com/questions/191295)
MacからUSBブート可能なWindows10インストールメディアを作成するのがハードル高かった

十数年ぶりにWindowsPCを自作した際にWindows10のインストールメディアを作成するのに苦労した話です。

# TL;DR

* 最新のWindows10イメージをダウンロード、定番のUNetbootinツールやddコマンドで実行
* イメージは起動するが、インストールエラー😨
  * FAT 4GB問題らしい
* 昔(2018年)のインストールメディアだと対象ファイル(install.vim)が4GB以下なので大丈夫そうだけど落とせそうにない
* wimlibというイメージ分割ツールを使ってイメージを作成することでインストールできた


# 必要なもの

* Mac
* Windows10のiso(2018年のじゃなくてよい)
* 8GB以上のUSBディスク


# 最小限の手順

## 1. Windows10のisoダウンロード

https://www.microsoft.com/ja-jp/software-download/windows10
2020年7月時点では「Windows10 May 2020 Update」でした

## 2. Macのディスクユーティリティでisoをマウント

<img width="1037" alt="スクリーンショット 2020-08-10 13.45.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/8105/89370b28-bfa7-abdf-394c-2bfcf2d78dee.png">

## 3. USBディスクのフォーマット

diskutilツールでUSBディスクをフォーマット

```
diskutil eraseDisk MS-DOS "WINDOWS10" MBR diskN
```

## 4. rsyncコマンドで基本的なファイルをコピー(install.vim以外)

install.vimというファイルだけ4GBを超えているのでいったん除いてコピー

```
rsync -avh --progress --exclude=sources/install.wim /Volumes/CCCOMA_X64FRE_JA-JP_DV9/ /Volumes/WINDOWS10
```

## 5. install.vimを分割してコピー

wimlibというツールで分割してコピー。3.8Gくらいを指定。

```
brew install wimlib
wimlib-imagex split /Volumes/CCCOMA_X64FRE_JA-JP_DV9/sources/install.wim /Volumes/WINDOWS10/sources/install.swm 3800
```

## 6. 完成😇

WindowsPCのUSBボートに挿して起動！


# 参考記事

MacでUSBに焼いたWindows10がインストールできなかったので対処した話
https://qiita.com/0nji/items/c3e28bf4135dd3137d2b

→ 2018/10のパッチ適用前のisoが落とせなかった、、

神記事（ほぼこの通り）
https://alexlubbock.com/bootable-windows-usb-on-mac
ReactサーバをプロキシにしてCORSに引っかからないようにする

create-react-appでreact環境を作りました。
次にAPIを叩きたいのですが、今のreactサーバからやってもいいけど負荷が集中するからあまり現実的じゃない。
(→役割分担させる。webサーバは基本的にページを返す。APIサーバは基本的に裏でAPI叩いてデータのやり取りを行う。)

そこでreactサーバとネットの間にもう一つサーバ(Flask)をかますことにしました。
ただ、このまま使ってもCORSに引っかかってうまくAPIを叩くことができません。
###CORS
セキュリティ的な問題でデフォルトで設定されている。
ブラウザから入力したものが意図しないリソースにアクセスされないように。
参考
https://qiita.com/geekduck/items/6f99a3da15dd39658fff#%E9%96%8B%E7%99%BA%E4%B8%AD%E3%81%ABapi%E3%82%B5%E3%83%BC%E3%83%90%E3%81%AB%E3%83%AA%E3%82%AF%E3%82%A8%E3%82%B9%E3%83%88%E3%82%92%E6%8A%95%E3%81%92%E3%81%9F%E3%81%84

###create-react-appのプロキシ設定
それ用のmiddlewareがあるからそれを使えば簡単に設定できる。
窓口は一つのポート番号にして、そこから裏で動いている別サーバにアクセすることが可能
参考
https://qiita.com/geekduck/items/6f99a3da15dd39658fff
https://applingo.tokyo/article/1568


#注意点
直接URLにFlaskのエンドポイントを入力しても画面は真っ白のまま、、、
一方で、コンポーネント内でaxiosを使ってgetするとうまくいく、、、
これは、**create-react-appの仕様上の問題で、access headerがtext/htmlじゃないもののみプロキシに渡すようになっているらしい。**
だから、直接URLに入力しても何も帰ってこないのか、納得。
詳しくは公式ドキュメントを参考にしてください。
https://create-react-app.dev/docs/proxying-api-requests-in-development/
Vue.jsで広告を埋め込んだコンポーネントを作る

## はじめに
エンジニア歴4年目に突入したハヤシと申します。（インフラ:2年,WEB:1年）
現在、前勤めていた会社の先輩と一緒に「Pokeloop」というアプリを作っており、そろそろ広告埋め込みたいなぁーと思ってVueで広告コンポーネントをつくってみました。google adsense等、大手の広告をvueに埋め込むやり方は結構出てくるけど、あまり有名じゃないところだと埋め込む方法が出てこなかったので備忘録的に残したいと思います！


ちなみに「pokeloop」はパーティー相性表をはじめとするポケモン対戦における便利なツールを提供しているサイトです！UI等かなりこだわってますので、ぜひ一度訪れてください！
https://pokeloop.com/

## 開発環境
vue: 2.6.10

## 扱う広告の種類
今回はjsを埋め込むと、自動的にDOMが生成されるタイプの広告を扱います。それ以外ではこのやり方ではうまく行かない場合があるかもしれません。

■動作確認広告
1.[忍者AdMax](https://admax.shinobi.jp/)
2.[アスタ](http://www.astrsk.net/)

## 作り方
自動的にDOMが生成されるタイプの広告をvueで扱うためには、iframeという他のサイトを埋め込めるhtmlのタグを使用して、広告を埋め込みます。単純にjsを埋め込むだけだとダメでした。

###OKな例
iframeタグを作成して、その中にjsタグを埋め込む形にしています。

```vue:ads.vue
<template>
 <div ref="ads" class="ad"></div>
</template>

<script>
export default {
  async mounted() {
    const iframe = document.createElement('iframe');
    const head = document.getElementsByTagName('head')[0];
    this.$refs.ads.appendChild(iframe);
    const html = '<body><script src="https://cdn.com/somescript.js"><\/script><\/body>';
    const iframeDocument = iframe.contentWindow.document;
    iframeDocument.open();
    iframeDocument.write(html);
    iframeDocument.close();
  }
}
</script>
```

<style lang="scss" scoped>
</style>

###ダメな例
これではうまくいきません。多分document.writeでDOMを作ってる部分が動かないためです。

```vue:ads.vue
<template>
 <div ref="ads" class="ad"></div>
</template>

<script>
export default {
  async mounted() {
    // スクリプトタグを生成
    let scriptEl = document.createElement('script');
　　 // スクリプトタグにjsをセットする
    scriptEl.setAttribute('src', 'https://cdn.com/somescript.js');
    // this.$refsを使い、DOMに埋め込む
    this.$refs.ads.appendChild(scriptEl);
  }
}
</script>

<style lang="scss" scoped>
</style>
```

## 終わりに
いかがでしたでしょうか。これで広告コンポーネントを作成することができると思います。

なにか記事の内容に不備があればご指摘お願いします。

見ていただきありがとうございました！
Ubuntuが異常終了した際にやるべきこと

# 概要
Ubuntuが異常終了した際に行ったことを記録として残します。
環境：Ubuntu 20.04 LTS

# fsck
Windowsでは`scandisk`に相当するコマンドでファイルシステムのスキャンと修復が行えます。
システムが異常終了した際に自動的に実行されますが、forcefsckファイルをホームディレクトリに作成することで、次回起動時に強制的に実行できます。

```shell:
sudo touch /forcefsck
```

結果の確認は以下の通り。

```shell:
sudo cat /run/initramfs/fsck.log 
```

特に問題なければ以下のように表示されます。

```shell:
/dev/nvma03x1: clean, 239896/31227904 files, 4604346/124895488 blocks
```

# debsums
Windowsでは`sfc/scannow`に相当するコマンドでインストール済みパッケージの整合性が確認できます。

```shell:
sudo apt install debsums
```

下記コマンドで変更のあった箇所のみを表示できます。

```shell:
sudo debsums -s
```

# 参考
https://www.xmisao.com/2014/02/06/force-fsck-or-reboot-fast-with-shutdown-command.html
http://manpages.ubuntu.com/manpages/trusty/man1/debsums.1.html
Anypoint Runtime Managerのカスタム通知を試してみよう！

# はじめに
　今回は、Runtime Managerの通知機能について、機能概要やユースケース、制約事項、実装方法について説明します。
　なぜ、この機能を調査しようと思ったきっかけですが、Anypoint Platformには「通知機能」と「アラート機能」があります。ユーザに通知するという目的は一緒で、アラート機能から通知機能を利用することもできるため混乱したのがきっかけです。
　ここでは通知機能の概要を把握して、通知とアラートを区別できるようになれば、要件を定義する際にお客様との認識の齟齬が解消できますね。

# 通知機能
通機能について、機能概要やユースケース、制約事項についてまとめました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/85c3aaf7-cafa-874f-f83e-bd3bfb2778e6.png)


[公式ヘルプ：Runtime Managerの通知](https://docs.mulesoft.com/jp/runtime-manager/notifications-on-runtime-manager)
[公式ヘルプ:カスタムアプリケーションアラートおよび通知](https://docs.mulesoft.com/jp/runtime-manager/custom-application-alerts)

# カスタム通知の仕組み
　MuleフローのCloudHubコネクタ又は、CloudHub APIから通知を登録できます。また、登録された通知はRuntime Managerコンソールのベルマークを押下すると画面で確認できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/8f171f50-255d-02d7-22f7-8e1b9b83255f.png)


# CloudHubコネクタ
　Anypoint StudioのMuleパレットからMuleプロジェクトにコネクタを追加し、Muleフローに配置すると利用できます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/9ce7211e-54a3-719f-2119-32a69d8c73d1.png)

　通知をRuntime Managerに登録するため、CloudHubコネクタの設定や、通知をアプリケーションに紐づける設定が必要です。設定は以下の通りです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/8e366c10-22cb-b47c-543f-ea46b6e0228d.png)

# CloudHub API
　Runtime ManagerのREST APIが公開されていますので、APIを利用して、通知の登録や更新、閲覧ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/76270/9697dde2-8c6b-363f-5cc7-b3fb1236b623.png)

```
パラメータ載せていおきます。ご利用ください。
Endpoint : https://anypoint.mulesoft.com/cloudhub/api/notifications
Header : 
    Authorization:Basic <ユーザID:パスワードをbase64でエンコード>
    X-ANYPNT-ENV-ID : <環境ID※ClientIDではありません。CloudHubコネクタ設定時に確認できます>
    Content-Type : application/json
POST:
    Body : { "domain": "<アプリケーション名>", "message": "hello world second.", "priority": "INFO", "transactionId": "id"}
PUTのMessage Body : { "status": "read" }
```

[Exchange:CloudHub APIポータル](https://anypoint.mulesoft.com/exchange/portals/anypoint-platform/f1e97bc6-315a-4490-82a7-23abe036327a.anypoint-platform/cloudhub-api/minor/1.0/console/endpoint/%233651/)

# 最後に
　いかがだったでしょうか？
　Runtime Managerの通知について概要やユースケース、制限事項、実装方法について説明しました。
　機能概要を理解すると、通知機能はシンプルで理解が簡単ですね。
　MuleSoftは、データ連携基盤として様々なバックエンドシステムやAPIクライアントと接続するので、アプリケーションの状態を把握したいという要件は多いいはずです。
　お客様の運用要件に合わせて柔軟に対応したいですね。では！！
Oracle SQL Developper Install

# はじめに

Oracle SQL Developper の Install 手順をシンプルに残します



# Install

Download

https://www.oracle.com/tools/downloads/sqldev-v192-downloads.html

![1597027729516.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/efa45b31-168f-1777-661d-0829da29e6d6.png)



Download

![1597027755556.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/1eaa0ff8-96c6-76f7-b834-4a82871c6e47.png)



ダウンロードしてきた zip を展開して、sqldeveloper.exe を実行

![1597028873362.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/630229d1-65a7-9643-9cc4-ba39a57323a5.png)



Import は No

![1597028961552.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/4b6964a4-98e9-da06-73b6-54fadc1d1fc6.png)



起動完了

![1597029240102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/1b1ea312-dfc6-7981-eef7-af3800a60be4.png)



# 接続

＋

![1597029304960.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/c5ea9ed9-ba67-f5d0-2a2a-f2992b197991.png)



各種パラメータを入れて、Save。Save の後に Connect

![1597030365947.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/3f1c22ab-1657-c4ea-e258-205d3e01142c.png)



```
SELECT TO_CHAR (SYSDATE, 'MM-DD-YYYY HH24:MI:SS') "NOW" FROM DUAL;
```


![1597032284063.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104247/5c7d6b5d-4253-db41-c5d6-733191d9fcf0.png)
【ubuntu20.04serverで仮想化基盤構築】kvmによるVM作成

# 必要なものインストール
```shell-session
user@ubuntu:~$ sudo apt -y install qemu-kvm libvirt-daemon bridge-utils virtinst libvirt-daemon-system
```

# isoダウンロード

## ubuntu20.04-desktop
```shell-session
user@ubuntu:~$ curl -OL https://releases.ubuntu.com/20.04/ubuntu-20.04.1-desktop-amd64.iso
```

## centos8
```shell-session
user@ubuntu:~$ curl -OL http://ftp-srv2.kddilabs.jp/Linux/packages/CentOS/8.2.2004/isos/aarch64/CentOS-8.2.2004-aarch64-boot.iso
```

# KVMで"CentOS8"VM作成(virt-install)
--network ...をオプションで入れなくてもbr0になっていた．入れるべきなのか入れなくともbr0に設定されるのかは確認できていない．

```shell-session
user@ubuntu:~$ sudo virt-install \
--name=centos \
--location=/iso/CentOS-8.2.2004-x86_64-minimal.iso \
--disk path=/var/lib/libvirt/images/centos8.qcow2,size=5,format=qcow2 \
--vcpus=1 --ram=1024 \
--graphics none \
--extra-args="console=tty0 console=ttyS0,115200n8"
```

# KVMで"ubuntu20.04"VM作成(virt-install)
ubuntu20.04はisoからVM作成ができなかった．ただし，--locationを--cdromに変更し--extra-argsを消したところインストール自体はできた．ただインストール時のセットアップが一切できずインストール開始してしまうのでインターネット経由で作成しました．

```shell-session
user@ubuntu:~$ virt-install \
--name=ubuntu2004 \
--location=http://us.archive.ubuntu.com/ubuntu/dists/focal/main/installer-amd64/ \
--disk path=/var/lib/libvirt/images/ubuntu2004.qcow2,size=20,format=qcow2 \
--vcpus=2 --ram=2048 \
--graphics none \
--extra-args="console=tty0 console=ttyS0,115200n8"
```

## インストール後にconsoleに入れない（ubuntu20.04）
インストール後，`$ virsh console ubuntu2004`でコンソールに入っても，何も反応がなく（centosは`centos8 login:  `が出てきた），調べたところコンソールを掴むために追加で設定が必要らしい．[こことか参照](https://blog.cybozu.io/entry/3792)
インストール時にipアドレス固定にしてあったので，自分の場合はsshでゲスト環境に入って作業をした．（openssh-serverもインストール済）

### ゲストOS側 [ここ参照](https://knqyf263.hatenablog.com/entry/2014/01/13/200509)
`/etc/init/ttyS0.conf`を新規作成し，以下のように編集する.とりあえず作成したが，これが解決に必要だったかは未検証．とりあえず動いたので...

```/etc/init/ttyS0.conf
start on stopped rc RUNLEVEL=[2345]
stop on runlevel [!2345]

respawn
exec /sbin/getty -L 115200 ttyS0 vt102
```

次に`/etc/default/grub`を追記編集.

```/etc/default/grub
+GRUB_CMDLINE_LINUX="console=tty0 console=ttyS0,115200n8"
+GRUB_SERIAL_COMMAND="serial --speed=115200 --unit=0 --word=8 --parity=no --stop=1"
```

編集後，以下コマンドでアップデート，シャットダウン（power off）,起動

```shell-session
$ sudo update-grub
$ sudo poweroff
$ sudo virsh start ubuntu2004
```

コンソールに入れることを確認

```shell-session
$ virsh console ubuntu2004
```

## 参考
* https://computingforgeeks.com/install-kvm-hypervisor-on-ubuntu-focal-fossa/
* https://centos.bungu-do.jp/archives/tag/virt-install
* https://www.golinuxcloud.com/virt-install-examples-kvm-virt-commands-linux/#7_virtinstall_location
* https://blog.cybozu.io/entry/3792
* https://knqyf263.hatenablog.com/entry/2014/01/13/200509
ラズパイへのssh接続を有効化する方法(2020年版)

# ラズパイへのssh接続を有効化する方法
Raspberry Piへssh接続するためには、sshサーバーが有効化されている必要があります。
デフォルトでは無効になっているので、以下のいずれかの手順を行って有効化してください。

なお、GUIなし版のOS(Raspbian Stretch Lite)をインストールした場合は、2番目の方法(CUI上で設定する方法)のみが使用できます。

## GUI上で設定する方法

1. 左上のメニューから「設定」→「Raspberry Piの設定」を選択
![ssh_raspi_gui1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192805/73df3982-f436-aad0-f496-c8a6e7c93757.png)

2. 「インターフェイス」タブを開く
![ssh_raspi_gui2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192805/2857884e-7836-b619-a045-bab1df526cfe.png)

3. 「SSH」について「有効」にチェックを入れる
![ssh_raspi_gui3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192805/70bb79ea-b460-e009-c9e7-d76dd37061fb.png)

4. 右下の「OK」ボタンをクリックする

以上でsshサーバーが有効になりました。

## CUI上で設定する方法(GUIが使えない場合)

1. 管理者権限で`raspi-config`を実行
    
    ```
    $ sudo raspi-config
    ```

2. 「5 Interfacing Options」→「P2 SSH」を順に矢印キーとEnterキーで選択・決定
   (バージョンによっては「8 Advanced Options」→「A4 SSH」の場合があるので注意)
![ssh_raspi_raspiconfig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192805/bbd54915-9d92-3bfa-2890-fabf7819b195.png)

3. 「<はい>」を選択してEnterキーを押す
![ssh_raspi_raspiconfig2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/192805/79effde2-7cb5-8ff4-40b9-af9b03fe983c.png)

以上でsshサーバーが有効になりました。

-------
※経緯: 別記事の執筆中にssh有効化方法を参照しようとしたところ、どれもGUI/CUIの片方しか紹介がなかったり`raspi-config`の設定項目が古いままだったりして不親切になりそうだったので、n番煎じですが新しくこの記事を書きました。
Reduxのデバックに必須！Redux DevToolsの使い方

react reduxを使用して開発しているときに必須のデバックツールだと思います。
Google Choromeのエクステンションでstateの偏移や、アクションの実行の履歴などを確認できます。

## Redux DevToolsをインストールする
chrome ウェブストアでインストールしましょう。

https://chrome.google.com/webstore/detail/redux-devtools/lmhkpmbekcpmknklioeibfkpmmfibljd?hl=ja
そしたらRedux DevToolsのアイコンが右上にでると思います。
![0_lNKJWkLVKZOMfFh9_.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401408/a88e89fc-9a91-d290-fe2c-09b235c022a1.jpeg)
そしたらreactのプロジェクトのindex.jsを書き換えましょう

```javascript:index.js
import React from 'react';
import { ReactDOM } from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, compose } from 'redux';

import App from './App';
import reducer from './reducers';

  const store = createStore(
   reducer,
   window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
  );

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.getElementById('root')
)
```

redux-thunkなどのミドルウェアを使用するならこうなります。

```javascript:index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { createStore, applyMiddleware, compose } from 'redux';
import reduxThunk from 'redux-thunk';

import App from './App';
import reducers from './reducers';

const composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__ || compose;
const store = createStore(reducers, composeEnhancers(applyMiddleware(reduxThunk)));

ReactDOM.render(
  <Provider store={store}>
    <App />
  </Provider>,
  document.querySelector('#root')
);
```

これだけで準備は完了です。

## Redux DevTools を使用する
あとはローカルサーバーを起動したときにアイコンをクリックすればウィンドウがでます。
右側にあるActionを押せばなんのActionが実行されたか、Stateを押したらStoreの状況を見ることができます。他にも機能があるので色々試してみてください。
![arbnb_redux_devtools.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/401408/9a11e216-df60-c98c-d08a-37722f91193a.png)

以上です。便利なデバックツールを活用して開発を行っていきましょう。
rails tutprial2章→herokuで「The page you were looking for doesn’t exist.」

#現象
>The page you were looking for doesn’t exist.

と表示される

#解決方法
下記を参考にgitで pushをする前に
> rake assets:precompile

と打ち込み、その後デプロイ。

#結果
次は異なるエラーが表示された
>We're sorry, but something went wrong.

#解決方法2
自分がハマったところだったので、下記を参考に
> $ heroku run rake db:migrate
を実行
https://qiita.com/mozzarella-841/items/50abfa6fcf4f3a8f3b9d

#結果2
無事micropostsのページが表示された

#参考
https://qiita.com/nao_yoshikawa/items/90143d846ada55ec87d4
【初心者向けハンズオン】kaggleの「住宅価格を予測する」を1行ずつ読み解く（第8回：予測モデルの構築）

# お題
* [第1回の内容はこちら](https://qiita.com/WdknWdkn/items/a7f5e4a2cc492676e12a)
* [第2回の内容はこちら](https://qiita.com/WdknWdkn/items/95eccfae1aac99babe7a)
* [第3回の内容はこちら](https://qiita.com/WdknWdkn/items/54ee2cdc56d85d5e795c)
* [第4回の内容はこちら](https://qiita.com/WdknWdkn/items/b3ec4606d533770e5eb5)
* [第5回の内容はこちら](https://qiita.com/WdknWdkn/items/17aa03188f728b6b563e)
* [第6回の内容はこちら](https://qiita.com/WdknWdkn/items/55a62c602f896cf9aedb)
* [第7回の内容はこちら](https://qiita.com/WdknWdkn/items/a01b2cf4f06c9e572fe2)

　有名なお題であるkaggleの「House Price」問題にみんなでチャレンジしていくことになったハンズオンの内容をメモしていく企画の第8回。解説というよりはメモのまとめだったりもしますが、どこかの誰かのためになれば幸いです。前回で準備がおわり、いざ解析段階にはいって、統計の勉強をもっとしておけばよかったと反省に反省を繰り返す状態です。

* 元々のお題：https://www.kaggle.com/c/house-prices-advanced-regression-techniques
* 参考にした記事：https://yolo-kiyoshi.com/2018/12/17/post-1003/

# 本日の作業

## 予測モデルの構築

### StandardScaler() #スケーリング
とりあえず以下の記事を読みます。そして本日は感想を書きます。
* スケール変換について：https://aizine.ai/preprocessing0614/

わかったこと：
* 特徴量の取りうる値、範囲を調整して同じ範囲に収めるよう変換してくれる。
* 例）「売上に効いてくる特徴量」で『訪問者数』『気温』とした場合、単純に『訪問者数』のほうが差分が大きく出てしまい、重要さの判定に実測に沿わない影響を及ぼす。
* スケール変換はいくつか手法がある。記事記載の内容のうち、今回使っているのはよくつかう（？）「StandardScaler変換」

### Lasso回帰モデル
とりあえず以下の記事を読みます、そして本日は感想を書きます（2度め）。
* Lasso回帰モデル：https://aizine.ai/ridge-lasso-elasticnet/
* 関連ワード「線形回帰」：https://aizine.ai/glossary-liner-regression/
* 関連ワード「過学習」：https://aizine.ai/overfitting0206/
* 関連ワード「コスト関数・平均二乗誤差」：https://aizine.ai/glossary-mse/

わかったこと：
* 今回は物件情報ということもあり、説明変数も多いためLasso回帰を採用。

### パイプライン構築
* とりあえず以下の記事を読みます。そして本日は感想を書きます。（3回め）*
* パイプラインについて：https://qiita.com/colako/items/b4f4159b77c0a87e978f

わかったこと：
* スケーリング、クラス生成などもろもろ流れをつくってくれる、と。（これは完全にわかったつもりになりたいやつの文章だ…）

# おしまい。

本日は一切コードを書かずに読み込みをする作業になりましたが、やはり背景知っとくのは大事というか、このハンズオンをやったあとに体系的にやると、なるほどとなりそうな気がした。
ITサービス継続性管理における段階的復旧(コールド・スタンバイ)、中間的復旧(ウォーム・スタンバイ)、高速復旧(ホット・スタンバイ)、即時的復旧(ホット・スタンバイ)

平成31年春期 午前問題55

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/60f4964b-e18a-6450-f434-3b57d4a70921.png)

コールド・スタンバイは段階的復旧？、通訳はね。。。。

ITIL 2011 editionでは、ITサービスの中断に対処するための戦略として以下の6つの復旧オプションを挙げています。

１、段階的復旧(コールド・スタンバイ)　cold standby
　コンピュータシステムを設置できる施設だけを確保しておき、障害発生時にはそこに機材などを搬入してバックアップサイトとして機能させる方式。障害発生後には、システムの導入とデータの復旧を行って業務を引き継ぐ。

２、中間的復旧(ウォーム・スタンバイ)　Warm standby
　バックアップサイトに本システムと同じ機器を全部(あるいは部分的に)設置しておく方式。障害発生後には、追加の機器やデータおよびプログラム媒体を搬入してから予備系システムを立ち上げて処理を引き継ぐ。

３、高速復旧(ホット・スタンバイ)　Hot Standby
　バックアップサイトに本システムと同じ機器及びバックアップデータを用意しておく方式。非常時にはデータの復旧を行ってから処理を引き継ぐ。本システムを同じものを稼働させておき、定期的に同期をとる方式もこれに含まれる。

４、即時的復旧(ホット・スタンバイ)　Hot Standby
　日常からバックアップサイトで本システムと同じものを稼働させておき、非常事態が起きたときに切れ目なく業務を引き継ぐ方式。常に本システムのデータとの同期が行われており、障害発生時に直ぐにその施設でシステムを運用できる体制になっている。

５、相互協定
　他の事業者と協定を結び、非常時には他の事業者のリソースを使用してITサービスを復旧させる方法。

６、手作業のワークアラウンド
　ITサービスが再開するまでの数日間、緊急的な措置として業務を手作業で遂行する方法。通常は他の復旧オプションと併用される。



・「ホットスタンバイ」＝予備のPCやサーバーの電源をつけたまま待機させることで、本番機に何か問題が発生しても**すぐに予備機に切り替える**ことができる状態。
・「ウォームスタンバイ」＝予備のPCやサーバーの電源はつけないものの、**起動させればすぐに本番機から予備機に切り替える**ことができる状態。
・「コールドスタンバイ」＝予備のPCやサーバーは用意してあるものの、**電源もつけず、本番機から予備機への準備もしていない状態**。


ーーーーーーーーーーーーーーーーーーーーーーーーーー
補足
ITILのITサービス継続性管理の達成目標に関する説明のうち，適切なものはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/e1ed9eed-ab5e-5a2e-4a32-f454199749e7.png)

ITサービス継続性管理は、火災、風水害、地震、事故、テロなどの不測の災害によってITサービスが中断・停止した場合に、企業活動への影響を最小限に抑え、事前に取り決めた時間内に復帰させることを目的とするプロセスです。

１、問題管理の目標
災害だけでなく，インシデントも含めた対策を実施する。

２、構成管理の目標
災害によって被害を被った情報システムの構成を修復する。

３、インシデント管理の考え方
災害の発生を予測したプロアクティブな予防措置よりも，事後の復旧に重点をおく。


４、ITサービス継続性管理の目標　　IT Service Continuity ManagementITサービス継続性管理（ITSCM）
災害が起こった後，一定期間内にシステムを復旧し事業を継続させる。


５、事業継続計画（BCP）
BCPとは事業継続計画（Business Continuity Plan）の頭文字を取った言葉です。企業が、テロや災害、システム障害や不祥事といった危機的状況下に置かれた場合でも、重要な業務が継続できる方策を用意し、生き延びることができるようにしておくための戦略を記述した計画書です。また、事業継続のための戦略はBCM（Business Continuity Manage ment）と呼ばれています。



参照：

https://www.ap-siken.com/kakomon/31_haru/q55.html

https://exture-ri.com/2018/12/05/%E3%82%A6%E3%82%A9%E3%83%BC%E3%83%A0%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%90%E3%82%A4%E3%80%81%E3%82%B3%E3%83%BC%E3%83%AB%E3%83%89%E3%82%B9%E3%82%BF%E3%83%B3%E3%83%90%E3%82%A4%E3%80%81%E3%83%9B%E3%83%83/


https://www.pm-siken.com/kakomon/24_haru/am2_20.html


BCP
https://www.nri.com/jp/knowledge/glossary/lst/alphabet/bcp
Vue.jsでwasm-bindgen(Rust+WebAssembry)の入出力を扱う

wasm-bindgenでHello,Worldできたという記事は多いが、wasmを本格的に扱うならVue.jsでJSONをやりとりするところまでテンプレにしておきたい。wasmのモジュールを読み込む前に`var app = new Vue()`をやっても意図したとおりに動いてくれないからasync/awaitなど工夫が必要だ。

まず、下記の記事を参考に`wasm-pack build --target web`でpkgディレクトリにwasmファイルができたところまで確認する。

https://qiita.com/jp_ibis/items/3205b4799cb567f8ebf5

ここで生成されたpkgディレクトリに適当なJSONファイルを置く。

```json:monster.json
{
    "monsters":[
        {"name":"ピカチュウ","value":10},
        {"name":"イーブイ","value":8}
    ]
}
```

参考記事のlib.rsを、こんな感じに書き換えて、`into_serde()`でMonsters型に取り込み、最もvalueが大きいモンスターの値をMonster型で出力する。

```rust:lib.rs
use wasm_bindgen::prelude::*;
use serde::{Serialize, Deserialize};

#[derive(Serialize, Deserialize)]
pub struct Monster {
    name: String,
    value: usize
}

impl Monster{    
    fn new() -> Self {
        Monster {name: String::new(), value: 0} // 名前のない怪物を生成
    }
    pub fn set_monster(&mut self, name: String, value: usize){
        self.name = name;
        self.value = value;
    }
}

#[derive(Serialize, Deserialize)]
pub struct Monsters {
    monsters: Vec<Monster>
}

#[wasm_bindgen]
pub fn return_max_monster(val: &JsValue) -> JsValue {
    let monsters: Monsters = val.into_serde().unwrap();
    let mut max_monster = Monster::new();
    for monster in monsters.monsters {
        if monster.value > max_monster.value {
            max_monster.set_monster(monster.name,monster.value);
        }
    }
    JsValue::from_serde(&max_monster).unwrap()
}
```

続けてVueでwasmとの入出力を書く。htmlではボタンのみ用意する。

```html:index.html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>hello-wasm example</title>
  </head>
  <body>
    <div id="app">
      <input v-on:click="returnMaxMonster" type="button" value="Max">
    </div>
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
    <script src="https://unpkg.com/axios/dist/axios.min.js"></script>
    <script src="monster.js" type="module"></script>
</body>
</html>
```

monster.jsで`(プロジェクト名).js`をimportする。（自分の場合は`cargo new --lib wasm`でプロジェクトを作ったので、`wasm-pack build --target web`でpkgディレクトリにwasm.jsが生成されている）

async/awaitでwasmのモジュールを初期化してからnew Vue()して、lib.rsで書いたreturn_max_monster()を呼び出す。

```js:monster.js
import * as mod from "./wasm.js";
(async () => {
    await mod.default();
    var app = new Vue({
      el: '#app',
      data: {
        monsters: null,
      },
      mounted: function(){
        axios.get("./monster.json").then(
            response => ( this.monsters = response.data )
        );
      },
      methods:{
        returnMaxMonster: function(){
          let s = mod.return_max_monster(this.monsters);
          alert(s.name);
        }
      }
    })
})();
```

ここまで書けたら、サーバを立ち上げて画面上のボタンをクリックしたらJSONがwasmで処理され、最も値が大きいモンスターの名前が表示される。

<img width="907" alt="スクリーンショット 2020-08-10 12.06.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/33389/23e90dcb-0255-af00-162e-a72a66a57bf9.png">

この仕組みを使って、ドラクエウォークのモンスターの最適な組み合わせを計算するサイトを作ったので、参考にしていただきたい。

https://github.com/usop4/dqw-wasm/
#備忘録　サーバーの基本知識②

#Linux
コンピュータ用のOS(オペレーティングシステム)の一種。
OSとは、operating systemの略で、コンピュータ全体を管理している基本的なプログラムのこと。

##Linuxの特徴
・オープンソースであり、誰でも無償で利用できる。
・品質の高い多くのソフトウェアが利用できる。
・世界中でサーバ用途として広く利用されているため信頼性が高い。
・操作を自動化するための仕組みが用意されており、サーバの運用が行いやすい。

→サーバー向けによく利用されている。

#ディストリビューション
OSの中核である「カーネル」とその周辺のソフトウェアの組み合わせ
LinuxにはCentOSやUbuntuと呼ばれるディストリビューションの種類がある

###CentOS
###Ubuntu

##パッケージ・マネージャ
・iOSの「App Store」のようなもの
・Mac OSではbrewを利用することが多い
・CentOSやAmazon Linuxではyumというコマンドを利用する

#基本的なLinuxコマンド
###ls
listの略

###ディレクトリ
コンピュータ上で複数のファイルを整理するためのファイルのこと


####カレントディレクトリ(.)
####親ディレクトリ(..)
####ホームディレクトリ(~)
####ルートディレクトリ(/)
####mkdir
Linuxで新規にディレクトリ(フォルダ)を作成するコマンド

#ファイル操作に関わるコマンド
##cp
copyの略
```terminal
% cp [コピー元] [コピー先]
```

##mv
```terminal
ファイルの移動
mv [移動させたいもの] [移動先]

名前変更
mv [元のファイル名][新しいファイル名]
```

##touch
```terminal
# 新規のファイルを作成する・アクセス時刻と更新時刻を現在の時刻に変更
touch [ファイル名]

#  sampleファイルのアクセス時刻や最終更新日時を2019年10月1日15:00に変更
touch -t 201910011500 sample
```
##cat
```terminal
# ファイルの閲覧
cat [ファイル名]

# ファイルの結合
cat [ファイル1] [ファイル2]
```

##tail
ファイルの終わり部分を表示するコマンド。 オプションをつけずに実行すると終わりから10行表示される。

```terminal
% tail -f error.log
```

#vi
CentOSやAmazon Linuxに標準で装備されているテキストエディタ
Blenderメモ GとGGの違い


##Gで移動とGGで移動の違い

- Gで移動
スタート位置と同じ大きさで移動する（サイズが一定）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592705/47142ff9-059b-a3b1-fd0d-7fa974a3f9df.png)

- GGで移動
メッシュに沿って移動する（サイズが可変）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592705/0b540b84-30ce-b556-bc16-a6a733d32cbc.png)
NoMethodError: undefined method `web_console'

#現象
railstutorial2章、Microposts作成時
herokuにpushしようとしたところ(git push heroku master)エラーが発生した。

【エラー内容】
**To ssh://heroku.com/pure-shelf-xxxxx.git
 ! [remote rejected] master -> master (pre-receive hook declined)
error: failed to push some refs to 'ssh://git@heroku.com/pure-shelf-xxxxx.git'**

ログを見ると下記のエラーが発生していた。
NoMethodError: undefined method `web_console'

#原因
このエラーは、Gemパッケージweb_consoleに関する設定を config/application.rb ファイルや config/initializers ディレクトリ内のファイルなどに記述すると発生します。

→ config.web_console.whitelisted_ips = ''
どこかでwebconsoleの設定をしてしまっていた

#解決方法
config/application.rbから
config.web_console.whitelisted_ips = ''
の記述を削除

#結果
git push heroku master再実行→pushが成功した

#参考
https://www.oiax.jp/books/rails4book/undefined_method_web_console.html
ITサービスマネジメントにおける問題管理プロセス

平成31年春期 午前問題54

ITサービスマネジメントにおける問題管理プロセスにおいて実施することはどれか。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/591618/acac7be3-d76e-599f-10ce-76963f8c659f.png)


１、問題管理プロセスは、
インシデントや障害発生の根本原因を突き止め、インシデントの再発防止のための恒久的な解決策を提示することを目的とするプロセスです。
主な活動は以下の通りです。
・インシデントの根本原因と潜在的な予防処置を特定する
・問題解決のための変更要求を提起する
・サービスへの影響を低減又は除去するための処置を特定する
・既知の誤りを記録する


２、インシデント管理プロセス
インシデントの発生後に暫定的にサービスを復旧させ，業務を継続できるようにする。


３、ITサービス継続性管理プロセス
インシデントの発生に備えて，復旧のための設計をする。


４、サービスデスクの役割
インシデントの発生を記録し，関係する部署に状況を連絡する。


参照：
https://www.ap-siken.com/kakomon/27_aki/q57.html