OmniAICreator/Qiita-1.07M huggingface dataset:
CloudFront + S3の静的ホスティングでメンテナンス画面の表示

サーバーが1台で冗長化構成をしていない場合に再起動などが必要なメンテナンスもあるかと思います。
例えば、EC2のインスタンスサイズを上げるとか、またはカーネルのアップデートなど。
そういう時に別のインスタンスを立ち上げるのもいいですが、今回はS3で静的ホスティングでメンテナンス画面を表示する方法を書いていきます。

大前提として、S3もCloudFrontも利用していることとします。

## メンテナンスページの準備
1. S3に新しいバケットを作成します。（アクセスはパブリックにしておく。）
1. メンテナンスページのhtmlを作成してS3にアップロードします。
![s3_maintenance.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75243/114f4ab5-e39a-891f-fd94-6cda7b0a5ca0.jpeg)


1. S3のプロパティタブから「静的ウェブサイトホスティング」を有効にします。![s3_static_hosting.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75243/40f391a0-ece1-45f8-75c0-2fda2cd27149.jpeg)
1. エンドポイントにアクセスして表示されることを確認します。

## CloudFrontの設定
1. 利用しているディストリビューションを選択し、メンテナンス用のオリジンを作成します。
    1. その際にオリジンドメインを先ほど作成したS3を選択します。
    1. 「S3 バケットアクセス」はOAIを使用にチェックを入れ、新しいOAIを作成します。

![cloudfront_create_origin.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75243/c8812281-68a9-6153-1df0-edb162f8eb50.jpeg)

1. 新しくビヘイビアを作成します。オリジンは先ほど作成したオリジンを指定します。

![cloudfront-create-behaver.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75243/9ba6afe8-b71e-4bc3-aaf2-6b9a8adc7ae3.jpeg)

## S3のバケットポリシーにCloudFrontのオリジンを許可
1. S3の「アクセス許可」からバケットポリシーに以下のポリシーを追加する。
    1. オリジンのIDとバケット名は適宜変えてください。

```
{
    "Version": "2008-10-17",
    "Id": "PolicyForCloudFrontPrivateContent",
    "Statement": [
        {
            "Sid": "1",
            "Effect": "Allow",
            "Principal": {
                "AWS": "arn:aws:iam::cloudfront:user/CloudFront Origin Access Identity {オリジンのID}"
            },
            "Action": "s3:GetObject",
            "Resource": "arn:aws:s3:::{バケット名}/*"
        }
    ]
}
```

  
**CloudFrontのオリジンID**
![cloudfront-origin-id.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/75243/d8b7c665-d0c8-02d5-56fa-014aa8db8f9b.jpeg)

## 表示の確認
1. https\://example.com/maintenance.html のパスで表示されたらOKです！

## 特定のIPのみメンテナンスを表示しない場合
1. CloudFrontの関数で新しく関数を以下のように追加します。

```
function handler(event) {
    var request = event.request;
    var clientIP = event.viewer.ip;
    // アクセス許可するIPを設定
    var IP_WHITE_LIST = [
     '{対象の特定IP}',
    ];
    // クライアントIPが、アクセス許可するIPに含まれていればtrueを返す
    var isPermittedIp = IP_WHITE_LIST.includes(clientIP);

    if (!isPermittedIp) {
        var response = {
            statusCode: 302,
            statusDescription: 'Found',
            headers:
                { "location": { "value": "https://example.com/maintenance.html" } }
            }

        return response;
    } else {
        return request;
    }
}
```
2. テストタブからリクエストを送信し、OKだったら発行タブから関数を発行します。
2. もし、関数を変えたい場合は、構築タブで関数を変更し、そのあと必ず毎回「関数を発行」をクリックしてください。でなければ反映されません。
2. あとは「関連付けられているディストリビューション」で関連付を追加し、対象のディストリビューションを選択すれば完了です。

## 最後に
いかがだったでしょうか？
AWSに慣れていないと少し難しく感じるかもしれませんが、一度試してみてください。
万が一急ぎや分からなければ、仕事の依頼という形になりますがお問い合わせ頂ければと思います。

## 投稿者について
山梨で[やまなみテクノロジーズ株式会社](https://yamanamitech.com)の代表をしている小畑です。
WordPress周りの改修やweb制作、SEO対策やデータ分析にお困りでしたらお問い合わせください。
Logstashのconf分割

# はじめに
Logstashのconfがめちゃくちゃ長い。私が見た時で3000行くらい。。。
修正する度にうんざりするので、ある程度の粒度で分割した。

# 注意点
logstashのconfを分割するときによく出てくるのがMultiple Pipelinesであるが、
Multiple Pipelinesの場合、各Pipelineごとにリソース割り当てを調整しないといけないため、ここではMultiple Pipelinesは使用しない。
> Multiple Pipelines
https://www.elastic.co/guide/en/logstash/current/multiple-pipelines.html

# 分割した場合、Logstashどのように読み込むか
Logstashは、処理をINPUT/FILTER/OUTPUTの3つに分けることが出来る。
設定ファイルに記載されている内容をLogstashが勝手にINPUT/FILTER/OUTPUTどれに当てはまるか識別してくれる。
読み込み順序は、INPUT→FILTER→OUTPUTの順番になる。
さらにINPUT/FILTER/OUTPUT内で設定ファイルが複数ある場合、設定ファイル名の英数文字を昇順で読む。
例えば、FILTER処理の中で共通処理をかませてから各処理を実行することも出来る。
```
./
├── 1-common.conf
└── 何かの処理.conf
```
必ず`1-common.conf`を実行してから、`何かの処理.conf`が実施されるようになる。


# 構成
FILTERの処理を分割し可読性を上げることにした。今回FILTER内で処理の依存関係はないので、設定ファイル名は気にしていない。
*confのディレクトリ構成*
```
./config
├── input.conf
├── category_A_filter.conf
├── category_B_filter.conf
├── category_C_filter.conf
└── output.conf
```
# 起動
```
/${logstah_home}/bin/logstash --path.config=./config/* 
```
設定ファイルを全て読み込ませるように起動している。上記の例はconfの設定のみにフォーカスしている。他起動オプションは各自で足すこと。
lenses boxをうごかした

# 位置づけ
lenses boxとやらを使うと次の取り組みに使えそうだったので、
環境構築を試しながらスクショやらメモやらを残している。

# goal
lensesをつかってkafka clusterとその周辺の仕組みを雑に動かしたい

## インフラ面
lensesio/boxでdockerで実験環境のようなものを動作させられる

## アプリ面
kafka topicを入力に、Streaming SQLを実行、データフローの可視化ができそう。

# start
ここから実施。
https://lenses.io/start/
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/de3aa9ef-2701-2890-e3fa-1a632e6c4b03.png)
メールアドレスを入れて登録

以下のようなメールがきた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/6a918220-be09-6700-023f-8ac6c2d36840.png)
実行してみる。

メールの中にdocker run コマンドが入ってるので実施

以降はこの手順に沿って手を動かす
https://lenses.io/apache-kafka-docker/
# ブラウザから管理画面へ
admin/admin でログイン
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/51c98f0c-8618-4767-b222-7757621db88d.png)

それっぽい画面に到達
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/ed27e4d6-f662-3ba2-9058-51a48650a5ff.png)

# SQL Studioとやらでデータをみる
~~なんのデータを見ているのかわからないが~~ 手順に従いSQLでデータを見る。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/828710a7-1378-4cbd-2126-a068be5eaecf.png)

実行結果が中央下側。

# 新しいKafkaトピックを作る
新しくデータを投入する。
Exploreを選択すると右上にCreateTopicがある
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/82da736a-c765-cad3-b2fc-9715a346d453.png)

適当にトピックを作成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/08e592c2-8f0d-812f-0046-f3fcf074bb39.png)

# データパイプラインの作成 
データパイプラインを作ってリアルタイムイベントをKafka topicとして投入する。

コネクター画面へ移動＆New Connector
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/17c760f5-9008-2234-793e-4f26065e45d6.png)

Fileコネクタを選択し、設定をコピペする。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/bc8ef504-5b23-7cd4-e54b-5e5308d3f059.png)

手順にはないが、SQL Studioでクエリをしてみる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/94f37fb8-350f-f297-0270-b48f8522f94f.png)
何かは取れてそう

# SQL Processor
streaming SQLでリアルタイムデータを処理

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/e46aca3b-5cf1-2345-5e18-058b42b7936e.png)

手順に含まれていた　streaming SQLを定義
内容的には speed_boatsができる模様
```
SET defaults.topic.autocreate=true;
INSERT INTO speed_boats
  SELECT STREAM MMSI, Speed, Longitude AS Long, Latitude AS Lat, `Timestamp`
  FROM sea_vessel_position_reports
  WHERE Speed > 10;
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/7d659912-162a-1f4f-fbe1-718b198f4356.png)

手順にないがExploreからデータを確認。
SQLに書かれているようにSpeedが10以上が抽出されたトピックが新しくできている。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/af0dcbed-1cfd-35a2-243c-d7d3a0272f81.png)

# Consumer Monitor
データ消費者の可視化（手順上画面開くだけ・・・かな）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/dd2e1e63-0e97-fab3-dd54-614655b3da05.png)

# リアルタイムデータフロー
Kafkaのトピックからどうデータが流れるかの可視化。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/19483/ecf78cb4-aae8-b93a-35ab-5c7df9d5b26a.png)

# アラートの設定
略
GraphQL: GraphQLをはじめる

本稿はGraphQL公式サイト「[Introduction to GraphQL](https://graphql.org/learn/)」の中身を日本語で説明し直しました(邦訳ではありません。)。

GraphQLはAPIに対するクエリ言語です。サーバーサイドのランタイムで、データに定義した型システムを用いてクエリが実行できます。GraphQLは特定のデータベースやストレージエンジンには縛られません。すでにあるコードやデータで利用できるバックエンドです。

GraphQLサービスは、型とその型のフィールドを定義し、それぞれの型のフィールドに関数を備えてつくります。たとえば、誰がログインしているユーザー(`me`)なのか、またそのユーザーの名前を教えてくれるサービスはつぎのようなコードです。

```graphql:GraphQL
type Query {
	me: User
}

type User {
	id: ID
	name: String
}
```

そして、フィールドと型には、つぎのような関数を備えます。

```graphql:GraphQL
function Query_me(request) {
	return request.auth.user;
}

function User_name(user) {
	return user.getName();
}
```

GraphQLサービスが(通常はwebサービスのURLで)起動すると、クエリを受け取って検証と実行が行えます。サービスは、まずクエリが参照するのは定義された型とフィールドのみであるかを確かめ、つぎに提供された関数の実行により結果を生成します。

たとえば、つぎのコードがクエリから生成されるJSON結果の例です。

```graphql:GraphQL
{
	me {
		name
	}
}
```

```json:結果
{
	"me": {
		"name": "Luke Skywalker"
	}
}
```

つぎのステップとしては「[GraphQL: クエリ(queries)と変更(mutations)](https://qiita.com/FumioNonaka/items/f22bfc2928d56469bf93)」をお読みください。
第2回：良い開発組織では「予定より早く終わりそうです」を聞く。

# バッファってなんだ？
第2回は「システム開発の計画にバッファが必要な理由」を説明させていただきます。
※本記事の第一回は[こちら](https://qiita.com/satou_ot/items/731158951e951a1e2851)になります。本記事の前にご一読いただければ幸いです。

>「バッファとはなんだ？」
>>「バッファとはバッファです」

という質問のやり取りが繰り返され続けている（笑）
システム開発現場の受注者・発注者の双方に参考になればと思います。　※[第一回](https://qiita.com/satou_ot/items/731158951e951a1e2851)をお読みください

**システム開発はタスク予定表どおりには進行しません。**
これは、見積もりの手法や、要件定義の精度、開発プロセスの習熟度、あるいは受注側の誠意の問題・・・ではないのです。開発チームに「頑張れ！」といっても解決しませんし。
ビジネスチームに「要件もっと細かく性格に纏めなさい」といっても解決しません。
そんなことは、どの会社も開発組織もプロジェクトも、とっくにしてきた事だからです。

事実としてシステム開発プロジェクトは作業計画通りには進行しません。
既にソフトウェアという産業が一般化して半世紀ほどにもなりますが。
その間に膨大なプロジェクトが実行され、結果として既に「一定程度の遅延や品質課題は発生する」ことが事実として明らかになっています。
たとえば、2020年の日本システムユーザー会JUSASの統計（ソフトウェアメトリックス）によれば約30%のプロジェクトは品質課題もしくは納期遅延の問題を多かれ少なかれ起こします。
https://juas.or.jp/cms/media/2020/05/20swm_pr.pdf


例えば、工期が20%以上、遅延する割合は13.3%となっています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529980/ace85fb0-de4e-17f9-b274-d7426c56377f.png)
出典：上述　2020年度　JUSAS：ソフトウェアメトリックス調査　より

また、背景はともかく統計の対象となった700のプロジェクトの約18%で品質に問題がある（品質換算率1以下）のプロジェクトとなりました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529980/aa51833a-a316-3bbf-1f7c-78d5d0340184.png)
出典：上述　2020年度　JUSAS：ソフトウェアメトリックス調査　より

プロジェクトの13%は大幅な計画予算の超過をしています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2529980/ead52347-0728-0036-8871-d8f4ee27edf9.png)
出典：上述　2020年度　JUSAS：ソフトウェアメトリックス調査　より

そして忘れてはならないのは「多くの会社で既にバッファを積んでプロジェクト計画をしている」という事実です。
なので、バッファを積んでなお、これだけリスクが顕在化していることになります。

遅延の原因は実に様々です。だからバッファが必要な理由も様々となるのです。
技術的な問題かもしれません。
開発会社の作業者のスキルレベルが足りないかもしれません。
要件が決まらないかもしれません。
インフラ基盤に思わぬ落とし穴がリリース日に見つかるかもしれません。
突然、社長交代してリリース直前でプロジェクトが見直しになるかもしれません。

そうした上記表のような品質や工期やコストなどの形でリスクが顕在化する
 **最大要因は「仕様変更」** です。

仕様変更は実に80%近いプロジェクトで発生します。
つまり「ほぼ確実に発生するプロジェクトリスク」なのです。

ですから**バッファが必要な理由は「必ず仕様変更は起こるから」** と言って良いことになります。

・・・次回は、仕様変更とバッファの関係、そしてバッファの参考値について投稿してみたいと思います。

沢山「いいね」をいただければ早筆になるかもしれません（笑）
CSSのみで縦横比を維持してトリミングされたサムネイルを作って横並びにしたい

# やりたいこと
- CSSのみで縦横比を維持したい
- サイズも縦横比もバラバラな画像をCSSのみでトリミングしたい
- 横並びにしたい
- IE11も対応したい

# やってみたこと
サイズ・縦横比の違う画像を用意しました。
![nekochan.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2073765/1e7110e0-0ba1-706e-fea2-3ddb14d4c1a8.jpeg)



HTML
```html
<div class="flexBox">
    <!-- 1枚目 800*533 -->
    <div class="item">
        <div class="trimming">
            <img src="demo_01.jpg">
        </div>
    </div>

    <!-- 2枚目 1000*1500 -->
    <div class="item">
        <div class="trimming">
            <img src="demo_02.jpg">
        </div>    
    </div>

    <!-- 3枚目 900*900 -->
    <div class="item">
        <div class="trimming">
            <img src="demo_03.jpg">
        </div>
    </div>
</div>


```

CSS
```css

body {
    max-width: 1000px;
    margin: 0 auto;
    padding: 20px;
}

/*====== 横並びにしたい ======*/
.flexBox {
    display: flex;
    justify-content: space-between;
}
.item {
    width: calc(100% / 3 - 20px);
}

/*====== 縦横比を維持してトリミングしたい ======*/
.trimming {
    position: relative;
    overflow: hidden;
    width: 100%;
    padding-top: 75%;
}
.trimming img {
    position: absolute;
    top: -50%;
    right: -50%;
    bottom: -50%;
    left: -50%;
    width: 115%;
    height: auto;
    margin: auto;
}

```
できました。
![nekochanAnimation.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2073765/2e4c41b2-29dd-53b5-c148-b2a81f2efe00.gif)

## ポイント
`.trimming` の `padding-top: 75%;` : 高さを指定しています。

`.trimming img` の `width: 115%;` : 1枚目の横幅が一番小さい画像が枠いっぱいになるようにしています。

`.trimming img` : 画像の縦横中央が表示されるように指定しています。

### その他
横並びはflexで対応。
itemというクラス名のdivをかませないとうまくトリミングできませんでした。
![nekochan_shippai.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2073765/0cd308d6-2cde-dc86-cef2-6e81bbe721f5.png)

`aspect-ratio`というプロパティを使用すると、上記より簡単に縦横比を維持できるようですがIE11で使えなかったので採用しませんでした。


---------------

この記事は以下の情報を参考にさせていただきました。

- [CSSだけで縦横比固定のトリミングされたサムネイルをつくる【内接・外接リサイズ】※2021年 aspect-ratioプロパティ追記](https://www.esz.co.jp/blog/2778.html)
- [[CSS] 縦横比やサイズの違う画像をそろえて並べたい](https://migi.me/css/image-unity-size/)
社会人になってからWeb制作を学び始めた人のメモ

# はじめに
私は2021年4月からweb制作チームへ異動しました。
まったくの初心者がweb制作を独学で学習するときに思ったことを書いていきます。

ちなみに学習スタート時のスキルレベルは、
・これまでweb制作に関する仕事は一切やったことがない
・趣味でホームページビルダーの自動生成モードを使って遊んでいた
・イラレフォトショは趣味＋前職で少し触っていた
このぐらいからでした。

# やったことと、自分の中での手ごたえ
※あくまでも私の個人的な感想です。

## 初心者向け動画講座を見る　△
独学を始めるにあたり最初に手をつけました。
簡単な講座＋自分で入力したコードを画面上で自動添削してくれるタイプは実務をイメージしやすくてよかったです。
一方、動画講座配信サイトで購入した初心者向け動画は私には合わなかったです。理解が追い付いている間は問題ないのですが、分からないところが出るたび動画をストップしたり細かく巻き戻したりするのが意外と億劫になりました。動画講座はある程度知識がある人がさらにステップアップしたいときに便利なのかなと思います。

## HTML写経　✖
ネットでおすすめされていた勉強方法だったのでチャレンジしてみました。
しかし、少なくとも私にとっては難しかったです。まず初心者でも理解しやすい構造のお手本サイトを探すのが難しいです。何も分からないままただ同じコードを真似るのはモチベーションが保てませんでした。シンプルに見えるサイトでもいろんな工夫をして作られているんだ、ということが分かったのはよかったです。

## 学んだことをone noteに逐一メモしていく　✖
始めは学んだこと・忘れてしまいそうなことを全部メモしていました。参考になるサイトからコピペして自分用のwikiを作ったら便利かなと思いはじめましたが、途中で初学者の場合は何もかも覚えておかないといけないことだらけだと気づき止めました。

## 学んだことを紙のノートに逐一メモしていく　△
勉強＝ノートを取るという学生時代の習慣で始めました。前述のonenoteへのメモと同じく途中でキリがないと気づいて止めましたが、手を動かしたことで頭の整理ができたのはよかったです。当時のノートを見ても何も参考にはならないのですがやってよかったかなと思います。

## 初心者向けの紙の書籍　〇
結局これが一番安定していました。自分のペースで勉強できるし、目次を見れば自分がどこまで理解しているのかすぐにわかるので学習の目安になりました。教科書兼ノートとして本に直接書き込みしながら使っていますが、情報が1か所にまとまるので別途ノートを取っていた時より圧倒的に理解する速度が速くなった気がします。

電子書籍は便利なので趣味ではよく購入していますが、勉強にはぱっと見で進捗状況が確認しやすい紙の書籍が向いていると思います。マーカーで色を引いたときの感触や、その時手元にあった飲み物の記憶など、直接内容に関係がないアナログなできごとが学習内容と結びついて記憶の定着に役立った気がします。

初心者向けのHTML+CSS本はたくさんあり迷ったのですが、最終的に装丁が一番好みの本を選びました。初心者が悩んだところでベストの本は選べないだろうし、出版社を通じて発売されたものはどれも内容は保証されているので、多分このぐらい気軽な選び方でいいと思います。
とあるブックデザイナーの方がおっしゃっていたのですが、とっつきにくい内容の本ほど紙は軽いものを選んでいるそうです。たしかにめくり心地が良い本だと、難しい内容でもページをめくろうという気持ちになりました。

# それでもいろいろ試しておいてよかった
結果的に紙の本で学ぶのが１番しっくりきましたが、最初から１つの方法で学んでいても多分理解できなかったと思います。いろんな方法を試して、ああでもないこうでもないと悩んだり、間違って覚えたり、疲れて休んでいる時間だったりが全部あったからこそ、最終的に手元にある本が読み進めやすくなったのかもしれません。

これからもっと成長すればまた考えも変わると思いますが、学習して約1年弱経った現在の感想として投稿させていただきました。これからもコツコツと学習を進めていこうと思います。
【Laravelエラー】Cannot add or update a child row: a foreign key constraint fails

## 環境
Laravel v9.5.1 (PHP v8.1.3)

## 状況

```php artisan migrate:refresh --seed```を実行したとき、外部キーを設定している場合に下記のエラーが出ることがある。


```
Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails...
```

## 原因
上記コマンドで```refresh```した後に```db:seed```を実行しているが、seedを実行するファイルの順番で子ファイルが親ファイルより先に実行されてしまっているから。


## 解決法
migrateがちゃんとされているかを確認しできていたら、
ファイルを指定して、親ファイルが先にseedされるようにする。

```
db:seed --class=HogeSeeder
```
プログラム習得～初めの一歩･･･その手前の入り口

## 一念発起してみる
永らくIT業界と関わりがあるものの、根が文系で、なおかつ職種も運用保守系のため、プログラミングとは疎遠であった。
が、まもなく4月、新学期（とは無縁だが）が始まる！
ここは一念発起して、プログラミングを勉強してみよう（してみたい、できたらいいな・・・）と思った。

プログラムと一言でいってみたものの、いろんなプログラミング言語があることくらいは知っている。
（今や小学生でも知っている）

C,Java,PHP,Ruby,アセンブラなどなど（って、本当は何も知らないのがバレバレである）。

なんだかんだネットを探索してみて、どうやらPython（というの）が最近の流行り（？）で、敷居が低いようだ（ホントか？）。
学習環境（開発環境？）も簡単に手に入りそうだ（という楽観的な憶測）。
とは言え、なかなかプライベートで机に向かってパソコンを操作する時間がなさそうだ。
（ま、いろいろプライベートも忙しくて、って最初の一念発起とはウラハラである）

## いつ実行するのか
さて、どうしたものか。。。そうだ！（って、最初からわかってたのだが、話の都合上、気づいたふり）
時間がないと言いながら、通勤の電車内での時間は割と無駄にしている。
たいていの人と同じように、スマホでゲームをしたり、ネットニュースを見たりとかなり非生産的である。
（いや、実はたいていの人は、スマホで生産的なことをしてるのかもしれない。これは失言だったかもしれない。
でも、スマホでコミックを読んでる人ばかりだ。と見せかけて、マンガ日本の歴史を読んで勉強しているのかもしれない。
でも、ほんとうは・・・以下略）

片道30分の通勤時間の有効活用としてPythonを勉強しよう！
と思ったけれど、ノートPCは重いので（！）って、違う、セキュリティ上、業務用ノートPCはロッカーに厳重に保管されているので、何かほかの手段を考えなければ。。
Python入門的な書籍を読むとか、スマホでプログラミング学習サイトを開くとか。。。

お、そうだ。
今から2，3年前、indiegogo（クラウドファンディングサイト）で購入したキーボード付きスマホ <b>Cosmo Communicator</b> が
部屋のオブジェになっている。
これを使えば電車の中でPythonの勉強もできるはず。

## ガジェット登場
<b>Cosmo Communicator</b> はGeminiPDAの後継機で、昔のPDA（パーソナルデジタルアシスタント）PSIONに似たガジェットです（唐突に呪文のような言葉を並べてみましたが、興味のある方はネットで検索を）。
![20220330_130606.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2220790/7715872b-b3c6-5fdf-7648-37d3c4524bc4.jpeg)

小さなノートPCのようですが、スマホです。
OSはAndroid10で、メモリ6GB/128GB、画面サイズはメインが約6インチ、カバー裏（？）のサブ画面が2インチで、Dual SIM対応で、物理nanoSIMの他、排他的にeSIMも1つ使えます。
なので、電車の中でも通信しながら、プログラミングの勉強ができます。便利ですね（ホントか？）。

ただ、スマホなのに日常的に持ち歩くには重い。。。
それで、手許に届いてから一週間後には部屋のオブジェと化していたのでした。
![20220330_113018.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2220790/22e9550d-2ef0-5627-e506-ff5769b3be5d.jpeg)

## 環境を整える？
前置きはこのくらいにして（って、今まで前置きだったのか）、早速、Python学習の環境を整えましょう。

まずは<b>Androidで使えるPython</b>を探してみます。
Google先生に訊いてみると、<b>Pydroid</b> と <b>QPython</b>というのが候補で出てきました。
どちらにしようか、一瞬迷いましたが、すぐにマヨラーとしてはQPython一択と気づきましたので、
早速、GooglePlayストアからダウンロードします。ファイルサイズは23MBくらい。

インストールが完了したら、開いてみます。
表示されたQPythonの画面には5つアイコンが並んでいます。
この中のEditorをタップして、開くとプログラムが書けるはずです。
![Screenshot_20220330-085337.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2220790/1c32cd39-e80e-e8b6-1283-c6ef819421b5.png)


ようやくスタートラインの手前に立てました。
さあ、ここから新しい知識を習得するための冒険が始まるんだ！！

  <b>- 完 -</b>

※週刊少年マンガ雑誌の連載によくある唐突な最終回のようになってしまいましたが、ここから真面目にプログラミング学習をスタートして行こうと思ってます（本当です）。
エンジニアに価値あるサービス作りを学ばせる講義の思い出話 第2回


## はじめに

こちらはシリーズになります
この記事の前に[第1回の伝えたかった価値観](https://qiita.com/kiitan/items/48d451837aa3a8af43c8)を読んだ前提で記載します

https://qiita.com/kiitan/items/48d451837aa3a8af43c8

前回は私がお手伝いしていた講義で伝えたかった価値観とそれが必要な理由を述べました
今回はそれを学ぶにあたりどのような手段を用いるのかについて記載します

### 前回の忘れ物の回収 

前回は「ものづくり」をしないエンジニアを育てることが目的であることをお伝えしました
しかし表現として「ものづくり」をしないエンジニアとはわかりにくい
なので価値に対して思考し作り出せるエンジニアとしてストレートに価値創造できるエンジニアと表現することにします

では続いてどうやって工夫して伝えていくことにしたのかをつらつら書いていきます

### 学習方法

前回のおさらいをすると学んで欲しいの下記の2点だけです
- 使ってもらえる価値を生み出せること
- 価値から対価を得ることができること

私はこれらを体験学習形式で学んでもらうことにしました
価値あるサービスの仮説を立てて検証しマネタイズまでのロードマップを引く過程で価値創造ができるエンジニアに必要要素を身につけてもらいます

### 使ってもらえる価値を生み出すことを学ぶ

第1の関門は手法を考えるエンジニアが手段と価値の違いを意識させることでした
まったく違う考え方をしなければならないため受け入れてもらうには失敗して気づくことが効果的であると結論に至りました
ただ失敗すればいいというものではなく素早く失敗に気づくことが大切です

そこでどうすれば素早く失敗し気づきを得られるようにするか問題となります
エンジニア向けの学習ですがプログラミングに没頭しては時間がかかりすぎます
そこでペーパープロトタイプやプロトタイピングツールを使って画面を作り自分たちの仮想顧客に対してインタービューを行わせました
素早くできるプロトタイピングを使って制作時間を小さくしインタビューを実施することでリリース前に素早く気づくことができるようにしました

プロトタイプを作成する時はもっとも顧客に刺さる部分だけ作るように指示します
これで自分たちの考えたサービスが何をコアの価値としているのかを定義させていきます
<!-- 実際ボロクロに言ってもらえると有用なのですが相当頑張ってやらないと大抵生易しいお世辞を拾ってきます
インタビューは難しいということを意識してしないと時間の無駄になります -->

インタビューを行わせるのは意見をもらって失敗に気づくというのもあるのですが自分たちの口で他人に説明させることが狙いでした
エンジニアにサービスを説明させると機能説明になります
練習としてメンターに対してインタービューをさせ気長に指摘し価値を説明する練習をさせることで手段と価値の違いを学習してもらいます
かなり力技ですが説明をさせ機能説明になっているところ指摘し言い換えさせるのを根気よくやっていくしかありません

また複数チームがあったため相互にレビューさせました
これが結構気づきに繋がっていました
なにせ他人の考えたものを批評した言葉がそっくりそのまま自分の考えたアイデアに当てはまることが発生するため第3者視点になることの大切さが骨身に染みこととなりました

ほっとくとエンジニアは大なり小なり作ることに喜びを感じるのでそちらに流れます
価値創造は失敗するのでともかく作ることより検証し証明・評価することを高速に回すことが必要だとわかってもらえれば及第点としていました

### 価値から対価を得ることを学ぶ

まず知らないことには考えようもないので普段自分たちが使っているサービスがどう行ったマネタイズを行っているのかをいくつか紹介します

次に自分たちのサービスが取りうるマネタイズを考えてもらいます
あとは基本的な顧客数を見積もりコストを試算して利益が上がるか計算してもらいます

学生でしたのでメンターも一緒になって拙い計画を立てていました
ただここで他のサービスや普段無料で使っているサービスがどこでマネタイズしているのか（または目指しているのか）を調べたり考えたりすることを学べました
普段から考えていると自分では思いつかない方法を学べるので今でも普段から考えるようにしています
ビジネスコンテストを見るのもおもしろですしマネタイズの方法を話してくれるのでおすすめです
コミュケーションの前に～私の「赤」はあなたの「赤」か？～


<h2>働き方の変化</h2>
<p>つい何年か前までは、仕事をする、と言えば出社するのが当たり前だった。<br>でも今は、多様な働き方が可能であることこそが当たり前の風潮。私も、自宅の一室を職場とするようになってからもう随分と経つ気がしている。<br>
どんな働き方でも、メリット・デメリットはある。例えば在宅での仕事が続くと、合間に家事をしたり、穴のあいた靴下も気にせず履けたりするけれど、1週間全く家から出なかったということも珍しくない。<br>
<br>
会社の仲間がひとつの場所に集まらずに仕事を進めていくことや、お客様ともリアルに対面する機会が減ったことに関して感じるメリット・デメリットは人それぞれだろう。<br>それでも、「コミュケーション」に関するあれこれはネットニュースなどでもよく取り上げられていたし、改善すべき課題だととらえている人も少なくないはずだ。</p>
<br>
<h2>「コミュニケーションの“成功”」とは何だ</h2>
<p>今はzoomやGoogle Meetなど、いる場所が離れていてもお互いの顔を見て話せるツールが多く活用されている。要件を伝え合うだけならば、ChatworkやSlackだけで十分足りるはずなのに、なぜ声を聞きたがるのか。顔を見たがるのか。そこに「コミュニケーションの“成功”」のための大事なポイントがあるのではないか。<br>
<br>
コミュニケーションと言うと、和気あいあいとおしゃべりをしたり、何かのイベントに参加したりする場面を思い浮かべる人が多いかもしれないが、それは間違いでないにしろ正しくもない。<br><strong>コミュニケーションとは「他人に耳を傾ける」ことだ。</strong><br>別に、極端に盛り上げたり、言いたくないことをわざわざ自ら話す必要もない。<br>相手が話しやすいように相槌を打ったり、興味を持って質問したり、話している時に相手がどんな表情をしているかを観察することがコミュニケーションだ。（これが上手にできる人は少ない。かく言う私も得意ではない。）<br>相手が何を思っているのか、伝えたいのかを把握することが、「コミュニケーションの“成功”」ではないだろうか。そのためには、文面だけでなく身振りや手ぶり、視線、声色などたくさんの判断要素が必要なことから、様々なツールが活用されていると考えれば合点がいく。</p>

<h2>「わかったこと」は本物か？</h2>
<p>クオリアという言葉をご存じだろうか。<br>クオリアは、私たちが意識的に主観的に感じたり経験したりする「質」のことを指している。<br>わかりやすく言えば、レモンを食べてすっぱいと感じたり、海を見て青いと感じた時の質感、とでも言えばいいだろうか。<br>
これはあくまでも<strong>主観的な感覚</strong>なので、同じレモンを食べても、同じ海を見ても、他の誰かと同一の感覚を持つことはできない。<br>しかし私たちは、「このレモンすっぱいね！」「うん、すっぱいね」という会話が成り立っているはずだ。<br>これは「レモン」と「すっぱい」に関してお互いに共通言語としての認識があるからであって、完全に同じ感覚を共有している証明にはならない。<br>「この物体をレモンと呼ぶんだな」「この感覚をすっぱいと表現するんだな」という、感覚→言語へ変換する過程はそれぞれ違うからだ。<br>
<br>
例えばAさんとBさんが同じリンゴを指さして「赤いりんご」と言ったとしても、同じクオリアが生じているとは言えない。<br>
Aさんが「（Aさんにとっての）赤と認識」して「赤と呼んでいる」色は、Bさんにとっては「（Aさんにとっての）オレンジと認識」して「赤と呼んでいる」色かもしれない。その違いは、どれだけ言葉や仕草や表情で伝え合ったとしても説明することはできない。<br>
コミュニケーションによって、相手の思いや伝えたいことがわかった！と思ってもそれは実際のところ不十分なのである。もしかすると、相手の感覚のうち十分の一も共有できていないのかもしれない。本当のところにかすりもしていない可能性だってある。</p>
※クオリアについては茂木さんの本が面白いと思う<br>
<a href="https://www.amazon.co.jp/%E3%82%AF%E3%82%AA%E3%83%AA%E3%82%A2%E3%81%A8%E4%BA%BA%E5%B7%A5%E6%84%8F%E8%AD%98-%E8%AC%9B%E8%AB%87%E7%A4%BE%E7%8F%BE%E4%BB%A3%E6%96%B0%E6%9B%B8-%E8%8C%82%E6%9C%A8%E5%81%A5%E4%B8%80%E9%83%8E-ebook/dp/B08CDN4GWP/ref=sr_1_4?__mk_ja_JP=%E3%82%AB%E3%82%BF%E3%82%AB%E3%83%8A&crid=2XYN3O6AT0V2&keywords=%E3%82%AF%E3%82%AA%E3%83%AA%E3%82%A2&qid=1648610779&rnid=2321267051&s=books&sprefix=%E3%82%AF%E3%82%AA%E3%83%AA%E3%82%A2%2Caps%2C522&sr=1-4" target="_blank"><img src="https://m.media-amazon.com/images/I/516wuZR8zaL.jpg"></a>

<h2>わからないからやる</h2>
<p>いくらコミュニケーションをとっても本当のところがわからないなら、やる意味がないのだろうか。否、やらなくなったらおしまいだ。1パーセントもわからないまま。<br>
何もわからない人と一緒に仕事をして、良いものができるだろうか。<br>
何もわからない人のために何かを作って、満足してもらえるだろうか。<br>
<br>
<strong>“わからないことを前提に”少しでも多く“相手が何を思っているのか、伝えたいのかを把握”しようとすることに意味がある。</strong><br>
<br>
ちょっと苦手だった同僚の「赤」が自分の「赤」よりもやわらかいことや、初めてのお客さまの「レモン」が自分の「レモン」よりもツルツルしていることになんとなく気が付けたら、もっと良い仕事ができるはずだ。</p>
100日でSQLの達人になる@LeetCode! Day57 <DELETE, TRUNCATE, DROPの違い>

## DELETE, TRUNCATE, DROPの違いについて理解する
前回に引き続き[LeetCode](https://leetcode.com/)の問題はお休み。
[LeetCode](https://leetcode.com/)ではあまり出てこないテーマを一気に学習します。
今回のテーマは`DELETE, TRUNCATE, DROPの違い`です。

`DELETE`, `TRUNCATE`, `DROP`も全てテーブルのデータを一括して削除することができます。

前回同様に[db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019)を使います。


### 構文は下記の通り
```:SQL
DELETE テーブル名 WHERE句 -- WHERE句を省略すると全データ削除
TRUNCATE TABLE テーブル名
DROP TABLE テーブル名
```

まとめると
|クエリ|削除範囲|ロールバック|速度|テーブル構造|
|-|-|-|-|-|
|DELETE|WHEREで指定可能|可能|遅い|残る|
|TRUNCATE TABLE|指定不可|不可能|早い|残る|
|DROP TABLE|指定不可|不可能|早い|残らない|

ロールバックについては十分に理解できていないのですが、
`COMMIT`していなければ削除の取り消しが可能ということです。

下記が実行例です。
<!-- -->
>     CREATE TABLE tbl1 (id INT, name varchar(1))
>     
>     INSERT INTO tbl1 (id, name) VALUES(1, 'a'),(2, 'b'),(3, 'c'),(4, 'd'),(5, 'e')
>     
>     SELECT id, name
>       FROM tbl1
>       
>     DELETE tbl1 WHERE id > 3
>          
>     SELECT id, name
>       FROM tbl1
>       
>     TRUNCATE TABLE tbl1
>     
>     SELECT id, name
>       FROM tbl1
>       
>     DROP TABLE tbl1
>     
>     -- SELECT id, name
>     --  FROM tbl1

>     GO
> 
> <pre>
> id | name
> -: | :---
>  1 | a   
>  2 | b   
>  3 | c   
>  4 | d   
>  5 | e   
> 
> id | name
> -: | :---
>  1 | a   
>  2 | b   
>  3 | c   
> 
> id | name
> -: | :---
> </pre>

*db<>fiddle [here](https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=5db20c3a75fa005de998a3a079018991)*

`DROP TABLE`後に、`SELECT文`を使用すると、テーブルそのものが無いので下記のエラーが出てきます。
```
Msg 208 Level 16 State 1 Line 20
Invalid object name 'tbl1'.
```

今日のポイントは`DELETE, TRUNCATE, DROPの違い`とした。
Let's Encrypt で証明書の期限が迫ってきたというメールが来た時の対応

有効期限切れが近づくと、次のようなメールが届きます。

```text
件名:	Let's Encrypt certificate expiration notice for domain "example.com"

Hello,

Your certificate (or certificates) for the names listed below will expire in 11 days (on 08 Apr 22 23:24 +0000). Please make sure to renew your certificate before then, or visitors to your web site will encounter errors.

We recommend renewing certificates automatically when they have a third of their total lifetime left. For Let's Encrypt's current 90-day certificates, that means renewing 30 days before expiration. See https://letsencrypt.org/docs/integration-guide/ for details.

example.com
```

## ブラウザーで確認　##

期限が 4月16日になっています。

## ssh でログインして、証明書ファイルの期限を確認

期限が 6月15日になっています。

```text
$ sudo openssl x509 -noout -dates -in /etc/letsencrypt/live/example.com/fullchain.pem
notBefore=Mar 17 23:51:22 2022 GMT
notAfter=Jun 15 23:51:21 2022 GMT
```

## openssl で確認　##

リモートで
期限が 4月16日になっています。

```text
$ openssl s_client -connect example.com:443  < /dev/null 2> /dev/null | openssl x509 -text | grep "Not"
            Not Before: Jan 16 07:30:04 2022 GMT
            Not After : Apr 16 07:30:03 2022 GMT
```

localhostで
期限が 4月16日になっています。

```bash
$ openssl s_client -connect localhost:443  < /dev/null 2> /dev/null | openssl x509 -text | grep "Not"
            Not Before: Jan 16 07:30:04 2022 GMT
            Not After : Apr 16 07:30:03 2022 GMT
```

## SSL Server Test で確認
[SSL Server Test](https://www.ssllabs.com/ssltest/)
期限が 4月16日になっています。

## 解決策 ##

```bash
sudo systemctl restart nginx
```

期限が 6月15日になりました。

原因不明ですが、cron で証明書を更新したあとの nginx の再起動が働いていなかったようです。
100日でSQLの達人になる@LeetCode! Day56 <DELETE文でデータを削除する>

## DELETE句について理解する
前回に引き続き[LeetCode](https://leetcode.com/)の問題はお休み。
[LeetCode](https://leetcode.com/)ではあまり出てこないテーマを一気に学習します。
今回のテーマは`DELETE句`です。
`DELETE句は、テーブルに対して条件に合う行データを削除する時に使用します。

前回同様に[db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019)を使います。

### 基本の構文
```:SQL
DELETE　テーブル名　WHERE句
ｰｰ下記でも全く同じ
DELETE　FROM　テーブル名 WHERE句
```

下記が実行例です。
<!-- -->
>     CREATE TABLE tbl1 (id INT, name varchar(1))
>     
>     INSERT INTO tbl1 (id, name) VALUES(1, 'a'),(2, 'b'),(3, 'c'),(4, 'd'),(5, 'e')
>     
>     SELECT id, name
>       FROM tbl1
>       
>     DELETE tbl1 WHERE id > 3
>          
>     SELECT id, name
>       FROM tbl1
>     GO
> 
> <pre>
> id | name
> -: | :---
>  1 | a   
>  2 | b   
>  3 | c   
>  4 | d   
>  5 | e   
> 
> id | name
> -: | :---
>  1 | a   
>  2 | b   
>  3 | c   
> </pre>

*db<>fiddle [here](https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=61a57b157e77c6a29ce7b97fbcdf2a02)*

`DELETE句`では、`SELECT文`を使用したサブクエリも使用可能。
`WHERE句`を指定しないと全件削除になってしまうので要注意！

今日のポイントは`UPDATE句で表を更新する`とした。
[その5]AWS-SAA-躓いたメモ

## 既存のEBSボリュームを暗号化ボリュームを変更するには
1. 既存のボリュームの`スナップショット`を作成
1. 作成したSnapShotを複製する際に暗号化オプションに指定
1. 暗号化されたSnapshotから`EBSボリュームを再作成`
1. EC2インスタンスから既存のEBSボリュームにデタッチ
1. EC2インスタンスへ暗号化されたEBSボリュームをアタッチ

## S3 Glacier
データは全てサーバー側で暗号化


## Amazon Guard Duty
悪意ある攻撃・不正操作などのセキュリティ脅威を検知するサービス


## RDS for Oracleのライセンス
- 自分のラインセンス(BYOL)
- ライセンス込み


## AWS Storage GateWay
`iSCSIテーブルデバイス`として扱える保存先である`iSCIイニシエータ`の宛先を変更するだけで、AWSへのバックアップが可能

キーワード：NFS,SMB,iSCSI,iSCSI-VTL


## RDSの`自動バックアップはデフォルトで有効`
自動化バックアップ機能を使うと、新しいエンドポイントを持つ新しいDBインスタンスを作成させる

## Route53レコードクエリの無料のものは`エイリアス`

AAAA(IPv6アドレス)
CNAME(正規名)
MX(メール交換)
NS(ネームサーバ)
PTR(ポインター)
SOA(管理情報の始点)
SPF(センダーポリシーフレームワーク)
SRV(サービスロケータ)


## RDSの高用性
マルチAZ


## RDSのマルチAZ配置
`異なるAZ`にあるスタンバイインスタンスにデータ複製


## EBSボリュームステータス
全てのチェックが成功→OK
失敗→`impaired`
実行中→`insufficient-data`

## ネットワークACLはルールは最も低いルール番号から評価

## S3 Glacier 3ヶ月未満でアーカイブを削除すると金がかかる。

## DBインスタンスタイプどちらも削除しても保持される
- 手動スナップショット
- 自動スナップショット

## AWSサポートプラン 4種類
- ベーシック
- デベロッパー
- ビジネス
- エンタープライズ


## DynamoDB Streamsは結果整合性
DynamoDBへの追加、変更履歴を24時間保持する

## DynamoDBのキャパシティユニット
- RCU
読み込み項目数✖️項目サイズ
- WCU
書き込み項目数✖️項目サイズ


## Auroraの4つのエンドポイント
### cluster endpoint
現在のマスターDBインスタンスに接続するエンドポイント読み込みができる唯一のエンドポイント

### Reader EndPoint
読み込み専用。スレーブが障害時昇格してマスターになる

### Custom endpoint
任意である

### InstanceEndPoint
クラスターの特定


## Storage Gateway
オンプレから利用するクラウドのストレージ

### ファイルゲートウェイ
オンプレのNFSまたはSMBファイルベースのアプリケーションからローカルキャッシュを使用し、S3に保存する


### テープゲートウェイ
AWSの仮想テープにオンプレミスデータをバックアップしアーカイブへ

### ボリュームゲートウェイ
オンプレのアプリからiSCIのブロックストレージとしてS3に保存する

## Route53はネットにアクセスできるエンドポイントに使用可のためオンプレでも可

## EC2とEBSでDBを構築する場合、EBSのボリュームはプロビジョンドIPOS SSD(i01)にする

## インターネットに出ないでS3とRedShiftを接続する場合、
amazonS3 VPCエンドポイント作成。Redshift拡張VPCルーティングを有効にする。


## ALB複数ドメインSSL化
ドメインを複数保持＋データの暗号化
→`SNI証明書`をALBに設定

## EC2セキュリティの脆弱性を診断したい時はAmazon Inspector
Amazon Inspector はセキュリティ評価サービス

## ECS +(S3,SQS)のIAM
タスク定義で`taskRoleRun`として指定
タスク実行ロール(executionRoleArn)もある。


## Ec2+s3は使用量が増えるとボリュームディスカウントが効く
→ Organizationの一括請求機能が有効

## EBSのボリュームタイプ選択時にサイズ<100GBの時gp2がやすい

## プライベートIPアドレスを指定してEc2インスタンス起動
→　Ec2作成後はプライベートIPアドレスを変更できない。
VPCにインスタンスを作成するときに、プライベートIPアドレスを割り当てる。

インスタンスのプロパティにアクセスするために、インスタンスのデータにアクセスが必要。


## Ec2のルートボリュームデバイス
インスタンス起動時、`ルートデバイスボリュームに格納されたイメージ`を使用してインスタんがブートされる。

`/dev/sdal`はルート用に予約されたボリューム


## NATインスタンス
送信下または送信先がインスタンスでない時もトラフィックを送受信できないといけないので、`送信元/先チェック`を消す。`SrcDestCheck属性を無効`へ


## RDSのマルチAZは配置のスタンバイは読み取りトラフィックの処理は`できない`
C＃VB.NETを使用してPDFをSVGファイル形式に変換する方法

## SVGファイル形式の紹介とその利点

SVGは、現在最も人気のある画像ファイル形式の一つとも言えます。その完全な英語名は、ScalableVector Graphicsであり、縮小また拡大することができるベクター画像のことを指しています。これは、WorldWide Web Consortium（W3C）アライアンスによって開発されたXML（ExtensibleMarkup Language）に基づく形式です。厳格に言えば、高解像度のWebグラフィックページをデザインできるオープンスタンダードのベクターグラフィック言語であるものです。ユーザーはコードを直接使用して画像を描画したり、任意のワードプロセッシングツールでSVG画像を開いたり、コードの一部を変更して画像をインタラクティブにしたり、いつでもHTMLに挿入してブラウザで表示したりできます。

## 他の画像形式に対するSVGを使用する利点は次のとおりです。

SVGは、多くのツール（メモ帳など）で読み取りおよび変更できます
SVGは、JPEGおよびGIF画像よりも小さく、圧縮性があります
SVGは伸縮性を持っています
SVG画像は、任意の解像度で高品質で印刷できます
SVGは、画質を損なうことなくスケールアップできます
SVG画像のテキストはオプションで検索可能です（マップの作成に最適）
SVGはJavaScript技術で実行できます
SVGは開放的なスタンダードです
SVGは純粋なXMLファイルです

## PDFファイルをSVGに変換する

開発者は、PDFコンポーネントであるSpire.PDFを使用して、C＃/VB.NETプログラムでPDFファイルをSVG形式に簡単に変換できます。次の内容では、Spire.PDFを使用してPDFからSVGファイルへの変換する方法を紹介します。
以下は、元のPDFドキュメントのスクリーンショットです。
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/5d2c7b1d-cba1-2662-de05-b9141c3b30e8.png)

開始する前に、[Spire.PDF](https://www.e-iceblue.com/Download/download-pdf-for-net-now.html)をダウンロードしてインストールし、C＃/ VB.NETプログラムを作成して、プロジェクトへの参照としてSpire.Pdf.dllを追加してください。
使用する名前空間：
using Spire.Pdf;
**ステップ１**　新しいPDFドキュメントオブジェクトを作成し、元のPDFファイルをロードする。
```csharp
PdfDocument doc = new PdfDocument();
doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\テスト.pdf");
```
**ステップ２**　PDFファイルを.svg形式で保存する。コンポーネントによって提供されるPdfDocument.SaveToFile(stringfilename、FileFormat fileFormat)メソッドを呼び出して使用する。
```csharp
doc.SaveToFile("Result.svg", 0, 0, FileFormat.SVG);
```
Spire.PDFは、PDFからSVG形式への変換以外に、PDFからWord、Html、Xps、PDF/Aおよびその他の形式への変換もサポートしています。
変換後の結果SVGファイルは次のように：
![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/278784/e4886d57-0f54-c101-b04d-c074773f3899.png)

 
## 完全なるコード一覧
**C#**

```csharp
using Spire.Pdf;

namespace Convert_PDF_to_SVG
{
    class Program
    {
        static void Main(string[] args)
        {
            PdfDocument doc = new PdfDocument();
            doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\テスト.pdf");
            doc.SaveToFile("Result.svg", 0, 0, FileFormat.SVG);
        }
    }
}
```
**VB.NET**

```vb
Imports Spire.Pdf
 
Namespace Convert_PDF_to_SVG
    Class Program
        Shared  Sub Main(ByVal args() As String)
            Dim doc As PdfDocument =  New PdfDocument() 
            doc.LoadFromFile("C:\\Users\\Administrator\\Desktop\\テスト.pdf")
            doc.SaveToFile("Result.svg", 0, 0, FileFormat.SVG)
        End Sub
    End Class
End Namespace
```

今回のPDFをSVGファイル形式に変換する方法は以上でした、最後まで読んでいただきありがとうございました。
100日でSQLの達人になる@LeetCode! Day55 <UPDATE句で表を更新する>

## UPDATE句について理解する
前回に引き続き[LeetCode](https://leetcode.com/)の問題はお休み。
[LeetCode](https://leetcode.com/)ではあまり出てこないテーマを一気に学習します。
今回のテーマは`UPDATE句`です。
`UPDATE句は、テーブルに対して一括でデータを更新する時に使用します。

前回同様に[db<>fiddle](https://dbfiddle.uk/?rdbms=sqlserver_2019)を使います。

### 基本の構文
```:SQL
UPDATE テーブル名 SET 列名１ = 値1, 列名2 = 値2 WHERE句など
```

下記が実行例です。
<!-- -->
>     CREATE TABLE tbl1 (id INT, name varchar(1))
>     
>     INSERT INTO tbl1 (id, name) VALUES(1, 'a'),(2, 'b'),(3, 'c'),(4, 'd'),(5, 'e')
>     
>     SELECT id, name
>       FROM tbl1
>       
>     UPDATE tbl1 SET id=id+1000
>          
>     SELECT id, name
>       FROM tbl1
>     GO
> 
> <pre>
> id | name
> -: | :---
>  1 | a   
>  2 | b   
>  3 | c   
>  4 | d   
>  5 | e   
> 
>   id | name
> ---: | :---
> 1001 | a   
> 1002 | b   
> 1003 | c   
> 1004 | d   
> 1005 | e   
> </pre>

*db<>fiddle [here](https://dbfiddle.uk/?rdbms=sqlserver_2019&fiddle=ea0c917756439d47ebbd4b3cbef4693e)*

`UPDATE句`では、`JOIN`や`CASE WHEN`なども使用可能。

今日のポイントは`UPDATE句で表を更新する`とした。
AlmaLinux 8を日本語化する

# What's？

タイトルどおり、AlmaLinux 8を日本語化するためのメモです。

# 環境

今回の環境は、こちら。

```shell
$ cat /etc/redhat-release
AlmaLinux release 8.5 (Arctic Sphynx)


$ uname -srvmpio
Linux 4.18.0-348.20.1.el8_5.x86_64 #1 SMP Thu Mar 10 11:31:47 EST 2022 x86_64 x86_64 x86_64 GNU/Linux
```

作業前のロケールおよびタイムゾーン。

```shell
$ localectl
   System Locale: LANG=en_US.UTF-8
       VC Keymap: us
      X11 Layout: us


$ timedatectl
               Local time: Wed 2022-03-30 03:28:08 UTC
           Universal time: Wed 2022-03-30 03:28:08 UTC
                 RTC time: Wed 2022-03-30 03:27:49
                Time zone: UTC (UTC, +0000)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no
```

ここから、日本語化していきます。

# ロケールを日本語にする

以下のコマンドで変更。

```shell
$ sudo localectl set-locale LANG=ja_JP.utf8
```

失敗する場合は

```shell
$ sudo localectl set-locale LANG=ja_JP.utf8
Failed to issue method call: Locale ja_JP.utf8 not installed, refusing.
```

`glibc-langpack-ja`をインストールしてから

```shell
$ sudo dnf install glibc-langpack-ja
```

再度実行。

```shell
$ sudo localectl set-locale LANG=ja_JP.utf8
```

確認。

```shell
$ localectl
   System Locale: LANG=ja_JP.utf8
       VC Keymap: us
      X11 Layout: us


$ cat /etc/locale.conf
LANG=ja_JP.utf8
```

キーマップも変えておきましょう。日本語系のキーマップを確認。

```shell
$ localectl list-keymaps | grep jp
jp
jp-OADG109A
jp-dvorak
jp-kana86
jp106
```

今回は、`jp106`にしておきます。

```shell
$ sudo localectl set-keymap jp106
```

確認。

```shell
$ localectl
   System Locale: LANG=ja_JP.utf8
       VC Keymap: jp106
      X11 Layout: jp
       X11 Model: jp106
     X11 Options: terminate:ctrl_alt_bksp
```

# タイムゾーンをAsia/Tokyoにする

タイムゾーンを`Asia/Tokyo`に変更。

```shell
$ sudo timedatectl set-timezone Asia/Tokyo
```

確認。

```shell
$ timedatectl
               Local time: 水 2022-03-30 12:34:40 JST
           Universal time: 水 2022-03-30 03:34:40 UTC
                 RTC time: 水 2022-03-30 03:34:07
                Time zone: Asia/Tokyo (JST, +0900)
System clock synchronized: no
              NTP service: active
          RTC in local TZ: no
```

# 日本語言語パックのインストール

この時点で割と日本語になっていますが、日本語言語パックもインストールしておきましょう。

```shell
$ sudo dnf install langpacks-ja
```

# まとめて

ここまでをまとめると、こんな感じに。

```shell
#!/bin/bash

# locale & keymap
sudo dnf install -y glibc-langpack-ja
sudo localectl set-locale LANG=ja_JP.utf8
sudo localectl set-keymap jp106

# timezone
sudo timedatectl set-timezone Asia/Tokyo

# lang pack
sudo dnf install -y langpacks-ja
```
System.Text.JsonでJSONをキャメルケースでシリアライズする

# はじめに

昔、`Newtonsoft.Json`があった（いまもある）。
`Newtonsoft.Json`は、変換が柔軟な反面、パフォーマンス等が犠牲になっている。

しかし、常に柔軟さが必要なわけではない。
変換が厳密でいい場合に、`Newtonsoft.Json`の機能は過剰であるから、よりパフォーマンスに優れたライブラリ`System.Text.Json`が作られた。

柔軟とはどういうことか？
例えば、`Newtonsoft.Json`では、JSONの`name`というキーがあったとき、これはC#の`Name`プロパティにデシリアライズできる。
`System.Text.Json`ではデフォルトではこれはできない。
でも、**JSONのキーはキャメルケースにしたいじゃん？**

# めんどくさい方法

C#のプロパティがどういう風にシリアライズされるか、は、プロパティごとに属性で定義できる。
```c#:個別に設定するめんどくさい方法
public class Model
{
    [JsonPropertyName("name")]
    public string Name { get; set; }
}
```
これで自由にキー名をコントロールできる。
が、プロパティが多いと、全部にこれを指定するのはめんどくさすぎる。

# 簡単な方法

キャメルケースにしたい！と決まっている場合は、わざわざプロパティに`JsonPropertyName`属性を指定せずとも、変換時の設定で一括でできる。
```c#:一括設定する方法
var options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
};
var json = JsonSerializer.Serialize(model, options);
```

プロパティについてる`JsonPropertyName`属性が優先されるので、基本はキャメルケースだけどこれだけ別の指定…もできる。

# もっと簡単な方法

Webでいい感じに使える、なんか、デフォルトの設定は無いの？→あります
```c#:WEBのデフォルト設定を通過う方法
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web);
var json = JsonSerializer.Serialize(model, options);
```
デフォルト設定として`JsonSerializerDefaults.Web`を指定すると、以下の設定がされる。
- シリアライズがキャメルケースになる
- デシリアライズ時にキーの大文字小文字が区別されなくなる
- デシリアライズ時に数値がダブルクオーテーションで囲まれていても良くなる

# おまけ：自分がよく使う設定

```c#:おまけ
var options = new JsonSerializerOptions(JsonSerializerDefaults.Web)
{
    Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
    //DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull,
    //WriteIndented = true,
};
var json = JsonSerializer.Serialize(model, options);
```
- Web設定をベースにしつつ…
- `Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping`
    - 値のエスケープをゆるゆるにする。
    - これをしないと、日本語もエスケープされて、読めなくなる。
        - `{"name":"\u3053\u3093\u306B\u3061\u306F"}`
    - 指定するとこう↓
        - `{"name":"こんにちは"}`
- `DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull`
    - 値がnullになってるプロパティを、JSONに含めなくする。
    - デフォルトでは`{"name":null}`みたいになるけど、これを付けておくと値がnullの場合は項目ごと無くなる。→`{}`
    - 適宜つける。
- `WriteIndented = true`
    - 出力をインデントする。
    - デバッグの時だけつける。
Hugo で記事の URL にエイリアスを設定する

# はじめに
- 静的サイトジェネレータ [Hugo](https://gohugo.io/) の設定のお話です
- 記事が増えると、 Web サイトを整理したくなりますよね。また、 URL を後から変えたくなることもあります。
- ただ、そうするとどこかからリンクされているページであればリンク切れを起こしてしまい、全部修正して回る羽目になります
- 自分のサイト内のリンクであればそれでもいいかも知れませんが、サイト外からリンクされている場合にはそういう訳にもいかないでしょう
- そのような場合は、記事にエイリアスを設定すれば解決します

# 検証環境
- hugo v0.93.3

# エイリアスの設定
- ページヘッダの Front Matter に ``aliases`` を記載することで、通常の URL に加えて、エイリアスによるアクセスが可能となります
- 実際には、エイリアスにアクセスすると本来の URL にリダイレクトされます

```toml:iosdc2019day1.md（抜粋）
+++
title = "iOSDC 2019 に Mac の環境構築に関する内容で登壇してきました"
date = "2019-09-07T07:33:45+09:00"
draft = false
toc = true
tags = [ "iOSDC", "iOS", "Swift", "macOS" ]
aliases = [ "/posts/iosdc2019day1/" ]
ogimage = "images/open_graph_logo.png"
+++

[iOSDC 2019 に Mac の環境構築の内容で LT 登壇します]({{< ref "/2019/iosdc2019pre.md">}}) で書いていましたが…
```

- 上記の記事に設定される本来のパスは [/2019/09/07/iosdc2019day1/](https://yagamo-style.com/2019/09/07/iosdc2019day1/) ですが、 [/posts/iosdc2019day1/](https://yagamo-style.com/posts/iosdc2019day1/) でもアクセスできます
- 実際にアクセスして、動作を確認してみてください

# まとめ
- 一度公開した Web ページの URL を変えるのは、いろいろと面倒です
    - でもやりたくなっちゃう
- そんな時は、この記事のようにエイリアスで対応しましょう

# 参考
- [URL Management | Hugo](https://gohugo.io/content-management/urls/)
【2022年最新】WordPressのEWWWとamazon-s3-and-cloudfrontプラグインでデータをマイグレーションする方法

この記事ではWordPressのEWWWプラグインで既存の画像データのパスを変更するデータのマイグレーション方法について記載しています。
今回はプラグインを利用してS3のみを利用しています。
CloudFrontに関しては範囲外になります。

## AWS側の作業手順
1. S3のバケットを作成
    1. S3は公開設定しておく。CloudFrontを利用している場合はCloudFront経由からのみアクセスOKとかの設定をしておくこと。
1. IAMユーザーの作成
    1. S3に対して全権限を付与しておく（AmazonS3FullAccess）

## WordPress側の作業手順
1. プラグインを追加
    1. [amazon-s3-and-cloudfront](https://ja.wordpress.org/plugins/amazon-s3-and-cloudfront/)
    1. [ewww-image-optimizer](https://wordpress.org/plugins/ewww-image-optimizer/)
1. wp-config.phpに作成したIAMユーザーのcredential情報を追加。
1. EWWWの設定画面で作成したバケットを指定。
    1. 「Remove Files From Server」をOFFにしておく。（サーバーに画像を残したい場合はONのままでいいが、オススメしない。）

## 画像をS3にアップロードする
1. サーバーにssh接続
1. 以下のコマンドでアップロードする。

```
aws s3 sync /{WordPressのインストールディレクトリ}/wp-content/uploads/ s3://{S3のバケット名}/wp-content/uploads/ --acl public-read
```

## データベースをマイグレーションする
1. WordPressのデータベースにログイン
1. 以下のコマンドでデータのマイグレーションを行う。（リージョンなどは確認してください）

```
insert into wp_as3cf_items (provider, region, bucket, path, original_path, is_private, source_type, source_id, source_path, original_source_path, extra_info, originator, is_verified)
select 'aws', 'ap-northeast-1', '{S3のバケット名}', substring_index(guid, '{domain}/', -1),substring_index(guid, '{domain}/', -1),0, 'media-library',ID,substring_index(guid, '/wp-content/uploads/', -1),substring_index(guid, '/wp-content/uploads/', -1),'a:2:{s:13:"private_sizes";a:0:{}s:14:"private_prefix";s:0:"";}', 0, 1 from wp_posts where post_mime_type in ('image/jpeg', 'image/png');
```

## 残作業
1. ロゴは上記のマイグレーションでは対応しきれないので、管理画面から指定し直す。
1. webp対応するのであれば、メニューのメディアからBulk Optimizeで画像を一括置換を行う。

## 投稿者について
山梨で[やまなみテクノロジーズ株式会社](https://yamanamitech.com/)の代表をしている小畑です。
WordPress周りの改修やweb制作、SEO対策やデータ分析にお困りでしたらお問い合わせください。
nvidia-smi が動かなくなったので対処する


ある日突然 nvidia-smi がエラーを吐くようになったので、解消までの作業ログです。  
突然エラーを吐くようになった原因は調査してません。  

## エラーメッセージ
```
$ nvidia-smi
Failed to initialize NVML: Driver/library version mismatch
`````

何やらバージョン違いで怒られている模様。

## カーネルのログを確認（抜粋）
```
$ dmesg |grep NVRM
[    8.110350] NVRM: loading NVIDIA UNIX x86_64 Kernel Module  450.142.00  Wed Jun 16 11:29:20 UTC 2021
[   13.010564] NVRM: API mismatch: the client has the version 470.103.01, but
               NVRM: this kernel module has the version 450.142.00.  Please
               NVRM: make sure that this kernel module and all NVIDIA driver
               NVRM: components have the same version.
[  478.234741] NVRM: client does not support versioning!!
```

カーネルモジュール（450.142.00）とクライアント（470.103.01）のバージョンが違うよと言われている。

## バージョンを確認（抜粋）
```
$ dpkg -l | grep nvidia
rc  libnvidia-compute-460-server:amd64     470.103.01-0ubuntu0.18.04.1         amd64        Transitional package for libnvidia-compute-470-server
ii  libnvidia-compute-470-server:amd64     470.103.01-0ubuntu0.18.04.1         amd64        NVIDIA libcompute package
hi  nvidia-fabricmanager-450               450.142.00-1                        amd64        Fabric Manager for NVSwitch based systems.
```

確かにカーネルログと一致。  
クライアントのバージョンをカーネルモジュールに揃えてみる。


## クライアントを削除
バージョンを揃えるために、現在インストールされているクライアントを削除する
```
$ sudo apt-get purge libnvidia*
```

## クライアントをインストール  
バージョンを揃えてクライアントをインストールする  
[参考](https://docs.nvidia.com/datacenter/tesla/tesla-installation-notes/index.html#ubuntu-lts) 
```
$ sudo apt-get install cuda-drivers-450
```


## 再起動後、確認
```
$ nvidia-smi
+-----------------------------------------------------------------------------+
| NVIDIA-SMI 450.172.01   Driver Version: 450.172.01   CUDA Version: 11.0     |
|-------------------------------+----------------------+----------------------+
| GPU  Name        Persistence-M| Bus-Id        Disp.A | Volatile Uncorr. ECC |
| Fan  Temp  Perf  Pwr:Usage/Cap|         Memory-Usage | GPU-Util  Compute M. |
|                               |                      |               MIG M. |
|===============================+======================+======================|
|   0  Tesla T4            On   | 00000000:00:1E.0 Off |                    0 |
| N/A   31C    P8     9W /  70W |      0MiB / 15109MiB |      0%      Default |
|                               |                      |                  N/A |
+-------------------------------+----------------------+----------------------+

+-----------------------------------------------------------------------------+
| Processes:                                                                  |
|  GPU   GI   CI        PID   Type   Process name                  GPU Memory |
|        ID   ID                                                   Usage      |
|=============================================================================|
|  No running processes found                                                 |
+-----------------------------------------------------------------------------+
```

解消しました。
ImageJ と cellpose を使って、細胞画像の輝度値を測定する。（２）

# 目的
顕微鏡撮影した細胞画像から、細胞膜領域と細胞質基質領域の範囲を選び、その平均輝度値を求めたい！

使用するアプリケーションは、以下の通りです。
- Fiji (ImageJ)　　　　　        
-画像解析ソフト
- anaconda 　　　　　　　　　　　　　　**←今回は、これのインストール！**
-Python を動かすところ
- cellpose
-Python で書かれた細胞画像の分節化に特化した、deep-learning に基づくアルゴリズム

上記アプリケーション（プラグインを含む）のインストールや、解析に必要なマクロを記録していきます。

### PC の環境
Windows 10

# この記事の範囲
Anaconda のインストール

Python を動かす方法としては、The Python Package Index を使う方法と、Anaconda を使う方法があります。
今回、Python を動かす理由としては、Python で書かれた cellpose を使いたいためです。
cellpose のインストールチュートリアルに、Anaconda を経由して Python を動かす方法で記載されていたので、今回は Anaconda を使用します。

# Anaconda のインストール

Anaconda のインストール方法は、下記の Python Japan の HP で詳しく記載されている方法の通りに行いました。
2022年3月時点で、Python の最新版は "3.9" です。cellpose のインストールナビには、「Python 3.8 を選んでね」とあり、少し心配をしたのですが、
無事に動くので、最新版の Anaconda を選択しても大丈夫だと思います。

[Python Japan による、Windows 版 Anaconda のインストール方法の紹介](https://www.python.jp/install/anaconda/windows/install.html)

上記のリンクの通り、

1) Anaconda の HP から、最新版の Windows 版 Anaconda をダウンロードします。

2) C:\Users\[your name]\anaconda3 もしくは、C:\Users\anaconda3 にインストールします。
このとき、オプションの選択ですが、デフォルトのままで大丈夫です。
-  PATH の設定はしなくてもいいです。Anaconda Prompt から cellpose を起動させればいいです。
-  Python を動かすシステムとして、Anaconda を設定します。



スタートボタンから、Anaconda3 > Anaconda Prompt (Anaconda3) をクリックすると、Anaconda 用のプロンプトが開かれます。
cellpose の起動は、このプロンプトから行うので、デスクトップにショートカットを作成するなどしておくと、便利です。


以上！
VSCodeで全角スペースなどのに黄色い枠(オレンジの枠？)が付いてしまうのを消すための設定方法

![名称未設定-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/3f807ed3-4530-a4f2-3f3d-58574398abf2.png)
全角スペースや全角の記号などで、それを目立たせるためにオレンジの枠で囲まれた表示になっていました。


日本語でメモしたりするときには邪魔になってしまうので、消す設定をしました。

このオレンジの枠は、新しく追加された設定「Unicodeハイライト表示」がデフォルトでオンになっているために表示されている、とのことです。

当記事内の引用部分は以下の記事から引用させていただきました
・[VS Codeで全角スペースを表示または非表示に設定する方法](https://zenn.dev/ayatokura/articles/vscode-article-5)


## 設定を変更する
### VSCodeの設定を開く
左下の歯車アイコン＞Settings
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/8c9e08ee-eaf8-e8fb-76fd-6b62ed32f221.png)


設定を「Unicode Highlight」で検索します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/17680273-f999-2679-ed06-ec8b822005bd.png)

### 全角スペースのハイライトを消すには
Editor > Unicode Highlight: Invisible Characters
> スペースを予約するだけの文字または幅がまったくない文字を強調表示するかどうかを制御します。デフォルトでオンになっているので、表示したくない場合にはチェックボックスでチェックを外す。

「オフ」にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/d6a9f495-f4df-4d2f-bdd6-9fe689271ee7.png)
日本語表示の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/dfa956fe-736c-309f-333d-add853186cb6.png)


### 記号のハイライトを消すには
Editor > Unicode Highlight: Ambiguous Characters
> 現在のユーザーロケールで一般的な文字を除き、基本的なASCII文字と混合される可能性のある文字を強調表示するかどうかを制御します。デフォルトでオンになっているので、表示したくない場合にはチェックボックスでチェックを外します。

「オフ」にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/383dc32d-9cc0-9d71-64bc-4291e25f6059.png)
日本語表示の場合
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/0d7c56e9-65d4-34f1-a5aa-b2b0de5dee9e.png)


## 設定が反映されないときは
もしかしたら「制限モード」になっているかもしれません。「信頼」してみてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/86ab565e-761d-35be-badc-fb1280306c13.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/64fcc0e3-7c1a-6531-552c-9c081e58f025.png)
↓
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/538652/17490690-8fdf-208b-12fc-495a85408ff7.png)
WEBページで CSS セレクタと XPath の検証・評価をする

Google Chrome の dev tools を利用すれば、CSS セレクタと XPath の検証を実施できる。

## CSS セレクタの検証

1. CSS セレクタの検証をしたい WEB ページを開き、[Google のデベロッパーツール](https://support.google.com/campaignmanager/answer/2828688?hl=ja)を開く
1. コンソールを開いて、式フィールドに JavaScript で `document.querySelectorAll('xxxxx')` を入力する
1. xxxxx は、検証したい CSS セレクタになる

### サンプル

Twitter のログインページに設置されているログインフォームを CSS セレクタで選択してみる。

入力するのは、`document.querySelectorAll('input[name="text"]')` になる。入力をしたら、`Enter` キーを押せば、対象の要素が選択されているかどうかがわかる。　

![css_selector.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248967/3d9b9ab2-3de0-89d1-5e59-d91645c8730e.png)

* [CSS Selectors](https://www.w3schools.com/cssref/css_selectors.asp)
* [CSS Attribute Selectors](https://www.w3schools.com/css/css_attribute_selectors.asp)

## XPath の検証

1. CSS セレクタの検証をしたい WEB ページを開き、[Google のデベロッパーツール](https://support.google.com/campaignmanager/answer/2828688?hl=ja)を開く
1. コンソールを開いて、式フィールドに JavaScript で `$x('xxxxx')` を入力する
1. xxxxx は、検証したい XPath になる

### サンプル

Twitter のログインページに設置されている "次へ" ボタンの要素を選択してみる。

入力するのは、`$x('//span[text()="次へ"]')` になる。入力をしたら、`Enter` キーを押せば、対象の要素が選択されているかどうかがわかる。　

![xpath.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/248967/6cd24954-d187-12bc-0d9d-853655d259a7.png)

* [XPath Syntax](https://www.w3schools.com/xml/xpath_syntax.asp)