OmniAICreator/Qiita-1.07M huggingface dataset:
SQL100本ノックまとめ

# 用途・目的
100本ノックを勉強して、個人的に苦手だと感じた箇所をまとめておき、今後の勉強に役立てる。

## 正規表現まとめ
### 特殊文字
<table>
  <caption>特殊文字紹介</caption>
  <thead>
    <tr>
      <th>特殊文字</th> <th>役割</th> <th>使用例</th> <th>取得例</th>
    <tr>
  </thead>
  <tr>
    <td> ^ </td> 
    <td> 先頭の文字（列）を指定　</td> 
    <td> ^a, ^[0-9] </td>
    <td> abc, 0xx-xxxx-xxxx
  </tr>
    <tr>
    <td> $ </td> 
    <td> 最後の文字（列）を指定　</td> 
    <td> 0$, [a-z]$ </td>
    <td> xxx-xxxx-xxx0 ,baseball 
  </tr>
  <tr>
    <td> . </td>
    <td> 任意の文字 </td>
    <td> .る</td>
    <td> 蹴る、放る、喋る</td>
  </tr>
  <tr>
    <td> * </td>
    <td> 直前の文字（列）の繰り返し </td>
    <td> おー*い</td>
    <td> おーい、おーーい</td>
  </tr>
　　　　<tr>
    <td> [] </td>
    <td> 指定した文字 </td>
    <td> </td>
    <td> </td>
  </tr>
　　　　<tr>
    <td> [] </td>
    <td> 指定した文字 </td>
    <td> --- </td>
    <td> 補足：</td>
  </tr>
</table><br>
正規表現に関する詳細な情報は、

[さるにもわかる正規表現](https://userweb.mnet.ne.jp/nakama/)

[正規表現がわからないときは文字コードがヒントになる](https://qiita.com/haruna-nagayoshi/items/dd6a7c43cdc55340292d)

に書いてあるのでそちらを参照する。
  
---
## PostgreSQLのデータ型の変換のまとめ
SQLの種類ごとデータ型の変換方法が異なり、ややこしいので、学んだものをメモする

<table>
  <caption>データ型変換方式</caption>
  <thead>
    <tr>
      <th>変換前の型 - 変換後の型</th> <th>関数</th>　<th>説明</th>
    </tr>
  </thead>
  <tr>
    <td>日付型 - 文字列型(YYYYMMDD形式) </td> 
    <td>to_char(col_name, 'YYYYMMDD')</td> 
    <td>日付型のデータを持つカラムをYYYYMMDDの文字列形式に変換。<br>'YYYY-MM-DD'等間に文字を入れることも可能</td>
  </tr>
  <tr>
    <td> 文字列型(YYYYMMDD形式) - 日付型 </td>
    <td> cast(col_name as date)<br>to_date(col_name, 'YYYYMMDD')</td>
    <td> どちらも使える。<br>to_date()の型指定は'YYYYMMDD'できず、YYYY-MM-DDとして表示される。</td>
  </tr>
  <tr>
    <td> 数値型 - 日付型 </td>
    <td> cast(cast(col_name as varchar) as date) </td>
    <td> 一度数値を文字列型に変換して、文字列を日付に変換する処理をする </td>
  </tr>
  <tr>
    <td> epoc秒型 - 日付型(YYYYMMDD形式) </td>
    <td> cast(to_timestamp(col_name) as date) </td>
    <td> エポック秒形式から日付型に変換する。エポック秒形式のデータをto_timestamp()を使って変換すると、YYYYMMDD に加え、タイムゾーンの情報まで返すことになるため、日付のみ必要なら、 to_timestamp()の外側にcast(~~ as date)が必要</td>
  </tr>
</table>


cast()とto_date()が混合しそう。（現に同じ役割を担う関数もあるし...）とりあえず、個人的にしっくり来ているcast()を中心にしっかり使えるようにする。
Python イテラブル・イテレーター・ジェネレータ式を簡潔に

Pythonを学ぶなかで、`イテラブル`、`イテレーター`、`ジェネレータ式`という存在に直面しました、、
これらはデータの処理やアルゴリズムの実装において非常に重要なものだそう。
本記事では、これらの概念をなるべく簡潔にまとめてみました。

# イテラブル (Iterable)
イテラブルは、メンバーを一つずつ返すことができるオブジェクトです。
リスト、タプル、文字列、辞書など、Pythonの多くの組み込みデータ型がイテラブルです。

### 特徴
- forループで繰り返し処理が可能
- イテレーターに変換できる（`iter()`関数を使用）。

### 例
```py:python
my_list = [1, 2, 3]
for item in my_list:
    print(item)
#->1
#->2
#->3
```
### イテラブルではないもの
イテラブルでないとは、forループなどを使い、その要素を一つずつ取り出すことができないことを意味します。

#### 整数 (int)

整数は単一の数値を表すため、イテラブルではありません。例えば、for i in 5:のようなコードはエラーを引き起こします。
#### 浮動小数点数 (float)

浮動小数点数も単一の数値を表すため、イテラブルではありません。
#### 論理値 (bool)

TrueやFalseのような論理値もイテラブルではありません。
#### NoneType

Noneは特別な値で、何も値を持たないことを表します。イテラブルではありません。
# イテレーター (Iterator)
イテレーターは、`next()`関数を使用して次の要素を返すオブジェクトです。
イテラブルから`iter()`関数を使って生成されます。

### 特徴
- `next()`関数を使って、次の要素を取得する
- 要素がなくなると、StopIteration例外を発生させる
-イテラブルよりも低レベルで、より制御が細かい

### 例
```py:python
my_list = [1, 2, 3]
my_iter = iter(my_list)

print(next(my_iter))  # 1
print(next(my_iter))  # 2
# my_iterにはもう要素がない場合、next(my_iter)はStopIterationを発生させる
```

# ジェネレータ式 (Generator Expression)
ジェネレータ式は、リスト内包表記に似た構文を用いて、一連の値を遅延評価で生成します。
ジェネレータはイテレーターの一種で、一度に一つの要素しかメモリに保持しません。

### 特徴
- 大量のデータを扱う場合にメモリ効率が良い
- 必要に応じて一つずつ値を生成し、`next()`でアクセスする
- リスト内包表記よりもメモリ使用量が少ない

```py:python
my_gen = (x * 2 for x in range(3))

for item in my_gen:
    print(item)  # 0, 2, 4
```
Ajax通信の私なりのベストプラクティスについて

## 背景
・それほどアクティブユーザーがいないウェブアプリケーションにおいて、やたらDB負荷が高かったりした際に、色々調査して、負荷対策や効率化を行なった際の話


## 静的なコンテンツに関しては、リクエスト時のxhrオブジェクトを再利用する
静的コンテンツの取得に関しては、同じリクエストパラメータで複数回リクエストを送信する設計を避け、既に実行された xhr オブジェクトの再利用を行うことで、サーバー負荷の軽減を図ります。

```javascript
// サンプルコード
var requestCache = {};

function fetchContent(params) {
  var key = JSON.stringify(params);
  if (requestCache[key]) {
    return requestCache[key]; // 既存のxhrオブジェクトをそのまま返却
  } else {
    var xhr = $.ajax({
      type: "GET",
      url: "your-endpoint",
      data: params
    });

    requestCache[key] = xhr; // xhrオブジェクトをキャッシュに保存
    return xhr;
  }
}
```

このコードでは、リクエストパラメータをキーとして xhr オブジェクトをキャッシュし、次回のリクエスト時に既存のキーが存在する場合は、保存された xhr オブジェクトをそのまま返却します。これにより、同じリクエストに対しては、新たなネットワークリクエストを行わずに済みます。

このようなキャッシュ戦略を採用することで、静的なコンテンツの効率的な取得と、サーバーへの無駄なリクエストの削減が実現されます。

この利点は、たとえば開発者ツールなどでリクエストが保留中のものがあった時、無駄に追加でネットワーク接続をつくらず、保留中のオブジェクトの結果を待ちます。
このオブジェクトの結果についてサーバー側でエラーだったりして保留中のままだったりするケースがあるので、timeoutさせたり、エラーハンドリングは必須です。


## 2. 動的なコンテンツに関しては、更新頻度を考慮して取得結果のキャッシュを制御する
動的コンテンツの場合、更新頻度を考慮して、キャッシュの有効期間やリフレッシュ戦略を適切に設計することが重要です。

1分未満で更新されるコンテンツであればそもそも都度リクエストさせる場合が好ましいでしょう
ただ1ユーザーが同じようなリクエストを何度も行う可能性があるユースケースがあるのであれば、負荷軽減でもう少し取得間隔を設ける（30秒に1回ぐらい同じ結果にする？）とか

```javascript
// サンプルコード
function fetchDynamicContent(params) {
  var key = JSON.stringify(params);
  var cache = requestCache[key];
  if (cache && cache.timestamp > Date.now() - 300000) { // 5分間のキャッシュ
    return Promise.resolve(cache.data);
  } else {
    return $.ajax({
      type: "GET",
      url: "your-endpoint",
      data: params
    }).done(function(response) {
      requestCache[key] = { data: response, timestamp: Date.now() };
      return response;
    });
  }
}
```


## あとがき
コードに関しては、AIにかかせたので動作確認はしてください。
上記は私も直近ajax通信周りで負荷軽減対策を行なって、比較的ベストプラクティスに近いのかな〜〜と思ったのでまとめました。
（その道のプロからしたら初歩中の初歩みたいな話かも...

ていうかajaxの中にcache: true　みたいなオプションがあるんだけど、同じパラメータリクエストを送っても上記のように保留中のxhrオブジェクトを再利用してくれたり...なんてことはなかった（してくれるものだと思ってた（もしかして私の書き方がよくなかった？本当はしてくれる？詳しい人教えて
viteのローカル起動サーバにhttpsでアクセスする

開発において、viteのローカル起動サーバにhttpsで接続したいケースがあったので、その方法を調べました。

## 方法1. オレオレ証明書を発行し、設定する

[mkcert](https://github.com/FiloSottile/mkcert)などでlocalhost用の証明書を発行し、それをvite.configに適用します。

https://github.com/FiloSottile/mkcert

### 1. 証明書発行

#### macの場合

brewを使うのが楽そう。

```sh
$ brew install mkcert
$ mkcert install
$ mkcert localhost
```

#### windowsの場合

chocoを使うのが楽そう。

```sh
$ choco install mkcert
$ mkcert install
$ mkcert localhost
```

chocoのinstallはこちらから
https://chocolatey.org/install

### 2. 証明書設定

vite.config.tsに以下のように設定します。
(証明書が`${プロジェクト直下}/cert`にあることを想定してます)

```ts
import fs from 'fs';

export default defineConfig(() => {
        server: {
            https: {
                key: fs.readFileSync('./cert/localhost-key.pem'),
                cert: fs.readFileSync('./cert/localhost.pem'),
            },
        }
}
```

## 方法2 vite-plugin-basic-sslを使う

[vite-plugin-basic-ssl](https://github.com/vitejs/vite-plugin-basic-ssl)

pluginを設定するだけで、https接続できます。
ただ、公式では推奨されていなく、ブラウザが警告を出すので、方法1の方が良さそうです。

> 基本的なセットアップでは、自己署名証明書を自動的に作成しキャッシュする 
> @vitejs/plugin-basic-ssl をプロジェクトのプラグインに追加することもできます。
> しかし、独自の証明書を作成することを推奨します。

[引用](https://ja.vitejs.dev/config/server-options.html#server-https)

### 設定方法

pluginに設定するだけです。

```sh 
$ pnpm install @vitejs/plugin-basic-ssl -D
```

```ts
// vite.config.js
import basicSsl from '@vitejs/plugin-basic-ssl'

export default defineConfig(() => {
  plugins: [
    basicSsl()
  ]
}
```

## まとめ

手間もそんなにかからないので、証明書を設定してやる方法を使うのが良さそう。
httpsの設定はviteのサーバオプションなので、本番viteサーバには影響はなさそうでした。
「そんなの、聞いてないよ！」「急に言われても困るよ！」対策

# 「そんなの、聞いてないよ！」「急に言われても困るよ！」と言われませんか？

調査依頼の時とか、業務を変更しようという時に、こういう言い方で、非協力的な人って必ずいます。
こうなると、内容と関係なくぎくしゃくしてしまいます。
最悪の場合は、内容でなく、伝え方が理由で、「忙しいから、こっちに来て、自分で調べろ！」「そんなことやってられない！」等になってしまい、なだめるのが大変！

経験的に「先日の件ですが、」で始めるとスムーズに進むことが多いです。

# 「先日の件ですが」にしよう(^^)/
なにかを依頼したい場合、1、2週間くらい前に「まだ準備中で詳しくは説明できないのですが、こういう理由で、来週あたりに、XXの件お願いしようと思ってます。その際はご協力よろしくお願いいたします。」とか、業務改革の場合も、いきなり発表するのでなく「こういった背景から、XXの件、見直しを進めています。まとまり次第、資料を使ってご説明しますので、もう少々お待ちください。」とか、前振りしておくと、スムーズに進みます。
これって、まずは、掲示板的なところに書くだけでも効果あります。

逆にそうしておかないと、「そんなこと聞いてないよ」「急に言われても困るよ」という方が必ずいるんです。
常に、そう言いがちな方に対しては、事前に「まだ他の方には話をしてませんが・・・」「まだ、数名にしかお伝えしてないのですが・・・」「依頼に当たり、特に重要な方には先にお伝えしてご意見を伺いたいのですが」みたいな伝え方をしておくと、スムーズに進みます。

# 特にややこしい人は、最初から味方につけよう。
特に、ややこしくなりがちの人、いわゆるクレーマーっぽい方は、上記予告編の後で、公開前にその方だけに説明資料を見ていただき、添削してもらうのも手です。その際は出来るだけ下手に出て、「先日の件の説明書いたのですが、分かり難いですかね、XXさんだったらどう書きますか？」とか言って、その方の言葉を少しでももらって、その言葉を埋め込みます。公開後に文句を言われてその相手をして、場合によっては修正するよりもずっと楽です。
また、口うるさい人を味方につければ、公開後にもその人が強い味方になってくれます。

お願いの際は、「先日お伝えした件ですが、おかげさまで、やっと説明資料が出来ました。こちらよろしくお願いいたします。」

これで、「そんなの、聞いてないよ！」「急に言われても困るよ！」は、かなり減ります。
R1Soft: 塩漬けシステムのハードウェア最新化方法

# はじめに
クラウドにおいてベアメタルを利用し続けていると、部品の在庫不足により、障害時に交換できないという状況に陥る可能性があります。そのため、事前にハードウェアの最新化を図る必要があります。
一方でしばしば稼働システムは塩漬けしたい。そこでOSはそのまま、ハードウェアのみアップデートする際の手順と注意点を記載します。


# 環境情報
- ①：バックアップ元サーバーA
    - プロセッサ：Broadwell
    - OS: Windows2012R2
    - 2017年デプロイ、以降Windows update適用なし
<br>

- ②：バックアップ元サーバーB
    - プロセッサ：Broadwell
    - OS: Windows2012R2
    - 2023年デプロイ
<br>

- ③：リストア先サーバー
    - プロセッサ：Cascade Lake
    - OS: Windows2022 (IBM CloudではWindows2012R2をCascade Lake上で選べない)
<br>

- backup ソフト
    - R1soft
    - Windows Backupについてはこちら (TBD)


# 手順の検討
手順を検討している中で、以下の事象が発生した
- ①(2017デプロイ)→③のリストアに成功、OS起動せず
- ②(2023デプロイ)→③リストアに成功OS起動

考察
- ドライバ不足によるストレージ参照失敗
    - Windows OSからシステムイメージ読み込みの失敗
    - ②のOSにはパッチが適用されている

最終的に、これらの考察が正しかったです。

# 最終的な手順
### 1. ドライバを比較して不足ドライバを洗い出し
②において、リストア前に利用せず、リストア後に利用しているドライバをリストした結果、`megasas35`というRAID Controller用ドライバが新規に利用されていることが分かりました。

```
> driverquery /v /fo table
```
 
ドライバの不足によってディスクをOSから見れない状態だったことで、OS起動していませんでした。

### 2. バックアップ元サーバーに不足ドライバを追加
ドライバのバックアップについては以下記事を参照ください。
https://anykey.bz/win/surface-backup-driver/

### 3. バックアップ取得＆リストアを実施
R1Softでのリストアは以下記事を参照ください。
https://qiita.com/takason/items/8e3055f27c9d8d0c83a3
演算子

UWSCRでは新たにいくつかの演算子が追加されています。

# 複合代入演算子

- `+=`
- `-=`
- `*=`
- `/=`

左辺の変数の値に対して右辺の値で計算を行い左辺の変数に代入します。

```php
a = 1
a += 2 // a = a + 2 と同じ
print a // 3

a -= 1 // a = a - 1 と同じ
print a // 2

a *= 3 // a = a * 3 と同じ
print a // 6

a /= 2 // a = a / 2 と同じ
print a // 3
```

# 代入演算子

- `:=`

`=` による通常の代入は文のように振る舞いますが、`:=`による代入は式となり代入された値を返します。

```php
print a := 100 // 100
print a // 100

b = c := 200
// c := 200 によりcに200が代入されている
print c // 200
// c := 200 という式が200を返すため、bに200が代入された
print b // 200

select a := 5 // selectの条件式として代入式を使う
    case 1,2,3
        print "<#a>が入力されました"
    default
        print "不正な値(<#a>)が入力されました、1～3を入れてください"
selend
```

:::note info
**UWSCにおける`:=`との違い**
UWSCでは以下の場合のみ`:=`が利用できました

- eval内での代入
- COMオブジェクトのメソッドの名前付き引数

UWSCRはevalの仕様がUWSCとは異なり、evalに渡された文字列をスクリプトと同等に解析・評価します。そのため`:=`はUWSCRの代入演算子として評価されます。また`=`による代入もそのまま利用可能です。

COMの名前付き引数はUWSCと同じように利用可能です。この場合、代入演算子としては機能しません。

```php
ws = createoleobj("WScript.Shell")
ws.Popup(Title := "ほげほげ", Text := "ふがふが")
print Title // [評価エラー] 識別子が見つかりません (Title)
```
:::

# 等価比較

- `==`
- `!=`

それぞれ`=`および`<>`による比較と同等です。

```php
a = 1
print a = 1  // True
print a == 1 // True

print a <> 1 // False
print a != 1 // False
```

# 論理演算子

- `andL`
- `orL`
- `xorL`

`and`, `or`, `xor`演算子は両辺の値によって論理演算かビット演算のいずれかが行われます。
それぞれに`L`がついた演算子は論理演算子となり、真偽値を返します。

```php
print 1 and TRUE  // 1
print 1 andL TRUE // True
print 2 or 1      // 3
print 2 orL 1     // True
print 3 xor 1     // 2
print 3 xorL 1    // False
```

# ビット演算子

- `andB`
- `orB`
- `xorB`

`B`の場合はビット演算子となります。両辺を数値とみなしてビット演算を行います。

# 三項演算子

- `?:`

三項演算子とは、値を返すif文のようなもので

```
条件式 ? 真の式 : 偽の式
```

という書式で使います。条件式が真の場合は真の式を評価した値を、偽の場合は偽の式を評価した値を返します。いずれも文は不可で必ず式である必要があります。

```php
print TRUE ? "hoge" : "fuga" // hoge
a = FALSE ? "foo" : "bar"
print a // bar
```
AngularでHTTPリクエストのテストをするときによくかくテストコード


# はじめに
WebAPI通信部分のテストをするときに必ずかいているテストコードが2つあるので忘れないようにメモ。

# 環境
- Angular v16
- Karma+Jasmine

# 期待通りのHTTPリクエストが行われているか

```typescript
it('GETリクエストが行われている', () => {
    service.fetchHogeList$().subscribe();
    const req = httpTestingController.expectOne('https://hoge/test');
    expect('GET').toEqual(req.request.method);
});
```

## expectOne
期待するURLと通信の種類(POSTとかGETとか)を使用するリクエストが
よばれたことを確認する。

# 期待通りのデータの取得ができているか

```typescript
it('期待通りのデータが取得できている', fakeAsync(() => {
    const expected: HogeListModel[] = [
      {
        hogeId: 'hogeId1',
        hogeName: 'hogehoge',
      }
    ];
    service.fetchHogeList$().subscribe(actual => {
      expect(expected).toEqual(actual);
    });

    const req = httpTestingController.expectOne('https://hoge/test');
    req.flush(expected);
}));
```

## fakeAsync
非同期の操作を同期の形でテストできる。

サポートする非同期操作
- Promise
- setTimeout など

このテストでは使っていないが、tick()関数を使うと、特定の時間が経過した後の状態をテストすることができる。


## flush
このテストではサーバーからの応答を疑似的にすることで、データをレスポンスとして返している。
非同期のHTTPリクエストを同期的にテストすることができる。

# テストコード全文

```typescript
import { TestBed, fakeAsync } from '@angular/core/testing';

import { AppService, HogeListModel } from './app.service';
import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing';

describe('AppService', () => {
  let service: AppService;
  let httpTestingController: HttpTestingController;

  beforeEach(() => {
    TestBed.configureTestingModule({
      imports: [
        HttpClientTestingModule
      ]
    });
    service = TestBed.inject(AppService);
    httpTestingController = TestBed.inject(HttpTestingController);
  });


  it('GETリクエストが行われている', () => {
    service.fetchHogeList$().subscribe();
    const req = httpTestingController.expectOne('https://hoge/test');
    expect('GET').toEqual(req.request.method);
  });

  it('期待通りのデータが取得できている', fakeAsync(() => {
    const expected: HogeListModel[] = [
      {
        hogeId: 'hogeId1',
        hogeName: 'hogehoge',
      }
    ];
    service.fetchHogeList$().subscribe(actual => {
      expect(expected).toEqual(actual);
    });

    const req = httpTestingController.expectOne('https://hoge/test');
    req.flush(expected);
  }));
});
```

## HttpClientTestingModule
HttpClientをテストするためのモジュール。
リクエストのモック化とフラッシュが可能になる。
https://angular.jp/api/common/http/testing/HttpTestingController#httptestingcontroller

# テストしていたコード

```typescript
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs';

@Injectable({
  providedIn: 'root'
})
export class AppService {

  constructor(
    private readonly httpClient: HttpClient,
  ) { }

  public fetchHogeList$(): Observable<HogeListModel[]> {
    return this.httpClient.get<HogeListModel[]>(
      'https://hoge/test'
    );
  }
}

export interface HogeListModel {
  hogeId: string;
  hogeName: string;
}
```
mindの研究 その39 - mindでwgetを実現する

# 概要
mindが謎なので調べてみた。
練習問題やって見た。

# 練習問題
mindでwgetを実現せよ。

# 方針
vbsの力を借りる。

# サンプルコード

```

出力ファイルは　ファイル。

メインとは
　「wget.vbs」で　出力ファイルを　新規オープンし
　「Function Wget(url)」で　出力ファイルに　一行書き込み
　「Set WshShell = CreateObject("WScript.Shell")」で　出力ファイルに　一行書き込み
　「FileName = Mid(url, InStrRev(url, "/") + 1)」で　出力ファイルに　一行書き込み
　「SamAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"」で　出力ファイルに　一行書き込み
　「hts = ""」で　出力ファイルに　一行書き込み
　「Set objHTTP = CreateObject("Microsoft.XMLHTTP")」で　出力ファイルに　一行書き込み
　「objHTTP.Open "GET", url, False」で　出力ファイルに　一行書き込み
　「objHTTP.SetRequestHeader "User-Agent", SamAgent」で　出力ファイルに　一行書き込み
　「objHTTP.Send」で　出力ファイルに　一行書き込み
　「Set objStream = CreateObject("ADODB.Stream")」で　出力ファイルに　一行書き込み
　「objStream.Type = 1」で　出力ファイルに　一行書き込み
　「objStream.Open」で　出力ファイルに　一行書き込み
　「objStream.Write objHTTP.responseBody」で　出力ファイルに　一行書き込み
　「objStream.Position = 0」で　出力ファイルに　一行書き込み
　「objStream.Type = 2」で　出力ファイルに　一行書き込み
　「objStream.Charset = "Shift_JIS"」で　出力ファイルに　一行書き込み
　「http_source = objStream.ReadText」で　出力ファイルに　一行書き込み
　「objStream.Close」で　出力ファイルに　一行書き込み
　「hts = http_source」で　出力ファイルに　一行書き込み
　「Set fs = CreateObject("Scripting.FileSystemObject")」で　出力ファイルに　一行書き込み
　「FileName = fs.BuildPath(WshShell.SpecialFolders("Desktop"), FileName)」で　出力ファイルに　一行書き込み
　「MsgBox FileName」で　出力ファイルに　一行書き込み
　「Set file = fs.CreateTextFile(FileName, True)」で　出力ファイルに　一行書き込み
　「file.Write(hts)」で　出力ファイルに　一行書き込み
　「file.Close」で　出力ファイルに　一行書き込み
　「MsgBox "ok"」で　出力ファイルに　一行書き込み
　「Set file = Nothing」で　出力ファイルに　一行書き込み
　「Set fs = Nothing」で　出力ファイルに　一行書き込み
　「Set objHTTP = Nothing」で　出力ファイルに　一行書き込み
　「Set objStream = Nothing」で　出力ファイルに　一行書き込み
　「End Function」で　出力ファイルに　一行書き込み
　「Wget("https://resolvenet.org/modules/contrib/webform/tests/files/sample.json")」で　出力ファイルに　一行書き込み
　出力ファイルを　クローズし
　「cscript wget.vbs」を　プログラム実行





```

以上。
数値判定 Python3編

https://paiza.jp/works/mondai/string_primer/advance_step4

出力された文字列が数値変換可能かみる

```py
S = input()
if  S.isdecimal() == True:
    print('YES')
else:
    print('NO')

```

他にもあたえらえたのが全部数値か調べるということで

```py
s = input()

if s.isdigit():
    print("YES")
else:
    print("NO")
```
技術顧問との1on1で得たマネジメントの教訓

## はじめに

本記事は[リンクアンドモチベーション Advent Calendar 2023](https://qiita.com/advent-calendar/2023/lmi)の1日目になります。

自分は少しずつプロジェクトをリードする機会が増え、「リーダー」や「マネージャー」の振る舞いを意識することが増えました。

そんな中で技術顧問の方と1on1で話したことが印象的だったので共有します。

※公開するにあたって分かりやすさを重視して脚色しています。

## マネージャーへの厳しい視線は自分に返ってくる

技術顧問「何か疲れてる？w」

ぼく「え、そうですかw」

技術顧問「なんとなく。」

ぼく「プロジェクトの責任者になって気負っているのかもしれません。ちゃんとやらなきゃって。」

技術顧問「別にちゃんとやらなくてもいいいんだよ。弱みを見せて支えてもらう方がやりやすかったりするよ。」

ぼく「周りの自分より若いメンバーはしっかりしているので、それでも全然良いと思うんですけど、何か気負っちゃうんですよね。。」

技術顧問「自分自身が過去にマネージャーに色々求めてきたんじゃない？これくらいやれよって思ってたでしょ？」

ぼく「...」

ぼく「めっちゃ思ってました。」

技術顧問「コードも書いて、次のプロジェクトの計画も立てて、メンバーの育成もして当然て思ってたんじゃない？」

ぼく「思っていた気がします。。」

技術顧問「それが自分に返ってきてるんだよ。過去の自分が現在の自分のハードルを上げているの。自分が自分にかけた呪いだよ。」

ぼく「なるほど。。」

:::note info
教訓
当然だけどマネージャーやリーダーは完璧な人ではない。
他人に完璧を求めると回り回って自分に返ってくる。
マネージャーも不完全な人間であることを理解しよう。
:::

## マネージャーの仕事とは？

技術顧問「自身はマネージャーの仕事についてどう思っているのかな？」

ぼく「コミュニケーションパスが多くて色々大変だと思ってます。」

技術顧問「ネガティブかポジティブだったらネガティブ寄りっぽいね。」

ぼく「そうですね。どちかというと良いイメージ持ててないです。大変そうだなという印象が強いです。」

技術顧問「色々な人と話して調整して、メンバーのモチベーションにも気を配って、やり損だと思ってるでしょ？」

ぼく「...(エスパーかよ)」

技術顧問「マネージャーってね、ある部署の大きな権限を持って目標達成できる人のことなのよ。問題解決の大きさと、使えるリソースが増えるってことなの。」

技術顧問「例えば1on1でメンバーの話を聞くだけってそりゃつまらないよ。受け身でやると何でもつまらないの。」

技術顧問「問題解決のために今までは1人の力でプログラムを書いていたのを、より大きなリソースを使ってできるって思うと楽しくない？」

ぼく「...!」

技術顧問「自分はICとしての仕事は一通りやり終えてしまったので、それからはいかにして自分以外のリソースを使うかにシフトしているよ。」

技術顧問「問題解決は能動的にやると楽しいよ。なんかリーダーっぽいポジションになったから一応1on1しとくかじゃモチベーションが上がらないのは当たり前。」

技術顧問「君のチームの目標は何ですか？」

技術顧問「その目標のためにどう自分と自分以外のリソースを使うかって考えようよ。そうすると楽しくなるから。」

ぼく「はい！！！」

:::note info
教訓
マネージャーの仕事は「物事をうまく取り扱うこと」「やりくりすること」。
マネージャーになると自分以外のリソースを使える権限が生まれる。
能動的に仕事をしないと楽しくなくなってしまう。
:::

## 問題解決と選択

技術顧問「これは万人に話す内容ではないんだけど、マネージャーとかリーダーになっていくと、理詰めで解けない問題にぶちあたるのね。」

技術顧問「例えばあるあるだと、品質を求めながらスピードも上げたいとか、個人のWillを大事にしつつ組織や事業の目的も大事にしないといけないとか。」

ぼく「ありそうです。」

技術顧問「そういったコンフリクトを両立して問題解決できるようにできると良いね。例えば残業なしと仕事の成果のどちらかを選択するのではなくて、一見相反することを両立して解決できると良いよね。」

技術顧問「そのためには、今までやった経験済みの作業で何とかするんじゃなくて、頭を使ったり、今までやったことないアプローチにチャレンジできると良いよね。」

ぼく「がんばります！！！」

:::note info
教訓
「問題解決」とは葛藤とか、矛盾とか、一見両立しないことを解決すること。
トレードオフのどちらかをとるのは「選択」。
:::

## おわりに

自分は熱血漢な感じのタイプじゃないのですが、上記の話はなかなかに心が動きました。

変に鵜呑みにしてしまうとマッチョ過ぎて辛くなってしまいそうですが、能動性を失うと仕事がおもしろくなくなるというのは自分にとっては真理だと思います。

生成AIが出てきたり色々と「物事をうまく取り扱うこと」が増えていますが、能動的に楽しく頑張っていこうと思います。
LPIC/Linux学習記録#2

〇自戒のための自己への宣誓
1. お前に足りないのはインプットだ！！！インプットしろ！！！インプットの奴隷になれ！！！
2. 記事の書き方とか今はどうでもいいから書け！！！インプットをアウトプットしろ！！！やる前からこだわりとか持つな！！！
3. 見られることとか評価されることとか気にするな！！！MECEとか構造化されてるかどうかとか気にするな！！！構造化はアウトプットの整地であって、インプットが足りないお前が手を出す領域ではない！！！ていうかお前頭良いんだからインプットに注力しろ！！歴史を刻め！！！歴史をまとめようとするな！！！未来を描け！！過去を清算するな若者め！！！！
4. 疑問を持つことを恥じるな！！！お前は頭はいいがインプットが足りない未熟者だ！！！インプットの奴隷になれ（再掲）！！！


〇学習記録
/etc/group: /etc/passwdのうちのgroupname:grouppassword:gid:所属してるユーザーが表示される感じ。
addgroup: グループを作成したいとき。
→グループにユーザーを追加したい場合は？
→→プライマリグループならusermod -g [group name] [username]で、サブグループならusermod -G [group name1, group name2, ..., group nameN] [username]で追加(変更)する。
→グループに割り当てられてる権限はどうやって見れるの？読み込み、書き込み、実行の３種類しかない？フォルダやファイルごとに権限を振ることはできる？そこまでしなくていい？（Linuxの目的ってそもそもなんだっけ？何に使いたいんだっけ？）
→→ls -lで見れるらしい（つまりIAMみたいにグループにポリシー割り当てたりするんじゃなくて、フォルダやファイルが基準らしい）。正直Linuxの目的とか今の自分じゃわからん。インプットの奴隷であれ！！！学び続けろ！！

usermod: ユーザーが所属するグループを変更したり、uidを変更したりできる。

①ユーザー作成：adduser -u XXX [username]
②グループ等確認：id [username]
③グループ作成：addgroup -g XXX [group name]
④グループ割り当て：usermod -g [group name] [username]
⑤グループ等確認：id [username]
Flutterの初期学習ロードマップ

Flutterを始めてから1ヶ月経ったので、
個人的に良かったソースやこんな順番でやったほうが良かったかも、というロードマップを主観で作成しました。

## STEP 1: チュートリアル :beginner: 
まずflutter大学の"Flutter基礎入門"を見るのがオススメです。
https://zenn.dev/kboy/books/ca6a9c93fd23f3

techpitのこちらの講座は、
他のソースにもけっこうある内容なのでコスパを考えると微妙かもしれません。
歴史を知るには良い教材です。
https://www.techpit.jp/courses/225

## STEP 2: 知識を広げる :book: 
こちらの本がオススメです。一番基礎寄りでした。

"マルチプラットフォーム対応 最新フレームワーク Flutter 3入門"
https://www.amazon.co.jp/%E3%83%9E%E3%83%AB%E3%83%81%E3%83%97%E3%83%A9%E3%83%83%E3%83%88%E3%83%95%E3%82%A9%E3%83%BC%E3%83%A0%E5%AF%BE%E5%BF%9C-%E6%9C%80%E6%96%B0%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-Flutter-3%E5%85%A5%E9%96%80-%E6%8E%8C%E7%94%B0%E6%B4%A5%E8%80%B6%E4%B9%83/dp/4798068527

こちらの本はこの段階で読むには僕には早すぎました。

"現場で使える Flutter開発入門"
https://www.amazon.co.jp/%E7%8F%BE%E5%A0%B4%E3%81%A7%E4%BD%BF%E3%81%88%E3%82%8B-Flutter%E9%96%8B%E7%99%BA%E5%85%A5%E9%96%80-Compass-Books%E3%82%B7%E3%83%AA%E3%83%BC%E3%82%BA-%E8%89%AF%E5%BC%98%E3%80%81%E4%B8%8A%E6%9D%91/dp/483997375X/ref=asc_df_483997375X/?tag=jpgo-22&linkCode=df0&hvadid=529520598444&hvpos=&hvnetw=g&hvrand=3522248993503052111&hvpone=&hvptwo=&hvqmt=&hvdev=c&hvdvcmdl=&hvlocint=&hvlocphy=1009565&hvtargid=pla-1390617710081&psc=1&mcid=cc9bdb2379413acdb6a63d3e799a2ac1&th=1&psc=1

## STEP 3: widgetの幅を広げる :tools: 
ここまで来たらなんでもいいのでアプリを作ってみるのが良いと思います。
chatGPTに聞けば大体作ってくれます...!

公式のWidget of the weekを見ましたが、数が多すぎて大変でした。
興味ありそうなやつだけ見るのがいいと思います。
https://www.youtube.com/playlist?list=PLjxrf2q8roU23XGwz3Km7sQZFTdB996iG

## STEP 4: 状態管理 :construction_site: 
このyoutubeがオススメ。
https://www.youtube.com/watch?v=0HVru4WtdWo
Googleは十分役に立ちますが1.0の知識が多いので一応注意。

書籍の場合はこちらがオススメです。

"基礎から学ぶ Flutter"
<src img="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/542326/5ed48df3-161a-252c-560f-9f5636f897eb.png" width="200">

https://www.amazon.co.jp/%E5%9F%BA%E7%A4%8E%E3%81%8B%E3%82%89%E5%AD%A6%E3%81%B6-Flutter-%E7%9F%B3%E4%BA%95-%E5%B9%B8%E6%AC%A1/dp/4863542941

## STEP 5: アーキテクチャ :tokyo_tower: 
MVVMで行く場合はこちらが参考になります。
"Flutter x Riverpod x MVVMで実現するシンプルな設計"
https://www.udemy.com/course/riverpod/

クリーンアーキテクチャの場合はこちら。
https://zenn.dev/chooyan/articles/eefc76dbd2ba25

## おわり
Flutterは最初イメージしにくいかもですが
シンプルですし、chatGPTもかなり詳しいので慣れれば作りやすく感じると思います！
最近は何を作るかとかUIを考える方が難しいです。
以上です！
日時データの変換その２ (paizaランク C 相当)

https://paiza.jp/works/mondai/string_primer/advance_step3

>日時が "yyyy/MM/dd hh:mm" の形式で与えられるので、年・月・日・時・分をそれぞれ出力してください。(ただし、足りない部分は0埋めすること）

以前習ったfstringが活躍する。
書き方忘れてたかもなので復習する

```py
date, time = map(str,input().split())
yyyy, MM, dd = map(str,date.split('/'))
hh, mm = map(str,time.split(':'))
print(f"{yyyy:0>4}")
print(f"{MM:0>2}")
print(f"{dd:0>2}")
print(f"{hh:0>2}")
print(f"{mm:0>2}")
```
AWS英語嫌い勉強生活：単語が鳴っても、私は覚えるのがいや！

皆さん、こんにちは！最近AWSがすごく流行っているって聞いたので、私もついにその波に飛び込むことにしました。さて、講座を購入してワクワクしながらスタートしたんですが、予想外の壁にぶつかりました。

なんと、英語がまるでチンプンカンプン！単語の意味がわからないどころか、単語自体が「何語？」って感じ。教材が英語で埋め尽くされているから、見るだけで頭がクラクラします。英語がおっかない…というよりも、英語に対する私の反応が「あ、またかよ」って感じです。

いざ勉強して覚えて、次の日にはもうすでに覚えてない。それを繰り返す日々。もう少しでAWS試験を受けるはずが、いつになったら試験を受けられるのやら…。

「AWS、君も英語で来るのかよ！？」って感じですね。でもまあ、なんとかなるでしょう。もしかしたらAWSの中の人たちは英語を勉強するためにAWSを作ったのかもしれませんよね。心が通じるといいな！

とにかく、私は今日も英単語に向かって叫びます。「覚えたらどうせ忘れるし、覚えても何に使うの？」って。英語の勉強は辛い…けど、だからこそ面白い！次に試験受けたら、試験官にも「単語は難しいよね〜」って言ってみようかしら。
LPIC/Linux学習記録#1

〇自戒のための自己への宣誓
1. お前に足りないのはインプットだ！！！インプットしろ！！！インプットの奴隷になれ！！！
2. 記事の書き方とか今はどうでもいいから書け！！！インプットをアウトプットしろ！！！やる前からこだわりとか持つな！！！
3. 見られることとか評価されることとか気にするな！！！MECEとか構造化されてるかどうかとか気にするな！！！構造化はアウトプットの整地であって、インプットが足りないお前が手を出す領域ではない！！！ていうかお前頭良いんだからインプットに注力しろ！！歴史を刻め！！！歴史をまとめようとするな！！！未来を描け！！過去を清算するな若者め！！！！
4. 疑問を持つことを恥じるな！！！お前は頭はいいがインプットが足りない未熟者だ！！！インプットの奴隷になれ（再掲）！！！

〇学習記録
/etc/passwd: パスワードが設定された順に作られるらしい。もともとはパスワードを見るためだったっぽいけど今はハッシュ化されてわからんくなってる(xで表示される）。なのでpasswdという名前がついてるらしい（諸説あるかも）。ユーザー情報を見たいときにcatすればいいらしい。UIDとかGIDとか本名（whoamiで表示されるやつ）とかパスワードとかホームディレクトリとかログインシェルとかが書かれてる。
ホームディレクトリ：ログインしたら最初にいるディレクトリ。
ログインシェル：最初にLinux systemとインタラクトする際に通る窓口みたいなものらしい。よくわからんけどとりあえず最初に触れるものらしい。シェルっていうくらいだから、そこに書かれてるものにコマンドが登録されていればパス書かずに使えるのかね。→違う。イメージは「お清めの場所」とか「バイオハザードの消毒ルーム」みたいな感じ。最初に身を整えて、空間の中に入っていく。その際、rootユーザーでログインするなら/bin/bashで身を清めて、つまりどんな人間が入っても同じようになるように初期設定して、そこから先は与えられた権限で仕事したり堪能したりする感じらしい。
グループ：グループ=権限の集合。ユーザーは１つ以上のグループに所属する。メインのグループとサブのグループがあって、メインのグループのことをプライマリグループという。自分が大学生だとして、大学がLinuxディストリビューション、学生が所属してる学部・専攻がLinuxユーザーのプライマリグループ、メインじゃないけど受けてもいいよって言われてる授業やサークルがサブグループになる。

〇復習用クイズ
①/etc/passwdは何に使うの？もともとは何？
②ログインシェルは何？何と関連してる？どんな文脈ででてきた？例えると何？
③グループは何で決まる？


〇クイズ答え
①登録されてるユーザー情報を知りたいとき。特に、どんなユーザーが登録されてるか、あとはそれらのユーザーのuidやgidなどの諸情報を知りたいとき。もともとは
②れイメージは「お清めの場所」とか「バイオハザードの消毒ルーム」みたいな感じ。最初に身を整えて、空間の中に入っていく。その際、rootユーザーでログインするなら/bin/bashで身を清めて、つまりどんな人間が入っても同じようになるように初期設定して、そこから先は与えられた権限で仕事したり堪能したりする感じらしい。
③グループ名と権限。ユーザーは１つ以上のグループに所属する。メインのグループとサブのグループがあって、メインのグループのことをプライマリグループという。自分が大学生だとして、大学がLinuxディストリビューション、学生が所属してる学部・専攻がLinuxユーザーのプライマリグループ、メインじゃないけど受けてもいいよって言われてる授業やサークルがサブグループになる。
回文判定 Python3編

https://paiza.jp/works/mondai/string_primer/normal_step11

回分かどうか判定せよという問題
ループを回して1文字ずつ取り出して等しいか調べ等しくなければNOを出すというロジック。
文字列を逆にする書き方とzip関数を新たに学ぶ。

```py 
S = str(input())
reS = S[::-1]

flag = 'YES'
for x, y in zip(S,reS):
    if x != y:
        flag = 'NO'
        break
print(flag)

```
でも実は、SとreSが同じだったらOKなのである。
たしかに。。。。


```py
S = str(input())
reS = S[::-1]
if S == reS:
    flag = 'YES'
else:
    flag = 'NO'
```
【時間を溶かした話】WARNING: Failed to load staticwebapp.config.json schema. Continuing without validation!

こんにちは、船井総研デジタルの@tuna828です。
業務でAzureのStaticWebAppsを利用しているのですが、
ローカル起動がうまくいかず時間を溶かしまくってしまいました。

# したかったこと
ローカル起動時にMicrosoftの認証画面に遷移するように設定したかった。
staticwebapp.config.jsonは設定済みで、リモートでは動くはずでした。

MSのドキュメントによれば
1 フロントエンドとバックエンドをまずローカルで起動
2 ルートディレクトリで下記コマンドを実行
~~~ 
swa start http://localhost:3000 --api-location http://localhost:7071 
~~~
で、http://localhost:4280 にアクセスすれば認証画面にリダイレクトしてくれるはず、、！

# WARNING: Failed to load staticwebapp.config.json schema. Continuing without validation!
なんでなん…？
ローカル起動自体はできたのですが、
staticwebapp.config.jsonを認識してくれず、jsonファイルで設定したルーティングで遷移しません。
ちなみにStaticWebAppsのアプリ上ではルーティングファイルとして機能しています。
ubuntu再起動したり、PC自体を再起動したりしてみましたが現象は解消しないまま。。。

# 結論
実は原因は現在も不明のままなのですが、
翌日再度起動してみたらうまくいきました。

なぜwarningが出たのか＆何も変更していないのにwarningが消えたのかわからないのがイヤでAzureのSRに問い合わせてみたのですが、
サポートチーム：swaのバージョンが古いからでは？
1.1.2以前ならバージョンアップしてみてください
私：1.1.4です
サポートチーム：社内では再現しません。。。

ということで原因は謎のままです。

理由もわからないまま記事を書くのは気が引けましたが、
「WARNING: Failed to load staticwebapp.config.json schema. Continuing without validation!」
が解決せずお困りの方がいらっしゃいましたら、
一晩置いたらワーニング解消した奴もいるので一度寝かせてみてください。
short of characters match of regex with notepad++

.: 1
?: 0 or 1, +: 1 or more: *: 0 or more character(s)

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/501146/dfdcac01-1511-9c43-c636-393536d36124.jpeg" width=26%/>

https://npp-user-manual.org/docs/searching/#regex-special-characters-for-searches
社内日報を内製化しよう(実装編) 

# 経緯
https://qiita.com/miyasaka-anyplus/items/93cb293994dcf57ab4be

# 構成

構成はメインにAWS基盤を利用しています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/ad92c2b7-c4a3-0c6f-e4fd-12aa7eeb6ff1.png)

- 開発言語: Vue
- フロント: S3 + Cloudfront
- API: APIGateway + Lambda
- DB: DynamoDB
- 認証: Cognito

# アプリダイジェスト

### ログイン画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/c6f073a7-a116-a455-c79b-9faa2f341175.png)

### メニュー画面

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/8bee9a95-48db-fb23-1b91-99a84cd52a41.png)

### 入力フォーム

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/0e4b9062-b816-76eb-92cf-ac1e351416c8.png)

### 日報参照

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/d7e9c40e-5367-151e-6df0-9d67b470bd64.png)


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/41936f0f-eda9-839a-3f62-cb026c20192d.png)

# CICD

CICDにはGithub Actionを利用しました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/502127/f2faff5b-f0c3-e34c-1e7f-38cb520d2e50.png)


# 今後の課題

日報アプリにはまだまだ課題があるので今後取り組んでいきます。

- メール通知機能
- ユーザー払い出し
- ベータ版の提供
- ファイル添付機能
- 前回日報の流用機能


# そのほかの取り組み

今年度はチームでに以下についても取り組みました。

- 社内運用効率化
- 社内運用ドキュメント化
CSSのfloatプロパティについて

## はじめに
RUNTEQに入学して2ヶ月の学習者です。
バックではなく、フロント側ですがこちらもすごく興味があったのでまとめました。
## 1.なぜこの記事を作ったのか
以前`float`プロパティを使用した時に挙動がよく分からなかった。間違い等があった際は指摘してもらえると助かります。
## 2.環境
- ブラウザはgoogle chromeを使用します。
## 3.floatプロパティとは
floatで囲った要素の周りに他の要素を回り込ませることが出来る。文字通り要素が浮いている(float)ような状態になる。

before
![before.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/cb49e576-0ec0-d996-fdec-83accc094426.png)
```html:index.html
<div style="width: 200px; height: 200px; background-color: red"></div>
<script>document.write('テキスト'.repeat(500))</script>
```
`div`タグに`float: left;`を設定すると

after
![after.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/cb974bec-7069-79f7-fd64-302832052f69.png)
`div`はブロック要素ですが、下にある"テキスト"が回り込んでくる。
## 4.理解を深める
以下のコードを書きました。
```html:index.html
<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>floatについて</title>
  <link rel="stylesheet" href="style.css">
</head>
<body>
  <main>
    <div class="box bg-red"></div>
    <div class="box bg-blue"></div>
    <div class="box bg-brack"></div>
    <div class="box bg-yellow"></div>
  </main>
</body>
</html>
```
```css:style.css
/* 見やすくする為に設定 */
* {
  margin: 0;
  padding: 0;
}
main {
  max-width: 1000px;
  margin: 0 auto;
}

.box {
  width: 200px;
  height: 200px;
}
.bg-red {
  background-color: red;
}
.bg-blue {
  background-color: blue;
}
.bg-black {
  background-color: black;
}
.bg-yellow {
  background-color: yellow;
}
```

ブラウザ
![検証前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/ccb2a4c2-3a11-58cc-dd32-4d9bbfa30a3f.png)
- ### 赤(.bg-red)に`float: left;`を設定
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/ff3e1e7b-7c09-6e0c-db91-a3d878ccc991.png)
青が赤へ回り込む。四角の位置が同じなので見えなくなった。
- ### 赤(.bg-red)と青(.bg-blue)に`float: left;`を設定
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/a6424a54-ff6e-1c86-4652-8379e1f3910a.png)
黒が回り込み、浮いた赤と青が並んだ状態になった。
- ### 赤(.bg-red)と青(.bg-blue)と黄(.bg-yellow)に`float: left;`を設定
![3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/cb9c49ee-d370-4e11-a2ae-9a565529c9f7.png)
黒が浮いていないので黄は回り込むことが出来ない。
- ### 全てに`float: left;`を設定
![4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/4d95b2e5-a983-bc2e-569d-f4188786ab5d.png)
5.回り込みをさせたくない時
- ### 赤(.bg-red)に`float: left;`を設定
![2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/ff3e1e7b-7c09-6e0c-db91-a3d878ccc991.png)
この状態の時に回り込む要素である青(.bg-blue)に`clear: left;`を指定すると
![検証前.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3627896/ccb2a4c2-3a11-58cc-dd32-4d9bbfa30a3f.png)

### その2 `float`させた要素の親要素にcssの擬似要素を追加する
条件は上記と同じにして
```html:index.html
<!-- .bg-redに親要素の追加 -->
<div class="clear-box"><div class="box bg-red"></div></div>
```
```css:style.css
.clear-box::after {
  content: "";
  display: block;
  clear: both;
}
```
これらを追記しても回り込まなくなる。
::afterは最後の行に擬似要素を追加しており、これがある為回り込むことが出来なくなった。
ChatGPTのない時代にママの孤独と向き合うアプリを開発した

この記事は[Code for Japan](https://www.code4japan.org/)のシビックテックチャレンジイベントにて取り組んだ子育ての悩みをITで解決することを目標とし、２か月後のNHKでの発表までにアプリを作成する開発軌跡です。

https://www.code4japan.org/news/cc-childcare

https://www.nhk.or.jp/minplus/0028/topic030.html

## 作成したもの

**子育てスナック　ひぐまさんの相談部屋**

> 「子育てが辛い。けど、相談する相手がいない…」
> 「ちっちゃな子育ての悩み、どこに相談すればいいの…」
> 「これから子育てにむけて何を準備しておけばいいのか漠然と不安…」

そんなことを思ったことはないでしょうか？
子育ての悩みは本当に多種多様、その中には想像以上に深い悩みもあります。
我が子を愛するからこそ悩みが尽きることはないでしょう。
悩みの種類・深さによらず、子育ての悩みをすこしでも軽くしたい、そんな思いから生まれたプロダクトです。

思いのたけ（お悩み）をあなたの言葉でひぐまさんにとにかく吐き出して下さい、
解決の助けになるかもしれないヒント（情報）をひぐまさんが探してきてくれます。

https://higuma-room.vercel.app/

## 要件定義

子育ての課題をいくつか話し合う中で、子育ての相談方法にフォーカスして深堀りしました。

- 誰に？
    - 深刻な悩み
        - 夫や家族に
        - 子育て中の人、または子育て経験者
    - それ以外
        - 家族や知人、友人
- いつ？
    - 困った時に
    - 話すタイミングがある時に
- 何を？
    - 子どものこと
        - 発育
        - 病気
- 相談方法は？
    - 対面で話す
    - 電話をかける
    - テキストメッセージ（LINEやメール）
- なぜ？
    - アドバイスが欲しい
    - 愚痴りたい

悩みの種類はたくさんありました。個人差もあります。
悩みはたくさんあるのに相談できる相手がいない、
相談したい人に気軽に相談できない、

`困った時に相談できない状況や誰に相談したらいいかわからない状況`を課題とし、
これをITで解決する方法の検討を始めました。

## 課題への取り組み

子育ての悩みをいつでも相談できるアプリの開発に着手しました。重視したことは下記の３点です。

1. 傾聴する姿勢をアプリで実現すること
1. 解決のヒントをアプリから提示すること
1. 人以外に相談することへの不信感をなくすこと

### 1.傾聴する姿勢を実現すること

悩みを相談したい人は自分でも何に悩んでいるのかわからない状態に陥ることや
イライラなどの心理状態から言語化することが難しいこともあります。
また具体的な悩みを解決したいではなく、自分の気持ちを吐き出したい状況もあります。

１リクエストに対して機械的にレスポンスを返す、
そんなシステムっぽい対応をするのではなく、
音声入力した結果をアプリが受け付けるようにして、人と話すような状況をアプリで再現できるようにしました。
また音声で利用できないシーンにも配慮して、テキストメッセージにも対応しました。

### 2.解決のヒントを提示すること

ユーザーの音声から悩みを受け付けたところで解決できる銀の弾丸はありません。これは対人であっても同じです。
それで、悩みの内容から検索した結果を数件提示することを実装しました。
類似の事例や同じ悩みを抱えている人の情報を選択式で表示することで
ユーザーは自身が欲しいものだけを選ぶことができます。
もし該当しなかった場合は再度話しかけることで検索内容を調整することできます。

### 3.人以外に相談することへの不信感をなくすこと

アレクサなど音声操作することはありますが、
アプリに向かってモヤモヤしたままの心情を話しかける利用シーンは日常生活でほぼありません。
またプライバシー情報を受け付けるので不信感を持たれないような配慮が必要となります。
人以外に話かけるものとしてぬいぐるみのようなキャラクターが必要となり、ひぐまをモチーフとしました。

> なぜひぐま？

エゾヒグマは、冬眠している1〜2月に、一度に2〜3頭を出産します。
クマの子育ては、出産から独り立ちまでの約３年間を全てを母グマだけが行う完全な「ワンオペ育児」を行うそうです。
子育て経験者に相談したい相手として完全に一致したのが採用した理由です。

https://spice.kumanichi.com/human-culture/human-culture-feature/90154/#google_vignette

# 最後に

このアプリは2022年の3月～5月に取り組んだ開発しました。
私が担当した部分はほんの一部分でしたが、優秀なエンジニアやデザイナーと一緒に開発でき、大変有意義な時間でした。
まさか、このアプリの半年後にChatGPTが登場するなんて...
今の技術を用いると簡単に構成できるので、これからもITでの解決を目指して個人開発を続けようと思います。

最後までご覧いただきありがとうございました。
dockerでpython環境を立てて入ってみる

株式会社OMJテクノソリューションズ Advent Calendar 2023　16日目の記事です。

dockerについて学ぶ必要に迫られ色々調べておりました。あまりイメージをつかめていなかったのでとりあえずpython環境を立ててみて入ってみようという内容です。

# 環境
・Apple M1
・macOS Ventura
・docker desktop 4.24.2

# 準備
docker desktop, VScodeをインストール。
VScodeの拡張機能である Dev containersを追加する。
![スクリーンショット 2023-11-23 16.34.35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780709/2fffbee1-21c5-ad85-7d9d-4ed9987cdfad.png)


最小限のフォルダ構成
```
test_folder
├── dockerfile
└── test.py
```
test.pyはなんでもいいですかね。
```test.py
print("hello")
```

# dockerfileを作成
```dockerfile
# ベースとなるイメージを指定
FROM python:3.8

# 作業ディレクトリを設定
WORKDIR /app

# カレントディレクトリの内容を作業ディレクトリにコピー
COPY . /app
```
とりあえずpython3.8が入っただけのコンテナですね。これにdev containersを使って入ってみます。
![スクリーンショット 2023-11-23 16.50.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780709/e01ac8fa-33f0-6f4c-e599-399165d4b7c7.png)

![スクリーンショット 2023-11-23 16.56.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780709/05cd21a5-6399-7e3e-b5ca-f1d8b7e3e18d.png)

![スクリーンショット 2023-11-23 16.57.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780709/5b656348-12bc-1a05-a8ad-620fea095b39.png)

![スクリーンショット 2023-11-23 17.00.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780709/e84d0b11-59e0-5468-079b-b46bbceb4543.png)

これでコンテナに入れました。左下の青いところにdev containerと表示されます。pthonだけ入ってる状態で test.pyをコンテナ内で動かせます。pip listもほとんど空なので確認してみてください。

![スクリーンショット 2023-11-23 17.02.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2780709/cc30551f-fed5-dc25-545c-07dbee14a781.png)


こんな感じで独立したコンテナの中を体感できました。動作確認やらテストやらをvscodeからコンテナ内でできますね。あとはdockerbuild内にrequirement.txtからのインストールとか環境変数の定義とかを追加していけば思い描いた環境が作れる気がします。

# 最後に
ホントに最小限でコンテナにはいるだけでした。ただ概念をつかむ一助にはなったかと思っています。どのツールもできることが多すぎて概念をつかむことすらままならないことがあるので、最小限から始めても良いのかなと思います。
DBeaverでテーブル入力したときのエイリアス自動補完をオフにする

## 設定方法
DBeaverのウインドウ>設定>エディタ>SQLエディタ>SQL補完
の`Insert table aliases (in FROM clause):`をN/Aに設定する。

![Cursor_と_設定.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2450260/fb6e221f-7476-8fcd-7c77-048b7187bed6.png)

## 参考

https://github.com/dbeaver/dbeaver/issues/8894
文字列表記

# 文字列リテラル表記

UWSCRの文字列表記はUWSCと同様にダブルクォーテーション(`"`)による表記に加え、シングルクォーテーション(`'`)表記が追加されています。

```php
print "ダブルクォーテーションによる文字列表記"
print 'シングルクォーテーションによる文字列表記'
```

シングルクォーテーションの場合は以下の特殊文字が変換されないという特徴があります。

- `<#CR>` (改行)
- `<#TAB>` (タブ文字)
- `<#DBL>` (ダブルクォーテーション)
- `<#NULL>` (NULL文字)

```php
print "特殊文字が変換されます: <#DBL>" // 特殊文字が変換されます: "
print '特殊文字がそのままです: <#DBL>' // 特殊文字はそのままです: <#DBL>
```

# 文字列内での変数展開

文字列内で`<#変数名>`を記述すると、その変数の値が展開されます。変数展開が可能なのはダブルクォーテーション表記のみです。

```php
// 変数fooを文字列内で展開する
foo = "world"
print "Hello, <#foo>!" // Hello, world!

// 存在しない変数は展開されません
print "Hello, <#bar>!" // Hello, <#bar>!

// シングルクォーテーション表記の場合は変数展開されません
print 'Hello, <#foo>!' // Hello, <#foo>!
```

# textblockex

UWSCと同様に文字列ブロック定数を定義するtextblockに加え、変数展開が可能なtextblockexが追加されています。textblockexの定数は遅延評価されます。

```php
foo = "world"
print tbex // Hello, world!

// 変数fooの値を書き換える
foo = "uwscr"
print tbex // Hello, uwscr!

textblockex tbex
Hello, <#foo>!
endtextblock
```
CentOSで特定期間のファイルを効率的に移動する方法

### はじめに

CentOSを使用している方々にとって、特定の期間に作成または変更されたファイルを効率的に別のディレクトリに移動する方法は、日常の作業をスムーズに進める上で重要な技術です。
この記事では、`find`と`mv`コマンドを組み合わせてこのタスクを実行する方法を説明し、それに関連する重要な注意点を共有します。

### 移動コマンドの概要

CentOSでは、以下のコマンドを使用して、特定の期間内に作成または変更されたファイルを移動できます：

```bash
find /source_folder -type f -mtime -7 -exec mv {} /destination_folder \;
```

#### コマンド解説：

- `find /source_folder`：探索を行うソースディレクトリ。
- `-type f`：ファイルのみを対象とする（ディレクトリは除外）。
- `-mtime -7`：過去7日以内に変更されたファイルを対象とする。
- `-exec mv {} /destination_folder \;`：見つかったファイルを指定したデスティネーションディレクトリに移動する。

### 実行時の注意点

1. **データの安全性**：`mv`コマンドは元の場所からファイルを削除するため、誤操作には注意が必要です。

2. **パスの正確性**：移動元と移動先のディレクトリパスが正しいことを確認してください。

3. **ディレクトリ構造の非保持**：このコマンドでは元のディレクトリ構造は保持されません。

4. **名前の衝突**：移動先に同名のファイルが存在する場合、上書きされる可能性があります。

5. **権限の確認**：適切なファイルとディレクトリのアクセス権限が必要です。

6. **コマンドのテスト**：本番環境で使用する前に、テストを行ってください。

7. **バックアップの推奨**：操作を実行する前に、対象のファイルやディレクトリのバックアップを取ることをお勧めします。

8. **シンボリックリンクの扱い**：必要に応じてシンボリックリンクの追跡の有無を選択してください。

### まとめ

この方法は、CentOSシステムで特定期間のファイルを効率的に整理するのに有用ですが、その実行には注意と正確な操作が要求されます。
すべてのステップを慎重に実行し、データの安全を第一に考えてください。この記事が皆さんの作業効率化に役立つことを願っています。
git fetch、git merge、git pullとは何か

git fetch＝「ローカルリポジトリを最新状態にする」と認識していたら
想定通りにローカルリポジトリが最新状態にならず困惑したため、
調べて分かったことを備忘録としてまとめます。

## 「origin/master」ブランチについて
git fetchを理解するためには、まず「origin/master」ブランチについて知っておく必要がある。

「origin/master」は、**リモートリポジトリのmasterブランチを追跡する**ブランチで、
以下の図のようにリモートリポジトリのmasterブランチと、ローカルリポジトリのmasterブランチの間にある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524073/cadbf7b4-dc88-8dd3-67fc-7c1d88a6d27c.png)


「リモートのmasterブランチを追跡する」なので、
「コードの内容」ではなく、「ブランチの情報」を追跡しているという点が大切。

## git fetchとは
git fetchとは、リモートリポジトリのブランチの最新情報を
ローカルリポジトリの**origin/master**に持ってくるコマンド。
「リモートリポジトリに新しくブランチが追加された」というような**ブランチの情報**が分かる。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524073/acf31c2e-c011-3935-13dd-8686bae77141.png)

図のように、ローカルリポジトリのmasterブランチは更新されない。
すなわち、リモートリポジトリで自分以外の人がコードを編集していたとしても、
ローカルリポジトリのmasterブランチではコードの変更点を見ることはできない。

 ## git mergeとは
 git mergeは、ローカルリポジトリのorigin/masterからmasterに最新情報を持ってくる。
 origin/masterの内容をローカルリポジトリのmasterにマージするため
 リモートリポジトリで変更のあった箇所をローカルリポジトリのmasterブランチで確認することができる。

 ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524073/d2fb9616-dfa4-d420-6ed6-5889e0533f49.png)

## git pullとは
git pullはgit fetchとgit mergeを一度に行うコマンド。
リモートリポジトリのmasterブランチからorigin/masterブランチを介して、
一気に最新情報を持ってくることができる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3524073/2706843b-0715-9e44-1368-e1597c50c80e.png)

ローカルリポジトリのmasterとリモートリポジトリのmasterで競合する変更があった場合は
コンフリクトが起きるため注意が必要。


## まとめ
git fetchではローカルリポジトリのmasterの内容は更新されないことが分かりました。
また、ローカルリポジトリを最新にしたい場合「とりあえずgit pullする！」ではなく
状況に応じてgit fetch、git merge、git pullを使い分けられるようにしたいと思います。

## 参考
https://qiita.com/wann/items/688bc17460a457104d7d

https://nekosoftware.wordpress.com/2015/02/03/git%E3%81%AE%E3%81%B5%E3%82%8F%E3%81%A3%E3%81%A8%E3%81%97%E3%81%9F%E7%9F%A5%E8%AD%98%E3%82%92%E8%AA%BF%E6%9F%BB%E3%81%97%E3%81%A6%E3%81%BF%E3%81%9F/

https://beyondjapan.com/blog/2021/09/git-clone-pull-fetch/
Linux コマンド

# cd
cdは作業するディレクトリを移動するlinuxコマンドです。「cd」は「change directory」の略です

# chmod
「chmod」は「change mode」の略です。UNIXおよびUNIX系オペレーティングシステムにおけるシェルコマンドの一種である。Premission変更（アクセス権限）です。

`chmod 権限設定　ファイルパス/ディレクトリ`
| 所有者権限 | グループ権限 | その他のユーザーの権限|

-rw-r--r--は
`-`「ファイル種別」が「ファイル」であり
`rw-`「所有者」に「読み取り」と「書き込み」の権限があり、
`r--`「所有グループ」に「読み取り」の権限があり、
`r--`「その他」に「読み取り」の権限がある

# ln
`ln`は、ファイルのリンク（ショートカット）を作成するためのコマンドです。

- ln [オプション] ファイル名 リンク名

（ファイルのリンク（ハードリンクまたはシンボリックリンク）を作成する）

- ln -s ファイル名 リンク名

（ファイルのシンボリックリンクを作成する）

- ln -s ディレクトリ名 リンク名

（ディレクトリのシンボリックリンクを作成する）

- ln -s ファイル1 ファイル2…… ディレクトリ

（指定したディレクトリの中にシンボリックリンクを作成する）

# ip
「ip」コマンドは、ネットワークデバイスやルーティング、ポリシーなどの表示と変更を行うコマンドです

- addr:ネットワークデバイスのIPアドレス

ip addrの主なサブコマンド

| コマンド | 意味 | 
|:-----------|:------------|
| add | 指定したIPアドレスを付加する  | 
| change | 指定したIPアドレスの設定を変更する  | 
| replace| 指定したIPアドレスの設定を置き換える（change同様、ただし指定したアドレスがない場合は追加する）  | 
| del| 指定したIPアドレスを削除する  | 
| list、show| 設定されているIPアドレスを表示する（デフォルト）  | 

# ping

オプションの一覧

- `-c`:回数を設定する<br>
例：`ping -c 4 192.168.179.10`
- `-i`:間隔(ミリ秒)を設定する<br>
例：`ping -i 10 192.168.179.10`
- `-p`:パケット内容を設定する
- `-s`:パケットサイズを設定する
- `-t`:TTLの数を設定する

# 圧縮
## gz
`tar xzvf package.tar.gz`

# 解凍
## xz
### xzコマンド

- xzの解凍-> tarの解凍
`$xz -dv xxx.tar.xz`
`$tar xfv xxx.tar`

- 纏め
`$xz -dc xxx.tar.xz | tar xfv -`

### tar
`$tar Jxfv xxx.tar.xz`

## gz
`tar czvf package.tar.gz package-dir`

# Firewall
ufw（Uncomplicated FireWall）は、ファイアウォールの設定を行うコマンドです。
systemctlコマンドはsystemdを操作するコマンドで、サービスの起動や停止・起動設定の変更と状態確認ができます。
## ポート
- 状態確認：`sudo ufw status` `systemctl status ufw`
- 有効：`sudo ufw enable` `systemctl start ufw`
- 無効：`sudo ufw disable` `systemctl stop ufw`
- ポート許可：`sudo ufw allow [ポート番号]`
- ポート拒否：`sudo ufw deny [ポート番号]`

## アプリケーションからWEBへのアクセス
- 確認：`sudo ufw app list`
- 許可：sudo ufw allow 'Nginx Full'

# find 検索

サンプル
`$ find . -name "my*"`

カレントディレクトリでmy先頭のファイルを検索
`$ find . -name "my*" -ls`



# local 検索

etc以下のすべてshのファイル
`$ locate /etc/sh`

`$ locate ~/m`
大文字小文字の反転 Python3編

https://paiza.jp/works/mondai/string_primer/normal_step8

1文字ずつ、大文字は小文字に、小文字は大文字にして出力せよという問題
pythonにはそれができる関数があるので

```py
print(input().swapcase())
```

これにて終わりですが、もしその関数がなかったらどう実装するか。
ひとまずその1文字ずつ切り出して大文字か小文字かを調べて変換するというのが考えられる。

1文字ずつ切り出す方法は以前やった。
小文字かを調べるのは`islower()`
他にも`isupper()`,`istitle()`がある。


```py
s = input()

for character in s:
    if character.islower():
        print(character.upper(), end="")
    else:
        print(character.lower(), end="")

print()
```
Unit Test

# Outline
先日、毎年恒例の新卒エンジニアに向けて、Unit Testに関しての座学を行った。
初歩的な内容ではあるが、Unit Testを学ぶにあたって有益であると思い、記事にした。


<iframe src="https://www.slideshare.net/slideshow/embed_code/key/iSqClWMfKgrAhs?hostedIn=slideshare&page=upload" width="476" height="400" frameborder="0" marginwidth="0" marginheight="0" scrolling="no"></iframe>


# password validation test

以下のように、有効passwordのテストを想定する。
この場合、エンジニアはどうテストをする？

・ UIでポチポチテストをする？
・ Unit Testを使う？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/d38ebce7-dafd-7f18-d605-1f66a004bcd4.png)

回答は、後ほど。


# UI test と Unit Test の違いはなに？

PHPのLarabel frameworkを用いて説明する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/a2436815-1ae6-9c5a-5d8b-c141ca7abfe5.png)

### UI Test
UI Testは左の図。
passwordの処理を実現するには、Laravel上でいくつかの

passwordのテストをするとき、moduleを経由してテストが行われる。
・ユーザー側の表示部分である、view
・URLを振り分けるRouting
・処理を振り分けるcontroller
・実際のパスワードのvalidationをおこなうuser-class
などなど。

また、passwordのフォームにたどり着くまでに、UI上で操作が必要になる
1. top pageに遷移する
2. login する
3. my pageに移動する
4. password変更に遷移する
5. passwordを入力する <--- ココ

つまり、passwordのvalidationを行うため、多くのmoduleテスト、UI操作が発生する。

当然、
・いろんなmoduleをテストしているため、バグがあったときの根本原因を探すとき、工数がかかる
・１つのテストするのに工数がかかる

### Unit Test
Unit testは右の図
user-classのみをテストする。
そのため、入力されたpasswordの文字のvalidationだけを行う。

以下、2つのテストパターンのコードの例である。
・８大文字英字のみ = Fail
・８大・小文字英字、数字 = True

```
    /** @test length=8 **/
    public function return_validate_06 (){

        $user = new SampleUser();
        $user->setPassword('ABCDEFGH');

        $result = $user->validatePassword();
        $this->assertFalse( $result);

    }

    /** @test large+small+number and 8 characters **/
    public function return_validate_46 (){

        $user = new SampleUser();
        $user->setPassword('Ab1DEFGH');

        $result = $user->validatePassword();
        $this->assertTrue( $result);

    }
```

このようなコードを書き、これをunit testに流すだけでテストが完了する


以上から、UI TestとUnit Testの違いは以下のようにまとめられる。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/1b2e2586-08a4-5a1c-3817-dd041c954739.png)

機能単位でテストを行う場合、Unit Testが非常に有効であることがわかる。


# Is Test coverage enough for Quality?

ただ、Unit Testは完ぺきではない。
特にunit testの可視化ツールをつかってcoverageをだしても、あくまでcoverageを示しているだけで
スペックに対する妥当性を可視化するものではない。

例えば、C0 coverage 100%を満たしたとしよう。
C0はすべてのrouteを網羅すると、100%である。

以下のように、passwordの文字数だけvalidateする機能があるとする。
そして、以下のようなコードを書いたとする。
すると、１テストケースで c0 coverageは100%になっていまう。
これで本当に考えうるテスト( 境界値、同値等　）を満たしているのだろうか？

また、あくまでテストによってコードのすべての分岐を通ったかどうかを測るのがcoverageであり、
仕様とあっているかどうかは見ていない。
そのため、その仕様をみたすようなテストケースをすべて記載されていないと、バグが起きる可能性がある。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/267085/42f2a731-6746-0468-d585-54fd299ac02f.png)


# Are Internal Quality (Unit Test) & Development Speed Trade-Off?

ここでは、 Unit Testと development speedがtrade-offになるのではないか？の議論である。
結論から言うと、最初はunit test(internal quality)を導入していると、productivityは low internal qualityに比べ低い。
しかし、規模が大きくなるにつれて、internal qualityを保っていると、productivityは上がると示している。

https://martinfowler.com/articles/is-quality-worth-cost.html
java OutOfMemoryErrorとJProfiler

## JProfiler紹介
ej-technologies社が開発したJavaアプリケーションのパフォーマンス診断ツールです。
今度はJProfilerを使用してアプリケーションのパフォーマンスを診断してみます。
## インストール
JProfiler UI をインストールします：
https://www.ej-technologies.com/download/jprofiler/files
## JProfilerで診断
サンプルコード
```java
public class OOMTest {

  public static void main(String[] args) {
    int i=0;
    List<String> list = new ArrayList<>();
    String str = "OOM and GC";
    while(true) {
      list.add(str);
      str = str + str;
      i = i++;
    }
  }
}
```
実行オプション
```shell-session
-Xms5m -Xmx5m -XX:-DoEscapeAnalysis -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=C:\dengxinrong\44.JVM
```
実行結果
```shell-session
java.lang.OutOfMemoryError: Java heap space
Dumping heap to C:\dengxinrong\44.JVM\java_pid24120.hprof ...
Heap dump file created [3939064 bytes in 0.012 secs]
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
	at java.util.Arrays.copyOfRange(Arrays.java:3664)
	at java.lang.String.<init>(String.java:207)
	at java.lang.StringBuilder.toString(StringBuilder.java:413)
	at OOMTest.main(OOMTest.java:14)
```
ヒープダンプファイル
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/171dee59-d415-ca31-1094-452255f576bc.png)

ダブルクリックでJProfilerで開く
大きなオブジェクト対象が確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/82f3be0d-a98b-8580-36e6-48aa59833337.png)

エラー発生した行も確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3184769/46e7a22a-484b-a702-f969-edd43a3fad0c.png)