OmniAICreator/Qiita-1.07M huggingface dataset:
js-cookieを使ってリロードしても継続的に同じタブメニューを開く方法

## はじめに
タブメニューを使用したページでは、リロードするとトップのタブに戻ってしまいます...
タブメニュー上で作業をしている場合、少し不便ですよね...

いくつか方法がありますが、今回はjs-cookieを使用して、リロードしても開いていたタブを開くことのできるページを実装していきます:shamrock:


## 開発環境
- Ruby 3.0.0
- Rails 6.1.3
- bootstrap 4.6.0
- js-cookie 2.2.1

## 準備
### railsアプリケーションの作成
本記事ではRails6を使用していきますので、Rails6のアプリケーションをご準備ください！

### bootstrapのインストール
rails6でのパッケージインストール方法はrails5と異なるため注意が必要です。
こちらの記事が非常にわかりやすいため、参考にされるとよろしいかと思います。
[Rails 6にjQueryとBootstrapを入れる](https://qiita.com/kazutosato/items/d47b7705ee545de4cb1a)


### js-cookieのインストール
js-cookieの記事はあまり多くなく、新タイプと旧タイプ両方の記事が混在しているため、間違えないように注意しましょう！
まずは[js-cookie](https://github.com/js-cookie/js-cookie)のパッケージをインストールします。

```terminal:terminal
$ yarn add js-cookie
```

package.jsonに追加されていれば完了です。

```package.json
"js-cookie": "^2.2.1"
```

## タブメニューの作成
bootstrapを使用してタブメニューを作成していきます。
[公式ドキュメント](https://getbootstrap.jp/docs/4.2/components/navs/#javascript-behavior)を参考にします。

```erb:hoge.html.erb
<!-- 選択タブ -->
<ul class="nav nav-tabs">
  <li class="nav-item active">
    <a class="nav-link active" data-toggle="tab" href="#home">Home</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" data-toggle="tab" href="#profile">Profile</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" data-toggle="tab" href="#messages">Messages</a>
  </li>
  <li class="nav-item">
    <a class="nav-link" data-toggle="tab" href="#settings">Settings</a>
  </li>
</ul>

<!-- 表示させるコンテンツ -->
<div class="tab-content">
  <div class="tab-pane active" id="home">...</div>
  <div class="tab-pane" id="profile">...</div>
  <div class="tab-pane" id="messages">...</div>
  <div class="tab-pane" id="settings">...</div>
</div>
```
ここまでくるとタブメニューの実装ができたかと思います！

## js-cookieの設定
次にjs-cookieの設定を行っていきます。

```js:app/javascript/packs/application.js
window.Cookies = require("js-cookie")

$(document).on('turbolinks:load', function() {
  $(function() {

    $('a[data-toggle="tab"]').on('show.bs.tab', function (e) {
      var tabName = e.target.href;
      var items = tabName.split("#");
      Cookies.set("openTag",items[1], { expires: 1/24 });
    });

    if(Cookies.get("openTag")){
      $('a[data-toggle="tab"]').parent().removeClass('active');
      $('a[href="#' + Cookies.get("openTag") +'"]').click();
    }
  });
});
```

- ```window.Cookies = require("js-cookie")```でviewファイルでjs-cookieを使用できるようにしています。

- ```$('a[data-toggle="tab"]').on('show.bs.tab', function (e) { ...``` では**選択タブを押したときの動作**を示しています。
開いているタブの href を参照し、# を分離します。そして```Cookies.set("openTag",items[1], { expires: 1/24 })```でopenTagに先ほど分離した値をvalueとしてcookieをセットします。
```expires:```ではcookieの持続時間を設定できます！単位は"日"なので1/24では1時間ということになります。

- ```if(Cookies.get("openTag")){...``` では**openTagにcookieが存在するときの動作**を示します。
一度 liタグ につけられた active をすべて外します。そののちに、格納されていたopenTagのcookieを参照してclickイベントを発生させ、元々開いていたタブを開きます。


このように設定することで、リロードをした際にも、保存されたcookieを参照し、開いていたもとのタブメニューを自動で開くことができます！


## 留意点
js-cookieは大幅アップデートにより、旧タイプと新タイプそれぞれのgithubが存在しています。同様にしてネットの記事でもそれらが混在しております。旧タイプではcookieを参照する際に

```js
$.cookie("")
```
としますが、これを新タイプで記述をすると、```$.cookie is not a function```と怒られてしまうので注意が必要です。
くれぐれもお気を付けください！
【Go言語】型アサーション vs リフレクション シンプルなベンチマーク


# はじめに

Goでのリフレクションはパフォーマンスに影響するので注意と耳にするがどんなものかベンチマークを取る。

# 今回のサンプルケース

型として`interface{}`な実態が`[]string`な値を引数に`[]string`を返す関数。

リフレクションを使う場合と型アサーションを使う場合でベンチマークを取ってみた。

```go:vs_test.go
package main

import (
	"reflect"
	"strconv"
	"testing"
)

var input []interface{}

func init() {
	for i := 1; i <= 10000; i++ {
		input = append(input, strconv.Itoa(i))
	}
}

// リフレクションを使う関数 は`interface{}`型で受け取りリフレクションをするので
// 柔軟に引数の値をさばくことができる。
func リフレクションを使う関数(target interface{}) []string {
	if target == nil {
		return nil
	}

	v := reflect.ValueOf(target)

	switch v.Kind() {
	case reflect.Slice:
		ret := make([]string, v.Len())
		for i := 0; i < v.Len(); i++ {
			x := v.Index(i)
			k := x.Kind()
			if k == reflect.Interface || k == reflect.String {
				s, ok := x.Interface().(string)
				if ok {
					ret[i] = s
				}
			}
		}
		return ret
	case reflect.String: // stringが引数の場合はそれをスライスにして返す。
		return []string{v.String()}
	default:
		return nil
	}
}

// 型アサーションを使う関数 はスライスであることを決め打ちしたうえで`[]string`
// に変換して返す関数である。
func 型アサーションを使う関数(target []interface{}) []string {
	ret := make([]string, len(target))
	for i, r := range target {
		s, ok := r.(string)
		if ok {
			ret[i] = s
		}
	}
	return ret
}

func Benchmark_リフレクション(b *testing.B) {
	var target interface{}
	target = input
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		リフレクションを使う関数(target)
	}
}

func Benchmark_型アサーション(b *testing.B) {
	var target interface{}
	target = input
	b.ResetTimer()
	for i := 0; i < b.N; i++ {
		型アサーションを使う関数(target.([]interface{}))
	}
}
```

# 結果

速度において型アサーションがリフレクションよりも3倍強速かった。メモリ利用は差は無し。

この3倍をどう捉えるかはシステム要件次第であるが選択肢に入れられないほどパフォーマンスが悪いわけではない。

```
$ go test -bench . -benchmem
goos: darwin
goarch: amd64
Benchmark_リフレクション-4                          6013            204633 ns/op          163840 B/op          1 allocs/op
Benchmark_型アサーション-4                         18973             61017 ns/op          163842 B/op          1 allocs/op
PASS
ok      go-comparison/typeassert_vs_reflection        4.431s
```

# 感想

テストの関数に日本語を使うのは違和感が無いが、アプリケーションコードの関数を日本語にするのは変に感じる。
毎回 git commit -m "" と打つのが億劫なので、シェル関数でショートカットを作成した

# ~/.zshrcに、1行追加するだけ。

``` ~/.zshrc
function gm() { git commit -m "$*" }
```

以上。

## 使用方法
追加/反映してくれるコマンドをターミナルに打ち込む。

```zsh
echo 'function gm() { git commit -m "$*" }' >> ~/.zshrc
source ~/.zshrc
(Gitリポジトリに移動、適宜編集、git addする。)
gm feat: commit msg
```

## 追加情報

### 公式ドキュメント/参考文献
http://zsh.sourceforge.net/Intro/intro_4.html
https://linuxjm.osdn.jp/html/GNU_bash/man1/bash.1.html

### 実行環境
MacBook Air (M1, 2020) 11.2.2（20D80)
zsh 5.8 (x86_64-apple-darwin20.0)

### その他
1. 誤り/提案等がありましたら、ぜひコメント等頂けますと嬉しいです。
2. `gm` 部分は関数名=呼び出す際に打つコマンドとなりますので、お好みでご変更ください。
【Rails】モデルのアソシエーションの書き方

# 環境
macOS: Big Sur Ver11.2.2
Rails: 6.0.0
Ruby: 2.6.5

# 困ったこと
モデルを作成したときにモデル名をアッパーキャメルケースで記述したとき、アソシエーションを書くときはどういう形式（アッパーキャメル？、キャメルケース？、スネークケース？）で書くのか迷いが生じた。
実際、書き方が違うだけでエラーが出て２時間も解決に時間を要したことから注意したいところ。

#実例
作成したモデルは以下の通り。
Acitive Hashのクラスも含んでます。

```ruby
class OrderDetail < ApplicationRecord
  belongs_to :order

  extend ActiveHash::Associations::ActiveRecordExtensions
  belongs_to :prefecture
  belongs_to :visit_time
  belongs_to :visit_day

  # バリデーションはフォームオブジェクトクラスに記述
end
```

```ruby
class VisitDay < ActiveHash::Base
  self.data = [
    { id: 0, name: '--' },
    { id: 1, name: '本日' },
    { id: 2, name: '明日' },
    { id: 3, name: 'あさって' }
  ]

  include ActiveHash::Associations
  has_many :order_details
end
```

```ruby
class VisitTime < ActiveHash::Base
  self.data = [
    { id: 0, name: '--' },
    { id: 1, name: '7時〜8時' },
    { id: 2, name: '8時〜9時' },
    { id: 3, name: '9時〜10時' },
    { id: 4, name: '10時〜11時' },
    { id: 5, name: '11時〜12時' },
    { id: 6, name: '13時〜14時' },
    { id: 7, name: '14時〜15時' },
    { id: 8, name: '15時〜16時' },
    { id: 9, name: '16時〜17時' },
    { id: 10, name: '17時〜18時' },
    { id: 11, name: '18時〜19時' },
    { id: 12, name: '19時〜20時' },
    { id: 13, name: '20時〜21時' }
  ]

  include ActiveHash::Associations
  has_many :order_details
end
```

見ていただければ分かる通り、３つのモデル（クラス）は全てアッパーキャメルケースで定義しています。
こういう場合、アソシエーションでモデル名を記述するときは**スネークケース**で記述すること！
初心者の自分はアソシエーションを書くときになんとなくキャメルケースで書いてしまい、それがエラーの原因となっていました。

皆様はどうぞお気をつけください。
Chrome OS，code-serverでカスタムフォントを使う

https://qiita.com/BonyChops/items/8e40b377e14b04cd5a9d

↑Chromebookでcode-serverをセットアップするにはこちら

この記事では，フォントをインストールできないChrome OSを使っている皆様でも，カスタムフォントを使用する方法を紹介します．デベロッパーモード等は使用しません．CrostiniのみでOKです．

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">ゴリ押しで埋め込めたwwww<br>うれしい <a href="https://t.co/jYSsI7eLBg">https://t.co/jYSsI7eLBg</a> <a href="https://t.co/k4Hwz4e2TU">pic.twitter.com/k4Hwz4e2TU</a></p>&mdash; Bony_Chops (@BonyChops) <a href="https://twitter.com/BonyChops/status/1368929577792249858?ref_src=twsrc%5Etfw">March 8, 2021</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/6edf650e-120f-e5f1-38fd-8faac088fdbc.png)

↓

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/175d3ebf-bcbe-0aff-4725-4727603add20.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/50c1deb1-d651-b59b-45bf-c69f4bdb41e9.png)

# やってみる
やってみよう

## フォントを落とす
好きなフォントを落としてください．今回は`powerline`．

```shell
$ git clone https://github.com/powerline/fonts.git
```

## フォントをコピー
`code-server`のホスト用ディレクトリに移動し，そこへコピーします．

```shell
$ cd /usr/lib/code-server/src/browser/media
$ sudo cp /path/to/file.otf ./ 
```

## `vscode.html`編集
編集する準備をします

```shell
$ cd ../pages # /usr/lib/code-server/src/browser/pages
$ sudo cp vscode.html vscode.html.old
```

`<head>`タグ内に`<style>`タグを作成し，以下のようにしてください．

```vscode.html
...
<head>
...
    <style>
        @font-face {
           font-family: "任意のフォントファミリー名";
           src: url("{{CS_STATIC_BASE}}/src/browser/media/file.otf");
        }
    </style>
</head>
...
```

## `code-server`のページリロード / 設定
ページをリロードし，`Ctrl` + `,`で設定を開く．`editor.fontfamily`(ターミナルであれば`terminal.fontfamily`)と検索窓に入れ，先程の`任意のフォントファミリー名`を追加する

以下は`firacode`の場合

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/14278f24-06e7-0f38-2a1e-12af5f13cc10.png)

入力窓からフォーカスを外すと瞬時に反映される．されれば成功．やったね．

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/601799/3594e9cf-0a77-50f3-e131-52ed39d3381e.png)
活躍の場面が多そうなhoverイベント

#はじめに
マウスカーソルを合わせた時に動作するwebページをよく見かけるので、調べてまとめます。

##hoverのイベント

```javascript
$('セレクタ').hover(マウスカーソルを合わせた時の処理,マウスカーソルを離した時の処理);
```

```javascript
$('セレクタ').hover(
  function(){
    //マウスカーソルを合わせた時の処理
  },
  function(){
    //マウスカーソルを離した時の処理
  }
);
```

`hover`の引数に２つの処理を記述します。
第一引数にマウスカーソルを合わせた時の処理、
第二引数にマウスカーソルを離した時の処理。
一つのイベントに2つの処理を記述することができる点が、意外でした。

コードが長くなっても、「どこを、どうする」の基本は変わらないことを意識して記述していくことが大切だと感じました。
Gem::Exception: can't find executable cap for gem capistrano. capistrano is not currently included in the bundle, perhaps you meant to add it to your Gemfile?

## 背景
bundle exec cap install
で怒られる

## 原因
・.bundle/configでproductionがwithoutになっていた
・bundle installが出来ていなかった
・なのに、bundle exec cap installを実行しようとしていたから

## 解決策
```
Group production do
end
```
を除外。

[転職に関して](https://encarisan.com/)たまに発信しています。
featureブランチ命名


featureブランチはスラッシュで区切ることができるため、ここに複数の情報を入れます。
具体的には

feature/201902/yousan/fix-admin-panel
といった形で作成しています。
feature/(yearmonth)/(username)/content
となっています。
その理由について述べます。

年月を入れる
featureの下に年月を入れています。
これはSourceTreeを使った場合のグルーピングやブランチ名でソートした場合、時間順でグルーピング、ソートすることができるからです。
開発が長くなってくるとブランチの数がそれなりに増えてきます。だいたい100個を超えたあたりから探すことが大変になってきます。
そこでこのようにスラッシュで区切ることで見通しを良くします。

image.png

GitHubのブランチはGitHub上で削除することができますが、Gitの実際の削除ではなく、GitHub上のソフトデリートです。
そのためGitコマンドなどで確認すると生きているブランチとして見えるため、「ちょっとこのブランチをチェックアウトして確認してほしい」とレビュー依頼を出す際など、探すことが困難になります。
こうしてグルーピングしておけば、少なくとも最新の月で絞り込めるため便利です。

Deleting and restoring branches in a pull request - GitHub Help


ユーザ名を入れる
ブランチ名にユーザ名（GitHubやSlackのユーザ名と揃えています）を入れます。
こちらも上記の理由と同じく、見通しを良くするということがあります。
またその他にもブランチの持ち主を特定するために入れています。「このブランチって使われてないけど、消して良いのかな…。誰に聞けば良いんだ…」ということを防ぐことが出来ます。

またプルリクエストと同様に責任者を明らかにする、ということがあります。
「このブランチは俺のブランチだから、テストが通らなければ俺が直す責任がある」ということで、責任の所在をはっきりさせることができます。
配列・オブジュエクトの変更をリアクティブに検出するには

数字や文字列などは簡単に検出できるが、配列・オブジェクトは一工夫必要

##TL;DR
`Vue.set()` を利用して変更させる

## やってみる
### 直接変更させた場合

```vue
<template>
  <div class="center">
    <div class="row">
      <div v-if="bool">ON</div>
      <div v-else>OFF</div>
      <button @click="bool = !bool">真偽値</button>
    </div>
    <div class="row">
      <div v-if="array[0]">ON</div>
      <div v-else>OFF</div>
      <button @click="array[0] = !array[0]">配列</button>
    </div>
  </div>
</template>

<script>
export default {
  layout: 'plain',
  data() {
    return {
      array: [false],
      bool: false
    }
  }
}
</script>

<style>
.center {
  width: 100px;
  margin: 0 auto;
}

.row {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
}
</style>
```

![sample1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510945/ae6b7ad3-b932-e6e9-a5e6-ab6c592645d3.gif)



単体のboolは値の変更に合わせて表示も切り替わるが、配列はそうもいかない（配列の値自体は変わっている）


### 配列の値をVue.set()で変更させる
中身を直接変更するのではなく、 `Vue.set(Array, index, value)` を利用してみる。
ここの例では、エイリアスである `this.$set()` にしています。

詳しいドキュメントは[こちら](https://jp.vuejs.org/v2/api/index.html#Vue-set)。

```vue
<template>
  <div class="center">
    <div class="row">
      <div v-if="bool">ON</div>
      <div v-else>OFF</div>
      <button @click="bool = !bool">真偽値</button>
    </div>
    <div class="row">
      <div v-if="array[0]">ON</div>
      <div v-else>OFF</div>
      <!-- 配列の値の変更の仕方を変える -->
      <button @click="changeValue()">配列</button>
    </div>
  </div>
</template>

<script>
export default {
  layout: 'plain',
  data() {
    return {
      array: [false],
      bool: false
    }
  },
  methods: {
    changeValue() {
      this.$set(this.array, 0, !this.array[0])
    }
  }
}
</script>

<style>
/* 省略 */
</style>
```

![sample2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/510945/753b956e-f878-9b72-4f00-3ef90c766625.gif)

いいかんじ！


## まとめ
Vueでは配列の中身や長さ、オブジェクトのプロパティの追加や削除の検出ができないため、それを可能にするためにVue側でメソッドが用意されていたんですね。

意外とこれに気づかずに実装を進めて、後々になって「何でここだけ動いてないん...?」となったのは自分の他にもいるんじゃないでしょうか...


## 備考
https://jp.vuejs.org/v2/guide/reactivity.html#%E5%A4%89%E6%9B%B4%E6%A4%9C%E5%87%BA%E3%81%AE%E6%B3%A8%E6%84%8F%E4%BA%8B%E9%A0%85
AWS MediaServicesの具体的なサービスとユースケース

# インターネットを介したストリーミングビデオ
現在主流のビデオは下記の2つのモードでストリーミングされます。

## リアルタイムライブストリーミング
リアルタイムライブストリーミングとは、ライブイベントの放送、もしくは事前に記録されたファイルの組み合わせである可能性がありますが、**開始時間**と**停止時間**が定義されています。

## ビデオオンデマンド（VOD）ストリーミング
ビデオオンデマンド（VOD）ストリーミングとは、いつでも視聴できる事前に記録されたファイルです。

# 共通するビデオワークフロー
* ビデオワークフローにはさまざまなバリエーションがありますが、ライブ、オンデマンド、どちらであってもほとんどすべてに共通する4つの基本的な段階があります。
それが下記の、INGEST、PROCESS、STORE、DELIVERです。

![図1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/9d7eddbc-8492-f4cb-6b71-c60771d80022.png)


## INGEST
INGESTとは、ソースコンテンツをシステムに取り込む段階です。
ソースコンテンツとは、例えば下記のようなものです。

* ライブカメラ出力
* 他のプロバイダーからのビデオストリーム
* 録音済みファイル
* ユーザー生成コンテンツ（電話、タブレット）
* ウェブカメラ

## PROCESS
コンテンツを操作または変換して利用可能にする段階です。
コンテンツを操作または変換とは、例えば下記のようなものです。

* 圧縮-帯域幅とファイルサイズの削減
* パッケージング-さまざまなプレーヤーデバイスのフォーマット
* 暗号化–アクセスの制限
* 収益化–広告挿入

## STORE
視聴者のリクエストに先立ってコンテンツを保存またはキャッシュする段階です。
例えば、下記のようなものです。

* 「巻き戻し」のためのライブストリームの一時的なキャッシュ
* ビデオオンデマンドの長期
* 長期アーカイブ

## DELIVER
多くの同時視聴者にコンテンツを配信する段階です。

# AWSのサービスが4つの段階でどのように使用されるか
![図2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/b6e2f4ca-d008-0895-2ddd-da3530422607.png)

## 各AWSサービスの概要
### AWS Elemental Live
高解像度の高帯域幅のソースコンテンツをより小さなバージョンに圧縮します。

### AWS Elemental Link
カメラや動画制作機器などのライブ動画ソースを直接取得し、AWSのMediaLiveに送信します。

### AWS Elemental MediaConnect
ライブビデオをAWSに取り込み、AWSグローバルネットワークを通じて安全に複数の送信先に送信できる新しいサービスです。

### AWS Elemental MediaLive
複数のライブストリームを低解像度、低帯域幅バージョンへの圧縮をします。
これにより、ブロードキャストおよびストリーミング配信用のライブ出力を簡単に作成できます。

### AWS Elemental MediaConvert
複数のビデオファイルを低解像度、低帯域幅バージョンへの圧縮します。

### AWS Elemental MediaPackage
接続されたTV、PC、タブレット、およびモバイルデバイスで再生するためにビデオストリームをフォーマットします。
**また、暗号化によってコンテンツを保護します。**

### AWS Elemental MediaStore
ビデオ、オーディオメディア用に最適化された高性能、低遅延のストレージサービスです。

### AWS Elemental MediaTailor
ターゲットを絞った広告をビデオストリームにシームレスに挿入します。

# ユースケース
## ライブのユースケース
![スクリーンショット 2021-03-08 23.17.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/060ac400-9364-d7a2-0d83-02ec13b41f61.png)
[引用元: Basic Live Example](https://www.aws.training/Details/eLearning?id=66648)

## VODのユースケース
![スクリーンショット 2021-03-08 23.17.57.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/457c1368-f8b2-0cad-4a7b-559832b48276.png)
[引用元: Basic VOD Example](https://www.aws.training/Details/eLearning?id=66648)

## 不正アクセスからコンテンツを保護するには？
* 一部のコンテンツは、自由に利用できるようになっています。
* 他のコンテンツへのアクセスは、収益または機密保持の理由で制限する必要がある場合があります。
=> DRMと呼ばれているやつ。

**DRMについては、AWS ElementalMediaPackageを使用して実装できます。**
![スクリーンショット 2021-03-08 23.23.01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/563635/326cc3f3-e434-242a-8ccf-417e25085d10.png)
[引用元: Protect Your Content from Unauthorized Access](https://www.aws.training/Details/eLearning?id=66648)

# 参考文献
* [Introduction to AWS Media Services by Use Case](https://www.aws.training/Details/eLearning?id=66648)
サーバーとは何かを理解する

Webアプリが完成したら、サーバーを利用して公開する必要があります。その前にそもそもサーバーとは何か、どのような種類があるのかまとめたいと思います。

#サーバーとは
サーバー(Server)は文字通り「提供する側」を意味し、利用者のリクエストに応じて、データやファイルなどの情報を取り出したり送り返したり、あるいはデータの保管・整理をするコンピュータやプログラムのことです。物理的に存在するものや、実体のないものがあることは頭に入れておきましょう！

#サーバーの種類
コンピュータとしてのサーバーは大きく分けて物理サーバーと仮想サーバーの2種類があります。利用する際は目的や予算に応じて最適なものを選ぶ必要があります。

###物理サーバー
物理サーバーは、物理的に存在する1台のサーバーのことです。
物理サーバーにはさらに「共用サーバー」と「専用サーバー」の2種類に分けられます。

共有サーバーは、1台のサーバーを複数人が共有するものでもので、「さくらサーバー」、「XSERVER」などがこれにあたります。
専用サーバーは、1台のサーバーを一人が占有するもので、排他的な運用が可能です。

###仮想サーバー
仮想サーバーは、1台の物理サーバー上で複数台のOSを動かすことで、“複数のサーバーと見なして”稼働させる仕組みのことです。
仮想サーバーはさらに「VPS」と「クラウドサーバー」の2種類に分けられます。

VSP(Virtual Private Server)は、「仮想専用サーバー」とも呼ばれ、サーバー上に仮想的に利用者向けの環境を構築して提供するもので、ネットワークなど共用で利用するものはあるものの、CPUやメモリなどは個別に割り振られることから共用サーバーに比べてハイパフォーマンスが期待できます。料金は求めるパフォーマンスに応じて課金されます。

クラウドサーバーは、特定のサーバーではなく、サーバーの機能が複数台に分散されており、必要な分のCPUやメモリを自由に設定することができます。料金は利用時間に応じて課金されます。

これまでの4種類のサーバーは、コンピュータとしてのサーバーです。それに対して用途に応じてさまざまな機能の提供を実現するのが、以下のソフトウエアとしてのサーバーです。

###Webサーバー
Web上において、利用者のWebブラウザ（Chrome、Safariなど）からのリクエストに応じてデータを返してあげるサーバーであり、HTTPを中心としたHTMLファイルなどを取り扱います。
Railsアプリの開発中に何度も打ち込むであろう

```
rails s
```

のコマンドで立ち上がるPumaもこれにあたります(このサーバ自体は、開発用のPC上に作られたものです。外部に公開しているわけではないので、他のPCからブラウザ経由でアプリケーションにアクセスすることはできません)。

###FTPサーバー
FTPとは「File Transfer Protocol」の頭文字で、ファイル転送プロトコルとも呼ばれています。FTPサーバーは、Webサーバーとのファイルの送受信を行なうサーバーです。

リクエストがあったときだけにファイルを送信するWebサーバーとは異なり、FTPサーバーは、利用者がコンピュータからサーバーにデータをアップロードしたり、サーバーからデータをダウンロードしたりすることができます。

###メールサーバー
メールサーバーは、メールの送受信サービスを提供するサーバーです。送信と受信はそれぞれ別のサーバーになっており、送信側をSMTPサーバー、受信側をIMAPやPOP3サーバーといいます。

###ファイルサーバー
ファイルサーバーとは、ネットワーク上でデータを共有・使用するためのサーバーです。
ファイルサーバー機能を利用すると、複数のサーバーおよび WindowsやMacなどさまざまなOSのクライアントPC間でのデータ共有をスムーズに行うことができます。

###データベースサーバー
データベースサーバーは、顧客情報などのデータを必要に応じて保存、上書き、抽出するためのサーバーであり、データの取り出しにはSQL（MySQLやPostgreSQLなど）を利用して抽出します。

###DNSサーバー
DNS（Domain Name System）サービスを提供するサーバーであり、利用者のリクエストに応じてインターネット上でアクセスする名前を解決してくれるサーバーになります。

###アプリケーションサーバー
アプリケーションサーバーは、利用者からのリクエストに応じて、Javaやphpなどのプログラムを実行して必要なデータを取り出す、特定の条件に応じた結果をWebサーバーに戻す役割を持っています。

#終わりに
サーバーといえば、データセンターの中で何台も置かれた黒い大きな箱というイメージがありましたが、それ以外にもさまざまな種類のサーバーがあることがわかりました。これらのサーバーの働きや連携によって快適なWebが利用できることを覚えておきましょう！

#参考
[サーバーとは？種類や用途について簡単に解説](https://www.rworks.jp/system/system-column/sys-entry/16259/)
[サーバーとは丨種類や役割を詳しく解説](https://www.tramsystem.jp/voice/voice-2369/)
[【Rails】rails serverコマンド(rails s)の使い方まとめ](https://pikawaka.com/rails/rails-s)
[Electron, Vue.js] IpcRenderer.on()でthis.countに代入しようとしたら失敗した

# 動機
ElectronのipcRenderer.on()内でthis.countに受け取った値を代入したかったのにうまく行かなかったので
解決はしたが原因がわかりません…

# 目次
うまくいかない例

```
  mounted() {
    ipcRenderer.on("setCount", (_, arg) => {
      this.count = arg;
    });
  },
```

# うまくいく例
なかなかグロテスクなコードになりました…
thisをコールバックの外に出してみたら何故かうまく行った

```
  async mounted() {
    this.count = await ((): Promise<string> =>
      new Promise((resolve) => {
        ipcRenderer.on("setCount", (_, arg) => {
          resolve(arg);
        });
      }))();
  },
```

関数を分けるなら

```
  methods: {
    async waitIpcMessage(): Promise<string> {
      return new Promise((resolve) => {
        ipcRenderer.on("setCount", (_, arg) => {
          resolve(arg);
        });
      });
    }
  },
  async mounted() {
    this.count = await this.waitIpcMessage();
  }
```

# 最後に
なぜこれならうまくいくのか知っている方は教えてください...
thisが外に出てるからうまくいくっぽい？よくわかりません

話は逸れますが非同期周りの書き方ってかなり複雑ですよね
Vue.js始めました。

＊学習初日の個人的なアウトプット用です。

Vue.jsとは、UIを構築するためのプログレッシブフレームワークであり、モダンなツールやサポートライブラリと組み合わせることで、洗練されたSPAを開発することもできる。

大きな特徴の一つとして、**双方向データバインディング**ができるという点が挙げられる。
データバインディングとは data と UI を結び付けるという意味で、双方向というのは data を更新すれば UI が更新されて、 UI を更新すれば data が更新されるという意味である。

入門のためここでは名前と簡単なリストを表示させる。

```index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>Vue practice</title>
  <link rel="stylesheet" href="css/styles.css">
</head>
<body>
  <div id="app">
　　<!--二重波括弧 {{}} で表現し UI を反映させる。そのままJavaScriptの式を書くこともできる。 -->
    <p>Hello {{ name.toUpperCase() }}!</p>

　　<!-- v-model を使うことで input タグに入力された文字を上の表示にリアルタイムで反映できる。-->
    <p><input type="text" v-model="name"></p>

    <h1>My Lists</h1>
    <ul>
      <li>{{ lists[0] }}</li>
      <li>{{ lists[1] }}</li>
      <li>{{ lists[2] }}</li>

      <!-- 上のリストは v-for を使って配列の中身を取り出すことが可能 -->
      <li v-for="list in lists">{{ list }}</li>
    </ul>
  </div>

　<!-- Vue.jsを読み込む -->
  <script src="https://cdn.jsdelivr.net/npm/vue"></script>

  <script src="js/main.js"></script>
</body>
</html>
```

- v-for や v-model など v- から始まる特殊な属性をディレクティブと呼ぶ。

```js/main.js
(function() {
  'use strict';

  // vm は view model の略
  var vm = new Vue({
    el: '#app', // el は elements の略
    data: {
      name: 'tanaka',
      lists: [
        'list 1',
        'list 2',
        'list 3'
      ]
    }
  });
})();
```

ブラウザで確認すると結果以下のような表示になる。

[![Image from Gyazo](https://i.gyazo.com/1553891e4f70e2a68ce99db7f17b625b.png)](https://gyazo.com/1553891e4f70e2a68ce99db7f17b625b)

以上です。
ブラウザにURLを打ち込んでサイトが表示されるまでの仕組み

ブラウザの仕組みって言葉で上手く説明するのが難しいので
調べたことを言葉で書いて、覚えていきたいと思います。


#ブラウザの仕組み

初めに、`DNSサーバー`にアクセスし、Webサイトの`IPアドレス`を特定します。
次に、そのIPアドレスを持つサーバーに対して`httpリクエスト`を送信します。
サーバーがそのhttpリクエストを元にクライアントの要求を承認すると、サーバーはクライアントに"200 OK"というメッセージを返します。
承認が行われるとサーバーからWebサイトの情報が`データパケット`という形で転送されてクライアント側に表示されるという仕組みです。
　


　

約1秒に満たない間にこれらのことが一瞬で行われているコンピューターは凄すぎます。
仕組みは理解しましたが、気になったワードがあったので調べて見ました。


##DNSサーバー
「Domain Name System」の略
ドメインとIPアドレスのを紐付けることができるサーバーのこと。
ちなみに**ドメイン**が住所みたいなもので、**IPアドレス**が通信の相手先を識別する番号のこと。
IPは（Internet Protocol）の略


##データパケット
データ通信において、ネットワーク経由でやりとりされる情報の伝送単位。パケット（packet）は英語で「小包」を意味する
　
　　

なるほど、少しは理解できたかなと思います。
知らないことについてまた調べを進めたいと思います。
Azure Application GatewayでX-Forwarded-For ヘッダーを書き換える

Application GatewayではHTTPヘッダーを書き換えることができます。
デフォルトではX-Forwared-Forヘッダーは **クライアントIPアドレス：ポート番号** となっていますが、ポート番号を表示させずにクライアントIPアドレスのみに書き換えてみました。
手順は既にApplication Gateway構築済みでバックエンドにWebサーバが稼働している状態を前提としています。

# 環境
* Azure Application Gateway Standard v2
* CentOS v8.2
* Apache httpd　v2.4.37

# Webサーバ準備
* httpdをインストールして起動します

```
$ sudo yum install -y httpd
$ sudo systemctl start httpd
```

* X-Forwared-Forログ出力設定をします

```
$ sudo vi /etc/httpd/conf/httpd.conf
[Before]
LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
[After]
LogFormat "%{X-Forwarded-For}i %h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
$ sudo systemctl reload httpd
```

* この状態でApplication Gateway経由でアクセスし、アクセスログを確認してみます

```
$ sudo tail -f /var/log/httpd/access_log
aaa.bbb.ccc.ddd:27107 10.0.0.38 - - [08/Mar/2021:10:42:17 +0000] "GET / HTTP/1.1" ~~省略~~
```

* こんな感じで **クライアントIPアドレス:ポート番号** が表示されます。ここからポート番号を削除したいと思います。

# Application Gateway HTTPヘッダー書き換え
* Azure PortalのApplication Gateway左バーより、[書き換え]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/ada33169-0519-072f-3082-463dffa3bac1.png)

* [書き換えセット]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/99104bdf-7256-c15b-b323-841ec25cfa80.png)

* [書き換えセット名]を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/8774437c-69e4-7fe0-fee6-e55328d31169.png)

* 関連付けるルールを選択し[次へ]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/f210f27d-faa8-69c8-98e1-d148b5164f5f.png)

* [書き換え規則の追加]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/ad8a8c11-b08a-3a02-ee6e-8644b47d664c.png)

* [書き換えルール名]を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/5d204a13-fbc3-cb69-ca1f-f34d8f471689.png)

* [実行]を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/8e1d5baa-24b0-2cbd-d851-406391fc8c1c.png)

* 以下のように入力し、書き換えセットを作成します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/180335/bde980b2-c8a0-680b-d7d3-cb5dc1bdf85b.png)

* 再度アクセスしてポート情報が消えていればOKです。

```
- aaa.bbb.ccc.ddd - - [08/Mar/2021:10:49:12 +0000] "GET / HTTP/1.1" ~~省略~~
```
C言語　printf文 マクロを用いたログ出力方法

printf()などで使用できる便利なマクロメモ


| 項目| マクロ名 |概要|出力指定子|
|:-:|:-:|:-:|:-:|:-:|
| ファイル名  |\_\_FILE\_\_| どのファイルによって出力されたログなのかが特定できる | %s|
|行番号|\_\_LINE\_\_| ファイル内のどこで出力されたログなのかが特定できる | %d|
| 関数名  |\_\_FUNCTION\_\_<br>\_\_func\_\_| どの関数で出力されたログなのかが特定できる  |%s|

↑printf()に使用できるプリプロセッサで標準定義されたマクロ

```C:C
例) printf("%s %d %s", __FILE__, __LINE__, __func__);
```
<br>

出力をマクロ関数化

```C:C
//ログ出力用の関数マクロ定義
//...の内容は__VA_ARGS__(可変個引数)にコピーされる
#define DEBUG_PRINT(...)     printf("%s(%d) %s:", __FILE__, __LINE__, __func__), printf(__VA_ARGS__)
```
↓

```C:C
例)DEBUG_PRITNT("ログ出力結果 %s \n", str);
```
Rを使ってYahoo! Financeから最長過去20年間のヒストリカルデータを取得する

この記事は「[証券のリスクとリターンを計算するアプリケーションを作ろう](https://qiita.com/canopysand/items/743e9aa88d4012d89b84#%E8%A8%AD%E8%A8%88%E6%96%B9%E9%87%9D)」のヒストリカルデータ取得機能の詳細について記したものです。
ヒストリカルデータは[tidyquant v1.0.2](https://www.rdocumentation.org/packages/tidyquant/versions/1.0.2)ライブラリの`tq_get()`関数を使用するので、まずはこの関数の仕様を詳しく見ていきましょう。
#tq_get()関数
[公式ページ](https://www.rdocumentation.org/packages/tidyquant/versions/1.0.2/topics/tq_get)のまんまですが、`tq_get()`関数は定量的データを`Tibble`形式で取得する関数です。
__使用法__

```R:tq_get()
tq_get(x, get = "stock.prices", complete_cases = TRUE, ...)
tq_get_options()
```
必須の引数が`x`で、ここにはヒストリカルデータを取得したい単一の文字列、単一（または複数）の銘柄記号、金属記号、通貨の組み合わせ、FREDコードなどを表す文字ベクトルまたはティッカーを入力します。
第2引数の`get`は任意で入力します。使用法に記載の通り、デフォルトの値は`"stock.prices"`です。
ちなみに、配当のヒストリカルデータを取得するオプションは`"dividends"`ですが、`"stock.prices"`と同時に使うことはできません。一つずつ取ってくる必要がありますね。

さて、この記事の主題である取得期間は、デフォルトで10年前の1月1日から関数を実行した日のようです。
過去20年間のヒストリカルデータを取得するためには、以下の引数を入力する必要があります。

* `from`：YYYY-MM-DD形式で開始日を表す文字列
* `to`：YYYY-MM-DD形式で終了日を表す文字列

`from`には`20年前の年-01-01`を、`to`には`1年前の年-12-31`を入力したいので、動的に年を入力する必要があります。
#年の計算
年の計算には__Dateオブジェクト__と__POSIXltオブジェクト__を使用します。
以下のサイトを参考にしました。

* [日付、時間関数Tips大全 - RjpWiki](http://www.okadajp.org/RWiki/?%E6%97%A5%E4%BB%98%E3%80%81%E6%99%82%E9%96%93%E9%96%A2%E6%95%B0Tips%E5%A4%A7%E5%85%A8)
* [［R］日付型データ（Dateオブジェクト）から年月日などの各要素を数値で抜き出す](http://goldenstate.cocolog-nifty.com/blog/2015/08/rdate-7376.html)

20年前の年は以下のコードで取得します。

```R
> as.POSIXlt(Sys.Date())$year + 1880
[1] 2001
```

同じようにして、1年前の年は以下のコードで取得します。

```R
> as.POSIXlt(Sys.Date())$year + 1899
[1] 2020
```

あとは、`paste()`関数で日付と連結すれば準備完了です。

```R
start_date <- paste(as.POSIXlt(Sys.Date())$year + 1880, "-01-01", sep = "")
end_date <- paste(as.POSIXlt(Sys.Date())$year + 1899, "-12-31", sep = "")
```

#まとめ
ということで、`tq_get()`関数を使って最長過去20年間のヒストリカルデータを取得するコードは以下の通りです。

```R
# パッケージのインストール
install.packages("tidyverse", repos = "http://cran.us.r-project.org", dependencies=TRUE)
install.packages("tidyquant", repos = "http://cran.us.r-project.org", dependencies=TRUE)

# コマンドライン引数の入力
args <- commandArgs(trailingOnly = TRUE)
x <- args[1]

# ライブラリのロード
library(tidyquant)
library(tidyverse)

# ヒストリカルデータを取得
start_date <- paste(as.POSIXlt(Sys.Date())$year + 1880, "-01-01", sep = "")
end_date <- paste(as.POSIXlt(Sys.Date())$year + 1899, "-12-31", sep = "")
tq_get(x, from = start_date, to = end_date)
今さら聞けない、ローカルのリモートブランチを削除する方法

GitHub上でブランチを削除しても、「git fetch」や「git pull」では更新されても、ローカル上のリモートブランチ情報は削除されず、残ったままになります。Git環境を綺麗に保つために必要なコマンドを自己流でまとめました。

## 【準備】まずローカルブランチの確認
```
git branch
```
削除するブランチ名を確認しておきます。
このとき、対象がカレントブランチ(現在のブランチ)になっていると削除ができないので移動をします。

## ブランチの移動
```
git checkout master
```
このとき移動するブランチは何でも良いです。

## ローカルのGit環境でブランチを削除する
```
git branch -d feature/xxxxxx
git branch -D feature/xxxxxx
```
これでローカルのブランチは削除ができます。
もしmergeしていなかった場合は、警告が出るので下の「-D」オプションを付けて強制削除ができます。

## ローカルにあるリモートブランチを確認する
```
git branch -a
```
このコマンド叩くと、リモートに「origin/feature/xxxxxx」がまだ残っていることに気付きます。

## 【本編】ローカルに残ったリモートブランチを削除する
```
git fetch --prune
git pull --prune
```
上記のどちらかのコマンドに「--prune」オプションを付けることでローカルに残ったリモートブランチ情報を削除することができます。

## ローカルのリモートブランチが削除されていることを確認する。
```
git branch -a
```
再度、上記コマンドを叩いてローカルのリモートブランチが削除されていることを確認します。
何故こんなことをするのかというと、開発が進むにつれて過去と同名のブランチ名を付けてしまったり、プレフィックス(接頭辞)が同じブランチを作成しようとした際に、エラーに遭遇することを避けるためです。

## 参考文献
- いちばんやさしいGit&GitHuBの教本(著 横田紋奈、宇賀神みずき)
- GitHub実践入門(著 大塚弘記)
- 独習Git(著 Rick Umali)  

Git&GitHubに関して色々、読んだのですが「--prune」オプションについてはあまり言及されていませんでした。やはり公式のリファレンスを読むことが遠回りに見えて近道だと感じました。
ijenims record 2021.03.08

# Topics

> この3～4日間の学習記録

## 学習記録

- paiza ラーニング：レベルアップ問題集 配列メニュー
- EF過去問
- 統計学の時間
- python - Alien Invasion


## その他

- 学習記録管理アプリとして、「進捗どうですか？」を試用。とりあえず使用感はそんなに悪くない。目標と進捗が見える化される
【Ruby】Base64変換ツール書いてみた

http://vipprog.net/wiki/exercise.html#u8004ae1

ここの問題を解いてみました
#コード

~~~Ruby
module Base64
  TABLE = [*"A".."Z", *"a".."z", *"0".."9", "+", "/"]

  module_function

  def encode(str)
    binary_ary = str.bytes.map do |b|
      t = b.to_s(2)
      t.size == 8 ? t : t.rjust(8, "0")
    end

    binary_str = binary_ary.join

    binary_ary  = binary_str.scan(/\d{6}/)
    binary_ary << binary_str[-(binary_str.size % 6)..].ljust(6, "0") unless binary_str.size % 6 == 0

    binary_ary.map { |x| TABLE[x.to_i(2)] }.join << "=" * (binary_ary.size % 4)
  end

  def decode(base_str)
    binary_ary = base_str.delete("=").chars.map do |s|
      t = TABLE.index(s).to_s(2)
      t.size == 6 ? t : t.rjust(6, "0")
    end

    chr_code_ary = binary_ary.join.scan(/\d{8}/).map { |b| b.to_i(2) }
    chr_code_ary.pack("c*")
  end
end
~~~

#コード(改)
色々ガバかったので改善しました
@scivola さんありがとう

~~~Ruby
module Base64
  TABLE = [*"A".."Z", *"a".."z", *"0".."9", "+", "/"]

  BIN_TO_CHAR = TABLE.map.with_index.to_h do |char, index|
    ["%06b" % index, char]
  end
  CAHR_TO_BIN = BIN_TO_CHAR.invert

  module_function

  def encode(str)
    binary_str = str.bytes.map { |b| "%08b" % b }.join
    binary_str << "0" * (-binary_str.size % 6)

    base_str = binary_str.gsub(/\d{6}/, BIN_TO_CHAR)

    base_str << "=" * (-base_str.size % 4)
  end

  def decode(base_str)
    unless base_str.size % 4 == 0 && base_str.delete("=").chars.all? { |c| TABLE.include?(c) }
      raise "wrong argument"
    end

    binary_str = base_str.gsub(/./, CAHR_TO_BIN)
    binary_str = binary_str.slice(0..-(binary_str.size % 8 + 1))

    [binary_str].pack("B*").force_encoding("UTF-8")
  end
end
~~~

#乾燥した感想
解き終わったとき最高に気持ちよかったです
改善点などあればぜひご指摘お願いします

~~~Ruby
binary_ary << binary_str[-(binary_str.size % 6)..].ljust(6, "0") unless binary_str.size % 6 == 0
~~~
ここの`unless`修飾子以降を書き忘れるという凡ミスを犯し、それに気づくのにめちゃくちゃ時間がかかりました
作業時間の80%は最後の20%の作業にかかる時間であるっていう至言を完全に理解した
.DS_storeファイルの個別削除

# .DS_storeファイルとは
Mac特有で、GitHubにcommitした拍子なんかに自動で生成される嬉しくないファイル。
メタデータを記録する不可視ファイルなので、要は不要なファイルです。

削除方法をググると親の仇ばりに、蛇蝎の如く嫌われている印象を感じます。
前述の自動生成、一回消しても再度誕生するなど、嫌われる理由に枚挙に暇がありません。

.DS_storeファイルは複数生成される事もあり、まとめて削除する方法は結構見つかります。
存在している全ての.DS_storeファイルの確認と削除ならば下記コマンドで処理が行えます。

**.DS_store確認コマンド**

```
＄ find . -name ".DS_Store" #確認コマンド
```
**.DS_store一括削除コマンド**

```
$ find . -name ".DS_Store" | xargs rm #まとめて削除コマンド
```

**削除に関する参考記事**
[[macOS][小ネタ] すべての.DS_Storeをコマンド一発で削除する]
(https://dev.classmethod.jp/articles/delete-all-ds-store/)

# 全部まとめてじゃなく個別に削除したい

自分の場合は、既にGitにcommitしており、作業ブランチで.DS_storeファイルまとめて削除してしまうと、自身のタスクと関係ない.DS_storeファイルまで削除される事がネックでした。必要のない変更点が出来る事が問題で、まとめて削除コマンドは使えませんでした。

自分にはappディレクトリ直下、及び隠しファイルの２箇所に.DS_storeファイルが生成されていました。その為、appディレクトリ直下の.DS_storeファイルの削除は容易でした。単純にターミナルで**cdコマンド**でappディレクトリへ移動し、前述の削除コマンドでappディレクトリ直下だけの.DS_storeファイルだけを狙い撃ちしました。

が、問題なのは隠しファイルの方。
普通に**lsコマンド**を叩いても出てこないので、何処に消すべきファイルが居るのか分かりませんでした。

そこで使用したのが、

```
$ sudo ls
```
でした。

このコマンドを使ってMacに設定しているパスワードを入力すれば、隠しファイルも表示されます。そうして通常の**rmコマンド**でファイル名を指定する事で個別の削除が出来ます。

**削除に関する参考記事2**
[Macのターミナルコマンド一覧（基本編）](https://qiita.com/ryouzi/items/f9dee1540a04a0bfb9a3)

基本的には.DS_storeファイルは不要なので、まとめて削除してしまうのが一番早いです。
しかし、何らかの理由で全部消えては困る、部分的に削除したい場合に参考になれば幸いです。
【初心者にオススメ】縦長のサイトでもスクショして1枚の画像にできる拡張機能「FireShot」が便利！

# どうも7noteです。WEBサイトのスクショにおすすめの拡張機能を紹介。

【ウェブページ全体をスクリーンショット - FireShot】

https://chrome.google.com/webstore/detail/take-webpage-screenshots/mcbpblocgmgfnpjjppndjkmgjaogfceg?hl=ja

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/3d44fc52-1aea-d89a-33f3-36a493f13ced.png)


## これがめちゃ便利

実際にFireShotを使ってスクショした画像がこちら。
![sample_pc.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/59ec0115-d2c8-6f50-ccb4-924387758d5f.png)

めっちゃ綺麗に撮れてます。

## 検証ツールと組み合わせて、スマホページも1枚にスクショ可能！

F12キーなどで検証ツールを立ち上げて、スマホ表示にしてから・・・パシャっと。

![sample_sp.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/45ab4f10-42f9-ffd3-fb74-93eec8e1ead1.png)



## 使い方

・GoogleChromeで[こちら](https://chrome.google.com/webstore/detail/take-webpage-screenshots/mcbpblocgmgfnpjjppndjkmgjaogfceg?hl=ja)にアクセスして、拡張機能をインストール。
・ブラウザの右上に拡張機能の青いSマークが増えているはずなので、スクショを撮りたいページにアクセスしたのち、このマーク↑<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/46c5580c-b35f-99ef-e4dd-ef3b151e04d5.png" width="30" style="margin: 0;">をクリック。
・「ページ全体をキャプチャ」をクリックすると撮影が開始されます。少し待つと新しいタブに撮影したスクショの画像と、保存方法などがかいたメニューがでてきます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/ca2e60ec-6973-551e-fabf-0e4a52da04be.png)
・好きな方法を選択して画像を保存、もしくはクリップボードにコピーして使えます。

## ローカルの開発環境もスクショ可能！

初期設定のままではローカルのデータ、つまり自分のPCのファイルをブラウザで開いたものはスクショ不可能なのですが、設定を変えることで可能になります！

拡張機能の管理画面から、以下のメニューをオンにします。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/107f8591-2fb9-4b9e-0322-2d1713d935ea.png)
↓↓↓↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/661092/fdb275d7-a8c8-bb0d-c81d-a0dacf20b389.png)



## まとめ

拡張機能なので、windowsでもmacでも利用できるのがいいですね。

#### おそまつ！
~ Qiitaで毎日投稿中!! ~
[【初心者向け】WEB制作のちょいテク詰め合わせ](https://qiita.com/7note)
UIButtonに紗をかける

layerでなんとかしようと思ったけど、これでいいや。

```swift

let view = UIView(frame: button.bounds)
view.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 0.2030837874)
button.addSubview(filterView)
```

🐣
****
フリーランスエンジニアです。
お仕事のご相談こちらまで
rockyshikoku@gmail.com

Core MLを使ったアプリを作っています。
機械学習関連の情報を発信しています。

[Twitter](https://twitter.com/JackdeS11)
[Medium](https://medium.com/@rockyshikoku)
Pythonの辞書キーを引用符で囲うか？

## 1. はじめに
　記事を執筆していたら辞書キーを引用符で囲う場合と囲わない場合の２つがあってややこしいと思いました。今回はこのことを記事にしたいと思います。あとこの記事を書くきっかけになった[Pythonでf文字列を用いて辞書の値を表示させる](https://qiita.com/mitsu4310/items/96d188ad2cc1e192f49a)も読んでいただけると筆者がサンシャイン池崎みたいに喜びます。

##2. 辞書キーを引用符で囲うか？
　以下のコードを見てください。結論をいうとf文字列を使う場合は引用符が必要でformatメソッドを使う場合は引用符を使ってはいけません。

```python:sample.py
dict = {"age": 20}

print(f'私は{dict["age"]}歳です')
print('私は' + str(dict['age']) + '歳です')
print('私は' + '{0[age]}'.format(dict) + '歳です')

```

##3. まとめ
　結論は先程も述べたとおり「f文字列を使う場合は引用符が必要でformatメソッドを使う場合は引用符を使ってはいけない」です。たったこれだけのことですがプログラミング初心者の自分はこの違いに気づかず1時間頭を抱えていました。一緒にエラーを1つずつ乗り越えていきましょう。
【GCP】Google Cloudの無料プログラム「Always Free」でCloud Storageを使う

# はじめに
Googleが提供するGoogle Cloud Platform (GCP)には2種類の無料プログラムがあります。ひとつはトライアル期間中に利用できる$300分のクレジット、もうひとつは使用量上限の範囲内であれば無料で利用できる「Always Free」と呼ばれるプログラムです。

本記事では、Always FreeプログラムでCloud Storageを使う具体的な方法について説明します。

# Always Freeプログラムについて
Always Freeプログラムでは、使用量上限の範囲内であれば一般的なGoogle Cloud Platformのプロダクトやサービスを無料で使用することができます。

## Cloud Storageの無料枠
2021年3月現在、Cloud Storageの無料枠は以下のようになっています。

|項目|無料枠|
|-|-|
|データストレージ|1ヶ月あたり5 GB|
|クラスAオペレーション|1ヶ月あたり5,000回|
|クラスBオペレーション|1ヶ月あたり50,000回|
|データ転送(外向き)|1ヶ月あたり1 GB|

クラスAオペレーションはオブジェクトの更新（INSERT, UPDATE）、クラスBオペレーションはオブジェクトの取得（GET）をそれぞれ意味します。また、Always Freeプログラムはリージョンが`us-west1`、`us-central1`、`us-east1`のいずれかを選択している場合のみ適用されます。

# Always FreeプログラムでCloud Storageを使う

## バケットの作成
Always FreeプログラムでCloud Storageを使うには、適用対象となるバケットを作成する必要があります。以下の手順でバケットを作成します。

[Google Cloud Platform](https://console.developers.google.com/)にサインインします。

左のメニューから「ストレージ」をクリックします。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/98c707e1-2bea-4853-ea62-82d4c111544f.png)

「バケットを作成」をクリックします。

![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/f8f1d1ea-12e3-a477-e184-6c8ddc142284.png)

バケットの作成画面で、バケット名を入力して「続行」ボタンをクリックします。

![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/5b863ce4-a4b1-1622-2c9e-62b1b069b13f.png)

ロケーションタイプ`Region`を選択し、ロケーションは`us-west1`、`us-central1`、`us-east1`のいずれかを選択します。いずれも米国リージョンとなりますが、比較的日本に近い`us-west1`をおすすめします。

![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/648d6c89-b0c2-06ac-b831-3a149f9e2f9b.png)

デフォルトのストレージクラス`Standard`を選択し、「作成」ボタンをクリックします。

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/4895867a-ea42-6c83-b10e-310f723a5cdb.png)

これでAlways Freeプログラム適用対象のバケットが作成できました。

## 作成済みのバケットの確認
既に作成済みのバケットがAlways Freeプログラムの適用対象かは以下の手順で確認できます。

[Google Cloud Platform](https://console.developers.google.com/)にサインインします。

左のメニューから「ストレージ」をクリックします。

![6.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/dda17e7d-d3be-30bf-b0e9-7af322099586.png)

確認したいバケット名をクリックします。

![7.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/0e90ab3e-5845-d708-1511-8873ccc4272a.png)

「構成」タブをクリックします。

![8.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/c02b1753-5a97-9a80-085d-2685ad1dfb29.png)

構成情報を確認します。

![9.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/417570/3e39ebfc-5509-8300-9116-948ba4b4ae25.png)

|項目|値|変更|
|-|-|-|
|ロケーションタイプ|`Region`のみ|不可|
|ロケーション|`us-west1`、`us-central1`、`us-east1`のいずれか|不可|
|デフォルトのストレージクラス|`Standard`のみ|可|

各項目がこのようになっていれば、当該バケットはAlways Freeプログラムの適用対象です。

デフォルトのストレージクラスのみこの画面から変更することができます（値の横のペンアイコンをクリック）。**ロケーションタイプ、ロケーションが違っている場合は、バケットを作り直す必要があります。**また、バケットを作り直したらサービスアカウントも作り直す必要があります。

# まとめ
Google Cloud Platformには2種類の無料プログラムがあり、そのうちのひとつであるAlways Freeプログラムは使用量上限の範囲内であれば無料で使い続けることができます。使用量上限は設けられていますが、小規模なプロダクトであれば十分な無料枠が提供されています。

本記事を参考にしてAlways FreeプログラムでCloud Storageを使っていただければと思います。
#1 PythonなチャットボットとJupyterLabの理解 ｜リーガテックの神を目指す駆け出しITコンサルがインフラエンジニアに転身するまで

### 背景

……そこで、せっかくですから、私のルーツであるインフラ系に立ち返り、**法律に詳しいインフラエンジニアになるべく（なんだそれは）、独自に技能の研鑽**を始めることにしました。
そして、夜は司法書士試験の勉強です。もうパーフェクトですよね。私はリーガテックの神になる、これはもう、間違いがございません。

それをQiitaに投稿する目的は、

* 同じような習熟度の仲間が見れば役に立つ
* アウトプットをした方が定着する

というだけです。頑張ってまいります！


### PJ概要
| 諸元 | 内容 |
|:--|:--|
| 言語 | python  |
|  インフラ |  heroku |
|  目的 |  slack連繋のチャットボット |

現在、私が簡単に設計したものを同期が作ってくれたアプリがあり、内容としては上記の表のような感じです。

しかしながら、**heroku環境では500時間しか無料では動かせない**ようであり、止まってしまいました。そこで、**AWSの研鑽も兼ねて、これをAWSに移行してみよう！**というチャレンジをします。

### JupyterLabの便利なショートカット

アプリ側の実装者・同期さまの環境はJupyterLab(Anacondaに附属しているのですね。初めて知りました）。まずはこれを理解せねばなりません。

| コマンド | 結果 |
|:-:|:-:|
| Shift+Etr  | セル内のコードを実行して下に追加  |
| Ctrl+Etr  | セル内のコードを実行  |
| D^2 | セルを削除  |
| A | 上にセルを追加  |
| B | 下にセルを追加  |
| Ctr+/ | コメントアウト  |
| 途中まで書いてTab | オートコンプリートによる補完 |

他にもここを叩くと色々出てくるようです。すごい。

>![スクリーンショット_2021-03-08_12_38_12.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319381/1ce57946-150f-7f29-bed6-dbaacd5e326d.png)

その他気になった点はこんな感じです。
（分かりやすいReadme.mdに助かる。。。）

* どうも、terminalみたいなイメージで使って良いようmasu.Chromeから開くとあたかもクラウドサービスのような感じになりますが、実際にはローカルホストで動いてます。
* `.ipynb`はあくまでもノートブック。実行ファイル部分を出力するには、メニューから`export as executable`。すると、実行できない部分はコメントアウトされた状態で、`.pyが出力されるよ。
* `Variable Inspector`というextensionはおすすめ。インストールしたら右クリックで使えるよ。

### わからない！
JLabを見渡しつつ、本体となるpythonのコードも読み込みます。

いくつか、見覚えのない点が、、

#### import Botって？
`from slackbot.bot import Bot, respond_to`
という記載が。importは分かるのですが、Botって何でしょう。
respond_toも聞いたことが。。ない。。

https://qiita.com/sukesuke/items/1ac92251def87357fdf6

`from slackbot.bot import Bot`
これが根拠となっていそう。ここで、`from`と`import`の区別ができていない自分に気づく……
……
>Pythonでライブラリやモジュールを読み込む際には「import」および「from」を使いますが、この2つは使い方がややこしく、違いをあまり分からずに使っている方もいると思います。

ですよね〜！（下記参考文献より）

https://programming-study.com/technology/python-import/

……ということで、モジュールをバイパスしてクラスとか関数を直接importする指令だったみたい。
やったぜ。

#### defってなんだ！？
pythonはちょっとだけやったことがあったのですが……defという表現を使った覚えがありません。
鍛錬が足りませんね。これも調べます。

https://www.tech-teacher.jp/blog/python-class/

色々みましたがこれが格別に分かりやすいです。
いままで、classは使ったことがありましたがdefは使っていませんでした。VB.netで世界観が止まっていたのだと実感します。
classより細かい単位化ができるということですね！

###この辺でpythonコードを読解
疑問点はこれで解消したので、ここで同期さまが書いてくれたコードを読解！しようと思います。

![スクリーンショット_2021-03-08_21_18_09.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319381/f5291284-0a30-5c5c-1a7e-25d5960ee3b7.jpeg)
![スクリーンショット_2021-03-08_21_37_03.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319381/38fa1acd-84c9-c610-1459-b8449cae5cde.jpeg)
![スクリーンショット_2021-03-08_21_50_14.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319381/34390f03-15bb-f48c-2107-1606008e7e10.jpeg)

……なんか理解できた気がします！

###気になった点

![スクリーンショット_2021-03-08_21_56_16.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/319381/1d5ee15c-531d-c1c5-946b-01e5faada675.jpeg)

**Spreadsheetからデータを取ってくるコードの冗長性が高そう**です。
効率化できないか次回以降検討してみます！

###次回予告

次は、**①冗長性問題の解決に取り組み**、さらに、**②現在の実行環境であるherokuの理解**を目指します！

###応用的だけどすごい勉強になる学習内容
https://blog.bitmeister.jp/?p=3911

`@respond_to`って何？という、知らなくても良いけど知ったらプロになれる疑問に答えてくれます。


###参考文献
https://ai-inter1.com/jupyter-lab/

https://www.tech-teacher.jp/blog/python-class/
Pythonでf文字列を用いて辞書の値を表示させる (2021年3月9日一部訂正のため追記)

##1. はじめに
　Rubyには式展開という便利なツールがありPythonにも同じものがあればいいなと思っていたらPythonにもf文字列という形でありました。今回はf文字列を用いて辞書の作成などを行っていこうと思います。

(注1)f文字列はPython3.6で導入された機能です。それ以前のバージョンでは使用できません。

(注2)rubyの式展開とは#{}のことです。

```ruby:sample.rb
age = 20
puts '私の年齢は#{age}です'
```

##2. f文字列を用いて辞書の値を表示させる
　まずは辞書をつくります。

```python:sample1.py
dict = {}

dict["名前"] = "山田太郎"
dict["年齢"] = 20
```

　次に「私の名前は山田太郎です。」という文と「私の年齢は20歳です。」という文章をf文字列を用いて出力してみます。

```python:sample2.py
dict = {}

dict["name"] = "山田太郎"
dict["age"] = 20

print(f'私の名前は{dict["name"]}です。')
print(f'私の年齢は{dict["age"]}です。')

# 出力結果
# 私の名前は山田太郎です。
# 私の年齢は20です。
```

　f文字列を使い辞書の値を出力させる際の注意点が１つあります。それはf文字列を囲う引用符と辞書のキー囲む引用符と同じ引用符は使えないということです**(例外あり　例外はまとめの後に記載)**。同じ引用符を使うとエラーになります。自分はしばしばf文字列と辞書を囲う引用符を同じにしてエラーになっています。
**(2021年3月9日追記　例外をまとめの後に記載)**

```python:sample3.py
dict = {}

dict["name"] = "山田太郎"
dict["age"] = 20

print(f'私の名前は{dict['name']}です。')
print(f'私の年齢は{dict['age']}です。')

# 出力結果
# SyntaxError: invalid syntax
```

　また辞書のキーを引用符で囲わなくてもエラーになります。

```python:sample4.py
dict = {}

dict["name"] = "山田太郎"
dict["age"] = 20

print(f'私の名前は{dict[name]}です。')
print(f'私の年齢は{dict[age]}です。')

# 出力結果
# NameError: name 'name' is not defined
```

##3. まとめ
　Python3.6以降ではf文字列を用いて辞書の値を出力させることができます。
あと余談で詳しく書いたのですが、コードの可読性はf文字列の方が良いのでf文字列を使ったほうが良いと思います。


##注3(2021年3月9日訂正のため追記)
　この記事を読んでいただいた方からf文字列を囲う引用符と辞書のキー囲む引用符と同じ引用符を使える場合があることを教えていただきました。本当にありがとうございます！そしてここで訂正させていただきます。本当に申し訳ありません。
　以下のコードのようにf文字列全体を三重引用符(""")で囲み辞書のキーをダブルクオーテーション(")で囲むとf文字列全体を囲う引用符と辞書のキーを囲う引用符を同じにできるそうです。いや、お見事！

```python:sample5.py
dict = {}

dict["name"] = "山田太郎"
dict["age"] = 20

print(f"""私の名前は{dict["name"]}です。""")
print(f"""私の年齢は{dict["age"]}です。""")
```

## 余談　f文字列 VS 文字連結
```python:sample6.py
dict = {}

dict["name"] = "山田太郎"
dict["age"] = 20

print('私の名前は' + dict['name'] + 'です。')
print('私の年齢は' + str(dict['age']) + 'です。')

# 出力結果
# 私の名前は山田太郎です。
# 私の年齢は20です。
```

　２つの例を比較すると前者のf文字列を用いたほうがコードの可読性が良いと思います。「私は山田太郎、20歳、大学1年生です。」という1つの文に「名前」、「年齢」、「学校種別」、「学年」の4つの変数がある文を出力しようとするとさらにf文字列のありがたみが分かると思います。

```python:sample6.py
dict = {}

dict["name"] = "山田太郎"
dict["age"] = 20
dict["school"] = "大学"
dict["grade"] = 1

# f文字列を使った場合
print(f'私は{dict["name"]}、{dict["age"]}歳、{dict["school"]}{dict["grade"]}年生です。')

# f文字列を使わなかった場合
print('私は' + dict['name'] + '、' + str(dict['age']) + '歳、' + dict['school'] + str(dict['grade']) + '年生です。')

# 出力結果
# 私は山田太郎、20歳、大学1年生です。
# 私は山田太郎、20歳、大学1年生です。
```


 


##参考文献
[Pythonの文字列が標準でf文字列になる（かも）](https://qiita.com/ksato9700/items/44caf7bf0329fb987499)
[【Python】文字列の埋め込みにはf文字列を使うべき](https://qiita.com/tetsuro731/items/ad3dedfafdae64e69e00)
javaでファイル更新監視アプリを作成する

#目的
javaでアプリを作りたいと思った。
とりあえず人からこんなものを作ったらと言われて作ってみた作品になります。
ということで今回作ったのは監視対象ファイルをCSVから読み込んでファイルサイズが変わったら
デスクトップのポップアップで通知してくれるデスクトップアプリです。

#環境構築
windows8
Pleiades All in One photon

#ソース
gitthubにて
https://github.com/mimicman/FileSurveillance/tree/main/src/jp/main

#ソースの説明
##MainUpdateCheker.java

MenuItemクラスでデスクトップのメニューに追加します。
メニューには開始、停止、再開などアプリを操作するメニューを追加しています。
Timerクラスで定期的に処理を実行しています。

##CsvLoad.java
CSVを読み込んでCSVに記載されている監視対象ファイルを読み込みます。

##Run.java
監視対象ファイルのサイズが変更されていないかを確認する処理を実施しています。

##UpdateChekerFrame.java
監視対象ファイルを可視化するため、フレームにファイル名等を表示しています。
【学習メモ】Kinesis

#Kinesis
ストリームデータを収集・処理するためのフルマネージド型サービスで主に3つのサービスで構成される。

・Amazon Kinesis Streams：ストリームデータを処理するアプリケーションを構築。
　　※主要なストリームデータはこのサービスによって使っていく。（代表サービス）
・Amazon Kinesis Firehose：ストリームデータをS3やRedshiftなどへ簡単に配信。
・Amazon Kinesis Analytics：ストリームデータを標準的なSQLクエリでリアルタイムに可視化・分析。
　※残り二つのサービスは組み合わせで使う。

##Amazon Kinesis Streams
ストリーミング処理をシャードに分けて分散させて実行するため高速処理が可能。
（シャードの数によって、データ処理のスピードが変わる。数が多ければ、負荷を分散化して高速処理が可能。）
※シャード：Amazon Kinesis データストリームの基本的なスループットの単位。

データプロデューサー：データ提供側。
データコンシューマー：データ利用側。

###Streamsへのデータの格納
reference:https://aws.amazon.com/jp/kinesis/data-streams/getting-started/?nc1=h_ls

データプロデューサーは、Amazon Kinesis データストリームに Amazon Kinesis Data Streams API、Amazon Kinesis Producer Library (KPL)、または Amazon Kinesis Agent を介してデータを格納できます。
![kinesis.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1082021/1638a014-adc3-d590-a465-3e8d4140227a.png)


##Amazon Kinesis Firehose
各種DBに配信・蓄積するためのストリーム処理を実施する。Lambdaと連携するとETLとしても機能する

##Amazon Kinesis Analytics
ストリームデータを標準的なSQLクエリでリアルタイムに分析
Djangoでアプリケーション名を変えたらmigrateができなくなってしまったときの対処方法をメモ

###環境

```
Python 3.8.7
Django==2.2
```

###エラー内容

アカウントの編集とかの操作するアプリケーション名を変更して

```
python manage.py makemigrations
```

をしたら

```
Traceback (most recent call last):
略
django.db.migrations.exceptions.InconsistentMigrationHistory: Migration socialaccount.0001_initial is applied before its dependency account_manage.0001_initial on database 'default'.
```

とエラーが発生。

```
python manage.py migrate
```

も同じエラー。
そこで、エラー文をググってみると、

https://qiita.com/kanzaki0507/items/df056f20f3c42bae1abf

があった！
書いてあるように、

```
python manage.py showmigraions
```

をやったら、前に作ったアプリケーションでmigrateしたデータが残ってた、、、。そりゃそうだな。
###解決方法
すべてのアプリケーションのmigrations直下の__init__.py以外のファイルを削除。

```
python manage.py makemigrations
python manage.py migrate
```

をしたら動いた！
Firefox で急に特定のドメインが開けなくなったときの対処法

# TL;DR

cf.

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

# 説明

どういうわけか、`app.slack.com` 配下のページ（Web 版 Slack）が開けなくなることがあります。この症状は、ほかのサイトにアクセスした場合でも発生することがあるようです。

開発者ツールで、ネットワークタブを開き、改めてアクセスを試みると、`NS_ERROR_DOM_ABORT_ERR` と出てくるのですが、あまり一般的なものではなさそうです。

https://bugzilla.mozilla.org/show_bug.cgi?id=1678795

https://twitter.com/xxmagai/status/1365878219476361218

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/253921/408093e3-fc4f-f774-17ae-c4f427a25d55.png)
by https://mastodon.cardina1.red/@lo48576/105629452274587293

[about:preferences#privacy](about:preferences#privacy) にアクセスし、Cookie とサイトデータ > データを管理…(M) から、`app.slack.com` を選択、削除、変更を保存すると、症状が改善します。
AWS Systems Manager とは

## 勉強前イメージ

AWSのシステム全体をまとめて管理するようなやつ？
管理系のサービスな気がするなぁ

## 調査

### AWS Systems Manager とは

AWSでインフラのサービスを管理や制御するためのサービスです。
複数のサービスのデータを表示して、リソース間でタスクを自動化する事が出来ます。

### AWS Systems Manager の特徴

- 複数のサービスのデータを一元化し、可視化させる
- リソース全体のタスクを自動化
- EC2とオンプレのサーバを管理することが出来る

### AWS Systems Manager の機能

- 高速セットアップ
- 運用管理
	- エクスプローラー
	- OpsCenter
	- Cloudwatch ダッシュボード
	- PHD
- アプリケーション管理
	- アプリケーションマネージャー
	- AppConfig
	- パラメータストア
- 変更管理
	- 変更マネージャー
	- 自動化
	- カレンダーの変更
	- メンテナンスウィンドウ
- ノード管理
	- フリートマネージャー
	- コンプライアンス
	- インベントリ
	- マネージドインスタンス
	- ハイブリッドアクティベーション
	- セッションマネージャー
	- Run Command
	- ステートマネージャー
	- パッチマネージャー
	- ディストリビューター
- 共有リソース
	- ドキュメント

### 費用

以下以外は無料

- 運用管理
	- エクスプローラー
	- OpsCenter
- アプリケーション管理
	- AppConfig
	- パラメータストア
- 変更管理
	- 変更マネージャー
	- 自動化
	- メンテナンスウィンドウ
- ノード管理
	- コンプライアンス
	- インベントリ
	- ハイブリッドアクティベーション
	- セッションマネージャー
	- Run Command
	- ステートマネージャー
	- パッチマネージャー
	- ディストリビューター

詳細の費用は [こちら](https://aws.amazon.com/jp/systems-manager/pricing/)

## 勉強後イメージ

いろんな機能がありすぎてややこしいけど、
AWS全体のインフラを管理できて、オンプレも管理出来るよ。
あと自動化とかも出来るよ、って感じか・・・
使ってみないとピンと来ないかもなぁ

## 参考

- [AWS Systems Manager の料金](https://aws.amazon.com/jp/systems-manager/pricing/)
- [AWS Systems Managerの機能とは？](https://www.acrovision.jp/service/aws/?p=1368)
- [AWS再入門ブログリレー AWS Systems Manager編](https://dev.classmethod.jp/articles/relay-re-introduction-2019-ssm/)