OmniAICreator/Qiita-1.07M huggingface dataset:
【Project Euler】Problem 60: 連結素数の集合

* 本記事は[ProjectEuler](https://projecteuler.net/about)の「100番以下の問題の説明は記載可能」という規定に基づいて回答のヒントが書かれていますので、自分である程度考えてみてから読まれることをお勧めします。

### 問題 60. 連結素数の集合

原文 [Problem 60: Prime pair sets](https://projecteuler.net/problem=60)

**問題の要約：5個の素数から2組を連結した数もすべての素数になるような5個の素数の和の最小値を求めよ。

まず2個の素数の連結したものが素数になることをチェックする関数**isCatPrime**を作ります。これは後から何度も呼ばれるのでメモ化で高速化するために**@lru_cacne**を指定します。

```python
from sympy import isprime, primerange
from functools import lru_cache
@lru_cache(maxsize=None)
def isCatPrime(p1,p2):
  return isprime(int(str(p1)+str(p2))) and isprime(int(str(p2)+str(p1)))
```

次に既に見つかった連結素数のリストに対して新たな素数**p1**がリストのすべての素数と連結素数になるがチェックする関数**isAllCatPrimes**です。

```python
# return True, only when p1 is CatPrime with all of p in plist
def isAllCatPrimes(p1, plist): 
  for p2 in plist:
    if not isCatPrime(p1,p2): return False
  return True
```

これで準備は整ったので再帰関数**findMore**で、リストの長さが5になるまで検索します。

```python
# return 5 prime set when found, otherwise return []
def findMore(foundPr, remPr):   # found primes list, remaining primes to be searched
  if len(foundPr) == 5:
    return foundPr
  for pp in range(len(remPr)):
    p = remPr[pp]
    if isAllCatPrimes(p, foundPr): # check p is cat prime pair with all of foundPr
      Pr5 = findMore(foundPr + [p], remPr[pp+1:]) 
      if len(Pr5)>0: return Pr5
  return []

N = 10**4
Primes = list(primerange(2,N))   # Prime list
for pp in range(len(Primes)):
  Pr5 = findMore([Primes[pp]],Primes[pp+1:])
  if len(Pr5)>0: 
    print(Pr5, sum(Pr5))
```
（開発環境：Google Colab）
和訳: TypeScript 設計目標 (TypeScript Design Goals)

GitHub上のmicrosoft/TypeScript Wiki にある"TypeScript Design Goals"の和訳です。TypeScript という言語が**目指しているもの**(Goals)と**目指していないもの**(Non-goals)がまとめられています。

(原文) TypeScript Design Goals · microsoft/TypeScript Wiki
https://github.com/Microsoft/TypeScript/wiki/TypeScript-Design-Goals

#TypeScript 設計目標
(2020/2/27)

##前書き
この文書は、私達が TypeScript 言語の基礎にした基本的な設計原理の概要を説明するものです。完全ではありませんが、言語を形作ってきた多くの決定の根拠となる規則の要約をねらいとしています。これら規則のいくらかは主観的で、また時には互いに矛盾しています ― 適切なバランスを保ち適切な例外を作る事は、プログラミング言語がいかに成功するかどうかの本質的要素なのです。

##目標(Goals)
1. エラーになる可能性のある構成要素の静的な識別。
1. より巨大なコードへの構造化機構の提供。
1. 生成されたプログラムに実行時のオーバーヘッドを課さない事。
1. 簡潔で、慣用的かつ、分かりやすい JavaScript コードの生成。
1. 組み合わせ可能で推論が容易な言語の作成。
1. 現在および将来の ECMAScript の提案(proposals)に準拠している事。
1. 全ての JavaScript コードの実行時の振る舞いを棄損しない事。
1. 式レベルでの文法の追加を避ける事。
1. 矛盾の無い、完全に消去可能な、構造化された型システムの使用。
1. クロスプラットフォームな開発ツールである事。
1. TypeScript 1.0 からの重大な破壊的変更を引き起こさない事。

##目標でないもの(Non-goals)
1. 既存言語の設計の完全なる模倣。代わりに、JavaScript の振る舞いとプログラム製作者の意図をこの言語の最も意味を成す指標として考える。
1. プログラム実行時のパフォーマンスの積極的な最適化。代わりに、実行環境の性能特性と上手く調和する、慣用的な JavaScript コードを生成する。
1. 健全、もしくは「証明可能なほどに正しい」型システムの適用。代わりに、正確さと生産性のつり合いを取る。
1. エンドツーエンドのビルドパイプラインの提供。代わりに、より複雑なビルド・ワークフローのために外部ツールがコンパイラを使用できるよう、システムを拡張性のあるものにする。
1. プログラム実行時に型情報を追加したり、それに依存する事。または型システムの結果によって異なるコードを生成する事。代わりに、実行時のメタデータを必要としないプログラミングパターンを奨励する。
1. 実行時の追加的機能やライブラリの提供。代わりに、既存ライブラリの記述に TypeScript を使用する。
1. ユーザーを驚かせるような振る舞いの導入。代わりに、他の一般的な言語で採用されているパターンに対して十分な考慮をする。
jupyterlab_variableinspector をインストールする。



以下のコマンドで、拡張機能をインストールする紹介があった。

```
jupyter labextension install @lckr/jupyterlab_variableinspector
```

しかし、ビルドがうまくいかなかった。`jupyter lab build`をしても下記のようにエラーが出た

```
An error occurred.
RuntimeError: JupyterLab failed to build
```

いろいろと方法を探していると、`conda`を使ったインストール方法が紹介されていたので、ことらを試したところ、jupyter labで`Open Valiable inspector`が使えるようになった。

```
conda install -c conda-forge jupyterlab-variableinspector
```

https://discourse.jupyter.org/t/jupyter-lab-failed-to-build/9745/4

よかった、よかった。
Accessクエリ 関数【日付操作編】③

備忘録として投稿します。
全13項目【日付操作編】④まであります。
今回は【日付操作編】③です。
#ACCESSの日付操作でよく使用する関数　その３
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2517880/443a26f4-f498-a611-4657-915a916aec57.png)
#まとめ
今回は
⑧指定した日付から月末までのデータを抽出したい。
⑨前月のデータを抽出する
⑩直近1週間のデータを抽出する
以上3つの項目についてまとめてみました。
ラスト1つの記事も参考にしてみてください。
Docker + Next.jsでAPIを叩く時のプチハマり


以前構築した Docker + Nginx + Node.js環境でAPIを叩く時にプチハマりしたことを書きます。
環境は↓

https://qiita.com/lvn-hanada/items/3bc9744f4384d277898a

## やりたいこと
`getServerSideProps`内と`NextPage`内それぞれでAPIを叩きたい。

## やったこと
#### NextPage内
エンドポイントが`localhost:8080/api/get-hoge`であるとする。

```ts
const res = await fetch('http://localhost:8080/api/hoge',
{
  method: 'GET',
  // 略
});
```

こちらはうまくいきました。が、

#### getServerSideProps内
```.ts
const res = await fetch('http://localhost:8080/api/hoge',
{
  method: 'GET',
  // 略
});
```

こっちは
`Server Error / Error: connect ECONNREFFUSED` ~~って出ちゃいました
調べていると、クライアントサイドとサーバーサイドで叩くドメインを変えないいけないようなので、

```ts
const res = await fetch('http://host.docker.internal:8080/api/hoge',
{
  method: 'GET',
  // 略
});
```

これでできました。

## 参考

https://github.com/vercel/next.js/discussions/17585
【TypeScript】keyofメモ

TypeScriptで `keyof` を利用すると、オブジェクトのプロパティ名を抽出し、ユニオン型を生成できる。
`keyof T` => `T typeのプロパティ名のユニオン型` を表現できる。

```typescript
type Item = {
  title: string;
  description: string;
};

type ItemKey = keyof Item;
// ItemKey は 'title'|'description' というユニオン型になる
```
存在と時間(Sein und Zeit)

文脈がまったく違うのは理解するものの、プログラミングをやって思う便利さの一つは時間の意義です。

過去は変えられない。これが悲しい事実かどうかはさておき、過去は変えられないので、過去の出来事は固定されたものとなります。固定されると準絶対的データとして取扱できます。

この時間の固定の性質で、どれだけのデータ処理が安定感をもたらされるかということは長年の実感です。そうすると、過去が変えられないことを嘆くのがすべてではないと思えます。
scikit-learnモデルのトレーニング、scikit-learnフォーマットでの保存

[Train a scikit\-learn model and save in scikit\-learn format \| Databricks on AWS](https://docs.databricks.com/applications/mlflow/tracking-ex-scikit.html) [2021/6/11時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

このノートブックはMLflowの[チュートリアル](https://www.mlflow.org/docs/latest/tutorials-and-examples/tutorial.html)をベースにしています。

このノートブックでは、モデルのパラメーター、メトリクス、モデル自身、グラフのようなアーティファクトをDatabricksがホストするトラッキングサーバーに記録するモデルトレーニングプロセスのトラッキングに、MLflowをどのように使用するのかを説明しています。これには、記録された結果をMLflowトラッキングUIで参照する方法も含まれています。

トレーニングしたモデルをAWS SageMakerにデプロイする方法に関しては、[SageMakerへのscikit\-learnモデルのデプロイメント](https://qiita.com/taka_yayoi/items/79f024874075ea9e1cd3)を参照ください。

# MLflow scikit-learnモデルのトレーニングノートブック

https://github.com/taka-yayoi/public_repo/tree/main/mlflow_quickstart_training_logging

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
EC-CUBE4 form 項目に独自の型を使う

## はじめに

DBAL Type を独自に増やした場合などの、フォームの作り方です。

※ EC-CUBE 特有の機能ではなく、Symfony の機能です。
※ DBAL Types を増やす方法は[こちらから](https://qiita.com/applexco/items/7f6f3100ae836711a7e5)

## ファイルの準備

```php:app/Customize/Domain/Gender/Gender.php
<?php

declare(strict_types=1);

namespace Customize\Gender;

class Gender
{
    public const MALE = 'male';
    public const FEMALE = 'female';

    /** @var string */
    private $value;

    public static function reconstruct(string $value): Gender
    {
        $gender = new self();
        $gender->value = $value;

        return $gender;
    }

    public function toScalar(): string
    {
        return $this->value;
    }
}
```

```php:app/Customize/Form/DataTransformer/GenderToStringTransformer.php
<?php

declare(strict_types=1);

namespace Customize\Form\DataTransformer;

use Customize\Gender;
use Symfony\Component\Form\DataTransformerInterface;

class GenderToStringTransformer implements DataTransformerInterface
{
    /**
     * Transforms an object (Gender) to a string.
     *
     * @param Gender|null $value
     */
    public function transform($value): string
    {
        if ($value === null) {
            return '';
        }

        return $value->toScalar();
    }

    /**
     * Transforms a string to an object (Gender).
     *
     * @param string $value
     */
    public function reverseTransform($value): ?Gender
    {
        if ($value === '' || $value === null) {
            return null;
        }

        return Gender::reconstruct($value);
    }
}
```

```php
<?php

declare(strict_types=1);

namespace Customize\Form\Extension\Front;

use Customize\Gender;
use Customize\Entity\MyEntity;
use Customize\Form\DataTransformer\GenderToStringTransformer;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints as Assert;

class MyEntityType extends AbstractType
{
    /** @var GenderToStringTransformer */
    private $genderTransformer;

    public function __construct(GenderToStringTransformer $genderTransformer)
    {
        $this->genderTransformer = $genderTransformer;
    }

    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('gender', ChoiceType::class, [
                'choices' => [
                    '男' => Gender::MALE,
                    '女' => Gender::FEMALE,
                ],
            ]);
        $builder
            ->get('gender')
            ->addModelTransformer($this->genderTransformer);
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => MyEntity::class,
        ]);
    }
}
```

## できあがり

`GenderToStringTransformer` クラスが重要で、オブジェクトと文字列の変換が自動的に行われます。

この設定がない場合は、`Catchable Fatal Error: Object of class Customize\Gender could not be converted to string` のようなエラーが発生します。
Reactorのdeferの使い方

[reactor-core](https://github.com/reactor/reactor-core)のMonoやFluxを使う上で、よくやってしまうリソース解放に関する誤りを、`Mono#defer`の使い方とともに説明します。
reactor-coreのその他の使い方については、[Reactor 3 Reference Guid](https://projectreactor.io/docs/core/release/reference/)を参考にして下さい。

## 前準備
[reactor-core](https://github.com/reactor/reactor-core)に従って、reactor-coreを使ったJavaプログラミングが出来る環境を準備します。

## 問題のあるコード
`Mono`や`Flux`の処理は、`subscribe`や`block`等の終端処理が呼ばれた際に実行されます。このため、終端処理が呼ばれるたびに、`doOnTerminate`等のハンドラーが実行されます。以下のように、`Mono`の外側で作成したリソースを`doOnTerminate`で`close`すると、2回目の終端処理の呼び出しはすでに`close`されているリソースに対して実行されてしまいます。

``` java
	private static class _SampleCloseable implements Closeable {

		private boolean _closed;

		@Override
		public synchronized void close() {
            // 2回以上、closeが呼ばれるとエラーになる。
			if (_closed) {
				throw new RuntimeException("Already closed.");
			}
			_closed = true;
		}

	}

	@Test
	public void testInvalidClose() throws Exception {
		var closeable = new _SampleCloseable();
		var mono = Mono.just("good").doOnTerminate(() -> {
			closeable.close();
		});
        // 内部でcloseが呼ばれる
		var value = mono.block();
		Assertions.assertEquals("good", value);
        // 内部でcloseが呼ばれる(2回目なのでエラーになる)
		Assertions.assertThrows(RuntimeException.class, () -> mono.block());
	}
```

## `defer`を使用した修正
`defer`を使用することで、`Mono`の内部でリソースの初期化を行う事が出来ます。

``` java
	@Test
	public void testDefer() throws Exception {
		var mono = Mono.defer(() -> {
            // リソースの初期化をdefer内で行います。
			var closeable = new _SampleCloseable();
			return Mono.just("good").doOnTerminate(() -> {
				closeable.close();
			});
		});
        // block実行時に、リソースが初期化されて、閉じられます
		var value = mono.block();
		Assertions.assertEquals("good", value);
        // block実行時に、リソースが初期化されて、閉じられます
		value = mono.block();
		Assertions.assertEquals("good", value);
	}
```

## 結論
`defer`を使うことで、リソースの初期化と解放をMonoやFluxに閉じて行う事が出来ます。
`Mono`や`Flux`の生成と同じスコープでリソースの初期化をしているケースでは、こちらの問題が発生する可能性を常に考慮する必要があります。
express-generator の使い方

次のページを参考にしました。
[Express のアプリケーション生成プログラム](https://expressjs.com/ja/starter/generator.html)

ライブラリーのインストール

```bash
sudo npm install express-generator -g
```

## プロジェクトの作成

```bash
express --view=pug myapp
```

依存関係をインストール

```bash
cd myapp
npm install
```

## サーバーの起動

```bash
DEBUG=myapp:* npm start
```

クライアントでポート 3000 にアクセスする

```bash
http http://localhost:3000
```

ソースを改造

```text:views/index.pug
extends layout

block content
  h1= title
  p Welcome to #{title}
  p Hello World!
  p こんにちは
```

クライアントでアクセス
![express_jan31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179446/73e66481-ac82-a2ff-884d-aa7c719dc141.png)

## forever でデーモン化
ライブラリーのインストール

```bash
sudo npm install forever -g
```

起動

```bash
forever start ./bin/www
```

```text
$ forever start ./bin/www
warn:    --minUptime not set. Defaulting to: 1000ms
warn:    --spinSleepTime not set. Your script will exit if it does not stay up for at least 1000ms
info:    Forever processing file: ./bin/www
(node:20939) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
(Use `node --trace-warnings ...` to show where the warning was created)
(node:20939) Warning: Accessing non-existent property 'padLevels' of module exports inside circular dependency
```

状況の確認

```bash
forever list
```

停止

```bash
forever stopall
```

ポートを指定しての起動

```bash
PORT=5000 forever start ./bin/www
```

## 確認したバージョン

```text
$ node --version
v20.2.0

$ express --version
4.16.1
```
SageMakerへのscikit-learnモデルのデプロイメント

[scikit\-learn model deployment on SageMaker \| Databricks on AWS](https://docs.databricks.com/applications/mlflow/scikit-learn-model-deployment-on-sagemaker.html) [2021/3/22時点]の翻訳です。

:::note warn
本書は抄訳であり内容の正確性を保証するものではありません。正確な内容に関しては原文を参照ください。
:::

このノートブックでは[scikit\-learnモデルのトレーニング、scikit\-learnフォーマットでの保存](https://qiita.com/taka_yayoi/items/093f68cb0983cf683647)で説明されている糖尿病データセットでトレーニングしたElasticNetモデルを使用します。このノートブックでは以下を説明しています。

- MLflowエクスペリメントUIを用いてデプロイするモデルを選択。
- MLflow APIを用いてSageMakerにモデルをデプロイ。
- `sagemaker-runtime` APIを用いてデプロイされたモデルを検索。
- 別のモデルに対してデプロイ、クエリープロセスの繰り返し。
- MLflow APIを用いてデプロイメントを削除。

DatabricksからAWS SageMakerにMLflowモデルをデプロイできるように、どのようにAWSの認証設定を行うのかについては、[機械学習モデルをSageMakerにデプロイするのためのAWS認証設定のセットアップ](https://qiita.com/taka_yayoi/items/e26e4546cdaf13069aad)をご覧ください。

:::note info
SageMakerエンドポイントへのデプロイがわかりにくいので補足します。
:::

MLflow SageMaker APIを用いてモデルをSageMakerエンドポイントにデプロイする際、AmazonのElastic Container Registry (ECR)のDockerイメージを指定します。SageMakerはモデルをサービングする際にこのイメージを使用します。

ローカルマシンでMLflow CLI:`mlflow sagemaker build-and-push-container`を実行し、`mlflow-pyfunc`イメージをビルドし、イメージをECRのリポジトリにアップロードします。ECRリポジトリに`mlflow-pyfunc`イメージが作成されます。アップロード完了後、DockerイメージのURLを取得することができます。

![](https://sajpstorage.blob.core.windows.net/demo20220129-pytorch-mlflow/ECR.png)

1. ローカルマシンでAWS CLIのインストール、設定`aws configure`を行います。
1. インストールされていない場合、PyPIで`mlflow`、　`boto3`をインストールしておきます。
1. ローカルマシンで`mlflow sagemaker build-and-push-container`を実行すると、Dockerイメージの作成およびECRへのアップロードが行われます。

```py:Python
# 以下でECR DockerイメージのURLを指定します。
# ECR URLは以下のフォーマットである必要があります: {account_id}.dkr.ecr.{region}.amazonaws.com/{repo_name}:{tag}
image_ecr_url = "<AWSアカウントID>.dkr.ecr.ap-northeast-1.amazonaws.com/mlflow-pyfunc:1.23.1"
```

上のURLを指定して、エンドポイントへのモデルデプロイを行います。

```py:Python
import mlflow.sagemaker as mfs
app_name = "diabetes-class-v1"
mfs.deploy(app_name=app_name, model_uri=model_uri, image_url=image_ecr_url, region_name=region, mode="create")
```

しばらくすると、エンドポイントがInServiceになるので、この後は予測結果を得るために
モデルに対してクエリーを実行することができます。

![sagemaker_endpoint_inservice.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1168882/4c1348de-869b-88fb-8d7d-7f0fc85e85b7.png)

# MLflow scikit-learnモデルトレーニングのノートブック

https://github.com/taka-yayoi/public_repo/tree/main/mlflow_quickstart_sagemaker_deployment

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
フロントエンドLT vol.1 ひとことイベントレポート

こんにちは！みやぞんです！

2022年1月27日にオンラインで開催された、弊社Another works主催 フロントエンドLTのイベントレポートになります！
どれも非常に内容の濃いLTでしたので、タイトルと感想を一言書かせていただきます！

https://anotherworks.connpass.com/event/234160/

# LTタイトル (サイト掲載順)
- 命名規則のレビューしたくない話(そるさん)
- 日本一簡単投稿!?　LINEフォトアルバムアプリを自作してみた(沖中がいこつさん)
- 「immer」で簡単！イミュータブル！(hakkeiさん)
- 令和最新版FCM(morishinさん)
- 状態管理ライブラリRecoilについて話します(まっちさん)
- ISR完全に理解した(みやぞん(私))
- StoryBook駆動で新規システムの開発を試してみた(kght6123さん)
- Blitz.jsで作るエンタープライズサービス(Yuta Okadaさん)
- みんなRef使ってる？(ひらまささん)
- React Testing LibraryのQueryについて整理してみた(古市武尊さん)


## 命名規則のレビューしたくない話　-　そるさん（株式会社Another works）
- あるディレクトリのは以下のクラス名や関数名、ファイル名を縛りたい
- ymlやjsonでかけて、ディレクトリごとにルールを設定できたりファイル名をクラス名に使うなどのルールを設定したい

そこで命名規則判定ツール「namelint」を自作！

ドキュメント管理コストやレビューコストが大幅に削減された話でした！
npm packageが公開されているのでぜひ触ってみてください！

https://www.npmjs.com/package/@another_works/namelint


## 日本一簡単投稿!?　LINEフォトアルバムアプリを自作してみた　-　沖中がいこつさん（個人開発）
なんとエンジニアではなくスーパー勤務の店長さんです！
「のこるん」というLINEフォトアルバムアプリをご自身でいちから開発しておられるとのこと！

日常の思い出をより簡単に残せるようにするのに最適なアプリで、
お子さんがアプリを使用している映像などでもその手軽さが伝わってきました！

クラファン開催中です！

https://camp-fire.jp/projects/view/528736

## 「immer」で簡単！イミュータブル！　-　hakkeiさん（株式会社Another works）
Reactが公式で推奨するイミュータブル実装のためのライブラリ「immer」についての発表でした！
Reactのためのhooksなども提供されていて非常に便利...！
cloneDeepとの比較もわかりやすく非常に勉強になりました。

圧倒的にパフォーマンスが良い！

https://www.npmjs.com/package/immer

## 令和最新版FCM - morishinさん（株式会社Magic Moment）
Firebase Cloud Messagingについての発表です！

Reactを使ってプッシュ通知ができるところまでのご紹介と、ハマリポイントについて。
私自身FCMを使ったことがなかったのですが、結構大きなハマリポイントあるんだなあと思いました...。

使う機会があったらmorishinさんの発表を見返そうと思いました！
朝考えた発表とのことでしたが、情報量がすごかったですw

## 状態管理ライブラリRecoilについて話します　-　まっちさん（株式会社Another works）
ステート管理ライブラリのRecoilについてのお話！
弊社では状態管理にRedaxを使用していますが、Recoilはそれよりもシンプルにかける場面もありそうでした！
Redaxとの比較が非常にわかりやすかったです！

https://recoiljs.org/

## ISR完全に理解した　-　みやぞん(私)（株式会社Another works）
ISRについての発表です！
ISRの選定理由やその挙動について深堀りした結果を発表しました！
速い！簡単！すごい！
そんな機能でございます。

発表内容は以下の記事にまとめています！

https://zenn.dev/topics/frontend

## StoryBook駆動で新規システムの開発を試してみた　-　kght6123さん(虎の穴ラボ株式会社)
StoryBook駆動で新規システムの開発を試してみた

StoryBookを使った開発についての発表です！
コンポーネントの実際のUIをGUIで確認できるだけでなく、使用をマークダウンで書くことができたり、APIが必要なコンポーネントに関してはモックを用意することができたりと、、！すごい！

https://storybook.js.org/

弊社でもStoryBookを一部導入しているので非常に勉強になりました。

## Blitz.jsで作るエンタープライズサービス - Yuta Okadaさん(株式会社BOOSTRY)
Blitz.jsはまだまだ記事も出回っていないこともあり未知でしたが、Railsに変わるフルスタックフレームワークということで個人的にすごく興味がありました。

プロダクトにすでに導入しているということが驚きでした！超最先端！

## みんなRef使ってる？　-　ひらまささん（株式会社Another works）
前回の外部LTの続編！
Refの歴史や、Refのユースケース、サンプルFormをRefを使って実装するなど、コードベースでわかりやすく説明してくれました。

Refはいいぞ！

https://ja.reactjs.org/docs/refs-and-the-dom.html

## React Testing LibraryのQueryについて整理してみた　-　古市武尊さん（コネヒト株式会社）
testing libraryのQueryについての注意点などを発表いただきました！

getByxxxにもたくさんあって、使い分けが大切であると知り勉強になりました。
getByTestIdの存在は知らなかったです...。要素内のテキストが動的な場合に非常に便利！

https://testing-library.com/docs/react-testing-library/intro/

## おわりに
今回は80名を超えるエンジニアにご参加いただき、大盛況となりました！
また第二弾も近々開催しようと思っていますのでお楽しみに！
dockerFile軽量化資料

#初めに
業務でdockerファイルを軽量化する必要があり、その調査でまとめた情報を載せます。
時間がなかったのでかなり殴り書きのようなメモですが、同じ悩みを持った人の助けになればと思います。
私自身、dockerの経験が薄くコンテナの初回のような情報も載せてあります。
時間ができたら、整理して再度記事にしようと思ってます。

#調査資料
docker軽量化　記事　資料
おまえのdockerファイルはまだ重い
https://speakerdeck.com/stormcat24/oqian-falsedockerimezihamadazhong-i?slide=15
↑スライドで視覚的にわかりやすい、どうして軽くしないといけないのかどんなものがいいのかのイメージが掴めやすい

dockerのイメージとコンテナの違い
https://and-engineer.com/articles/YaSPjRIAACAAkhMI

dockerイメージのレイヤの考え方
https://www.itbook.info/network/docker02.html

dockerコンテナイメージを軽くする理由
・ポータビリティが向上する
・ノード障害等でコンテナが別ノードに移動する際により早く起動できる
・これらは、サービスの復旧の速度を早めることにつながる
https://blog.mosuke.tech/entry/2020/07/09/container-image-size/


dockerファイル公式git
libから現場の公式発表dockerコードが見れる
https://github.com/docker-library/official-images

大体以下の三つに絞れる
・Alpine Linux
・Ubuntu
・Debian

厳しい
・CentOS
理由：
モジュールが揃いすぎている＝dockerのイメージとしては重くなってしまう

とにかく軽い運用を目指すならAlpine Linux
安定的な運用を目指すならUbuntuかDebian

Alpine Linux
軽量重視で作られたLinux ディストリビューション　イメージのサイズがとにかく小さい
しかし、Pythonなど一部の言語で速度が遅くなる可能性がある　
理由：libcに一般的な互換性が不足している
https://superuser.com/questions/1219609/why-is-the-alpine-docker-image-over-50-slower-than-the-ubuntu-image


Debian Slim
タグの説明
https://www.ted027.com/post/docker-debian-difference/
↑これにどの時どのタグを使った方がいいのかの情報が記載されている
https://prograshi.com/platform/docker/docker-image-tags-difference/

Distroless 
GoogleがメンテしているDockerのベースイメージ群
カンファレンス
https://swampup2017.sched.com/
README
https://github.com/GoogleContainerTools/distroless/blob/main/base/README.md
sysdigにも評価されている
https://sysdig.jp/blog/dockerfile-best-practices-2/

shellもパッケージマネージャーもない＝セキュリティとしては強くなる
https://ceblog.mediba.jp/post/662840014480326656/コンテナイメージとしてdistrolessを使うべき理由って/amp


参考資料
Dockerイメージを軽量化する
https://qiita.com/gorohash/items/2358b4b9e0c708e510d0
Dockerfileのアンチパターンと軽量化方法
https://qiita.com/takky/items/401344672a803469b896
dockerイメージの軽量化
https://qiita.com/ytanaka3/items/8c308db2ee58ea63626a
社内のdockerfileのベストプラクティスを公開します（Forcia）
https://www.forcia.com/blog/002273.html
dockerでRunをまとめた方がいいとは限らない
https://future-architect.github.io/articles/20210121/

docker-slimについて

コンテナの最適化ツール？
機能 特徴
・静的および動的解析による最適化
・最適化後にDockerFileを自動作成
・Go製のDocker Container Imageサイズ圧縮自動化ツール
・静的(Dockerfile)及び動的(各レイヤーでのプロセスの起動情報など)な解析による最適化
・ダイエットしたImageだけではなくDockerfileも作成してくれる(リバースエンジニアリング)
・デモではnode.jsのイメージが431.7MBから14.22MB(約97%削減!)

https://qiita.com/ryuichi1208/items/c96d39a57e11d54f02bf

https://junchang1031.hatenablog.com/entry/2016/02/11/171449
https://hawksnowlog.blogspot.com/2019/12/getting-started-with-docker-slim.html?m=0
GitHub
https://github.com/docker-slim/docker-slim
https://dockersl.im/
https://scrapbox.io/kimihiro-n/DockerSlim_%E4%BD%BF%E3%81%A3%E3%81%A6%E3%81%BF%E3%81%9F
面倒なEC2インスタンスssh接続を超速で行えるようにした

# 目的
ec2のインスタンスにログインする時に、特に久しぶりだとコマンドを忘れたり、覚えていてもパブリックDNS探すのが面倒だったり、そもそもこの長いコマンドを打つのが嫌だった。。。

```
$ ssh -i <key_name> ec2-user@<Public_DNS>
```

まさかこれを簡単にする方法があるとは知らなかった。
# 前提
- EC2インスタンスを起動済み
- ElasticIPをそのインスタンスにアタッチ済み

# 概要

# .sshディレクトリ を作成し、権限を付与する
```bash
$ mkdir ~/.ssh
# 所有者に全ての権限を与える
$ chmod 700 ~/.ssh
```

# key.pemを.sshディレクトリに移動し、権限を付与する
EC2インスタンス起動時にダウンロードした自分のキーをkey.pemに置き換えること。
所有者にread権限のみ与える。

```bash
$ mv key.pem ~/.ssh
$ chmod 400 ~/.ssh/key.pem
```

# configにSSH接続情報を登録しておく
configファイルがsshディレクトリ以下になければ作成する

```
$ touch ~/.ssh/config
$ vi ~/.ssh/config
```

```~/.ssh/config
host ec2_login
  HostName <PublicDNS>
  Port 22
  User ec2-user
  IdentityFile ~/.ssh/key.pem
```

HostNameにはインスタンス詳細に記載の自分ものを。
Userはいつもsshする時に使うUser名。
IdentityFileは前述で移動したkeyを。

# configファイルの権限
所有者のみread/write権限を与える

```
$ chmod 600 ~/.ssh/config
```

# ssh接続してみる
```bash
$ ssh ec2_ec2_user
Last login: Sun Jan 30 21:56:11 2022 from softbank219059166010.bbtec.net

       __|  __|_  )
       _|  (     /   Amazon Linux 2 AMI
      ___|\___|___|

https://aws.amazon.com/amazon-linux-2/
```

# できた！！
wsl2 ubuntu gitlab runner install

#インストールメモ
Dockerインストール

```
sudo apt update
sudo apt install apt-transport-https ca-certificates curl software-properties-common
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu focal stable"
sudo apt update
sudo apt install docker-ce
sudo systemctl status docker
```

GitLab Runnerインストール

```
sudo wget -O /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-linux-amd64
sudo chmod +x /usr/local/bin/gitlab-runner
sudo useradd --comment 'GitLab Runner' --create-home gitlab-runner --shell /bin/bash
sudo /usr/local/bin/gitlab-runner install --user=gitlab-runner --working-directory=/home/gitlab-runner
sudo systemctl enable gitlab-runner
sudo systemctl start gitlab-runner
sudo systemctl status gitlab-runner.service
```

GitLab Runner登録

```
sudo /usr/local/bin/gitlab-runner register
Runtime platform                                    arch=amd64 os=linux pid=8618 revision=98daeee0 version=14.7.0
Running in system-mode.

Enter the GitLab instance URL (for example, https://gitlab.com/):
https://gitlab.com/
Enter the registration token:
gitlab runnerのトークン
Enter a description for the runner:
[DESKTOP-4BU08N3-wsl]: test
Enter tags for the runner (comma-separated):
test
Registering runner... succeeded                     runner=bRHaFW_7
Enter an executor: kubernetes, custom, docker-ssh, ssh, virtualbox, docker+machine, docker-ssh+machine, docker, parallels, shell:
docker
Enter the default Docker image (for example, ruby:2.6):
python:3.9
Runner registered successfully. Feel free to start it, but if it's running already the config should be automatically reloaded!
Weighted Hough

# Indroduction
Today I would like to introduce a variety of Hough transform, which named "weighted Hough transform"[1].

# The weighted Hough Transform
The idea is super simple.
Instead of using binarized edge input (edge or non-edge), I directly use edge intensity as an input of Hough, and vote based on the edge intensity. 
 As an small tips, it's better to cut small edge value input to accelerate the process. 

# Example result
Here is a input from opencv sample aero3.png:
![aero3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753103/c91be849-c5eb-2269-58b2-d123cc2c4609.jpeg)

If you use ordinary Hough transform after ordinary Canny edge detection, the result becomes like this;
![standardHough_aero3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753103/4a0297bb-e115-9a53-97dd-dcc21404b5b4.png)
You can see it extracts not so stronger edge first.
You cannot change the situation just changing the Hough threshold. 

On the other hand, the weighted Hough transform output stronger edge first;
![weightedHough_aero3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753103/0409ce68-0b98-e7f6-bb0b-e1971bc5a574.png)

For your interest, I also put the result of probabilistic Hough;
![standardHough_aero3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/753103/91f0762d-4277-e3a2-25c4-791311cef4af.png)
The situation is the same with standard Hough transform.

# Implementation
I already made a pull request to OpenCV community.
I will notice you later when it is merged.

# Summary
Today, I introduced the algorithm; weighted Hough transform.
It uses edge intensity as an input though standard Hough transform just accespts binarized edge image.
The weighted Hough transform can detect stronger edge first.
I hope this function will be widely used in the world.

# Reference
[1] Mohammad K. Ibrahim, E. C. L. Ngau, and Mohammad Farhang Daemi "Weighted Hough transform", Proc. SPIE 1607, Intelligent Robots and Computer Vision X: Algorithms and Techniques, (1 February 1992); https://doi.org/10.1117/12.57063
Next.jsのチュートリアルでエラーが出た話

nextのバージョンは10.2.3です。（最新版ではないです）

エラーで詰まったのはこの章の話です
https://nextjs.org/learn/basics/dynamic-routes/render-markdown

##結論から

バージョンが最新版ではないライブラリをインストールしてください

```
npm install --save remark@13.0.0 remark-html@13.0.2
```

lib/posts.jsの記載を変更してください

```js:posts.js
import remark from 'remark'   //{}はずすだけ
import html from 'remark-html'
```

##経緯

###1.まずreamrkとremark-htmlというライブラリを入れる

```
npm install --save remark remark-html
```

###2.チュートリアルの通りにソースコードを修正して、下記にアクセス
http://localhost:3000/posts/ssg-ssr
http://localhost:3000/posts/pre-rendering

###3.すると、下記エラーが発生
![スクリーンショット 2022-01-31 4.12.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320179/896cba04-b82b-123a-b644-b365cdc811a4.png)

```terminal:ターミナルに出力されたエラー
~~~/node_modules/remark/index.js:1
(function (exports, require, module, __filename, __dirname) { import {unified} from 'unified'
```

###4.ライブラリ（remark）のバージョンが良くないと思い、下記で最もダウンロードされているバージョンに下げる
https://www.npmjs.com/package/remark

```
npm install --save remark@13.0.0
```

```json:package.json
  "dependencies": {
    "gray-matter": "^4.0.2",
    "next": "^10.2.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "remark": "^13.0.0",   //14.0.2→13.0.0に変更されたことを確認
    "remark-html": "^15.0.1",
    "unified": "^10.1.1"
  }
```

###5.再度 http://localhost:3000/posts/ssg-ssr にアクセス

エラーが少し変わった。今度はremark-htmlでエラーが出てるっぽい

![スクリーンショット 2022-01-31 4.24.05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320179/7b4c39ac-1469-29fd-1a7e-dec8a58466d2.png)

```terminal:ターミナルに出力されたエラー
~~~/node_modules/remark-html/index.js:15
import {toHtml} from 'hast-util-to-html'
```

###6.4と同様、ライブラリ（remark-html）を最もダウンロードされているバージョンに下げる
https://www.npmjs.com/package/remark-html

```
npm install --save remark-html@13.0.2
```

```json:pacackage.json
  "dependencies": {
    "gray-matter": "^4.0.2",
    "next": "^10.2.3",
    "react": "^17.0.2",
    "react-dom": "^17.0.2",
    "remark": "^13.0.0",
    "remark-html": "^13.0.2",  //15.0.1→13.0.2に変更されたことを確認
    "unified": "^10.1.1"
  }
```

これで流石にいけると思った


###7.再度 http://localhost:3000/posts/ssg-ssr にアクセス

発狂。
ただ、is not a functionだから関数（remark）をうまく読み込めてないのかなと思う

![スクリーンショット 2022-01-31 4.33.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320179/64179a16-4d66-96a8-4d96-e8c207efe789.png)

```terminal:ターミナルに出力されたエラー
TypeError: (0 , remark__WEBPACK_IMPORTED_MODULE_3__.remark) is not a function
    at getPostData (webpack-internal:///./lib/posts.js:83:80)
    (省略)
```

###8.importの記述を修正

```js:posts.js
import { remark } from 'remark'  //公式チュートリアルではこう書けと記載してある
import html from 'remark-html'
```
↓

```js:posts.js
import remark from 'remark'   //{}はずすだけ
import html from 'remark-html'
```

###9.再度 http://localhost:3000/posts/ssg-ssr にアクセス

解決。

![スクリーンショット 2022-01-31 4.42.55.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/320179/05940b17-b337-a9ae-281a-5ed0fea99946.png)

next最新版なら普通に動くみたいなオチだったら悲しい
2022/1/31主にITとかセキュリティの記事

【特別企画】名和氏の特別レポート - 「セキュリティ強化」を唱えるだけでは逆効果のことも
https://www.security-next.com/133376

NTT西の光受付システム障害がようやく解消、対応に8カ月かかったわけ(1/28)
https://xtech.nikkei.com/atcl/nxt/news/18/12120/?i_cid=nbpnxt_ranking

大阪府警に「サイバー局」　２５０人規模、対策の司令塔機能(1/28)
https://www.sanspo.com/article/20220128-OBQL2TBWUVLCZOCSSKWF34UF4M/

ネット中傷、リツイートで「違法」も　有識者ら中間報告(1/29)
https://www.nikkei.com/article/DGXZQOUC246IW0U2A120C2000000/

パソコンに「ウイルス汚染」　６０代男性が２０万円詐欺被害(1/28)
https://www.sakigake.jp/news/article/20220128AK0003/

サイバー犯罪摘発、過去最多　24.3％増で初の1万件超(1/28)
https://news.yahoo.co.jp/articles/e648a82f3335668aaa717152ebb5ec1c10e69698

日能研からメアド28万件流出か　中学受験生の保護者ら(1/29)
https://news.goo.ne.jp/article/kyodo_nor/business/kyodo_nor-2022012901000357.html

件名「【重要】ウーバーイーツ ご注文内容の確認」、Uber Eatsをかたるフィッシングメールに注意
偽サイトで電話番号やメールアドレスを詐取(1/28)
https://internet.watch.impress.co.jp/docs/news/1384409.html

北京五輪でサイバー攻撃増加か - 米専門家が予測、防御が課題に(1/29)
https://www.nara-np.co.jp/global/2022012901000352.html

｢年間1万件超｣ サイバー犯罪捜査に本腰　その名も｢サイバー特別捜査隊｣(1/28)
https://www.fnn.jp/articles/-/306495?display=full

成熟期に入ったSaaSビジネス「次なる本命領域」はどこだ(1/28)
https://newspicks.com/news/6592258/body?sentlog
なぜ重大な問題を見逃すのか? 間違いだらけの設計レビュー　要約

ドキュメント作成者 (レビューを受ける人)

レビューを受ける前
・観点の提示
・レビュワ―の工数の見積もり

レビューの目的は
テストや横展開などの修正工数を削減することが目的。

レビューを受けた後
・指摘された問題の方よりの確認
・受けた指摘事項に関連する問題への横展開
・対応方針の決定
・修正作業の割り当て


レビューの種類
テクニカルレビュー …… 技術リーダーが主導するドキュメントチェック。ITの現場で行われている一般的なレビュー方法
ウォークスルー …… ドキュメント作成者が主役となって実施する自由度の高い相談会。テクニカルレビューよりもカジュアル。
マネジメントレビュー …… プロジェクトの状況把握や商人を目的としたレビュー。
第三者レビュー …… プロジェクト外の有識者などがレビュアーとなるレビュー。



レビューの手順
以下の基本手順を要件定義、基本設計、詳細設計といった工程ごとに1回ずつ実施する。
1. レビューの準備
2. 問題の検出
3. 問題の指摘
4. 修正・フォロー


リーダーの準備
検出すべき問題種別の選定
指針となるシナリオの作成
簡易なレビューの実施検討
レビュアーの選定と割り当て
ドキュメント配布と告知
UnityでShaderを書き始めるミニマムな手順

UnityでShaderを書いて動かすためのミニマムな手順をまとめる。

具体的には、以下のように紫のグラデーションをシェーダーで描画させる。

![スクリーンショット 2022-01-31 1.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/1f6f84f6-f91e-0cf5-ed05-3690e744e58d.png)


## 確認環境
- MacBook Pro (16-inch 2019)
- macOS Monterey 12.0.1

## 1. プロジェクトを作成する

ここではUnity 2020.3.18f1、URPで作成する（BRPでも同様の手順でOK）

![スクリーンショット 2022-01-31 1.49.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/da66047b-84fd-33ad-89d4-2b0b58099161.png)

## 2. アセットウインドウで右クリックして [Create] -> [Shader] -> [Unlit Shader]

![スクリーンショット 2022-01-31 1.51.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/d0b2da8d-9ed7-dde6-d47d-c5a13ddbcec3.png)

名前は"NewUnlitShader"のままでよい。

## 3. アセットウインドウで右クリックして [Create] -> [Material]

![スクリーンショット 2022-01-31 1.51.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/dc8e0411-d308-3574-141f-c1ac684ffff0.png)

名前は"New Material"のままでよい。

## 4. マテリアルのインスペクタのShaderに"NewUnlitShader"を選ぶ。[Unlit] -> [NewUnlitShader]

![スクリーンショット 2022-01-31 1.52.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/ca3e50f7-4600-a361-d9ea-b16bc4cdadb6.png)

![スクリーンショット 2022-01-31 1.52.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/6e2beaa0-5bf6-1335-5651-548042afca37.png)


## 5. ヒエラルキービューで右クリックして[3D Object] -> [Plane]

![スクリーンショット 2022-01-31 1.51.09.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/c663c766-3ef3-0fef-70ff-2a3439bb4c4c.png)

![スクリーンショット 2022-01-31 1.52.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/e61b9681-ede3-4b99-fba6-26532ed5dfb5.png)

## 6. Planeのインスペクタを開き、作ったマテリアル（"New Material")をドラッグ&ドロップする。

![スクリーンショット 2022-01-31 1.52.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/448367d1-dfd7-3e08-1672-852759bf91bd.png)

## 7. 作ったシェーダー（NewUnlitShader）を開き、frag関数を以下のコードに書き換える。

```hlsl
fixed4 frag (v2f i) : SV_Target
{
    float4 col = float4(i.uv, 1.0, 1.0);
    return col;
}

```

以下のように紫のグラデーションがシェーダーによって描画される。

![スクリーンショット 2022-01-31 1.53.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/198108/1f6f84f6-f91e-0cf5-ed05-3690e744e58d.png)


以上

## 参考: 

- Unityゲームプログラミングバイブル2nd P214「レイマーチング：基礎から応用まで」
    - サンプルコード: https://github.com/gam0022/UnityBible2-RaymarchingTutorial
Arduino勉強メモ

#ArduinoとEthernet Sheild2で通信してみた

###注意事項
・Ethernet Sheild2を購入していること
・Ethernet Sheild2の裏面に記載のあるMACアドレスをメモしておくこと

###序章
プログラムの中身は他の方が書いているブログやissueなどに載ってあるので今回はTipsのようなものを書いていこうと思う。

#####IPについて
Ethernet.beginを用いたMacアドレスとIPの設定の際には自動取得後にそのIPアドレスを設定するのが楽。
１．まずはIPアドレスを含めないEthernet Sheild2の初期設定を行う。

```
Ethernet.begin(ここにMACアドレスを入れる)
```

２．ArduinoのIDEの画面右上にシリアルモニタ（虫眼鏡のアイコン）があるからそこをクリック。
３．エラーが無く、コードが正常にコンパイルされたらシリアルモニタ上にIPアドレスが表示される。
４．シリアルモニタで表示されていたIPアドレスをEthernet Sheild 2の初期設定に追加する。

```
Ethernt.begin(ここにMACアドレスを入れる, ここにIPアドレスを入れる)
```
これで設定するIPアドレスが他で使われていないかを確かめる手間が省けた。

#####ポート番号について
Ethernetでは以下のコードによってポートを指定する。

```c++
EthernetServer server = EthernetServer(80);
```
EthernetServerの80という番号はHTTP通信を行うよ、という意味である。ポート番号というのは色々と予め決められており、HTTP以外の通信を行う際は他の番号を割り当てる必要がある。その他通信規格は"ポート番号"と調べれば出てくるので見てみると良い。
ちなみに、今回はWebサーバーを基準に考えているので、HTTP通信を用いたWebサーバーということで80番を指定している。

#####HTMLについて
EthernetShield2による通信と言えばWebページによるArduinoの操作だろうか。

この場合、Webページを構成するHTML（Webページのプログラミング言語）のコードをクライアント（Arudinoを操作する側）に丸ごと送信してWebページを表示させるという流れになる。

使用するのはEthernetClientクラスのprintln関数。この関数内に一行ずつHTMLのコードをString型として入れていく。
例は以下の通り。

```c++
void returnHTML(EthernetClient client) {

  //---HTTP HEADER---
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println();

  //---HTML DOC------
  client.println("<!DOCTYPE HTML>");
  client.println("<html>");
  client.println("<head>");
  client.println("<meta name=viewport content=\"width=80px, initial-scale=4, maximum-scale=4, user-scalable=no\" />");
  client.println("<title>A Remote</title>");
  client.println("</head>");
  client.println("<body style=\"color:rgb(205,205,205);background-color:rgb(96,96,96);text-align:center;\">");
  client.println("Remote<br />");
  client.println("<form method=GET>");
  client.println("<input type=submit name=1 value=ON /><br />");
  client.println("<input type=submit name=0 value=OFF />");
  client.println("</form>");
  client.println("</body>");
  client.println("</html>");

}
```

#####最後に今回発生したよくわからないエラーについて
以下のようなエラーがコンパイル時に出力されることがあったので、一応メモしておこうと思いました。

```
In file included from C:\Program Files (x86)\Arduino\libraries\Ethernet\src\Dns.cpp:8:0:
```

これはArduino自体のエラーらしく、コンパイル及び実行には何ら影響は無いそうです。
ですが、毎回エラーが出るのも鬱陶しいですし、一応エラーが出ないようにする方法を載せておきます。

```c++
#define htons(x) ( ((((x)&0xFF)<<8)&0xFF00) | (((x)>>8)&0xFF) )
```
これを自分のプログラムコードの一番最後の行に書いておくとエラーは消えます。どんなことを定義しているのかは僕も知らないです。

#### この記事があなたのエンジニアキャリアの一助になれば幸いです。
#### もしこの記事が役に立ったと感じたら、ぜひ「♡」で教えてください！
ファイルの入力と出力のテストコード

最近、ファイルを取り込み加工して出力する単純なプログラムを作成しましたが。作業期間が限られていたこともあり、必要最低限のテストコードしか整備できませんでした。。

**実装**

```Java:App.java
public class App {
    public static void main(String[] args) throws IOException {
        String input_str = file_read();
        input_str += "\n追記!";
        file_output(input_str);
    }

    public static String file_read() throws IOException {
        Path file = Paths.get("src/main/resources/input/test.txt");
        return Files.readString(file, Charset.forName("UTF-8"));
    }

    public static void file_output(String value) throws IOException {
        File output_file = new File("src/main/resources/output/test.txt");
        FileWriter filewriter = new FileWriter(output_file);          
        filewriter.write(value);
        filewriter.close();
    }
}
```

**テストコード**


```java:AppTest.java
public class AppTest {
    @Test public void test_file_input() throws IOException {
        assertEquals(
            kusatest.App.file_read(),
            Files.readString(Paths.get("src/main/resources/input/test.txt"))
        );
    }

    @Test public void test_file_output() throws IOException {
        for (File delete_file : new File("src/main/resources/output/").listFiles()) delete_file.delete();
        kusatest.App.file_output("テストです");
        assertEquals(
            "テストです",
            Files.readString(Paths.get("src/main/resources/output/test.txt"))
        );
    }

    @Test public void test_app() throws IOException {
        for (File delete_file : new File("src/main/resources/output/").listFiles()) delete_file.delete();
        kusatest.App.main(null);
        assertArrayEquals(
            Files.readAllBytes(Paths.get("src/main/resources/output/test.txt")),
            Files.readAllBytes(Paths.get("src/main/resources/output_check/test.txt"))
        );
    }
}
```

入力／出力／入力から出力の3パターンのテストコードです。社内外とファイル授受する場合は、対向システムとテストファイルを渡して事前に取り込めるか？確認することがあると思いますが、そこで取り込み確認できた場合は、それのファイルをテストの正常ケースとしてテストコードに含めています。少しずつ空き時間に整備していきたい。。
[JS]インラインスタイルを操作できるようになろう

アウトプットとして

#インラインスタイルとは
HTML要素の開始タグの中に直接CSSのソースコードを記述するプロパティの指定方法。
JavaScriptでは,メソッドを使って指定した要素上に新しい属性を追加、または既存の属性の値を変更したり、属性を取得することができます。

##setAttributeメソッド
指定した要素上に新しい属性を`追加`、または既存の属性の値を`変更`できます。

```javascript
要素.setAttribute(name, value)
```
要素の取得の仕方はこちら
[HTMLの要素を取得する方法](https://qiita.com/Shi-raCanth/items/7ae6c1efac28668571b3)

- nameは属性の名前を文字列で指定します。
- valueは属性に設定したい値を指定します。

例

```haml:HTML
<div id="test">テスト</div>
```

```javascript:JavaScript
const sample = document.getElementById("test")

sample.setAttribute("style", "color: red;")
// <div id="test" style="color: red;">テスト</div> が取得できる
```

##removeAttributeメソッド
指定した要素から、特定の属性を`削除`できます。書き方はsetAttributeと同じです。

```javascript
要素.removeAttribute(name, value)
```

例

```html:HTML
<div class="contents" id="apple">りんご</div>
```

```javascript:JavaScript
const apple = document.getElementById("apple")

apple.removeAttribute("class", "contents")
// <div id="apple">りんご</div> が取得できる(class="contents"が取り除かれている）
```

##getAttributeメソッド
要素上の指定した属性の値を戻り値として返します。

```javascript
要素.getAttribute('属性名')
```

例

```haml:HTML
<div class="contents" id="apple">りんご</div>
```

```javascript:JavaScript
const apple = document.getElementById("apple")

apple.getAttribute("class")
// => contents というclass名が取得できる
```


#まとめ
以上のメソッドを活用することで
・カーソルを持っていくと文字の色が変わる
・クリックするとプルダウンメニューが現れる　　etc...
などの動きをブラウザで操作できるようになる（関数やif文など、色々なものと組み合わせる必要はあるけど）

#追記(２０２２０２０１)
`インラインスタイルを操作する`という目的の場合、setAttributeより[styleプロパティ](https://developer.mozilla.org/ja/docs/Web/API/HTMLElement/style#setting_styles)を使用したほうが簡単に書けることをコメントでいただきました！ありがとうございます！

```javascript
//setAttribute
sample.setAttribute("style", "color: red;")

//styleプロパティ
sample.style.color = 'red';

//処理は両者とも同じ
```




　
※補足等ありましたらコメント頂けると幸いです
痒いところに手が届くvim正規表現の部分置換

# はじめに
ゲームWikiを作成するにあたり、以下の様な置換をしたい場面があった。

* QuickTinking -> Quick_Thinking

要は、英字の小文字と大文字の間に半角スペースを入れたいんだが、これが意外と検索し辛くてこづった。
同じ轍を踏まない様に、以下に記しておく。



# 結論

今回のケースでは、以下のコマンドを打てば良い。

```
:%s/\v(\l)(\u)/\1_\2/gc
```

* `\v` の Very Magic により正規表現をエスケープ不要で記載できる。
* 小文字を `\l`, 大文字を `\u` で指定する。
* 小文字と大文字の間に半角ススペースで挟むため、`()` で囲んだ箇所を `\1`, `\2` で割り振る。

以下、段階的に解説していく。

# 解説

### \v （Very Magic） 
vim で正規表現を書くと、 `\(abc|)\+`　の様に、都度エスケープ文字が必要で可読性が大きく損なわれる問題がある。

vimでは、正規表現の頭に `\v` を追記することで `(abc)+` の様に従来の正規表現の書き方ができる。


常に適用したい場合は、 .vimrc に　`nmap / /\v` を記載すると常に / 検索で `\v` が適用される。

### 大文字と小文字の区別
小文字は `\l`, 大文字は `\u` で指定できる。

### 部分置換の方法
一部分だけを置換したい場合、 `()`（ホールドバッファ）を指定した上で、 `\1` - `\9` で呼び出すことができる。




# 参考記事
* [ここまで出来る！Vimの(ちょっと高度な)正規表現と検索/置換テクニック](https://qiita.com/m-yamashita/items/5755ca2717c8d5be57e4)
* [Hack #166: ローマ字の大文字/小文字を変換する
](https://vim-jp.org/vim-users-jp/2010/08/08/Hack-166.html)
* [vim (vi) でマッチした文字列の一部を置換](https://www.mazn.net/blog/2009/01/06/170.html)
Pythonでフルスクラッチサイトテンプレートの開発をしてみた。

#アプリ開発課題
### 今回の実装ルールと目的
#### 目的
* 10日前後を目安に簡易webアプリを開発する。
* Webアプリケーションの開発する基本部分の理解
* 誰でも開発ができるような構造を心がける。
* レスポンス、リクエスト、データ登録、ファイル出力の部分を理解する。
* バージョン管理ツールの使用方法(クローン、コミット、プッシュ、プルリクエスト)が扱えるようにする。
* アプリケーションのデプロイ方法を知る。
* CICDについて理解をする。
※CICDとは
継続的インテグレーション/継続的デリバリーの略


#### この内容を一通りできるようになると何が得られるか
* 基本的なWebアプリケーションの仕組みが理解できる。
* SQLなどでデータ操作が理解できる。
* バージョン管理ツールの使用方法が理解できる。
* Linuxでのコマンド操作を少し理解できる。

#### 実装ルール
誰が開発しても似たような実装になるような構造にするため、極力外部のライブラリを使用せずにpythonの標準ライブラリのみを用いて開発をする。
他の言語でのリプレイスやリファクタリングなどの視野を考え、より柔軟により汎用性を考えて開発に臨む。
共通化できる部分やツールは別途作成する。

#### 改めて今回開発する機能について
* アカウント登録機能の実装
* アカウント情報の検索機能の実装
* アカウントの情報ファイル出力処理の実装
* アカウント登録画面
* 検索画面
* ログイン画面
* ログインパスワードハッシュ化(暗号化処理)

#### 余裕があったらしたいこと
* フロント部分をVue.jsなどを利用する。
* pythonにしかできない機能を実装する。

#### 他開発するツールとして
* テーブル作成ツール(DDLツールを作成しテーブル作成を簡易化させるため)
* データ登録ツール(指定したデータベースにcsvファイルを指定してテーブルに登録させるため)

####　事前準備
* ローカルにpython=3.9.0をインストールしていること
* バージョン管理としてGithubのアカウントを作成していること
* html,css,python,SQL,データ操作言語、マークアップ言語、スクリプト言語をなんとなく理解できていること(全く理解がなくても大丈夫です。)

#### 環境
* MacOs(Windowsでも問題ないです)
Windowだとlinuxが使用できないためPowershellもしくはコマンドプロンプトになります。

#### 使用する開発言語
バックエンド：python
フロントエンド：Vue.js(余裕があれば)
データベース：sqlite3(python標準ライブラリでインストール不要なため)

#### 開発の大まかな流れについて
①ローカルにpythonで仮想環境を構築
②仮想環境内にメインのディレクトリを構築
③②で作成した環境下で開発
④②で作成したディレクトリがGithub上でのリポジトリとして扱うこととする

#### 進捗
* ログイン画面 (済)
* アカウントの情報ファイル出力処理の実装 (済)
* アカウント登録画面 (済)
* 検索画面 (済)
* 簡易的な画面設計書 (済)
* テーブル作成ツール (済)
* データ登録ツール (済)
* アカウント登録機能の実装 (済)
* アカウント情報の検索機能の実装 (済)
* パスワードハッシュ化処理(済)

#### スケジュール感覚
以下の内容を実施した後の完成イメージ
→ https://qiita.com/noss08327439/private/b6c3db2d271c6c1ea92f
1日目：仮想環境構築、簡単な設計、テーブル作成ツール開発、データ登録ツール開発
→ https://qiita.com/noss08327439/private/5bcc9e81650236f944ba
2日目：htmlで画面作成(アカウント登録画面、検索画面)
→ https://qiita.com/noss08327439/private/d03371bbd4a09cc3fcda
3日目：アカウント登録画面とバックエンドの紐付け
→ 実施内容取りまとめ中
4日目：検索画面とバックエンドの紐付け
→ 実施内容取りまとめ中(開発済み)
5日目：動作確認
→ 実施内容取りまとめ中(開発済み)
6日目：ログイン画面作成
→ 実施内容取りまとめ中(開発済み)
7日目：ログイン処理実装、動作確認
→ 実施内容取りまとめ中(開発済み)
8日目：総合動作確認&Herokuでのデプロイ
→ 実施内容取りまとめ中(開発済み)
9日目：バッファ
10日目：バッファ


> P.S
開発状況は随時こちらに記載していくので参考にしてください。
以下のURLにて開発状況を適宜更新しています。
https://github.com/nosscafe66/noss/tree/main/Dev/Kadai
【PHP】 error_reporting ディレクティブ

# PHP の error_reporting ディレクティブとは

phpinfo() を実行すると、 error_reporting ディレクティブという設定値が整数値として表示されます。
この error_reporting ディレクティブは、エラー出力レベルを設定するもので、以下のエラーの種類それぞれについて、どのエラーを出力するかを 16ビットのビットマスクで構成し、10進数で表したものとなっています。

| 設定値 | 定義済み変数        | 説明                                                                 | 
| -----: | ------------------- | -------------------------------------------------------------------- | 
| 1      | E_ERROR             | 重大な実行時エラー。                                                 | 
| 2      | E_WARNING           | 実行時の警告 (致命的なエラーではない)。                              | 
| 4      | E_PARSE             | コンパイル時のパースエラー。                                         | 
| 8      | E_NOTICE            | 実行時の注意メッセージ。                                             | 
| 16     | E_CORE_ERROR        | PHPの初期始動時点での致命的なエラー。                                | 
| 32     | E_CORE_WARNING      | （致命的ではない）警告。                                             | 
| 64     | E_COMPILE_ERROR     | コンパイル時の致命的なエラー。                                       | 
| 128    | E_COMPILE_WARNING   | コンパイル時の警告（致命的ではない）                                 | 
| 256    | E_USER_ERROR        | ユーザーによって発行されるエラーメッセージ。                         | 
| 512    | E_USER_WARNING      | ユーザーによって発行される警告メッセージ。                           | 
| 1024   | E_USER_NOTICE       | ユーザーによって発行される注意メッセージ。                           | 
| 2048   | E_STRICT            | コードの互換性を維持するためのコードの変更についての提案メッセージ。 | 
| 4096   | E_RECOVERABLE_ERROR | キャッチできる致命的なエラー。                                       | 
| 8192   | E_DEPRECATED        | 実行時の注意。将来のバージョンで動作しなくなるコードについての警告。 | 
| 16384  | E_USER_DEPRECATED   | ユーザー定義の E_DEPRECATED同等の警告メッセージ。                    | 

# error_reporting の設定値をわかりやすく

しかしながら、これらのビットがどのエラーを表しているかを覚えるのもたいへんで、ビットマスクの計算も面倒ですよね。

そこで、 error_reporting の整数値をエラーの定義済み定数に分解する小さなプログラムを作成しました。

```PHP:error_reporting.php
<?php
$level = $argv[1];
$types = array(
	'E_ERROR', 'E_WARNING', 'E_PARSE', 'E_NOTICE',
	'E_CORE_ERROR', 'E_CORE_WARNING', 'E_COMPILE_ERROR', 'E_COMPILE_WARNING',
	'E_USER_ERROR', 'E_USER_WARNING', 'E_USER_NOTICE', 'E_STRICT',
	'E_RECOVERABLE_ERROR', 'E_DEPRECATED', 'E_USER_DEPRECATED'
	);

foreach ($types as $type) {
	eval ("\$error['$type'] = $type ;");
	$on = ($level & $error[$type]) == 0 ? '-' : '+';
	echo implode(':', array($on,$type,$error[$type])).PHP_EOL;
}
```

使い方

```
php error_reporting.php [error_reportingの設定値]
```

error_reporting の設定値を引数にして、実行すると以下のように出力されます。各定義済み変数の左が「+」となっていれば出力されるエラー、「-」の場合は表示されないエラーです。

```
$ php error_reporting.php 22519
+:E_ERROR:1
+:E_WARNING:2
+:E_PARSE:4
-:E_NOTICE:8
+:E_CORE_ERROR:16
+:E_CORE_WARNING:32
+:E_COMPILE_ERROR:64
+:E_COMPILE_WARNING:128
+:E_USER_ERROR:256
+:E_USER_WARNING:512
+:E_USER_NOTICE:1024
-:E_STRICT:2048
+:E_RECOVERABLE_ERROR:4096
-:E_DEPRECATED:8192
+:E_USER_DEPRECATED:16384
```

よろしければお納めください。

# 参考

https://www.php.net/manual/ja/errorfunc.constants.php
ハッシュに関する解説

rubyシルバーを勉強していくなかで、hashについてちゃんとわかっていなかった今回は解説させていただこうとおもいます。

##ハッシュって？
ハッシュとは、配列と似ていますが、**keyというものと、valueというものがある配列**です。
具体的に、コードを見ていきましょう！

```
hash = {'Satou' => 19, 'Hashimoto' => 35, 'Yamada' => 23}
```
こういうふうな書き方をします。
keyというものが、Satou, Hashimoto, Yamadaです。
valueというものが、19, 35, 23です。

このハッシュのメリットが、keyを目印にして、valueを取得することができるんです。

これと似たものに配列というものがあります。
配列は、0,1,2のような数字で値を取得するような書き方をするんですね。

ハッシュの方が直感的でいいですね。

##ハッシュの値の取り方
先ほどのコードを書いてみましょう

```
hash = {'Satou' => 19, 'Hashimoto' => 35, 'Yamada' => 23}

#keyを全部取得して、それを配列で返す。
hash.keys
=> ["Satou", "Hashimoto", "Yamada"]

#valueを全部取得して、それを配列で返す。
hash.values
=> [19, 35, 23]

#あるvalueに対応した、keyを取得
hash.key(19)
=> "Satou"

##あるkeyに対応した、valueを取得し、それを配列で返す。
hash.values_at('Satou')
=> [19]

hash.['Satou']
=> 19
```
そのほかの値の取得方法もありますので、気になる方は、[こちら](https://www.sejuku.net/blog/15137)を参考にしてください！

##シンボルについて
シンボルとは、「:」という書き方です。
では公式ドキュメントになんて書いてあるんでしょうか？
>Rubyの内部実装では、メソッド名や変数名、定数名、クラス名などの`名前'を整数で管理しています。これは名前を直接文字列として処理するよりも速度面で有利だからです。そしてその整数をRubyのコード上で表現したものがシンボルです。

>シンボルは、ソース上では文字列のように見え、内部では整数として扱われる、両者を仲立ちするような存在です。

>名前を管理するという役割上、シンボルと文字列は一対一に対応します。また、文字列と違い、immutable (変更不可)であり、同値ならば必ず同一です。

[公式ドキュメント](https://docs.ruby-lang.org/ja/3.0/class/Symbol.html)より

つまり、見た目上は、文字列でも、中身は数字なんですね。
これの何がいいのか？僕個人的には、一番のメリットは**処理速度が速い**ということだとおもいます。
他にメリットがありますので、それを知りたい方は[こちら](https://qiita.com/yyykms123/items/6a6ae7fe8cd9263a3d1c)を参照してみてください。

##実際のコードを見ていきましょう

```
#書き方➀
hash = {:'Satou' => 19, :'Hashimoto' => 35, :'Yamada' => 23}
puts hash[:'Satou']
# 19

#書き方➁
hash = {'Satou': 19, 'Hashimoto': 35, 'Yamada': 23}
puts hash[:'Satou']
# 19

#値の取り方は、上のコードと同じようにとれる
```

##実際に問題を解いてみよう

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2485775/e5f405b2-3920-bc1d-948e-4bc51a5139e2.png)

この問題では、
klassという変数に、Classクラスから新しいインスタンスを作成して、そのオブジェクトを代入します。
そして、そのkeyであるオブジェクトに、valueの100を作ります。つまり、ハッシュをつくります。
3行目では、上のコードでも書いたような書き方で書かれていますね。
つまり、keyに紐づいた、valueを取得しています。

このコードを実行すると、取得できる値は、

```
klass = Class.new

hash = {klass => 100}

puts hash[klass]
# 100
```
100が出てくるような選択肢を選べばいいんですね。

###選択肢を見ていきましょう
####選択肢1

```
klass = Class.new

hash = {klass: 100}

puts hash[klass]
```
1行目までは同じですね。
2行目もハッシュの書き方➁の書き方です。
3行目をよく見てみると、値の取り方が違いますね。もし、100を取りたかったら、

```
puts hash[:klass]
```
と書くべきですね。

選択肢1の値の取り方をすると、nilになるんです。

####選択肢2

```
klass = Class.new

hash = {}
hash.store(klass, 100)

puts hash[klass]
```
2行目で、空のハッシュを作ります。
３行目でstoreメソッドを使ってます。storeとは英語で「格納する」という意味です。
つまり、hashにklassをkeyに、valueを100としたhashを作ります。コードで書くなら、

```
{#<Class:0x00000000086b8660>=>100}
```
そして4行目で、keyに対応したvalueを取得してます。この書き方は、「ハッシュの値の取り方」の最後に書いてあります。
このコードを実行すると、100が取得できるので、1つ目の正解です

####選択肢3
ここまで読んでいただいた方であれば、選択肢3はnilになることが分かるとおもいます。
選択肢1の解説を読んでいただければわかるとおもいます。

####選択肢4
ここまで読んでいただいた方であれば、選択肢4は100になることが分かるとおもいます。
2行目のHashメソッドは、新しいハッシュを作成してくれるというメソッドです。

以上です。
何か間違いがございましたら、ご教示いただけますと幸いです。

【参考文献】

https://qiita.com/yyykms123/items/6a6ae7fe8cd9263a3d1c

https://docs.ruby-lang.org/ja/3.0/class/Symbol.html
Linuxでコマンドを定期実行する方法

# 概要
LinuxでサーバのCPUやメモリの使用率など一定間隔で実行したい場合に、利用するスクリプトを作成する。
whileとsleepコマンドで実現する。

## シェルスクリプトの作成

ソースコード

```
#!/bin/bash

# command_listに定期的に実行したいコマンドを追加する。
# コマンドの実行間隔をINTERVALに定義する。単位は秒。
# ログアウト後も実行する場合は、「nohup bash loop_exec.sh &」で実行する。
# スクリプトの実行は、「ctrl + C」もしくは「kill -9 <pid>」で停止する。

INTERVAL=3

function command_list() {
        date
        free -h
        lsblk
        df -h
        ss -atup
        ps aux
}

while true;
do
        command_list >> watch.log
        sleep ${INTERVAL}
done
```