OmniAICreator/Qiita-1.07M huggingface dataset:
[Python入門] #1 HelloWorldとPrintについて

# 目次
[1.はじめに](#1-はじめに)
[2.前回のおさらい](#2-前回のおさらい)
[3.HelloWorldの解説](#3-HelloWorldの解説)
[4.printについて](#4-printについて)
[5.使ってみよう](#5-使ってみよう)
[6.さいごに](#6-さいごに)
# 1. はじめに
この記事ではPythonでのコードの書き方について簡単に説明します。今回は主に**Print**を扱いますので、すでにPrintの使い方を理解している人は次の記事に進んでください。
Replitなど(オンラインエディタ)でも同様にコーディング可能ですので、ぜひご活用ください。
(この記事はWindows向けで、筆者はWindows10・Python3.9・メモ帳を使用しています。)
# 2. 前回のおさらい
Python3のインストールなどの環境構築と、少しだけコーディング。
前回紹介の**HelloWorld**についても今回解説します。
# 3. HelloWorldの解説
```py
# HelloWorldを表示するコード
# '#'はコメントを意味します。

print("HelloWorld") 
```
前回紹介したこちらのコードです。これについて簡単に解説しておきます。
まず **#** はコメントを表します。**#** の後に書かれた内容は実行されません。
```py
print("内容")
```
で画面に内容を出力できます。
この時、内容は **"** で囲う必要があります。(内容の前後に **"** をかく)
そのため、HelloWorldのコードはHelloWorldという内容を画面に出力します。
この後、実際にPrintについて詳しく解説します。
# 4. printについて
先ほど解説した通り、
```py
print("内容")
```
で内容を画面に出力できます。
これも先ほど説明しましたが、 **"** で内容の前後をくくる必要があります。
ただ、これには **くくらない場合**があります。それは、先に設定した値(変数)を代入する場合です。この場合は以下のように記述します。
```py
設定名 = "値"
print(設定名)
#"値"が出力される
```
このように、先に値を設定し、名前を付けておくことができます。その名前をprint()に **"** なしで記述すると値を表示させることができます。 **"** で囲むと、 **設定名** が出力されてしまうので気を付けてください。これをもとに例を一つ書いてみます。
```py
name = "Hello_World"
print(name)
print("Hello_Python")
#"Hello_World"と"Hello_Python"が出力される
```
こんな感じです。主に代入を用いるのは、その設定した値を複数使用する場合です。一度のみの使用の場合は最初に紹介した方法でいいでしょう。変数についても別記事で詳しく説明予定です。
# 5. 使ってみよう
さあPrintについてわかりましたか？今回はPrintだけで一つコードを書いてみましょう。
```py
Start = "さあ！冒険の始まりだ！"
print("ようこそ！")
print("あなたは勇者です。") 
print("この世界を救うために旅に出ます。")
print(Start) 
```
このコードを実行するとこれらの内容が出力されます。
ゲームのオープニングみたいですね。これらをうまく活用すればゲームのセリフやオープニングだって作れちゃいます！
このコードを任意のスクリプトエディタにペーストし、実行してみましょう。
# 6. さいごに
いかがでしたか？コーディングの基礎について書きました。次回からは "モジュール" をどんどん使用してさらにいろいろなものを作れるようになっていきます！
お楽しみに。
Qiitaのマークダウンで新しいコンテンツの埋め込みを使えるようにする方法

## この記事は何
Qiitaのマークダウンは↓の[qiita-markdown](https://github.com/increments/qiita-markdown)というライブラリでコンテンツのサニタイズなどを行っています。

https://github.com/increments/qiita-markdown


こちらはOSSで公開されているため、自分が使いたい埋め込みスクリプトなども、必要な実装を行い、PRを出せば利用が可能になります。

この記事では、具体的にどのような実装を行うと良いかをまとめていきます。

## qiita-markdownとは
まず実装について説明する前に、[qiita-markdown](https://github.com/increments/qiita-markdown)がどのようなライブラリなのかを説明します。
qiita-markdownはQiitaのMarkdownをHTMLに変換する処理に実際に使っているMarkdownパーサーです。
Markdownの中には、HTMLのスクリプトタグなども自由に記述することができるのですが、Qiitaは不特定多数のユーザーがMarkdown記事を投稿できるため、悪質なスクリプトなどを投稿できないように、HTMLタグをサニタイズしています。

ただ、Qiitaの中でも使っても問題ないスクリプトタグなどは、ホワイトリスト形式でサニタイズをスキップしています。

つまり、qiita-markdownで使いたい埋め込みタグがある場合、qiita-markdownにそのタグをホワイトリストとして追加する必要があります。

ホワイトリストには、以下の二つがあります。


- scriptタグやiframeタグに指定できるURL
- scriptタグやiframeタグに指定できる属性

この二つのホワイトリストに、埋め込みたいタグの条件に合わせて実装を追加することができればQiitaでの利用が可能になります。（正確にいうと、実装を追加後、gemのリリース→Qiita内でのバージョンアップが必要なため、少しタイムラグはあります）

## 埋め込みタグのホワイトリスト追加の流れ
ホワイトリストに追加する流れを説明します。

### ホワイトリストに追加する埋め込みタグの定義を行う
https://github.com/increments/qiita-markdown/tree/master/lib/qiita/markdown/embed

↑のように、`lib/qiita/markdown/embed/`内に、埋め込みタグの定義を行います。

URL以外に、特定のdata属性なども設定する必要がある場合は、↓のようにそれぞれ設定するようにしましょう。

https://github.com/increments/qiita-markdown/blob/master/lib/qiita/markdown/embed/speeker_deck.rb

### `lib/qiita/markdown/transformers/filter_*.rb` のURLホワイトリストに定義したURL、HOSTを追加する
追加したい埋め込みタグが`iframe`の場合は [lib/qiita/markdown/transformers/filter_iframe.rb](https://github.com/increments/qiita-markdown/blob/master/lib/qiita/markdown/transformers/filter_iframe.rb)に、追加したい
埋め込みタグが`script`の場合は[lib/qiita/markdown/transformers/filter_script.rb](https://github.com/increments/qiita-markdown/blob/master/lib/qiita/markdown/transformers/filter_script.rb)のホワイトリストに定義したURL、HOSTを追加しましょう。

### 定義した属性をホワイトリストに追加する
[lib/qiita/markdown/filters/user_input_sanitizer.rb](https://github.com/increments/qiita-markdown/blob/master/lib/qiita/markdown/filters/user_input_sanitizer.rb)に新たに許容したい属性がある場合は追加を行いましょう。すでに許容されていた場合は、特に触る必要はありません。

### テストを書く
追加したホワイトリストが正しく動いているか、テストを書きます。
qiita-markdownでは[rspec](https://github.com/rspec)を用いてテストを作成しています。
↓のように、`spec/qiita/markdown/processor_spec.rb`にテストを追加します。

https://github.com/increments/qiita-markdown/blob/master/spec/qiita/markdown/processor_spec.rb#L1467

## 最後に
Qiitaのmarkdownの処理はOSSとして公開しているため、誰でも使いたいタグなどを追加することができます。
使っている中で使いにくいところや、そもそもの処理を追加する中での不便さなどがあれば、ぜひフィードバックをいただけると嬉しいです。

Devトークも公開しているので、もし直接お話ししたい場合は気軽に「話したい」をお願いします！

https://jobs.qiita.com/employers/qiita-inc/dev_talks/27

https://jobs.qiita.com/employers/qiita-inc/dev_talks/3
Go言語を始めたい方へ ~ Hello World から ゴルーチン まで ~

![gopher_fiveyears.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2173896/d6a4258e-a9cb-91f2-b29d-04617034515b.jpeg)

## 概要
本記事は、Go言語を始めたい方に対して、Go言語開発者として抑えておきたい『 1〜10 ＋α 』をまとめたものである。
初心者はもちろん、中級者の方の基本振り返り用としても活用して頂けることを期待している。

## How to Go言語
### HelloWorld
https://qiita.com/GL-Kageyama/items/8b012d078e484100ec85

### スライス
https://qiita.com/GL-Kageyama/items/46cd77f71ef6b03e7816

### マップ
https://qiita.com/GL-Kageyama/items/f753e3b807d1894e88a4

### 構造体
https://qiita.com/GL-Kageyama/items/cf132db7714eaee774da

### メソッド
https://qiita.com/GL-Kageyama/items/1fbb61e92ce0b03c228b

### エラーハンドリング
https://qiita.com/GL-Kageyama/items/d87b67adec5ab1b4529a

### パッケージ
https://qiita.com/GL-Kageyama/items/5514957d4484515469be

### インターフェース(&循環参照の分離)
https://qiita.com/GL-Kageyama/items/daf473ab42f585b7e6f8

### キュー(Queue)
https://qiita.com/GL-Kageyama/items/890aa0197a5fdfd394a4

### 再帰(フィボナッチ数の計算)
https://qiita.com/GL-Kageyama/items/43cff62568b745c08db4

### ゴルーチン
https://qiita.com/GL-Kageyama/items/22f511dfa3042d3feca1

### チャネル
https://qiita.com/GL-Kageyama/items/ede938064f57a3c9ac6a

### for - select in ゴルーチン
https://qiita.com/GL-Kageyama/items/521307a4b09c7f35132e

### WebSocket サーバー&クライアント
https://qiita.com/GL-Kageyama/items/39aeea8b962ab31487c5

### システムパフォーマンスチェック
https://qiita.com/GL-Kageyama/items/b22ba3949ded634353b3
FlutterのStatelessWidgetで全てのウィジェットのビルドが終わったタイミングで処理を実行する方法

## やりたいこと
タイトルの通り、``StatelessWidget`` で全ての ``Widget`` のビルドが終わったタイミングで処理を実行したかった。
``build()`` 内で ``Provider``の初期化処理を書こうとしたが、初期化済を表すフラグをビルド中に変更しようとしたら　``setState() or markNeedsBuild() called during build.`` というエラーが発生したのでどうしようとなっていた。

## 結論
``WidgetsBinding.instance.addPostFrameCallback`` を使用する。

```dart
class ExampleWidget extends StatelessWidget {
  const ExampleWidget({super.key});

  @override 
  Widget build(BuildContext context) {
    WidgetsBinding.instance.addPostFrameCallback((_) {
      print('全てのウィジェットのビルドが終わったタイミングで実行したい処理を記述');
    });
    return Scaffold(
      // ...
    );
  }
}
```

これを使用することで、``build()``　内で
1. ``Provider`` の初期化済フラグが ``false`` なら初期化処理
1. 初期化処理完了後、全てのウィジェットのビルドが終わったら初期化済フラグを ``true`` に変える

ことができ、エラーを回避することができた！

## 感想
見つかってよかった…。助かった。
何か間違っていること等あればコメントください。

## 参考にした情報
[FlutterでsetState() or markNeedsBuild() called during buildエラーが発生した場合のトラブルシューティング](https://zuma-lab.com/posts/flutter-troubleshooting-called-during-build)
Volumio3(Raspberry Pi)でRadikoを再生する環境構築

以下の方に移動しました。

https://fickle-it.net/2022/11/volumio3-radiko-player-install/

https://fickle-it.net/2022/11/volumio3-radiko-timefree-download/

はじめまして、mOqOmです。
突然ですがVolumioでRadikoを再生したいですよね！
有志の方が作成したvolumio_jpradioだと私の知識が足りなく起動ができず困っていたのでNode.jsに移植してみました。
~~20221010時点ではダウンロード機能はないですが、~~ サービスとして自動起動設定を行うことも可能となっています。
20221102タイムフリーダウンロード機能を追加しました。

早速ですが、volumio_jpradioをNode.jsに移植した私のvolumio_jpradioについてのインストール方法を記載したいと思います。

まずインストールする環境は以下の通りとなっています。
※npmは後述の手順でアップデートを行い、その他のバージョンについてはVolumio3(Ver:3.378)をインストールした環境のままのバージョンです。
以前のバージョンではインストールされていなかったffmpegがデフォルトでインストールされているので手順を飛ばしています。
### 動作環境
+ Raspberry Pi 4 Model B(Raspberry Pi Zeroも同じ手順で可能)
+ Volumio3(Ver:3.378)
+ Node.js(Ver:14.15.4)
+ npm(Ver:8.19.2)
+ Python3(Ver:3.7.3)
+ Python2(Ver:2.7.16)
+ ffmpeg(Ver:4.1.9-0+deb10u1)

### インストール
以下の流れに沿ってインストールを進めていきます。
#### 日本時間にするためTimezoneを変更
```
$ sudo dpkg-reconfigure tzdata
# Asia→Tokyoを選択
```
#### プロジェクトのクローン
```
$ git clone https://github.com/mOqOm/volumio_jpradio ./radio
$ cd radio
```
#### パッケージのインストール
```
$ sudo apt-get update
$ sudo apt-get install -y build-essential
# npmのアップデート
$ sudo npm install -g npm
# パッケージのインストール
$ sudo npm install express sqlite3 node-yaml-config date-utils xml2js log4js got capitalize m3u-file-parser icy-metadata cron tough-cookie
```
#### 動作確認
```
$ node /home/volumio/radio/app.js
# Volumio3の「Playlist」>「Radiko」から選局
```

### 自動起動(サービス化)
動作確認までできれば残りデーモンに登録する手順のみです。
これをすると、Volumio3の起動時にvolumio_jpradioが自動で起動されます。

#### サービスの作成
```
$ sudo mkdir /usr/lib/systemd/system
$ sudo nano /usr/lib/systemd/system/radio.service
```
#### radio.serviceの書込み内容
```
[Unit]
Description=radio
After=network.target

[Service]
ExecStart=/usr/bin/node /home/volumio/radio/app.js
Restart=always
User=volumio
Group=volumio
KillMode=process
WorkingDirectory=/home/volumio/radio

[Install]
WantedBy=multi-user.target
```
#### デーモンのリロードと自動起動設定
```
$ sudo systemctl daemon-reload
$ sudo systemctl start radio.service

$ sudo systemctl enable radio.service
```

### Radikoのログインについて
最後にRadikoのプレミアム登録されている方向けの内容になります。
Radikoのアカウントでログインを行うには、プロジェクトをクローンした際にある「config.yaml」ファイルを変更する必要があります。
下記の変更前、変更後の差分のようにmailとpassの#を削除し、自身のアカウント情報を入力するとログインできます。

変更前
```
  account :
    #mail : xxx@yyy.zzz
    #pass : foobarhogehoge
```
変更後
```
  account :
    mail : xxx@yyy.zzz
    pass : foobarhogehoge
```
### おわりに
この移植は完全ではないと思われるのでバグ等があった場合はできる限り修正を行いたいと思いますので、お力添えをお願いいたします。
それではよいVolumioライフを！
### 参考サイト
* [NanoPi NEOにインストールしたMPDでradikoを聞く](http://burro.hatenablog.com/entry/2019/02/16/175836)
* [Github for Streaming server for relaying "radiko" radio stream to Music Player Daemon (MPD)](https://github.com/burrocargado/RadioRelayServer)
* [Trunkene/volumio_jpradio: Japanese radio relay server for Volumio](https://github.com/Trunkene/volumio_jpradio)
AWS AmplifyでコンテナREST APIをデプロイしiOSアプリと通信する

# はじめに
AWS Amplifyを用いることでバックエンドの構成をほぼ意識することなくAPI, 認証、データベースなどをAWS環境に構築し、フロントエンドアプリケーションから呼び出すことができます。
REST APIを作成すると、Amazon API GatewayとAWS Lambdaを用いたイベント駆動型の環境を構築できます。ですが、ユースケースによってはイベント駆動ではなく、常駐型のサーバが適切な場合もあるかと思います。
AWS Amplifyではプロジェクト設定を変更することで、このようなケースにコンテナを用いて対応することができます。

今回は、AWS Amplifyを用いてコンテナREST APIをデプロイし、iOSアプリと通信したいと思います。

# 環境
Amplify CLI: v10.0.0
Xcode: v14.0.1

# 手順
1. Xcodeプロジェクトを作成します。
2. Xcodeプロジェクトディレクトリ直下でAmplify CLIを用いて `amplify init` でAmplify プロジェクトを初期化します。
3. Amplify CLIを用いて `amplify configure project` を実行し、container-based deploymentsを有効にします。

上記の手順を実施することで、コンテナREST APIをデプロイする準備が整います。

# iOSアプリからコンテナREST APIに通信する
コンテナREST APIをデプロイした場合もiOSアプリとAPIのインターフェイスは、Amazon API Gatewayです。
これは、AWS Amplify標準のREST API (Amazon API Gateway, AWS Lambda)と同じ構成です。
ですので、iOSアプリからのリクエストはAmplifyライブラリのAPIカテゴリを用いることができます。

```swift
// デプロイしたREST APIのパスを指定する
let request = RESTRequest(path: "/")

Amplify.API.post(request: request) { result in
    switch result {
    case .success(let data):
        let str = String(decoding: data, as: UTF8.self)
        print("Success \(str)")
    case .failure(let apiError):
        print("Failed", apiError)
    }
}
```

# コンテナREST APIの実態
AWS AmplifyでコンテナAPIを有効にすることで実際には以下のAWSリソースがデプロイ・利用されています。
- Amazon VPC
- Amazon API Gateway
- AWS Fargate (Amazon ECSがコントロールプレーン)
- Amazon ECR
- AWS Cloud Map
- AWS CodePipeline
- AWS CodeBuild

# Tips
- `amplify configure project` を実行し、container-based deploymentsを有効にすると `amplify/.config/project-config.json` の`frontend` keyの値がjavascriptに変更されてしまいます。そのため、Amplify + iOSプロジェクトに必要な `awsconfiguration.json` と `amplifyconfiguration.json` が消えてしまいます。`amplify configure project` を再度実行し、必要なファイルを再生成する必要がありました。
- `amplify env remove <env-name>` で環境を削除してもAmazon ECR上のリポジトリは削除されませんでした。手動で削除するなどの対応が必要です。

# Graviton2を指定できないのカナ!?
AmplifyのコンテナAPIはAWS Fargateをデータプレーンとします。既定のCPUアーキテクチャはx86_64です。ARMプロセッサ環境で問題なくコンテナが動作するようであれば、性能と価格が優れているAWS Gravitonプロセッサを選択したいです。ただ、Amplify CLIで作成したCloudFormationテンプレートを編集して再デプロイ等試してみましたが、AWS FargateにGraviton2を指定することができませんでした。有識者の方やり方あったら教えてください。

# 参考資料
- [AWS で iOS アプリケーションを構築する](https://aws.amazon.com/jp/getting-started/hands-on/build-ios-app-amplify/)
- [Amplify Framework Docs - ADVANCED WORKFLOWS Serverless containers](https://docs.amplify.aws/cli/usage/containers/)
- [Amplify Framework Docs - API (REST) Getting started](https://docs.amplify.aws/lib/restapi/getting-started/q/platform/ios/)
【Laravel】自作コマンドから別のArtisanコマンドを実行する方法

Laravelには様々なArtisanコマンドがあるが、以下のコマンドで簡単にArtisanコマンドを自作できる。

```PHP
php artisan make:command (コマンドファイル名）
```

以下のようなファイルが生成される。

``` PHP
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;

class TestCommand extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'command:name'; 

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Command description';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        return 0;
    }
}

```
# 生成したCommandクラスの解説
$signatureプロパティでコマンド名を指定することができる。

```PHP
protected $signature = 'test:Hello'; 
```

$descriptionプロパティでコマンド名を指定することができる。
```PHP

protected $description = 'testです'; 
```

handleメソッドにコマンドで実行する処理を記述することができる。
```PHP

public function handle()
{
    $this->comment('こんにちは！');
    return 0;
}

```
以下のコマンドで、登録されたArtisanコマンドの一覧が確認できるが先ほど作成したコマンドが登録されていることがわかる。
```PHP
php artisan list
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545959/5f2aecf6-d67c-b3fd-c881-6ef3a376bc05.png)
$signatureプロパティで指定したコマンドを実行すると、handleメソッドが実行される。
```PHP
php artisan test:hello
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545959/3706904e-0d56-2001-2c4a-55a748f53469.png)

# 自作コマンドから別のArtisanコマンドを実行する
Commandクラスのcallメソッドを実行する。
```PHP
$this->call('cache:clear');
$this->call('make:controller', ['name' => 'testController']);
```
コマンドを実行すると、別のArtisanコマンドを呼び出すことができた！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545959/9ac48ae3-3e2a-9e1f-01c1-ee47ad0b962e.png)

プロジェクトに応じた自作コマンドを作って作業効率ができそうですね！

# 参考
コマンドの実装方法が詳しく解説されていておすすめです。

https://www.amazon.co.jp/PHP%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-Laravel-Web%E3%82%A2%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E9%96%8B%E7%99%BA-%E3%83%90%E3%83%BC%E3%82%B8%E3%83%A7%E3%83%B38-x%E5%AF%BE%E5%BF%9C-%E7%AB%B9%E6%BE%A4/dp/4802613008

3種類のArtisanコマンドを呼び出す方法を解説されていて、勉強になりました。

https://qiita.com/orange634nty/items/9cbcc5cbe9174966a74b
Salesforce認定アドミニストレーター試験の公式練習問題を解説してみた-その049

こんにちは。本橋孝昭です。

Salesforce認定アドミニストレーター試験の公式練習問題があるのはご存じでしょうか。
Trailheadにフラッシュカードとして何度も解ける練習問題がございます。

今回はTrailhead
アドミニストレーター認定の準備: データと自動化
ワークフローと自動化の学習

にある練習問題5問目をご紹介します

なお今回の内容は動画でも紹介されています
https://www.youtube.com/watch?v=qL3YlETH74Q



今回の問題はこちらです

https://trailhead.salesforce.com/ja/content/learn/modules/administrator-certification-prep-security-and-data-management/study-up-on-security-and-access?trail_id=administrator-certification-prep

![5.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/8f5899a8-503d-06e9-9779-9cd3b4be2a6c.png)


正解はBとCです

承認プロセスの設定は４つございます

・Todo
・メールアラート
・項目自動更新
・アウトバウンドメッセージ


![最終承認０１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/0a6788f0-6565-e204-8e36-bf2114fee505.png)


承認プロセスの詳細はこちらをご覧ください

https://trailhead.salesforce.com/ja/content/learn/projects/build-a-discount-approval-process/create-an-approval-process
Vercelのfair use policy違反をしたから謝ったら許してもらえた話

# まとめ
- Vercelでfair use policy違反をしてアカウントを停止されたら、一ヶ月後にサポートに謝罪の問い合わせを送ると1日くらいで停止を解除してくれる


# やってしまったこと
- nextで作ったアプリをVercelにデプロイしていた
- Vercelはホビープラン
- next/imageのOptimization Source Imagesを使いすぎたせいで、アカウントが「402: PAYMENT_REQUIRED」で停止された
    - next/imageのOptimization Source Imagesを使いすぎの件はこちらの記事で解決策を書いてます→[VercelからImage Optimization Source Imagesの使いすぎ警告が来た時の対応](https://qiita.com/0ba/items/46709d24bc81efe1cb6c)

# 対応してこと
- fair use policyによると諸々のリソースの使用上限が一ヶ月単位で定められているので、とりあえず一ヶ月待ってみた
- 一ヶ月が4週間なのか30日なのか31日なのかわからなかったから、31日間は待ってみた。
→停止解除ならず

- どこかの記事で2回問い合わせで謝ったら解除してもらえたと書いてあったので、自分も問い合わせから以下の文面を送ってみた。
    - ちなみに問い合わせは[この画面](https://vercel.com/help)の下部にある問い合わせフォームからおこなった。
    - PROBLEM AREAはDeploymentsを選択
    - SEVERITY LEVELはホビープランだとLevel4しか選べなかったので4を選択
 
```
Subject: Can you remove 402: PAYMENT_REQUIRED

-----------------------------------
Area: Deployments
Project: oshi-kyoku
Deployment Url: oshi-kyoku-xxxxxxxxx.vercel.app
Name: xxxxxxx
Previous Page: Not Specified
-----------------------------------
A month ago, the service was suspended for violating the fair use policy.
Because I didn't understand the next/image options and I exceeded the limits of Image Optimization.
I'm sorry.

Updated to not exceed the Image Optimization limit as it now sets the options correctly.

One month has passed since the service was suspended, so could you restart the service?
```


# 結果
２日後にVercelに登録しているメールアドレスあてに担当者から「解除しといたぜ」という返事がきた。

# 結論
- Vercelでfair use policy違反をすると一ヶ月で解除してもらえるけど、自分からお願いする必要があるっぽい。
    - 無料で使わせてもらっているので、感謝と謝罪の心は大事
- あまりVercelのアカウント停止について言及されている記事がなかったので、反面教師としてこの記事が誰かに役に経つと良いなと思って書いた。

というわけで晴れて停止解除となったサービスの紹介記事はこちらです↓笑
[【個人開発】推し曲を動的に生成したOGP付きで共有できるサービス「推し曲.com」を作りました](https://qiita.com/0ba/items/baf8415e0f1593f81cd1)

サービス自体はこちら↓
https://oshi-kyoku.com/

Twitterもやってるので、よければフォローお願いします。
→https://twitter.com/ObataGenta
BeautifulSoup初心者のselectデバッグ手順

# はじめに
最近BeautifulSoupを使ったWebスクレイピングを学習中です。
特定の要素をCSSセレクタでselectしようとしても、空配列が返ってくることが結構多いので、
その場合の自分なりの対処法を、半分備忘録代わりに書こうと思います。
(今更感満載かもしれません)

もっと良いやり方知ってるよ！って方は優しく教えてください笑

## 書かないこと
- Pythonのインストール手順
- BeautifulSoup等ライブラリのインストール手順

# 環境
- OS: Windows11
- ブラウザ：Chrome
- BeautifulSoupのバージョン: 4.11.1
- Pythonのバージョン: 3.10.1

# 題材
[カロリーSlim](https://calorie.slism.jp)というサイトから、栄養素一覧を取ってくるというスクリプトを書いていたので、
こちらを題材にしたいと思います。
今回は[あさりのみそ汁](https://calorie.slism.jp/200293/)の栄養素を取ってきたいと思います。

# selectを用いた要素取得
栄養素一覧を取ってくるとなると話が長くなるので、今回は食物繊維のグラム数を取得したいと思います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666190/010aaedb-b905-4ba4-3c85-93cfad73483b.png)
(題材をヨウ素取得にしましょうっていう洒落を利かせようと思いましたが、ややこしくなりそうなのでやめます)

まずはページ全体のパース
```python
import requests
from bs4 import BeautifulSoup

url = "https://calorie.slism.jp/200293/"
res = requests.get(url)
soup = BeautifulSoup(res.content, "lxml")
```

取得したい要素(今回は`0.68g`)にマウスカーソルを合わせ、右クリック⇒検証
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666190/92d9af6e-6fc3-e538-6b94-4f230f7d23c9.png)

Chromeの開発者ツールが開くので、`<span class="etc content">0.68</span>`の箇所で、右クリック⇒`Copy selector`
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/666190/69a4a313-7d8e-5ce7-a13e-42a6831ed8f6.png)

コピーしたCSSセレクタを貼り付けて、中身を見てみます
```python
result = soup.select('#etc > div > table > tbody > tr:nth-child(1) > td.valMeasure')
print(result)

> []
```
はい、空の配列が返ってきました。

# デバッグしてみる
大体途中までは取得できているはずなので、結果が返ってくるまで子要素を消していきます。

```python
result = sourp.select('#etc > div > table')
print(result)

> [<table style="width:100%;"> <tr> <td class="name">食物繊維 総量</td><td class="valMeasure"><span class="etc_content">0.68</span><span class="etc_unit">g</span></td> <td class="guide" style="text-align: right;">5.7g～</td> </tr> <tr><td colspan="3"><div class="graph"><img height="8px" id="dietary_fiber_total_amountGraph" src="//cdn.slism.jp/calorie/images/bar01.gif" width="11.93%"/></div></td></tr> <tr> <td class="name">食塩相当量</td><td class="valMeasure"><span class="etc_content">1.76</span><span class="etc_unit">g</span></td> <td class="guide" style="text-align: right;">～2.5g</td> </tr> <tr><td colspan="3"><div class="graph"><img height="8px" id="sodium_chloride_equivalentGraph" src="//cdn.slism.jp/calorie/images/bar01.gif" width="70.4%"/></div></td></tr> </table>]
```

`table`タグまで遡ってようやく取得できました。
結果を見てみると、`table`タグの次は`tbody`タグではなくて`tr`タグになってますね。
`tbody`タグを取っ払ってみます。
```python
result = soup.select('#etc > div > table > tr:nth-child(1) > td.valMeasure')
print(result)

> [<td class="valMeasure"><span class="etc_content">0.68</span><span class="etc_unit">g</span></td>]
```
無事取得できました。
あとは、`0.68`という値を取得しにいきます。
`span`タグのvalueになってるので、`span`タグまで潜った方がよさそうですね。
```python
result = soup.select('#etc > div > table > tr:nth-child(1) > td.valMeasure > span.etc_content')
print(result[0].contents[0])

> 0.68
```

欲しい要素を取得することができました。

# おわりに
BeautifulSoupの細かい仕様を理解していないので、なんでtbodyタグが取得できなかったのかは分かりませんが、
ChromeのCSSセレクタとBeautifulSoupのパース結果が異なるから起きる事象なのかと思われます。
BeautifulSoupのパース結果を実際に見てみるってのが大事ですね。

Seleniumでもスクレイピングしたりしてるんで、Seleniumバージョンのデバッグ手順も今後書きたいと思います。
ASP.NET CoreにおけるURLクエリ文字列（URLパラメーター）のコントローラー側の受け取り方

ASP.NET Core MVCプロジェクト（.NET6.0）において、URLクエリ文字列（URLの"?"以降に追加されるパラメーター）をコントローラーで受け取る方法うを2通り解説します。

# あらかじめ予定された名前のパラメーターを受け取る場合

コントローラーの引数として値を受け取ります。

### URLの記述
```
https://example.com/Home/Index?param1=10&param2=20
```

### コントローラーの記述

パラメーターと同じ名称のメソッド引数に値が格納されています。

```C#
public IActionResult Index([FromQuery] int? param1, [FromQuery] int? param2) {
    //コントローラー引数としてクエリ文字列を受け取り。
    //パラメーター名と引数名を一致させる必要がある。
    Console.WriteLine(param1); // 10
    Console.WriteLine(param1); // 20

    return View();
}
```

# 名前が未定のパラメーターを受け取る場合

Request.QueryにURLパラメーターが連想配列としてバインドされているので利用します。

### URLの記述
```
https://example.com/Home/Index?param1=10&param2=20
```
### コントローラーの記述

こちらの方法では、引数をあらかじめ指定する必要がなく、動的にパラメーターを受け取ることが出来ます。

```C#
public IActionResult Index() {
    var params = Request.Query;

    Console.WriteLine(params["param1"]); // 10
    Console.WriteLine(params["param1"]); // 20

    return View();
}
```
[Python入門] #0 環境構築

# 目次
[1.はじめに](#1-はじめに)
[2.Pythonについて](#2-Pythonについて)
[3.インストール](#3-インストール)
[4.スクリプトエディタ](#4-スクリプトエディタ)
[5.使ってみよう](#5-使ってみよう)
[6.さいごに](#6-さいごに)
# 1. はじめに
Pythonに関して基礎の基礎に関する質問をもらうことが結構あったので基礎に特化した記事を書いてみようと思い書いている次第です。
この記事ではPythonを使う前に、環境構築について説明します。もうすでに構築済み、理解できているという方は次の記事に進んでください。
(この記事はWindows向けで、筆者はWindows10を使用しています。)
# 2. Pythonについて
グイド・ヴァン・ロッサムにより創り出され、1991年にリリースされたプログラム言語の一種です。Python2とPython3があり、場合によっては2のみ3のみのものも存在するので気を付けてください。Python2はサポートも切れているため、**この記事では "Python3.9" を使用します。**
# 3. インストール
1. [Python公式サイト](https://www.python.org/downloads/) よりダウンロードしてください。現在の最新verは "3.10.7" のようです。
2. ダウンロードしたexeファイルを開き、インストールします。
**この時、パスを通すみたいなものにチェックを入れてください。**

**番外編**
OSにインストールしたくないという人は、[replit](https://replit.com/) や [paiza.io](https://paiza.io/ja/languages/python3) というオンラインサービスもありますので活用するのもいいと思います。
# 4. スクリプトエディタ
その名の通りスクリプトをエディトするやつです。Pythonでもちろんコードを書くわけですが、そのときに使用するソフトウェアを決定しましょう。今回はおすすめを3つあげておきますので、自分に合ったものをお使いください。
1. メモ帳
起動簡単・容量取らない・使いやすい！シンプルに使いやすいですね。
普通にtxtファイルを新規作成して中身を編集後、拡張子を.pyにリネームします。

2. [Visual Studio Code](https://code.visualstudio.com/)
Microsoftの高機能エディタ。無料で高機能、、、結論最強です。
Pythonのほかにもjsやhtmlなど幅広く扱えます。

3. [Notepad++](https://notepad-plus-plus.org)
これも無料で高機能の素晴らしいエディタです。容量的にも優しいエディタですね。
VSCode同様、jsやhtmlなど幅広く扱えます。
# 5. 使ってみよう
Pythonの環境は作れましたか？いよいよコードを書いてみましょう！細かいコード構築の説明は別記事で紹介予定なので、今回は簡単なコードを1つ説明します。
```py
# HelloWorldを表示するコード
# '#'はコメントを意味します。

print("HelloWorld") 
```
このコードは **HelloWorld** と表示するものです。
このコードを任意のスクリプトエディタにペーストし、実行してみましょう。
コードの詳細な解説は別記事で行う予定ですので、「へーPythonってこんなコード書くんだー」くらい思っといてください。
# 6. さいごに
いかがでしたか？本当に基礎を書きましたが、案外こんな基礎を書いている記事がなかったので、少し丁寧に書いてみました。初めての記事だったので不備がありましたら教えていただければ幸いです。
次回以降はいよいよ本格的にコーディングしていきます！
TA-F333ESXを修理してみた

8月くらいに突然SONYの80年代のアンプのTA-F333ESXが壊れました。現象は電源を入れてもプロテクションが外れずLEDが赤のままの状態です。

このアンプは2014年にも同じように故障して、ヒューズ抵抗を一本交換しました。

今回も同じだろうと思って確認したところ、隣のヒューズ抵抗が切れてました。

![FUSEREG.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/ab055604-5dbd-ca0e-480a-be55b54bc197.png)

前回交換したのが赤いところで、今回はその隣が切れてしました。

交換した部品はこれです。

![写真（2022-10-10 9.33）.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/e8e94047-a523-f91f-06ab-1e5ebdd75eac.jpeg)

基板はそのままで、底蓋を外してぎりぎり作業ができました。パターンはあまり強くないので注意が必要です。

ちゃんとプロテクションが外れるようになりました。

以前お金があったころにコンデンサーは大きいもの意外は取り替えてあります。

このアンプはダイレクトにしないとノイズがでるのですが、ダイレクトではちゃんと聞けるので良しとしています。

元々インジケーターはランプだったのですが、確かかなり前に切れて修理してもらった時にLEDに交換されていたようです。

せっかくあけたので埃だらけだったので、ブローアーを買ってきて綺麗にしたいと思います。

音は出るようになったのですが、音がおかしいです。どっか接触が悪いような気がします。ぼちぼち調べてみたいと思います。
【Flask】flashを使ったメッセージの表示

## Flashを使ってログイン時のエラーメッセージを表示する

### コード

```python.py
from flask import Flask, flash

# Login
@app.route('/login')
def login():
    return render_template('login.html')


# lockin check
@app.route('/logincheck', methods=['POST'])
def logincheck():
    user_id = request.form['user_id']
    pwd = request.form['password']
    session['username'] = user_id

    # make pwd hashed by "get_digest()"" function
    password = get_digest(pwd)
    id_pwd_hash = get_user_data()

    if user_id in id_pwd_hash:
        if password == id_pwd_hash[user_id]:
            session['login'] = True
        else:
            flash('Authentication failed! Please check your input.')
            session['login'] = False
    else:
        flash('Authentication failed! Please check your input.')
        session['login'] = False

    if session['login']:
        return redirect(url_for('index'))
    else:
        return redirect(url_for('login'))

```

```login.html
{% block main %}

<h2>Login Authentication</h2>
<h3>Please input User ID and Password!</h3>

{% with messages = get_flashed_messages() %}
    {% for message in messages %}
        <li>
            <i>
                <font color="orange">{{ message }}</font>
            </i>
        </li>
    {% endfor %}
{% endwith %}

<form method="POST" action="/logincheck">
    <p><input placeholder="User ID" type="text" name="user_id"></p>
    <p><input placeholder="Password" type="password" name="password"></p>
    <p><input type="submit" value="SEND"></p>
</form>

{% endblock %}

```

::: note info 
ポイント
+ flash()モジュールをインポートする
+ pythonファイルにflashメッセージを記載
+ {% with messages = get_flashed_messages() %} メッセージ {% endwith %} htmlのフォームの上部に記載 
:::

![auth_failure.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/699739/3307b4e4-9c91-74cb-e3dd-774e1152f85a.png)
AI Programmerの作法 その19

# 概要
AI Programmerの作法、調べてみた。
atcoderやってみた。

# 投入したソースコード
- C++
- X 円を払ってりんごを 1 個手に入れる。
Y 円を払ってりんごを 3 個手に入れる。
りんごをちょうど N 個手に入れるには最低何円必要ですか？

# 実行結果

```
X 円を払ってりんごを 1 個手に入れる。
Y 円を払ってりんごを 3 個手に入れる。
りんごをちょうど N 個手に入れるには最低何円必要ですか？

#include <iostream>
using namespace std;

int main() {
    
    int x, y, n;
    
    cin >> x >> y >> n;
    
    int ans = (n / 3) * y + (n % 3) * x;
    
    cout << ans << endl;
    
    return 0;
    
}

```

# paiza.io

# 入力

```
10
25
10
```

# 実行結果

```
85
```

# 成果物

https://paiza.io/projects/zAf98SjYiC0SGRdXiqAooA

以上。
非エンジニアにLDAPを説明する

# 本記事の目的

前職にて LDAP(Lightweight Directory Access Protocol)を知らない人向けに説明するための資料を作っていたのだが、他でも役立つかもしれないので Qiita に投稿してみる。LDAP について説明している記事は少なからずあるけど、絵で説明しているものが少ない印象・・・絵があってもけっこう複雑な感じで、自分も LDAP について知るために結構苦戦した記憶。

本記事では、LDAP を全く知らない人向けに **「LDAP ってこういうメリットあるよ！」** というのをなんとなく知ってもらうことを目的としてます。興味をもっていただければ、別記事でいろいろ学んでいただければと。

# 身近な LDAP

身近なところでどう LDAP が利用されているかを説明するのがわかりやすい気がする。
例えば、学校とか職場によっては PC 利用室みたいな、複数の PC が用意されていてどれでも自由に利用できるスペースがあると思う。このスペースにおいて、どの PC についても同じ ID / パスワードでログインできるはず。

![image1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2902882/70061c6b-beda-97c9-648d-fe06d6a9a7e8.png)

では、これはそれぞれの PC に対して同じ ID / パスワードを 1 つひとつ登録しているのか？というと、そうではない。もしそうだとしたら、担当者の稼働が大変なことに・・・例えば大学であれば毎年新入生が何百・何千人と入ってくる際に 1 つひとつの PC に認証情報を登録していくのは大変。。

上のような課題を解消できるのが LDAP、と捉えるといい。1 つひとつの PC に登録するのではなく、LDAP サーバを用意してその 1 台のみに認証情報を登録しておく。

![image2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2902882/7c27eb9c-1679-8b82-620b-fd8c1584a41a.png)

こうすることで、LDAP サーバ 1 台のみに情報登録するだけでよくなるので、認証情報登録の手間を軽減できる。
それぞれの PC で ID / パスワードを入力した際には、LDAP サーバに問い合わせて、認証情報が正しいかどうかを判断する仕組み。

また、このやりかたのメリットは他にも以下がある。
* 学生が卒業したとか社員が退職したとかの場合でも、LDAP サーバだけ情報を変更すればいい
* 利用者の姓が変わった場合でも、LDAP サーバだけ情報を変更すればいい

大学とか職場において、どの PC でも同じ ID / パスワードを使ってログインできる場合にはおそらく Windows 端末を使っていると思う。この場合は LDAP を利用した ActiveDirectory という Microsoft のサービスを利用している。もしかすると「90 日ごとにパスワード変更を要求される」みたいなことに出会った人がいるかもしれないが、これも ActiveDirectory の機能によるもの。
* LDAP と ActiveDirectory の違いについて：前者はプロトコル、後者は LDAP を用いたサービスという理解でよさそう。ここではあまり言及しないが、以下が参考になりそう。
    - [LDAPとActive Directory（AD）の違い](https://www.okta.com/jp/identity-101/ldap-vs-active-directory/)


# 終わりに

* LDAP を勉強し始めた際にワケがわからなすぎたのだけど、上記みたいに LDAP を身近に感じられると学習の一助になるかなと思って投稿してみた。とはいえ、奥が深いので自分も理解はまだまだだけど・・。
* ここでは触れなかったが LDAP の特徴としてはツリー構造があると思う。ツリー構造の学習で自分は以下 2 記事にお世話になったので記載しておきます。
    - [【図解】初心者にも分かるLDAP入門～仕組みや概念,スキーマ,認証/連携の具体例,ADやデータベースとの違い～](https://milestone-of-se.nesuke.com/l7protocol/ldap/ldap-summary/) の「LDAP とデータベースとの違いは？」章
    - [LDAP Authentication](https://www.infraexpert.com/study/security19.html) の「LDAP識別名とは」章
Python,Ruby,PHP,Java,JavaScript,Perlのライブラリ作成方法の比較


<a href="https://qiita.com/yuki_kimoto/items/f9c2454e7f9130ddb003">Qiita > プログラミング言語の比較</a>

Python,Ruby,PHP,Java,JavaScript,Perlのライブラリ作成方法の比較

# Python

https://qiita.com/mofumoffy223/items/a461efba5c80acafdbf0

# Ruby

https://qiita.com/suketa/items/ab6b88093de4a54b3b06

# PHP

https://qiita.com/nuuuuume/items/fd2e0d69fb5430c26bd0

# Java

https://qiita.com/haruto167/items/162551100449ea5c7e6d

# JavaScript

https://www.sejuku.net/blog/65313

# Perl

https://perlzemi.com/blog/20161130148051.html
ネットワークACLを作成する

# ネットワークACLを作成する
AWSマネジメントコンソールにログインしてください。
VPCダッシュボードに移動してください。
VPCダッシュボードの[ネットワークACL]をクリックしてください。
![スクリーンショット 2022-10-09 7.27.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/f7509d07-6852-d317-018c-fbae61ead49e.png)

ネットワークACLのページが表示されます。
[ネットワークACLを作成]をクリックしてください。
![スクリーンショット 2022-10-09 7.28.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/994b4419-cf66-f8b9-bc9c-cfe8d3037bab.png)

任意の名前を入力し、NACLを作成するVPCを選択してください。
[ネットワークACLを作成]をクリックしてください。
![スクリーンショット 2022-10-09 7.29.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/61a61367-646c-65a5-df43-aa16b4143465.png)

# インバウンドルールを登録する
ネットワークACLのページで、作成したネットワークACLをチェックします。
[インバウンドルールタブ]をクリックしてください。
[インバウンドルールを編集]をクリックしてください。
![スクリーンショット 2022-10-09 7.33.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/b6af11a5-8054-fed7-015d-9e3c58bef352.png)

[新しいルールを追加]をクリックしてください。
すべての送信元からのSSH、HTTP、HTTPSを許可するルールを入力してください。
[変更を保存]をクリックしてください。
![スクリーンショット 2022-10-10 7.28.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/3b921a92-309a-565e-7414-8adbe9fadd24.png)

# アウトバウンドルールを登録する
[アウトバウンドルールタブ]をクリックしてください。
[アウトバウンドルールを編集]をクリックしてください。

[新しいルールを追加]をクリックしてください。
すべての送信先へSSH、HTTP、HTTPSを許可するルールを入力してください。
[変更を保存]をクリックしてください。
![スクリーンショット 2022-10-10 7.32.48.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/269decdb-4c1a-2e32-0f1f-7ddadffd2f5e.png)

# 作成したネットワークACLをサブネットに関連づける
[サブネットの関連付けタブ]をクリックしてください。
[サブネットの関連付けを編集]をクリックしてください。
![スクリーンショット 2022-10-10 7.34.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/2c5f3a56-c5f5-6325-8ce9-9a04b78a03b1.png)

関連付けるサブネットをチェックしてください。
[変更を保存]をクリックしてください。
![スクリーンショット 2022-10-10 7.35.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/0a38a676-6cba-c461-6411-ad4e5c947795.png)

# アウトバウンドルールにエフェメラルポートのルールを登録する
ネットワークACLのページで、作成したネットワークACLをチェックします。
[アウトバウンドルールタブ]をクリックしてください。
[アウトバウンドルールを編集]をクリックしてください。

[新しいルールを追加]をクリックしてください。
ポート範囲に[1024-65535]と入力します。
**今回のポート範囲はテストのための値になります。**
**実際は、マニュアルやガイドなどを参考に、必要なポート範囲を限定してください。**
[変更を保存]をクリックしてください。
![スクリーンショット 2022-10-10 7.41.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/e957d07f-4af9-3068-62a5-eff8130e2b7d.png)

# (オプション)インバウンドルールにエフェメラルポートのルールを登録する
EC2のyumコマンドを実行する場合、インバウンドルールにもエフェメラルポートのルールを登録する必要があります。　インバウンドルールにエフェメラルポートのルールがない場合、yumコマンドがタイムアウトしてしまいます。

ネットワークACLのページで、作成したネットワークACLをチェックします。
[インバウンドルールタブ]をクリックしてください。
[インバウンドルールを編集]をクリックしてください。

[新しいルールを追加]をクリックしてください。
ポート範囲に[1024-65535]と入力します。
![スクリーンショット 2022-10-10 7.51.46.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/14202/d894d8b7-be5a-4891-f39d-383e479384ea.png)

以上で、ネットワークALCの作成は終わりです。
C言語でも使えるstatic_assert


ニッチな話題ですが、古い環境でもコンパイル時にテストしたいという話です。
こちらからの引用です。

https://stackoverflow.com/questions/3385515/static-assert-in-c

上の記事にある通り、新しい規格のC言語とかgccとかC++では別の手段があります。
あと流儀？も大量にあります。
古い環境では結局どれを使えばいいかという話。

- C99,C89でもVisualStudioでも使える。
- 同じファイルで複数回使っても名前が被らないために行番を入れている。
- 構造体の中や共用体の中以外ならほとんどの場所で使える。

という工夫が入っているのが、こちらのCOMPILE_TIME_ASSERTとのこと。
```
#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1]
#define COMPILE_TIME_ASSERT3(X,L) STATIC_ASSERT(X,static_assertion_at_line_##L)
#define COMPILE_TIME_ASSERT2(X,L) COMPILE_TIME_ASSERT3(X,L)
#define COMPILE_TIME_ASSERT(X)    COMPILE_TIME_ASSERT2(X,__LINE__)

COMPILE_TIME_ASSERT(sizeof(long)==8); 
int main()
{
    COMPILE_TIME_ASSERT(sizeof(int)==4); 
}

```

## 鑑賞

##### 動作のコアはこれです。
```
char static_assertion[(!!(COND))*2-1]
```
- 配列のサイズが負になるとコンパイルできないという仕様を使っています。CONDがtrueのときサイズが1になり、falseのとき-1になります。
- 三項演算子を使った形`static_assertion_##MSG[(COND)?1:-1]`にしないのは古いcc65でも動作できるようにとのこと。さすがにどっちでもいい。

##### 続いてこの範囲について考えます。
```
#define STATIC_ASSERT(COND,MSG) typedef char static_assertion_##MSG[(!!(COND))*2-1]
```
- typedef を使っているのが重要①。サイズが'!!(COND))*2-1'のchar型の配列 の別名 `static_assertion_##MSG`を定義しています。あくまで別名の定義なので、配列の実体が作られることはありません。
- typedef を使っているのが重要②。.cのファイル内で別名を定義しているので、最大でも影響範囲はファイル内です。名前`static_assertion_##MSG`が重複するかどうかはファイル内だけ考えればいいことになります。
- トークン連結演算子 (##)により、MSGを変えることで宣言の重複を防ぎます。


##### 最後にこの部分。
```
#define COMPILE_TIME_ASSERT3(X,L) STATIC_ASSERT(X,static_assertion_at_line_##L)
#define COMPILE_TIME_ASSERT2(X,L) COMPILE_TIME_ASSERT3(X,L)
#define COMPILE_TIME_ASSERT(X)    COMPILE_TIME_ASSERT2(X,__LINE__)
```
- 自動的に重複を防ぐために行番号に変換される組み込みマクロ`__LINE__`を使います。STATIC_ASSERTでtypedefを使っているおかげで、考慮する範囲はファイル内のみになっていたのでした。よって`__FILE__`の結合は不要です。
- トークン連結演算子 (##)や文字列化演算子(#) がある関数マクロの宣言ではマクロ定数は展開されません。一見無駄に見える`#define COMPILE_TIME_ASSERT2(X,L) COMPILE_TIME_ASSERT3(X,L)`の行は`__LINE__`を数字に展開するためにあります。

##### ここまできてあれですが。
- 同じ内容の配列のtypedefが重複してもエラーにならないのでは？visual studioでちょっと実験した感じだとならないです。規格は調べきれず。多分、STATIC_ASSERT(COND,MSG)で十分だけど安全のためCOMPILE_TIME_ASSERT(X)を使います。
- 使ってないtypedefがあると警告がでるコンパイラがありました。[LLVM (clang-cl)](https://learn.microsoft.com/ja-jp/cpp/build/clang-support-msbuild?view=msvc-170)。抑制が要りそうです。
Pythonで点を四角形で同じ色で覆う方法

2022/10/10:最終更新
# はじめに
Pythonで点を四角形で同じ色で覆う方法を紹介します．
点はscatterで作成し，四角形はLineCollectionで作成します．


これを実現したい．
![scatter_and_plot.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2885323/984ceff2-4a29-ade7-a29d-4e595e5ca745.png)


# 開発環境
Mac OS Montery v.12.6
Python 3.9.11
numpy = 1.23.3
matplotlib = 3.6.0

# 目次
<!-- タイトルとアンカー名を編集 -->
1. Pythonで点を四角形で同じ色で覆う方法


<!-- 各チャプター -->
<a id="#Chapter1"></a>
# Pythonで点を四角形で同じ色で覆う方法


```python:rect_linecollection.py
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.colors import ListedColormap
from matplotlib.collections import LineCollection

#変数の宣言
DATA_NUM=100
RANGE_START=[[-2,-2],[1,1],[1,-2]]
RANGE_END=[[-1,-1],[2,2],[2,-1]]
X=np.random.uniform(RANGE_START,RANGE_END,(100,3,2))
X=X.transpose(1,0,2)
X_RECT=np.array([[[-2,-2,-1,-1,-2],[-2,-1,-1,-2,-2]],[[1,1,2,2,1],[1,2,2,1,1]],[[1,1,2,2,1],[-2,-1,-1,-2,-2]]])
X_RECT=X_RECT.transpose(0,2,1)
X_COLOR=np.linspace(0,1,3)
X_COLOR=np.repeat(X_COLOR[:,None],DATA_NUM,axis=1)
cmap=plt.get_cmap('viridis')
kar=np.linspace(0,1,3)
LABEL=[0,1,2]

#描画の宣言
fig=plt.figure()
gs=fig.add_gridspec(1,1)
ax1=fig.add_subplot(gs[0,0],aspect='equal')

#描画スタート
ax1.scatter(X[:,:,0],X[:,:,1],c=X_COLOR)
cmap = ListedColormap(cmap(kar))
lc = LineCollection(X_RECT, cmap=cmap,linewidth=5)
lc.set_array(np.array(LABEL))
ax1.add_collection(lc)
plt.show()

```
atcoder 競プロ典型90問　第29問　おぼえがき

自分用です。詳しいことは何一つ書いてアランです。

https://atcoder.jp/contests/typical90/tasks/typical90_ac

左右に高さ0のW個のマスがあり、ここN個のl_i番目からr_i番目のマスをちょうど覆うように高さ1のレンガを順に積んでいき、最終的なレンガの上面の高さを求める問題。

区間に対する処理なので普通にセグ木で解こうかと思った。
解説によると遅延評価セグ木を使うと長さWの配列1回につきO(logW)で解けるらしい。

遅延評価セグ木は主に
・配列のある区間をxに更新(update)/xを加算(add)
・配列のある区間の最小値・最大値・合計などを求める。
をO(logW)で処理できるらしい。

もーちょい詳しく見てみたいので以下のサイトを訪問。

https://tsutaj.hatenablog.com/entry/2017/03/30/224339

普通のセグ木は値が加算されると上のノードまでどんどん伝搬させていくが、遅延評価はそれをクエリでそのノードにアクセスしたときまでその更新をサボることで範囲の長さLのとき、O(LlogN)かかる処理をO(logN)にできるらしい。賢い。

あらかた理解したため実装。
初期化のときに遅延配列の宣言をして、評価・加算などの処理で遅延配列に対して処理をするらしいが・・・


書いたことないことを理由に思考をサボり、解説をパクる。
遅延評価セグ木も更新をサボっているため、これで対等。



```c++:f.cpp
class segment_tree{
private:
    int sz;
    std::vector<int> seg;
    std::vector<int> lazy;
    void push(int k){
        if(k < sz){
            lazy[k*2] = max(lazy[k*2], lazy[k]);
            lazy[k*2 + 1] = max(lazy[k*2 + 1], lazy[k]);
        }
        seg[k]  = max(seg[k], lazy[k]);
        lazy[k] = 0;
    }
    void update(int a, int b, int x, int k, int l, int r){
        push(k);
        if(r <= a || b <= l)return;
        if(a <= l && r <= b){
            lazy[k] = x;
            push(k);
            return;
        }
        update(a, b, x, k * 2, l, (l+r) >> 1);
        update(a, b, x, k * 2 + 1, (l+r) >> 1, r);
        seg[k] = max(seg[k * 2], seg[k * 2 + 1]);
    }
    int range_max(int a, int b, int k, int l, int r){
        push(k);
        if(r <= a || b <= l)return 0;
        if(a <= l && r <= b)return seg[k];
        int lc = range_max(a, b, k * 2, l, (l + r) >> 1);
        int rc = range_max(a, b, k * 2 + 1, (l + r) >> 1, r);
        return max(lc, rc);
    }

public:
    segment_tree() : sz(0), seg(), lazy() {};
    segment_tree(int N) {
        sz = 1;
        while(sz < N) {
            sz *= 2;
        }
        seg = std::vector<int>(sz * 2, 0);
        lazy = std::vector<int>(sz * 2, 0);
    }
    void update(int l, int r, int x) {
        update(l, r, x, 1, 0, sz);
    }
    int range_max(int l, int r) {
        return range_max(l, r, 1, 0, sz);
    }
};
```

以上、丸パクリさせていただいた。

ところで、「：」がついたコンストラクタは初期化子リストと言われるもので、変数名(初期化)で書くらしい。
普通にコンストラクタを書くより、効率的 & const変数の初期化ができるので優秀らしい。
(コンストラクタ内に書くやり方は初期化ではなく代入で、しれっと初めに各クラスのデフォルトコンストラクタで初期化されていることにより初期化＋代入という二度手間が発生しているため)



ということで、29問目、無事AC

丸パクリしたことにより、応用出来るかは不安。


ところで、作用素が可換か、非可換かなどで、処理が変わるなど、遅延セグ木には注意するところが割と多いんだそう。
遅延セグ木に限ったことじゃないけど、Pythonなどインタプリタ言語では非再帰のほうが高速だよね。とかも。

具体的には以下を参照

https://ikatakos.com/pot/programming_algorithm/data_structure/segment_tree/lazy_segment_tree

この辺は抽象化するときにでも詳しく見ることにする。
以下、抽象化するとき用

https://algo-logic.info/segment-tree/
FinTech [X-Techの派生分野①]

# はじめに
IT×ビジネスという視点で週1本記事を投稿しています。
もし興味のある方は下のリンクから他の記事も見ていただければ幸いです。
 [@7_inai_](https://qiita.com/7_inai_)

本記事では、X-Techの派生分野①としてFinTechについてまとめます。
X-Techについては[こちらのリンク](https://qiita.com/7_inai_/items/126f512fa47823237500)からご確認ください。

# FinTechとは
FinTech(フィンテック)とは`Finance(金融)とTechnology(技術)を組み合わせた造語で、金融サービスと情報技術を掛け合わせた領域`を指します。

# FinTechの成長の背景
### ■スマホの普及
多くの人がインターネットに接続された高性能コンピュータを持ち歩くようになったことで、__ATMや支店窓口といった物理的な建物が不要__ となりました。それにより、大規模な資本を持った企業による市場の独占が緩和され、小規模な新興企業も参入できるようになりました。

### ■ブロックチェーンの台等
金融とIT技術を組み合わせる上で、一番の問題となるのはセキュリティです。お金は信頼を得ることで価値を保持できるため、信頼が無くなればお金としての価値もなくなってしまいます。そのため、安全性を確保することが一番の問題となっていました。それを解決した要因の１つが [ブロックチェーン](https://qiita.com/7_inai_/items/2ea53163ae5ec3df9cfe)です。ブロックチェーンという改ざんが非常に難しい技術が台頭してきたことにより、セキュリティ面での信頼性向上に繋がりました。



# 分野一覧
### ■決済サービス
- スマートフォンでのモバイル決済
→PayPay,楽天Pay
- 指紋認証で手ぶら決済(スマホすら不要)
 →Liquid社

### ■家計管理サービス
- 複数の金融資産をアプリで一元管理→MoneyForward

### ■ネットバンキング
- ATMと同等の機能をスマホのアプリとして所有
→各銀行

# 終わりに
テクノロジーの進化によって金融業界は大きく進歩してきました。新しい技術を目にした時に、自身の業種には無関係と思うよりも、その技術の役割を抽象化し、どうすれば活かせるかを考えることでこれからの産業の発展にも着いていけるようになるでしょう。


最後までお付き合いくださりありがとうございました。
LPC812MAXのシリアルでHello Worldと出力(3)(USBTX,USBRX)



x mbed2リビジョン144
x リビジョンを変更できる人むけ

目的
シリアルのテスト


![o_con896.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/04a27001-25dc-cb23-3f39-02ed642df666.jpeg)


![o_con897.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/23c61073-8770-2e3f-01e0-e2322b7e5b15.jpeg)



参考


https://os.mbed.com/users/okini3939/notebook/Serial_jp/


```c++



//SER_HELLO_812_V3

#include "mbed.h"

//        TX      RX
Serial pc(USBTX, USBRX); //812

//メイン関数
int main()
{

    //無限ループ
    while(1) {

        //表示
        pc.printf("Hello World !\r\n");
        pc.printf("%d",1234);
        pc.printf("\r\n");

        //1秒の待ち
        wait_ms(1000);

    }//while

}//main




```


![o_con833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/9a858404-5f9d-9f44-7157-94ce0c559cb8.jpeg)
ExcelVBA：数字⇔文字列変換

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/335742/c69d70be-816f-346a-ab1a-994ae4d09e62.png)
上記の表から、申請者ごとにソフト名とその申請理由をそれぞれカンマ区切りで抽出したい場合に組んだVBA。

```
Dim i as integer

'1行目の右端まで処理を繰り返す
For i = 2 To ThisWorkbook.Sheets("list").Cells(1, Columns.Count).End(xlToLeft).Column

    user = Cells(1, i)

'templateシートをコピーして一番右に追加する。
    ThisWorkbook.Sheets("template").Copy After:=Sheets(Sheets.Count)
    Set objWorksheet = ActiveSheet
    ActiveSheet.Name = user
    
'数字を列番号に変換
    Dim colNum As Long
    colNum = i
'--- アドレス文字列 ---'
    Dim tmpStr As String
    tmpStr = ThisWorkbook.Worksheets(user).Cells(1, colNum).Address(True, False)
'--- 列番号を格納する変数 ---'
    Dim colAddress As String
    colAddress = Left(tmpStr, InStr(tmpStr, "$") - 1)

'各列の2行目から6行目までを選択し、soft_listに格納
    soft_list = colAddress & "2:" & colAddress & "6" 
'各列の7行目から11行目までを選択し、reason_listに格納
    reason_list = colAddress & "7:" & colAddress & "11"
    
'TextJoin関数を用いて範囲内の文字列を結合
    soft = WorksheetFunction.TextJoin(", ", True, Worksheets("list").range(soft_list))
    reason = WorksheetFunction.TextJoin(", ", True, Worksheets("list").range(reason_list))
```

**ポイント1 　シートのコピー**
```
ThisWorkbook.Sheets("template").Copy After:=Sheets(Sheets.Count)
Set objWorksheet = ActiveSheet
ActiveSheet.Name = user
```
Set objWorksheet = ActiveSheet　とすることで、コピーした後のシートが選択された状態とすることで、継続して作業が可能。今回の場合は、シート名をuserに変更した。

**ポイント2　数字を列番号に変換（Addressプロパティ）**
```
    Dim colNum As Long
    colNum = i
'--- アドレス文字列 ---'
    Dim tmpStr As String
    tmpStr = ThisWorkbook.Worksheets(user).Cells(1, colNum).Address(True, False)
'--- 列番号を格納する変数 ---'
    Dim colAddress As String
    colAddress = Left(tmpStr, InStr(tmpStr, "$") - 1)
```
Addressプロパティ構文
```
Cells([行番号], [列番号]).Address([行の相対参照 ], [列の相対参照])
```
・相対参照か絶対参照かを指定する引数はTRUEかFALSEで指定する。
　TRUEにすれば絶対参照の形式（$が付いた形式）でアドレスを表す文字列が返される。

・列番号を取得するには、行の相対参照のみをTRUEにして値を取得する。
　その結果、「A＄1」のようなアドレスが返されるので、「$」よりも左側を抽出すれば列番号が取得できる。
【出典】http://www.fingeneersblog.com/1483/
・InStr関数は、引数string1で指定した文字列の中から、引数string2で指定した文字列を検索して、見つかった位置を返す。

**ポイント3　TextJoin関数**
TextJoinプロパティ構文
```
TextJoin (delimiter、ignore_empty、text1, [text2],...)
```
| 引数 | 説明 |
|:-----------|:------------|
| delimiter（必須）  |区切る文字| 
| ignore_empty（必須）|TRUE の場合、空のセルは無視される。|
| text1（必須）|結合するテキスト項目。 文字列またはセルの範囲などの文字列の配列。|
```
 soft = WorksheetFunction.TextJoin(", ", True, Worksheets("list").range(soft_list))
```
range(soft_list)への入力
動かない：range((cells.(1, i): cells.(6, i))
動く：range(A2:A6)
→このためにAddressプロパティで列情報をアルファベットで取得した。
LPC812MAXのシリアルでHello Worldと出力(2)(D0,D1)


x mbed2リビジョン144
x リビジョンを変更できる人むけ

目的
シリアルのテスト

![o_con894.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/4a7b51b6-acea-72f0-e0e3-72ea72f0d846.jpeg)


![o_con895.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/d3929daa-d4cf-1095-f2f3-3d98f19ee975.jpeg)


![o_con897.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/5ddd762f-74a1-c2ae-6939-d60c8de68a11.jpeg)




参考


https://os.mbed.com/users/okini3939/notebook/Serial_jp/


```c++


//SER_HELLO_812_V2

#include "mbed.h"

//        TX  RX
Serial pc(D1, D0); //812

//メイン関数
int main()
{

    //無限ループ
    while(1) {

        //表示
        pc.printf("Hello World !\r\n");
        pc.printf("%d",1234);
        pc.printf("\r\n");

        //1秒の待ち
        wait_ms(1000);

    }//while

}//main



```


![o_con833.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/3be59758-429a-5e75-7a43-0f5e45cb8004.jpeg)
【Ruby】ファイルのパスからファイル名とディレクトリを分割したい

# 概要　
ファイルのパスからファイル名とディレクトリを分割する方法をメモ。

## ファイル名のみ取得する場合

パスから一番後ろのスラッシュに続く要素を取得するには、File.basenameメソッドを使用します。
第１引数でファイル名を表す文字列を指定します。
第２引数でサフィックスを文字列で与えます。'.*' という文字列を与えた場合、'*' はワイルドカードとして働き '.' を含まない任意の文字列にマッチします。

例
```ruby
p File.basename("ruby/ruby.c")          #=> "ruby.c"
p File.basename("ruby/ruby.c", ".c")    #=> "ruby"
p File.basename("ruby/ruby.c", ".*")    #=> "ruby"
p File.basename("ruby/ruby.exe", ".*")  #=> "ruby"
p File.basename("ruby/y.tab.c", ".*")   #=> "y.tab"
```

## 対象が存在するディレクトリのパスを取得する場合

対象が存在するディレクトリのパスを取得する場合（一番後ろのスラッシュより前の要素）を取得するには、File.dirnameメソッドを使用します。
第１引数でファイル名を表す文字列を指定します。
第２引数で末尾からいくつ取り除くかを指定します。

例
```ruby
p File.dirname("dir/file.ext")    # => "dir"
p File.dirname("file.ext")        # => "."
File.dirname("/home/gumby/work/ruby.rb", 2) # => "/home/gumby"
File.dirname("/home/gumby/work/ruby.rb", 4) # => "/"
```

## ファイル名と対象が存在するディレクトリのパスを分割して配列で取得する場合

ファイル名と対象が存在するディレクトリのパスを分割して配列で取得する場合File.splitメソッドを使用します。

```ruby
[File.dirname(pathname), File.basename(pathname)]
```
と同じ結果となります。

例
```ruby
File.split("/home/gumby/work/ruby.rb") # => ["/home/gumby/work", "ruby.rb"]
```

# 参考
* File.basename
https://docs.ruby-lang.org/ja/latest/method/File/s/basename.html

* File.dirname
https://docs.ruby-lang.org/ja/latest/method/File/s/dirname.html

* File.split
https://docs.ruby-lang.org/ja/latest/method/File/s/split.html
WindowsでSSD換装後の起動時にエラー「0xc000000e」で起動しない場合の対処方法

## インストールメディアから立ち上げてスタートアップ修復

Windows10、11では、インストールメディアはネットでダウンロードしてインストールできます。
USBメモリを一本使用して、インストールメディアを作成しておきます。
https://www.microsoft.com/ja-jp/software-download/windows11

Windows起動時のブートメニューで、USBを優先して起動するように設定すると、Windowsのインストール画面が出てきます。

ここで「このコンピューターの修復」を選択します。　←重要！

オプションの選択で、「トラブルシューティング」→「スタートアップ修復」を選択します。
これを２〜３回繰り返して解決できればOK!

解決できなければ次へ。


## コマンドプロンプトからの修復
前節と同手順で、オプションの選択「トラブルシューティング」→「コマンドプロンプト」を選択し、コマンドプロンプトを立ち上げます。

### DISKPARTでボリュームを確認
```
X:¥Sources>DISKPART
DISKPART>list volume
```
ここでWindowsが入っているボリュームを確認します。
Labelが「Windows」のところに、Windowsが入っています。
今回の場合は、Ltrが「C」のところにWindowsが入っていると仮定して話を進めます。

```
DISKPART>exit
```
exitでDISKPARTを終了します。

### bcdbootを試す
```
X:¥Sources>bcdboot C:¥Windows /l ja-JP
```
これで通ればOK！

## それでも通らない場合は・・・

クローン方法を変えましょうw
テーブルの動的フィルタ機能を雑に実装しよう extablefilter (jQueryプラグイン)

# はじめに

https://www.cyokodog.net/blog/extablefilter/

https://github.com/cyokodog/jquery.ex-table-filter

extablefilterは、テーブルのフィルタリングを画面実装したいときに便利なjqueryプラグインです。
「input入力すると、テーブルが動的に絞り込みされる」実装を実現します。
あまりにもよくお世話になる(この時代でもなお)ので備忘録を兼ねて紹介させてください。
MITライセンスです。

# 使い方

## シンプルな例

 1. jquery読み込み 
 1. extablefilterを読み込み 
 1. inputやtableを含むHTMLを書く
 1. input formとtableに対してexTableFilterを実行

という順番になります。以下が例です。

```HTML
<!-- スクリプト読み込み -->
<!-- The integrity and crossorigin attributes are used for Subresource Integrity (SRI) checking -->
<script  src="https://code.jquery.com/jquery-3.6.1.min.js"
  integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
<script src="http://www.cyokodog.net/jquery.ex-table-filter/jquery.ex-table-filter.js"></script>

<!-- ページの中身 -->
<p>
  <input type="text" id="myfilter" class ="input form-control">
</p>
<p>
<table id="mytable" border=1 class="table table-striped">  
    <thead>
        <tr><th>No</th><th>英語</th><th>日本語</th></tr>
    </thead>
    <tbody>
       <tr><td>1</td><td>first</td><td>１番目</td></tr>
       <tr><td>2</td><td>second</td><td>２番目</td></tr>
    </tbody>
</table>
</p>

<!-- フォームIDがmyfilterのinputに対して、テーブルIDがmytableの項目のフィルタリングを有効にする -->
<script>
jQuery('#mytable').exTableFilter('#myfilter');
</script>
```


# Codepen

※例はbootstrapで見た目を整えています。

## いずれかの列に含まれる文字列に対し、ユーザのテキスト入力でフィルタリングする
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="YzLRzWO" data-user="nazunamix" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nazunamix/pen/YzLRzWO">
  Untitled</a> by Naz (<a href="https://codepen.io/nazunamix">@nazunamix</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

## 自動生成されたチェックボックス、ラジオ、セレクターでフィルタリングする
<p class="codepen" data-height="300" data-default-tab="html,result" data-slug-hash="qBYQZxR" data-user="nazunamix" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/nazunamix/pen/qBYQZxR">
  extablefilter2</a> by Naz (<a href="https://codepen.io/nazunamix">@nazunamix</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>


# おわりに
この他にも色々とカスタマイズできるオプションがあるので、ぜひ公式ページをご確認ください。
jqueryが許される環境であればお好みで…
ターミナルでの削除ショートカット

はじめに
--
ターミナルを使う場面がどんどん増えていきますが、そういえばショートカットあんまり知らないなと思ったので少しづつアウトプットして慣れていこうと思います。


行の末尾まで削除
--
現在の位置から行末まで削除するコマンド
~~~
Ctrl + k
~~~

行頭まで削除
--
現在地から行頭まで削除するコマンド
~~~
Ctrl + u
~~~

前の単語の先頭まで削除する
--
前の単語の先頭まで削除するコマンド
~~~
Ctrl + w
~~~

参考
--
https://support.apple.com/ja-jp/guide/terminal/trmlshtcts/mac