OmniAICreator/Qiita-1.07M huggingface dataset:
Oracle Analytics Cloud：データフローで処理を分岐する

# はじめに
Oracle Analytics Cloud（**OAC**）には、分析のためのデータセットを作る「データフロー」という機能があります。
データフローでは、元となるデータセットから列を分割・結合したり、データセット同士を結合したり、様々な処理を「ステップ」として順番に実行することができます。
この記事では、処理を分岐して単一のデータセットを2つのデータセットに分割する方法を紹介します。

# 使用するデータセット
OACのチュートリアルで公開されているSample Order Lines.xlsxを元データとして使用します。
事前にデータセットとしてアップロードしておいてください。

https://docs.oracle.com/en/cloud/paas/analytics-cloud/tutorial-create-first-visualization/#before_you_begin

# データフローの作成
OACにログインし、「作成」から「データ・フロー」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/05dca3a4-8c29-2696-ecb9-bfd292090382.png)

事前に登録しておいたデータセット「Sample Order Lines」を選択し、「追加」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/deea9360-af50-12c3-a126-0af66748aee6.png)

# 処理の分岐
追加したデータセットの右側にマウスポインタを移動して、「＋」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/52e896f3-07cb-1157-1d5f-7e37a3f94ea5.png)

メニューの中から、「分岐」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/b2a0ba0c-6122-c166-eba1-f0c113abf2c7.png)

分岐の数を指定します。今回は「2」にします。
処理が2つに分岐し、それぞれに「データの保存」ステップが自動的に追加されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/f8472995-d2c9-8aa6-b017-b481e1fe9c54.png)

分岐ステップと上のデータの保存ステップの間にマウスポインタを移動し、「＋」をクリックしてステップを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/affd0fa3-8c41-9f5b-7442-7126cf745533.png)

「フィルタ」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/1048c89a-396c-1d81-b25e-ebef912fa699.png)

「Ship Mode」列でフィルタします。選択する値は「Delivery Truck」です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/29e5830d-584b-e68a-6af4-21c83356ded1.png)

下の分岐にも同様の手順でフィルタステップを追加し、「Ship Mode」列の「Express Air」と「Regular Air」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/4d9fff68-5e9a-0ace-7c24-62a94e8ed04a.png)

# データフローの実行
上の分岐のデータの保存ステップで、データセット名を「Sample Order Lines トラック便」とします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/ad94744d-afc2-bc35-6ddc-44ea188ea368.png)

下の分岐のデータの保存ステップでは、データセット名を「Sample Order Lines 航空便」とし、データフローを「保存」します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/250037a0-93b5-f986-5ea5-797f80c2fe44.png)

任意の名称を入力します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/21ee8bd9-2022-3ca2-a792-9c424675cba1.png)

保存したデータセットを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/ca636bd7-ddca-c603-710d-3061d31ab3b0.png)

しばらくすると、データフローにより2つのデータセットが作成されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342206/ceeffa46-a8db-96fe-63c4-9019edd60fa3.png)

それぞれの内容をワークブックで確認してください。
D Wifi, d0000 に繋げているのに圏外 (No Connection) となる時の対処法

D Wifi、d0000に接続しているにもかかわらず圏外（No Connection）になる際の対処法です。

圏外表示の場合、以下のリンクを開いて強制的にログインページにアクセスしてください。

[ログインページ](https://wlan.m-zone.jp/wlan/portal.jsp)

https://wlan.m-zone.jp/wlan/portal.jsp

こちらにログインすると、通信が可能になります。便利な場合には、ショートカットを作成するかメモしておくと便利です。

```
https://wlan.m-zone.jp/wlan/portal.jsp
```

以上で終わりです。
wslでelixir その102

# 概要
wsl(wsl2じゃない)で、elixirやってみた。
練習問題、やってみた。

# 練習問題
グローバルIPアドレスを求めよ。

# 方針
- req使う。
- checkip使う。


# サンプルコード

```
Req.get!("https://checkip.amazonaws.com")
|> Map.get(:body)

```

以上。
select要素内で区切り線が使えるようになったらしい！

Chrome119からフォームのselect要素内のoptionの間に区切り線として`<hr>`が使えるようになったとのこと！

:::note warn
Safariでもすでにサポートされており、Firefox119では区切り線なしで表示されるので利用は検討が必要ですが…
:::

これまで見やすさを考慮したいために`<optgroup>`を利用してたと思いますが直感的になって嬉しい気持ちです！

```html:これまで
<select>
  <optgroup label="あ行">
    <option>あ</option>
    <option>い</option>
    <option>う</option>
    <option>え</option>
    <option>お</option>
  </optgroup>
  <optgroup label="か行">
    <option>か</option>
    <option>き</option>
    <option>く</option>
    <option>け</option>
    <option>こ</option>
  </optgroup>
</select>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/61d8c5a2-b4b5-3a1f-90ff-eaf1f83d2370.png)

```html:これから
<select>
  <option>あ</option>
  <option>い</option>
  <option>う</option>
  <option>え</option>
  <option>お</option>
  <hr>
  <option>か</option>
  <option>き</option>
  <option>く</option>
  <option>け</option>
  <option>こ</option>
</select>
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/146612/08411243-829c-618f-4b7b-f69ceaa57ed1.png)

## まとめ
選んだ例が良くなかった気がしますが…。
フォーム関連のデザインはこれまで制約が多かったところ表現の選択が広がったのは良いことだと思いました！

項目が多いと高さが出てしまうのでそんな時には選択としてありかもしれません！
YAMLについて簡単なまとめ

はじめに
---
この記事では、YAMLについてまとめていきたいと思います。
大まかな概要をまとめているので、より詳しく知りたい方は参考のURL先がおすすめです。

目次
---
1. YAMLとは？
1. 読めるようになってみよう
1. 書いてみよう
1. まとめ

# YAMLとは？

読み方はヤムル、拡張子は.yml(.yaml)

データシリアライズ言語の一種で、YAMLは略称、正式名称は"**Y**AML **A**in't **M**arkup **L**anguage"。

直訳は「YAMLはマークアップ言語じゃない」
XMLの進化系とか言われがちだけど、マークアップ言語ではない。

そして公式の説明は「すべてのプログラミング言語にとって人間に優しいデータシリアル化標準」
公式いわく、簡単に理解ができると思う。
XMLとかJSONとか一回やったことあると特に分かりやすいかもしれない。

# 読めるようになってみよう

書くためには、まず読めるようになってみよう。
何も知らない状態でも雰囲気でなんとなくわかる気もする。

<問題①>
```yaml 
fruits:
 - apple
 - banana
 - orange
```
詳しくは分からなくても、なんとなくわかる気がすると思う。
　
問題①はフルーツという括りの中にりんご、バナナ、オレンジの三つが格納されている、ということになる。


では次の問題を読んでみよう。

<問題②>
```yaml 
#従業員名簿
employees:
 - name: "Tanaka Tarou"
   age: 30
 - name: "Yamada Hanako"
   age: 25
```

さっきと同じで、従業員という括りの中に、タナカタロウ(30),ヤマダハナコ(25)がいる、となります。

さすが人間に優しいと公式で言っているだけあってめちゃくちゃ読みやすい。
なんとなーーくわかったと思うので、もっと細かくYAMLのデータについてまとめる。


# 書いてみよう
書くために、先ほどの問題②を例に用いて詳しく書いていく。

### ハッシュ(マッピング)
まず、データは`キー`と`値`があり、`:`で区切って、**キー: 値**で記述されている。
配列が混ざってくるからややこしくなるだけですべてこの形での記述になる。
先ほどの問題だとキーが`name`で値が`"Tanaka Tarou"`になっている。

:::note warn
【記述の際の注意事項】
`:`の後は**半角スペース**を忘れないこと
:::

### 配列(シーケンス)
順序付けて保持するデータ型、**配列**
記述する際には`-`を用いる
先ほどの問題の答えを正しく言い直すと、「従業員という**配列**の中に、タナカタロウ(30),ヤマダハナコ(25)がいる」になる。

先ほどの記述の仕方はブロック型。
横書き１行（フロー型）でも記述できるらしいけど、頻度は低いと思うので今回は省略する。

:::note warn
【記述の際の注意事項】
`-`の後は**半角スペース**を忘れないこと
:::

配列やハッシュのように、他の要素を持つデータ型をコレクションと呼ばれ、それ以外のデータはスカラーと呼ばれる。
コレクション型はどちらも**ずっとネスト（入れ子構造）することができる**。

### 値(スカラー)
他の要素を持たないのでスカラー。
YAMLは値を自動的に判別してくれる。整数や浮動小数点、真偽地以外は文字列として認識される。
使用頻度の高い、数値と文字列以外の値については省略する。

##### 数値
整数や浮動小数点などの数値はそのまま記述するだけで表現できる。
キー`age`の値`30`は数値の「30」として表現されている。
##### 文字列
値は`"(ダブルクォーテーション)`、もしくは`'(シングルクォーテーション)`で囲むことで文字列として強制的に文字列として認識させる。
先ほどの`"Tanaka Tarou"`も文字列として認識されている。

### コメント
コメントは`#`をつけると以降のその行の文字すべてがコメントと認識される。

:::note warn
【記述の際の注意事項】
**その行すべてがコメント行と認識される**ので気を付けなければならない。
:::

<例>
```yaml 
#従業員名簿　ここはコメント行、こちらは特に問題なし
employees: #従業員　←こう書いてしまうと、行すべてがコメントとなるので、employeesは無効となる。
 - name: "Tanaka Tarou"
   age: 30
 - name: "Yamada Hanako"
   age: 25
```

# まとめ
:::note warn
【記述の際の注意事項】
* ハッシュ　
 　`:`の後は**半角スペース**を忘れないこと
* 配列
 　`-`の後は**半角スペース**を忘れないこと
* コメント
　**その行すべてがコメント行と認識される**

 〇インデントは揃える
:::

〇YAMLってそんなに難しくない


# 参考
https://magazine.rubyist.net/articles/0009/0009-YAML.html

https://yaml.org/spec/1.2.2/
GitHub Copilot 導入で開発者の満足度が向上！プルリクエスト数も増加したデータ公開

ゆめみでは全社的に GitHub Copilot の利用を推進しています。
ただGitHub Copilot Businessを全社的に導入する前に１つのプロジェクトで先行して導入実験を行っておりました。

このプロジェクトでGitHub Copilot の満足度アンケート（NPS調査）とFindyTeam＋の調査を行ったので結果を共有してみようと思います。
導入しようか検討されている場合のご参考になれば。

# ゆめみの GitHub Copilot 導入後のNPS(PSJ)およびFindyTeam+の調査結果
以下NPS(PSJ)のアンケート内容と結果です。
- 計算方法はNPSの日本版の計算式であるPSJを採用しております。( -100 〜 100 )
    - 点数 0〜10点で各項目を評価
        - ※計算式：（推奨者 − 批判者）／全体人数 × 100
            - 推奨者：８点以上
            - 中立：５〜７点
            - 批判者：４点以下

# 総合PSJ: 45.8


|質問 | PSJ値 |
|:-----------|------------:|
|GitHub Copilotを利用して、どれくらい満足していますか？|75|
|GitHub Copilotを使用することで、プロジェクトの生産性が向上しましたか？|75|
|GitHub Copilotを導入する前と比べて、コードの品質やセキュリティに関して向上を感じていますか？|37.5|
|GitHub Copilotを導入したことでテストコードのカバレッジが向上したと感じますか？|0|
|GitHub Copilotを導入したことでドメインについて熟慮する時間は増えましたか？|0|
|あなたはGitHub Copilotを同僚や友人におすすめしますか？|87.5|

以下 メンバーの感想をまとめメリット・デメリットを記載しました。

## メリット

- 単純な入力が自動生成されることで、作業効率が大幅に向上しており、全体として非常に助かっている。
- ダミーデータの作成や同じような実装を繰り返す時に自動補完してくれるため、時間節約につながる。
- コード補完を頻繁に行ってくれるため、特定のコードの補助だけでなく全体的にコード作成がスムーズになる。
- コメントなど日本語を考える部分でも補完してくれて便利である。
- NPS(PSJ)の結果を見ると、GitHub Copilotの満足度とプロジェクトの生産性、友人に推奨するかどうかのスコアは高い。

## デメリット

- Copilotの適切な使い方を覚えないと、使えないコードが提案されるという感覚がある。
- 類似の実装があまりない場所については頻繁に間違った候補が出てくるため、間違った推薦があると煩わしい。
- プロジェクト内のコードに引っ張られている感覚が強く、テストコードではCopilotからの提案が漏れを防ぐことはあるが、それがプロジェクト全体の効率改善に直結するわけではない。
- NPS(PSJ)の結果を見ると、コードの品質やセキュリティの向上、テストコードのカバレッジ向上、ドメインについて熟慮する時間が増えたかどうかのスコアは低い。

# Findy Team+
![findy Team+.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/41761/5cc838aa-1d34-8aa8-6920-71388759d1e1.jpeg)
## 分析
- GithubCopilot導入後、**１日の１人当たりのプルリク数が1.2から2.1に増加**
    - 導入前はおおよそ0.8~1で推移している
    - その後一番低い時点でも1.3でおおよそ1.6くらいを目処に推移
- プロジェクト開発を促進するために増員を２回行っておりGithubCopilotのみの影響ではないが開発に貢献している可能性はある。


# 総評

結論として、GitHub Copilotはエンジニアリングにおける効率・生産性向上に対して大きなメリットを提供していることが確認できます。

特に単純な入力やダミーデータの自動生成、日本語コメントの補完など、エンジニアの手間を省き作業効率を向上させることが評価されています。

しかし一方で、その使用方法を完全に理解しコントロールするまでの学習曲線や、一部のコード提案の精度に関する問題点も指摘されています。

テストコードのカバレッジやドメイン熟考の時間増加については現時点での効果を実感していないエンジニアも一定数おられます。

これはCopilotの能力や使用方法、またはエンジニアの期待とのギャップかもしれません。

Findy Team+の情報からも一人当たりのプルリク数の向上も見られることから一定の貢献は予想されます。ただしプロジェクト改善の影響もあり誤差の範囲の可能性も少し残っています。

これらの点も含めた使い方の共有や、これらの課題を解決するための新たな機能提供などが期待されます。

全体的には、GitHub Copilotはエンジニアリングの生産性を向上させる有用なツールであることが確認できましたが、さらなるパフォーマンス向上とユーザーエクスペリエンス改善が求められることも明らかになりました。

# 余談
- GitHubからも導入に関する調査報告がありました。
  - 概ね同じ用な印象を持っています
  - https://github.blog/2023-10-10-research-quantifying-github-copilots-impact-on-code-quality/
- ゆめみではGithub Copilotなど生産性向上を目的としたAI支援について推進しています。
  - ただしクライアント側でAIの利用が禁止されている場合は利用しておらず、プロジェクトの状況に合わせて実施しております。
頼みの綱AWS Support

# はじめに
S3+CloudFrontやserverless deployなどの構成で開発することになったものの、未経験のためかなり苦戦しました。詰まっていることを上司に相談していたところ、AWSサポートという存在を教えていただきました。

# 頼みの綱AWS Support
会社とAWSでSupportを利用できる契約をしているとのことでしたので、有難く利用させていただきました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/487a1e04-0719-5445-3206-6fefd447c523.png)

早いと翌日に回答が返ってきますが、事象の再現に情報が不足していると改めて返信する必要があります。
このやり取りだけで2営業日などをかけているともったいないので、事象の再現に必要な情報はできる限り添付しましょう。

最後に実際の問い合わせ例を挙げます。

## 問い合わせ例 

### Q.複数のbuildファイルをアップロードしてそちらに対してアクセスできるようにしたい。オリジンパスにワイルドカード（source/*/build）を設定することは可能か？

### A.オリジンパス設定にワイルドカードを使用することはできない
---

### Q.serveless deployを実行するとCREATE_FAILED: BucketPolicyが発生する。

### A.ブロックパブリック設定が有効化の場合、新規にパブリックアクセスを許可するポリシーを設定することができない。認証情報の権限有無に限らずポリシーの設定が失敗する。

# おわりに
苦戦していた中、このようなサービスを知ることができて良かったです。
3. Longest Substring Without Repeating Characters

### 例
```python
Input: 
    s = "pwwkew"
Output: 
    3
Explanation: 
    The answer is "wke", with the length of 3.

```

### CODE
```python
def lengthOfLongestSubstring(s):
    left, max_length = 0, 0
    substring = set()
    for right in range(len(s)):
        if s[right] not in substring:
            substring.add(s[right])
            max_length = max(max_length, right - left + 1)
        else:
            # ifではなくwhile
            while s[right] in substring:
                substring.remove(s[left])
                left += 1
            # 結局、右要素をaddする
            substring.add(s[right])
            
    return max_length
```
```set()```で初期化ができて、```add```・```remove```で処理する。
57. Insert Interval

#### 例
```
Input: 
    intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]]
    newInterval = [4,8]
    
Output: 
    [[1,2],[3,10],[12,16]]

Explanation: 
    Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10]

```

### CODE
```python
def insert(intervals, newInterval):
    left, right = [], []
    newStart = newInterval[0]
    newEnd = newInterval[1]
    for i in intervals:
        if i[1] < newStart:
            left.append(i)
        elif i[0] > newEnd:
            right.append(i)
        else:
            newStart = min(i[0], newStart)
            newEnd = max(i[1], newEnd)
    middle = [[newStart, newEnd]]
    return left + middle + right

```
AI-102試験対策のまとめ「ビデオファイルから分析情報を取得」

## はじめに
Azure AI Engineer Associate(AI-102)取得に向けた勉強でまとめた内容を本記事では投稿しています。
試験範囲の内容を私が勉強していく中で、
・忘れてしまっていた内容
・他の知識と絡めて理解した方が良い内容
・Microsoft Learnの読解に苦戦した内容
などをできるだけ分かりやすく簡潔にまとめることを意識しています。
Azureの勉強を一から始め、AI-102取得を目指している方の参考になれば幸いです。
※本記事の内容が必ず試験に出るわけではないこと、ご注意ください
※勉強しながら投稿しているため、追加で学んだことがあれば随時投稿内容を更新します。

## 試験対策のまとめ
### ビデオファイルから分析情報を取得
この機能が役立つシナリオ例
* 予告編用の映画ハイライトの作成
* ニュース番組でビデオの古いクリップを使用
* ソーシャルメディア用に短いコンテンツを作成

#### **新しいプロジェクトの作成**
1. [Azure AI Video Indexer](https://www.videoindexer.ai/)Webサイトにアクセスし、サインインする
1. 「プロジェクト」タブを選択
1. 「新しいプロジェクトの作成」を選択
1. 鉛筆アイコンを選択し、プロジェクトの名前を設定

#### **プロジェクトにビデオを追加**
※現在、プロジェクトに同じ言語でインデックス付けされたビデオのみ含めることが可能
1. 「ビデオの追加」を選択  
    ※アカウント内のすべての動画と検索ボックスが表示される
1. 「追加」を選択してビデオをプロジェクトに追加

#### **プロジェクトで使用するクリップを選択**
各ビデオの右側にある下向き矢印を選択すると、タイムスタンプ(ビデオのクリップ)に基づいてビデオ内の分析情報が表示される
1. 特定のクリップのクエリを作成する場合は、検索ボックスを使用
1. 「分析情報の表示」を選択して、表示したい/したくない分析情報をカスタマイズ
1. 「フィルターオプション」を選択してフィルターを追加し、探しているシーンの詳細を更に指定  
    ※複数フィルター追加可能
1. 結果に満足したら追加するセグメントを選択し、このプロジェクトに追加するクリップを選択

#### **プロジェクトをレンダリングしてダウンロード**
1. プロジェクトが保存されていることを確認
1. 「レンダリング」を選択し、「続行」を選択
1. レンダリングが完了するとプロジェクトが正常にレンダリングされたことを示す通知が表示
1. 通知を選択してプロジェクトをダウンロード(mp4形式)

* 参考
    - https://learn.microsoft.com/ja-jp/azure/azure-video-indexer/use-editor-create-project


## 次の試験対策のまとめ
* **AI-102試験対策のまとめ「Custom Vision Serviceのモデルのエクスポート」**

https://qiita.com/fsd-jume/items/4c6bb2c3b99bbd4538b8

## 学習内容をまとめたページの一覧

https://qiita.com/fsd-jume/items/65aba5d5514e023fd66d
[SwiftUI]条件分岐でViewを変える方法

# ボタンを押したらビューが切り替わる方法

```swift
import SwiftUI

struct IscheckedView: View {
    //完了したかどうかのIsCheckedという変数
    @State private var IsChecked = false
    
    var body: some View {
        VStack{
            Button {
                //IsCheckedを切り替える
                self.IsChecked.toggle()
            } label: {
                Text("切り替えるよ")
            }
        }
    }
}
```

IsCheckedという変数を用意し、IsCheckedを切り替えるToggleを用意します。

そこで切り替わった時には、文章で「チェックされたよ」↔︎「未チェックだよ」という文章にしようと思います。

この時、if文の条件分岐でそれぞれ書き分けることができます。
```swift
import SwiftUI

struct IscheckedView: View {
    @State private var IsChecked = false
    var body: some View {
        VStack{
            //isCheckedが真の時
            if(IsChecked){
                Text("チェック済みだよ")
            //isCheckedが負の時
            }else{
                Text("未チェックだよ")
            }
            Button {
                self.IsChecked.toggle()
            } label: {
                Text("切り替えるよ")
            }
        }
    }
}
```

また下のように、三項演算子で書くこともできます！


```swift
import SwiftUI

struct IscheckedView: View {
    @State private var IsChecked = false
    var body: some View {
        VStack{
            IsChecked ? Text("チェック済みだよ") : Text("未チェックだよ")
            Text(IsChecked ? "チェック済みだよ":"未チェックだよ")
                
            Button {
                self.IsChecked.toggle()
            } label: {
                Text("切り替えるよ")
            }

        }
    }
}
```

またモディファイヤーを変えることもできます！
例えば。。。

```swift
import SwiftUI

struct IscheckedView: View {
    @State private var IsChecked = false
    var body: some View {
        VStack{
            Text("完了かなあ")
                //三項演算子でモディファイヤーを変える
                .foregroundColor(IsChecked ? .red : .green)
            ToggleView(IsChecked: $IsChecked)
        }
    }
}

struct ToggleView: View {
    @Binding var IsChecked: Bool
    var body: some View {
        VStack{
            Button {
                self.IsChecked.toggle()
            } label: {
                Text("切り替えるよ")
            }

        }
    }
}
```
これで、ボタンを押すことで、文章の色が赤↔︎緑に変わります。

このように、三項演算子やif文を使うことで、見た目や文章を変えることができるのです！
空の配列を渡すとTrueが返される理由をなるべく簡潔に説明する


# 結論

「配列が持つ要素がなんちゃら」を判定する関数は
「配列に要素が存在するならば、それらの要素がなんちゃら」を判定する関数と解釈でき
配列に要素が存在しない場合、前件が偽となるためvacuous truth[^1]で真となる。

[^1]:[空虚な真 - Wikipedia](https://ja.wikipedia.org/wiki/%E7%A9%BA%E8%99%9A%E3%81%AA%E7%9C%9F)

# この記事を書こうと思ったきっかけ

https://qiita.com/nextvision-sugakir/items/6e2069cd9d6a704a3d0c
2023/11/14主にITとかセキュリティの記事

ChatGPTでデータベースに侵入　機密情報を漏えいさせるコードを生成　英国と中国の研究者らが実証(11/12)
https://www.sankei.com/article/20231114-N6DCN3EFHBJXXPHZOU5NM5H3RA/

中国背景の刺客「ブラックテック」　支社・子会社から機密情報を狙い撃つ「槍」(11/12)
https://news.yahoo.co.jp/articles/36f115e6b8d268a251d2152993c6c7b04908ce2a?source=rss

入力履歴、位置情報など5つのオプションから選べる！iPhoneのリセット機能の正しい使い方(11/12)
https://gunosy.com/articles/aQVKK

ハッキングされないパスワード生成カード「PassCard」(11/12)
https://news.livedoor.com/article/detail/25337133/

ブッキング・ドットコム悪用して客のカード情報盗む　世界規模で被害(11/11)
https://news.yahoo.co.jp/articles/560faaa66a57bdef2362e8ac2c9bded0bb43f70f

AIをコントロールするために、暗号資産から学べること（あるいは暗号資産業界ができること）(11/12)
https://www.coindeskjapan.com/187964/

アクティビストが企業攻撃にAIを使用！株主総会の「質問」も「答え」も両方自動生成する時代に…株式市場に巨大インパクト(11/12)
https://mag.minkabu.jp/politics-economy/21453/

木澤佐登志『闇の精神史』から考える、「持続可能」以外の未来像(11/12)
https://news.yahoo.co.jp/articles/2311e9e9f4d85f5c0c57f0f790e40f1951d38a2c?source=rss

7割超のフィッシングはDMARCで止める、すり抜けたメールにも多層防御で対抗(11/13)
https://xtech.nikkei.com/atcl/nxt/column/18/02631/110900008/

ユーザー名とパスワードが正しいのにNASが利用不能に、NTLM認証廃止の波紋(11/13)
https://xtech.nikkei.com/atcl/nxt/column/18/00001/08610/
Docker をwindowsでインストールしたい

# 概要
Docker をwindowsでインストールする方法をまとめます。

# Docker Desktop for Windowsをインストールしよう！
以下のURLからインストールすることができます。

https://docs.docker.com/desktop/install/windows-install/

以下にある画像の"Docker Desktop for Windows"という青いボタンを押してください。

![スクリーンショット 2023-11-11 173102.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709775/56cc8486-783d-db81-5b7f-f7c5682a38a9.png)

以下のように表示されますがOKを押してください。

![スクリーンショット 2023-11-11 173532.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709775/9bc7b74c-cf85-332e-e2d3-188a606dce41.png)


しばらく待つとインストールが完了し、
以下の画面が表示されますので、acceptを押してください

![スクリーンショット 2023-11-11 191332.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709775/078efc36-0282-bee4-43aa-6391dcf2be78.png)

一旦はfinishで大丈夫です。

![スクリーンショット 2023-11-11 191447.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709775/7dca7564-8863-19c3-d6cd-ed8928726596.png)

Sign upを押してサインアップしてください。

![スクリーンショット 2023-11-11 191524.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709775/ad3c73b9-1e02-b3a6-4fb2-53be89060038.png)

以下、設定画面。
![スクリーンショット 2023-11-11 191545.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709775/813c796f-a5a8-2849-87ec-8b048e1e2a3e.png)

設定がおわり、サインインすると以下の画面になります。

![スクリーンショット 2023-11-11 191926.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2709775/727d105a-c30f-fbea-3612-96a415d7af79.png)

これでDocker Desktop for Windowsのインストールの完了です。

# インストールできたか確認

```
$ docker version
Client:
 Cloud integration: v1.0.35+desktop.5
 Version:           24.0.6
 API version:       1.43
 Go version:        go1.20.7
 Git commit:        ed223bc
 Built:             Mon Sep  4 12:32:48 2023
 OS/Arch:           windows/amd64
 Context:           default

Server: Docker Desktop 4.25.0 (126437)
 Engine:
  Version:          24.0.6
  API version:      1.43 (minimum version 1.12)
  Go version:       go1.20.7
  Git commit:       1a79695
  Built:            Mon Sep  4 12:32:16 2023
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          1.6.22
  GitCommit:        8165feabfdfe38c65b599c4993d227328c231fca
 runc:
  Version:          1.1.8
  GitCommit:        v1.1.8-0-g82f18fe
 docker-init:
  Version:          0.19.0
  GitCommit:        de40ad0
```

ちゃんとできているみたいですね！
おつかれさまでした！
Azure で設定したアラートを全部出す方法

「すべてのリソース」というマネージド・サービスの横断で全部の作ったリソースが表として出て、簡単なフィルターが使えるものがあり、ごちゃ混ぜ感がすごくて最初驚いたけど、使ってみると思いの外すごく便利。マネージド・サービスがたくさんあるのであれ作ったやつどこだっけな？がだいぶ解消されるのと、あっこのサービスは裏でこんなの生成しているんだってのがリンクを頑張って掘って探さなくてもわかるのが嬉しい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18843/165579d6-942b-942a-5510-d30b70e6312f.png)

---

全く同じような話で、全部のアラートは？というアラートに絞った状態で欲しい場合がある。実はこれもあるらしい。[Azure ポータル](https://portal.azure.com/) -> 左のメニューから[モニター] -> [アラート] -> [アラート ルール] -> [クエリを開く] -> [クエリの実行]
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18843/eeb590bc-f12d-3176-2606-b13a78c33817.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18843/85fdf509-185e-7ca5-ebd7-058ed28cdc23.png)


```kql
resources
| where type in~ ('microsoft.insights/metricalerts','microsoft.insights/scheduledqueryrules') and ['kind'] !in~ ('LogToMetric','LogToApplicationInsights')
| extend severity = strcat("Sev", properties["severity"])
| extend enabled = tobool(properties["enabled"])
| where enabled in~ ('true')
| project id,name,type,properties,enabled,severity,subscriptionId
| union (resources | where type =~ 'microsoft.alertsmanagement/smartdetectoralertrules' | extend severity = tostring(properties["severity"])
| extend enabled = properties["state"] =~ 'Enabled' | where enabled in~ ('true') | project id,name,type,properties,enabled,severity,subscriptionId), (resources | where type =~ 'microsoft.insights/activitylogalerts' | extend severity = "Sev4"
| extend enabled = tobool(properties["enabled"]) | mvexpand innerCondition = properties["condition"]["allOf"] | where innerCondition["field"] =~ 'category'
| where enabled in~ ('true') | project id,name,type,properties,enabled,severity,subscriptionId)
| order by tolower(name) asc
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18843/dfcb2fe6-ac49-07e9-31f4-cdbd40acc10d.png)
【C#・WPF備忘録】exeにdllを埋め込む方法3つ試した

仕事でC#アプリケーションを開発していたら、**exeファイル単体でどこでも好きな場所に配置して実行できるようにしたい**という要望がありました。

しかしそのアプリはdllを複数参照していて、通常なら exeと同じ階層にdllを配置していないと動きません。

そこで**exeにdllを埋め込む**ような形で**単一で動作するexeファイルの作成方法**を調査しました。

# <font color="6495ed">開発環境</font>

C# 6.0
.NET Framework 4.6.2
Visual Studio 2015
WPF

少し古い環境でしょうか。。でも仕事だとこんなこと結構ありますよね(?)
次に紹介する3つの方法のうち、ネット検索でたくさんヒットする1つ目と2つ目の方法では動作せず、途方に暮れていました…。

# <font color="6495ed">exeにdllを埋め込む方法3つ</font>

### <font color="#fab387">1. Costura.Fodyを使う方法</font>

https://marunaka-blog.com/c-sharp-embed-dll-file/2224

Costura.Fodyは3つの中で最新の方法です。

Nugetパッケージをインストールするだけで環境が整うので手軽です。
(設定をカスタマイズしたい場合はプロジェクト直下に FodyWeavers.xml を作成する必要があります。)

ビルドするとdllが生成されず、exeの中に埋め込まれる！
…ということですが私の環境で行ったところ、残念ながら埋め込まれませんでした。

参考記事では Visual Studio 2017 以上を前提としていますが、私の環境は Visual Studio 2015。**Costura.Fodyは古いバージョンの Visual Studio には非対応なのかもしれない**と思いました。

### <font color="fab387">2. ILMergeを使う方法</font>

https://goodlife.tech/posts/ilmerge.html

ILMergeは旧来から存在する方法です。

Nugetパッケージとソフトウェアの2つの形式があり、好きなほうを選択できます。

※ソフトウェアとしてインストールする場合、[【こちらのGitHubページ】](https://github.com/mono/nuget/blob/master/Tools/ILMerge/ILMerge.msi)で"Raw"をクリックするとmsiをダウンロードできます。

ILMergeを使うにはビルド後にコマンドを実行する必要があります。(自動化は可能)
コマンドを実行すると、ビルドで生成されたファイルをもとに、exeがもう1つ生成されます。これにはdllが埋め込まれています。

私の環境で試してみると、このexeは生成されたものの、実行してみると「リソース"View/MainView"を検索できません。」というエラーが発生してしまいアプリを起動できませんでした。

その後[こちらの記事](https://cointoss.hatenablog.com/entry/2017/02/21/121209)で、**ILMergeはWPFでは使えない**ということを知りました。XAMLリソースに対応していないということですが、上記のエラーも確かにそれっぽい内容です。

### <font color="fab387">3. 埋め込みリソースにする方法</font>

https://cointoss.hatenablog.com/entry/2017/02/21/121209

dll以外の拡張子のファイルもexeに埋め込むことができる万能な方法です。

しかも環境設定も、やってみると思ったより簡単。
Nugetパッケージのインストールが不要な点も良いかも。

① csprojファイルに、参考記事どおりコピペする。
② Program.csを作成し、参考記事どおりコピペする。(足りないパッケージはusing必要)
③ プロジェクトの設定で、スタートアップオブジェクトにProgram.csを指定する。


ビルドするとdllも生成され、一見いつも通りに思えますが、exeにはdllが埋め込まれています。これをデスクトップに配置して実行すると見事正常に動作しました！

というわけで**埋め込みリソースにする方法**でなら、**Visual Studio 2015 / WPF** の環境でも**exeにdllを埋め込むことができました**(´；ω；`)♡

ご自身の開発環境ややりたいことに合わせて方法を選んでみて下さい。
MySQLデータベースを40秒で支度する

# 必要なもの
* Docker
* ネット環境
* お好みのDBクライアント(ここではDBeaverを利用）
* bashかzshが実行可能な環境（MacとLinuxで確認 Windowsはwslを利用する）

# 手順

* テキトーなディレクトリにdocker-compose.ymlファイルを作成して開く
```yml:docker-compose.yml
version: '3.8'
services:
  mysql:
    image: mysql:latest
    container_name: mysql-container
    environment:
      MYSQL_ROOT_PASSWORD: password
      MYSQL_DATABASE: mysqldb
      MYSQL_USER: user
      MYSQL_PASSWORD: password
    volumes:
      - ./db/data:/var/lib/mysql
    ports:
      - "3306:3306"


```
```bash:ターミナル
docker compose up -d
```
* DBクライアントを開いて以下接続設定で空っぽのDBが開けるはず
    * DBeaverの場合はドライバのプロパティタブからallowPublicKeyRetrievalをTrueにしておく 
        * user：`user`または`root`
        * pasword:`password`
        * port: 3306
* 停止するときは以下コマンドを実行
    * DBコンテナが消えるが編集したDB内データは`./data`ディレクトリに同期する設定にしてあるため停止しても消えない
```bash:ターミナル
docker compose down
```
* 再度起動するときは`docker compose up -d`でOK

# トラブルシューティング

* `Error response from daemon: Conflict. The container name "/mysql-container" is already in use by container "・・・". You have to remove (or rename) that container to be able to reuse that name.`
    * 既に同じ名前のコンテナが出来上がっている場合のエラー
    * 以下コマンドを実行
        ```bash 
        docker system prune
        ```
UnityのTextMeshProのLinkタグで、長いURLを扱う


UnityのTextMeshProでサポートしているタグは
開始終了のタグ自体を含めて128バイトのバッファで解析を管理されているようで、
例えばLinkタグで長いURLを扱おうとするとパースが途中で終了して
表示がおかしくなってしまう。

これは以下のようにURLを短縮して対策できる。

1. ITextPreprocessor継承クラスで、元のテキストを変換できる
2. URLをRegexで拾って、元のテキスト内のURLに対して短い文字列で変換をかけつつ辞書を作る
3. Clickイベント発火時にLinkInfo.GetLinkIDと比較して元の値を取得する

# ITextPreprocessor継承クラスで、元のテキストを変換

ITextPreprocessorは、対象のTextMeshProGUIのテキストが更新された時に、
元のテキストを受け取って変換したテキストを返却することができる。

```csharp
private class TextPreprocessor : ITextPreprocessor
{
    public string PreprocessText(string text)
    {
        return text;
    }
}
```

```csharp
TextMeshProUGUI m_TextMeshProGUI;
TextPreprocessor m_TextPreprocessor = new TextPreprocessor();

if (TryGetComponent(out var m_TextMeshProGUI)){
  m_TextMeshProGUI.textPreprocessor = m_TextPreprocessor;
}
```

# URLをRegexで拾って、元のテキスト内のURLに対して短い文字列で変換をかけつつ辞書を作る

元のテキスト内のURLテキストを正規表現で検出し、
短い文字列と入れ替えながら、それをキーとした辞書を作成する。

```csharp
private class TextPreprocessor : ITextPreprocessor
{
    private const string UrlRegexPattern = @"https?://[\w!\?/\+\-_~=;\.,\*&@#\$%\(\)'\[\]]+";

    public Dictionary<string, string> ShortenUrlMap { get; private set; } = new();

    public string PreprocessText(string text)
    {
        ShortenUrlMap.Clear();

        var matches = Regex.Matches(text, UrlRegexPattern);
        foreach (var match in matches.Select(x => x.Value).Distinct())
        {
            var key = $"{ShortenUrlMap.Count}";
            text = text.Replace(match, key);
            ShortenUrlMap.Add(key, match);
        }

        return text;
    }
}
```

# Clickイベント発火時にLinkInfo.GetLinkIDと比較して元の値を取得する

上記で変換されたキーはそのままLinkIDとして入っているので、
作成済みの辞書から元の値を取得する。

```csharp
// IPointerClickHandler継承クラスで、Linkタグ部分へのクリック判定をする場合
public void OnPointerClick(PointerEventData e)
{
    var linkInfos = m_TextMeshProGUI.textInfo.linkInfo;
    if (linkInfos.Length <= 0)
    {
        return;
    }

    var index = TMP_TextUtilities.FindIntersectingLink(m_TextMeshProGUI, e.position, e.pressEventCamera);
    if (index < 0)
    {
        return;
    }

    var linkInfo = linkInfos[index];
    var linkId = linkInfo.GetLinkID();

    if (m_TextPreprocessor.ShortenUrlMap.TryGetValue(linkId, out var url))
    {
        Application.OpenURL(url);
    }
}
```
iOSでのレイアウト崩れ問題とその対処法


## 事象

Next.js と Tailwind CSS を使用してiOS向けのレスポンシブ対応を行っている際に、mainタグにh-screenを適用してもiOSのアドレスバーが画面下部に表示されることでレイアウトが崩れる現象が発生しました。

## 対処法

この問題の原因は、iOSでのビューポートの高さ (vh) が動的に変化するため、アドレスバーの表示によってビューポートの高さが変わり、それがレイアウト崩れを引き起こしていました。これを解決するためには、Tailwind CSSの設定を以下のように変更します。この設定では、標準のビューポート高さ (vh) ではなく、ダイナミックビューポート高さ (dvh) を使用しています。

```tailwind.config.ts
module.exports = {
  theme: {
    extend: {
      // Solutions for Safari address bar display issues
      height: {
        screen: ["100vh", "100dvh"],
      },
      minHeight: {
        screen: ["100vh", "100dvh"],
      },
      maxHeight: {
        screen: ["100vh", "100dvh"],
      },
    },
  },
};
```

## vh と dvh の違い

vh (Viewport Height) はビューポートの高さの100分の1を指し、画面の可視領域を基に計算されます。一方、dvh (Dynamic Viewport Height) はiOSデバイスにおける動的なビューポートの高さを指し、アドレスバーやツールバーの表示による高さの変化を考慮に入れた値です。iOSではアドレスバーの表示によってビューポートの高さが変わるため、dvh を使用することでこれらの変化に柔軟に対応できます。

## 参照

主にこちらの記事を参考にさせていただき、
とても助かりました！ありがとうございます！

https://zenn.dev/futa/articles/90d7410650a73e
https://zenn.dev/cti1650/articles/4d36c8a667f88a

自らの備忘録のために投稿してますが、なにかお役に立てましたら幸いです！:clap:
また、なにか間違ってましたらご指摘いただけますと幸いです！:pray:
AtCoder ABC 322 C-Festival Pythonで愚直解から最適解まで考えてみる

## 問題概要

https://atcoder.jp/contests/abc322/tasks/abc322_c

この問題は単純に線形探索で解こうとすると2重ループになり、実行時間制限の２秒を超えてしまう。
そのためどうにかして2重ループを避ける必要がある。

## 愚直解

まずは愚直解。というか私は最初この方法で解いてしまった。

```python
N, M = map(int, input().split())
A = list(map(int, input().split()))

#　後続の処理でAの要素（花火が上がる日）を探索したいためlistをsetに変換
hanabi_day_set = set()
for i in range(M):
    hanabi_day_set.add(A[i])

# 花火が上がる日をTrue, そうでない日をFalseをセット
day_flg_list = [False] * (N + 1)
for i in range(1, N + 1):
    if i in hanabi_day_set:
        day_flg_list[i] = True

# １日目からN日目まで線形探索して、i日目から何日後に花火が上がるか確認する
for i in range(1, N + 1):
    count = 0
    for j in range(i, N + 1):
        if day_flg_list[j]:
            print(count)
            break
        else:
            count += 1
```

この方法だとforの二重ループを使っているため、計算量はO(N^2)かかる。このように単純に実装してしまったらTLEになる。

## 改善案

計算量O(N)でどうやって実行できるか考えてみる。
愚直解の外側のループについては、N個の要素に対して花火は上がるのか、上がらないのかを確認する必要があるため、残す必要がある。
よって内側のループをもう少し最適化できないか考えてみる。
見直してみると、愚直解の内側のループは各要素から次の要素までどれくらい離れているか要素を一つずつ辿っていっている。実はここを一つ前の結果を使ってその日が次花火が上がる日からどれくらい離れているかを求めることができる。
今回は後ろから要素を見ていき、もし花火が上がる日であれば0を追加、もしそうでなければ前の要素+1日を足した要素を追加する。そして最後に逆順に並び替える。
そうすることで各要素を辿らず、O(1)で計算することができる。

以下、解答例。

```python
N, M = map(int, input().split())
A = list(map(int, input().split()))

hanabi_day_set = set()
for i in range(M):
    hanabi_day_set.add(A[i])

day_flg_list = [False] * (N + 1)
for i in range(1, N + 1):
    if i in hanabi_day_set:
        day_flg_list[i] = True

#　後ろの要素から見ていって、花火が上がる日であれば0、そうでなければ最後に確認した要素から1足した値を設定する
ans_list = [0]
for i in range(N - 1, 0, -1):
    if day_flg_list[i]:
        ans_list.append(0)
    else:
        ans_list.append(ans_list[N - i - 1] + 1)

# 最後に逆順に並び替えて、出力する
rev_list = list(reversed(ans_list))
for i in range(N):
    print(rev_list[i])
```

参考

https://drken1215.hatenablog.com/entry/2023/10/02/140500

## 別解

この方法はある日にち（1日目、2日目…）を基準にして、その日にちがどれくらい次花火が上がる日から離れているのか計算している。

この方法も内側のループはO(1)で実行可能である。

```python
N, M = map(int, input().split())
A = list(map(int, input().split()))

day = 1
for i in range(M):
    while A[i] - day >= 0:
        print(A[i] - day)
        day += 1
```

## まとめ
今回やってしまった愚直解は、要素を一つずつ辿ってどれくらい離れているかを確認していたのがよくありませんでした。まあ今回のような問題で配列の要素を一つずつ見ていくようではそりゃTLEになりますよね。。
今回の問題から前の計算結果を使って次の値を計算することで、計算量をO(1)にすることを頭の片隅に入れておきたいと思いました。
MacでDocker Desktopをターミナルからコマンドのみでバックグラウンド起動する

# 事前設定

* Docker Desktopを開いて右上の歯車マーク→左ペインのGeneral→Open Docker Dashboard at startupのチェックを外しておく
    * update後に勝手にチェックが外れていることがある・・・

# 起動

ターミナルから以下コマンドを叩けばOK
```bash
open --background -a Docker
```
Ubuntu 20.04 を起動したらGUIじゃなくなった(よくあるやつね)

## 概要

https://ctfbook.github.io/2nd/

こちらの本の環境構築の中でVagrantでUbuntuを立ち上げたとき、GUIでログイン画面が出なかったので対処法を書いておきました。

以下のように/etc/gdm3/custom.confを開きます。

```bash
sudo vi /etc/gdm3/custom.conf
```

以下の行のコメントアウトを削除します。

```text
#WaylandEnable=false 
```

保存して閉じたら再起動してください。
GUIでログイン画面が表示されるはずです。

以上

## Wayland とは

https://linuxfan.info/ubuntu-gdm-wayland-false

> Ubuntu 18.04 LTSのデスクトップ環境には、「X.Org」と「Wayland」という、2つの「ディスプレイサーバー」がインストールされます。ディスプレイサーバーとは、クライアントプログラムと通信してウィンドウを画面上に描画したり、マウスやキーボードの入力をクライアントプログラムに送信したりといった役割を担うサーバープログラムです。Linuxデスクトップには「X.Org」が広く用いられています。一方、「Wayland」は新しく設計、開発されているディスプレイサーバーです。将来的に「Wayland」への切り替えが進んでいく見込みですが、Ubuntu 18.04 LTSの初期設定では、ログイン画面のみ「Wayland」が使われ、デスクトップ環境では「X.Org」が使われるようになっています。しかし、ハードウェアによってはWaylandによるログイン画面の描画がうまく動作せず、正常にログイン画面が表示されません。

## ディスプレイサーバとは

https://ja.wikipedia.org/wiki/%E3%83%87%E3%82%A3%E3%82%B9%E3%83%97%E3%83%AC%E3%82%A4%E3%82%B5%E3%83%BC%E3%83%90

> ディスプレイサーバは、ウィンドウシステムにおいて、ポインティングデバイス・キーボード・ディプレイのハードウェア制御を行い、遠隔または同一のコンピュータ上で動作する他のプログラムに対し、ポインティングデバイス・キーボード・ディスプレイによる入出力の機能を提供するプログラムである。機能の提供はディスプレイサーバプロトコルと呼ばれる通信プロトコルを通じて行われる。

ここまで読めば脱線としては十分でしょう。
本当に以上。
ChatGPTの課金に関するあれこれ

# 概要
ChatGPTに関するあれこれと題して、小説風にサブスクリプションを始めるまでを綴っています。


# 物語

### 登場人物
まさる：本作の主人公。IT業界で働く若手社員。

 

### 第1章：情熱の輝き

東京の高層ビルが立ち並ぶIT企業で働くまさるは、日々コードと会議に追われていた。彼は若手ながらも技術力を認められ、重要なプロジェクトに携わることが多かった。しかし、そんな日々の中で、彼の心の奥底には、最新技術への興味と情熱がくすぶっていた。

毎朝の通勤電車では、まさるは周囲の人々と同じく、スマートフォンの画面に目を落としていた。しかし、彼が見ているのは仕事のメールや資料ではなく、Twitterで流れる最新のITトレンドに関する情報。彼の目は、新しい技術やガジェットのニュースに輝きを見せる。

オフィスでは、彼は静かで、あまり目立たない存在だった。けれども、プログラミングのスキルと問題解決能力は高く評価されていた。しかし、彼自身は日々の仕事に疲れを感じ、かつての情熱が薄れつつあることに心を痛めていた。それでも、最新のITトレンドに触れるときだけは、彼の目にかつての情熱がよみがえる。

まさるの心には、技術の進化に対する深い興味と、それを追い続ける静かな決意があった。彼にとって、技術はただの仕事の道具ではなく、世界を変える可能性を秘めた魔法のようなものだった。

 

### 第2章：GPTSの衝撃

ある朝のこと、通勤電車の中でまさるは、ふとTwitterで「GPTS」のリリースに関するツイートを目にした。GPTSは、ChatGPTの最新バージョンで、従来のバージョンよりも高度な対話能力と分析機能を備えていた。このニュースは、まさるの心に強い衝撃を与えた。

オフィスに着いたまさるは、昼休みを利用してGPTSについてさらに詳しく調べた。その機能の一つ一つが、まさるの想像を超えるものだった。特に、GPTSが持つ深い学習能力と広範な知識ベースは、彼の心を強く惹きつけた。これは単なるアップデートではなく、AIの未来を大きく変えるかもしれない革新だった。

日々の業務に追われる中で、まさるはGPTSのことを考えると、久しぶりにわくわくする気持ちを感じた。彼は、この新しい技術が自分のキャリア、そして未来にどのような影響を与えるかを想像し始めた。彼にとって、GPTSはただのツールではなく、新しい可能性の扉を開く鍵だった。

会社の同僚たちは、まさるが昼休みにGPTSについて熱心に調べているのを見て、好奇心旺盛な一面に気づき始めた。まさるはいつも静かで、自分の興味をあまり表に出さないため、この変化は周囲にとって新鮮だった。

 

### 第3章：決断の瞬間

翌週、まさるは仕事の合間にもGPTSのことが頭から離れなかった。彼はこの新しいツールを使って、何か大きなことを成し遂げたいという強い欲求を感じていた。ある晩、自宅の静かな部屋でパソコンの画面を見つめながら、彼は深く考え込んだ。今の自分に満足しているのか、それとも新しい挑戦をしたいのか。

そこで、彼は重要な決断を下す。ChatGPTのサブスクリプションプランを購入することにした。これは彼にとって、ただのサービス登録以上の意味を持っていた。まさるにとって、これは自分のキャリアにおける新たな一歩、そして未知への挑戦の始まりを意味していた。

購入ボタンをクリックする瞬間、まさるの心は高鳴った。彼は、この決断が自分の人生をどのように変えるかを想像し始めた。彼はGPTSを活用して、自分の技術知識を広げ、さらにはITに関する情報を発信するブロガーとしての新たなキャリアをスタートさせることを決意した。

この決断は、まさるにとって、日々のルーティンからの脱却を意味していた。彼は、自分自身に新たな挑戦を課し、自分の可能性を信じて一歩踏み出す勇気を持った。

 

### 第4章：新たな始まり

サブスクリプションを開始したまさるは、自宅のパソコンでGPTSと対話しながら、新たなキャリアへの第一歩を踏み出した。彼は、GPTSを活用してITの最新情報を分析し、それを自分のブログで発信することにした。彼のブログは、技術的な深さと個人的な視点を兼ね備えていた。

毎晩、彼は仕事から帰宅すると、GPTSと共に新しい記事のアイデアを練り、技術の解説や市場の動向について書き始めた。彼のブログは徐々に読者を獲得し、IT業界内で注目されるようになった。まさるの文章には、技術への深い理解と情熱がにじみ出ていた。

しかし、新しい挑戦は容易ではなかった。ブログの運営と仕事の両立は大変で、多くの時間と努力を要した。まさるは夜遅くまで起きて記事を書き、週末も研究に費やした。しかし、彼にとってそれは苦労ではなく、情熱を注げる価値ある仕事だった。

オフィスでは、同僚たちがまさるの変化に気づき始めた。彼らは、まさるが昼休みや空いた時間にブログの記事を書いているのを見て、彼の情熱と努力を認めるようになった。まさるのブログは、同僚たちにも影響を与え、彼らの中にも新しい技術への関心が芽生え始めた。

 

### 第5章：未知への挑戦

まさるのブログは、日に日に読者を増やし、彼の名前は徐々にIT業界で知られるようになった。しかし、彼の本当の挑戦は、これから始まる。彼はGPTSの深い知識を活用し、これまでにない切り口での技術分析や市場予測を発信し続けた。

仕事とブログの運営の両立は困難を極めたが、まさるはそのプレッシャーを力に変えていった。彼は毎日、新しい記事を書き、読者からのフィードバックを真摯に受け止め、さらなる知識を求めて研究を重ねた。彼のブログは徐々に、専門家や業界関係者にも注目されるようになった。

オフィスでも、まさるの変化は明らかだった。かつて静かで目立たなかった彼が、自信に満ち、意見を積極的に発信するようになった。同僚たちは彼の変貌に驚きつつも、彼の情熱に触発され、自分たちも新しい技術への関心を深めていった。

まさるは、GPTSを活用して、自分自身の限界を超える挑戦を続けた。彼は新しい技術に関する洞察を深め、業界の動向を的確に捉え、読者にとって価値ある情報を提供し続けた。彼のブログは、IT業界における新たな視点とインスピレーションの源となった。


# ブログ
ブログにも記載しています。お越しください！

[はてなブログ記事](https://marontechlife.hatenablog.com/entry/2023/11/14/001338)

# 以上
コードレビューは通らない

こんにちは、[さとう](https://www.notion.so/f5514364f03a412f8af6c09b352c9d64?pvs=21)です！

先日、こんな記事を書きました。
[コードレビューしてみよう！](https://www.notion.so/61def52eb8b245d5a4ef69fa34aa04da?pvs=21) 

レビューをした結果、すべての行に指摘が入り、更には設計ごと変更する、という結末を迎えてしまいました。
この例は極端に思えるかもしれませんが、似たようなことが実はよく発生します。

# コードレビューを通る人は高度人材

よく指摘が入る部分を並べてみました。

- テストコードがない・足りない
- テストカバレッジが低すぎる
- Value Objectを使っていない
    - 最大値の設定をしていない
    - 基本データ型をそのまま使っている
- ミュータブルなオブジェクトを作っている
- 可視性が広すぎる
- 循環依存が発生している
- ドメインロジックがドメイン層以外に漏れ出している

(これらすべてを人間がレビューする必要はありません。LinterなどのツールをCIに組み込めば、自動で検査してくれるものもあります。)

さて、これらすべてをクリアできる基準のコードを書ける人はどれくらいいるでしょうか？

このレビューを素通りできる人は、**相当レベルが高い**と考えられます。
このような、コードレビューの要求値が高い、という問題をどうすれば解決できるでしょうか。

# モブプロを実践する(三人寄れば文殊の知恵)

もしあなたが初心者で、ひとりでコードを書いた場合、すべての行に指摘が入る可能性があります。

すると、あなたはこのように思うはずです。
- 「一生懸命コードを書いたのに、すべて上書きされてしまう」
- 「レビューされた部分が多すぎて、対応しきれない」
- 「どうせすべて書き直すので、自分がコードを書く意味がない」

これではモチベーションが下がりますし、何より学びを得られていません。
学びの最適化をするためには、この状況は改善しなければなりません。

これを達成するために、**複数人でコードを書くようにしましょう**。
また、モブプロにはシニアエンジニアを呼ぶようにします。

より素早くフィードバックを得ながら、コードを書くことによって、先ほどの問題を軽減することができます。

# 品質は捨てられない

スピードを確保するために、コードレビューの要求値を下げることで対応しようとしてしまうことがありますが、これは間違いです。
なぜなら、「**品質を捨てたらスピードが確保できないから**」です。

詳細はこちらをご参照ください。
[質とスピード（2022春版、質疑応答用資料付き） / Quality and Speed 2022 Spring Edition](https://speakerdeck.com/twada/quality-and-speed-2022-spring-edition)

# 結論

- モブプロをしよう！
- 品質は捨てられないよ！

# 終わりに

ソフトウェアは現代において欠かせない存在になっています。
ソフトウェアエンジニアに求められるレベルは非常に高いですが、それをクリアした上で、私たちは「規律、基準、倫理」を守らなければいけません。

# 参考資料

[質とスピード（2022春版、質疑応答用資料付き） / Quality and Speed 2022 Spring Edition](https://speakerdeck.com/twada/quality-and-speed-2022-spring-edition)

[Clean Craftsmanship 規律、基準、倫理](https://www.kadokawa.co.jp/product/302206001224/)

[継続的デリバリーのソフトウェア工学　もっと早く、もっと良いソフトウェアを作るための秘訣](https://bookplus.nikkei.com/atcl/catalog/22/12/01/00531/)
単回帰分析を用いた頻発月経の分析と予測

# はじめに

#### 頻発月経とは
頻発月経は、オムロン ヘルスケア株式会社様のウェブサイト「[オムロン式美人](https://www.healthcare.omron.co.jp/bijin/qa/menstruation_Q36.html#:~:text=%E7%94%9F%E7%90%86%E5%91%A8%E6%9C%9F%E3%81%8C24%E6%97%A5,%E9%A0%BB%E7%99%BA%E6%9C%88%E7%B5%8C%E3%81%A8%E3%81%84%E3%81%84%E3%81%BE%E3%81%99%E3%80%82)」にて、以下のように説明されています。
> 一般的に、生理の周期は25日～38日が正常の範囲内です。これより短い場合は、頻発月経といいます。

#### 分析の動機
当方数カ月ほど頻発月経を経験しており、今の状態は理想的な状態と比べてどれほど悪いのかを数値的に知りたい、また、次の生理周期の予測を月経の前後および最中の体調不良の対策に役立てたいと考えました。

頻発月経に悩む世の女性にも活用していただけると幸いです。

# 分析手順

今回は、説明変数を「月経があった月」、目的変数を「生理周期（前の月経の開始日から次の月経の開始日の前日までの日数）」として単回帰分析を行います。

また、言語はPythonを使用しております。


まず全体的な分析の手順を示します。
1. 単回帰分析に必要な外部ライブラリをインポートする
2. 月経があった月と生理周期のデータを準備する
2. 先ほど準備したデータを分析しやすいように加工する
2. 回帰モデルを作り、データを学習させる
2. 学習結果を散布図と回帰直線として表示する
2. 学習結果から、来月の生理周期を予測する

次に、実際に使用したデータとコードを示します。

### 1. 単回帰分析に必要な外部ライブラリをインポートする

numpyなどの外部ライブラリをインポートします。
また、ここでグラフをインラインで表示するように設定します。
```python
import numpy as np
import scipy as sp
import pandas as pd
from pandas import Series, DataFrame

import matplotlib.pyplot as plt
import matplotlib as mpl
import seaborn as sns
sns.set()
%matplotlib inline
```
### 2. 月経があった月と生理周期のデータを準備する
pandasのDataFrameを用いて、月経があった月と生理周期のデータの２次元データを作成します。
```python
data = {
    'Month': ['2022-12', '2023-1', '2023-2', '2023-3', '2023-4','2023-5','2023-6','2023-7','2023-8','2023-9','2023-10','2023-11'],
    'Period': [29,30,23,22,24,22,20,26,23,27,23,20],
}
df = pd.DataFrame(data)
```
### 3. 先ほど準備したデータを分析しやすいように加工する
先ほどのデータでは、月経があった月を文字列データとして記述しています。
このままだと回帰分析の手法が使えないので、文字列データを数値データに変換します。
```python
# 月を数値に変換
df['NumericMonth'] = pd.to_datetime(df['Month'], format='%Y-%m').dt.to_period('M').astype('int64').astype('int32')
```
### 4. 回帰モデルを作り、データを学習させる
まず、単回帰分析に必要な外部ライブラリをインポートします。
```python
import sklearn
from sklearn import linear_model
```
次に、先ほど読み込んだ外部ライブラリと加工したデータを用いて、単回帰分析モデルを作成し、データを学習させます。

```python
# 説明変数と目的変数の取得
X = df[['NumericMonth']]
y = df['Period']

# モデルの作成と学習
model = linear_model.LinearRegression()
model.fit(X, y)
```
### 5. 学習結果を散布図と回帰直線として表示する
学習したデータをもとに、モデルに回帰直線の予測をさせます。
予測した直線を、元データの散布図とともに表示します。
```python
# 予測
y_pred = model.predict(X)

# 回帰直線の描画
plt.figure(figsize=(10, 6))
plt.scatter(X, y, color='pink', label='Actual')
plt.plot(X, y_pred, color='red', label='Regression Line')
plt.title('Polymenorrhea')
plt.xlabel('Numeric Month')
plt.ylabel('Period')
plt.ylim(0, 40)
plt.xticks(rotation=45)
plt.legend()
plt.tight_layout()

# グラフを表示
plt.show()
```

### 6. 学習結果から、来月の生理周期を予測する
```python
# 来月の説明変数を作成
next_month = pd.DataFrame({'NumericMonth': [df['NumericMonth'].max() + 1]})

# 来月の出力を予測
next_month_pred = model.predict(next_month)

print("来月の出力の予測値:", next_month_pred[0])
# 出力: 来月の出力の予測値: 21.242424242424192
```
頻発月経の判断の目安が24日であることを考慮すると、あまりよろしくない結果であることが分かります。

# 留意事項
- データ分析に関しては初心者なので、コードの作成はChatGPTに手伝ってもらいました。
- 今回は単回帰分析を使用しておりますが、今後は他の回帰分析の方法も試してみます。
- 初投稿です。訂正すべき箇所等ございましたらご指摘頂けるとありがたいです。
エンジニア視点で考えるデザインの力：Designship2023参加記

この記事はdesignship2023に参加した際のレポートです。
デザインカンファレンスに初めて参加したので、エンジニア目線で学んだことやコミュニティ運営者としての気づきなどをメモとして残しておきます。

## [Designship2023](https://design-ship.jp/2023)とは

> 産業革命によって誕生した「デザイン」は、
現代にいたるまでその意味と対象を広げ続けてきました。
> 
> いまやデザイナーがすべてのデザインを司るのは実質不可能。我々は数多ある星の中から星座を見出すがごとく、
氾濫したデザインに意味づけをおこなう必要があります。
> 
> Designshipはデザインが広がりすぎたそんな時代の中で、
デザイナーひとりひとりの物語に沿って、
デザイン同士を接続する機会を提供します。
>
> 最前線のデザインを学び、第一線のデザイナーと語り合う、年に一度のデザインの祭典をお楽しみください。
> 


公式ホームページより引用
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1212014/a4bb92a1-a274-fdb5-c32f-1a1b948b3da3.jpeg" width="50%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1212014/cb67322f-c4da-691a-45d1-392143ce1d72.png" width="50%">

## エンジニアカンファレンスとの違い
エンジニア系のカンファレンスは良く行ったり見たりするのですが、デザインのカンファレンスは初めてでした。

大きく感じた違いは、圧倒的に「体験できるコンテンツ」が多いことです。

例えば、参加者が自分のイラストを描いて展示できるワークショップや、クリエイティブなガチャガチャなど、参加者が直接関われるアクティビティが豊富でした。エンジニア系のカンファレンスももちろん楽しいのですが、DesignShip2023では、思い返したときに記憶に残るような内容（体験）が多かったように思います。

## 何を学んだのか
飛び入り参加＆私用の間で出向いたため、セッションも数えるほどしか聞けなかったのですが、自分が聞いたセッションの共通点としては、各社デザイナーとしてどうすれば業務を効率化、仕組み化できるか。組織の中でコミュニケーションをデザインできるかといった話を言ってたように思います。

自分自身も仕組みをいかに作るかという文脈が好きで、そのために継続的に良い体験や組織が回る仕組みはデザインできるはずと考えていたのですが、セッションを聞いていくつか事例や取り組みがあることを知ることができました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1212014/6764e976-2745-9e70-1463-ec44616030d3.png" width="70%"/>

## 考えたこと、感じたこと
今回の参加で、それぞれ直近で活かせそうな内容がありました。
### コミュニティ運営者として
私はあまてくというエンジニアコミュニティと最近は学内カフェでSOIスクランブルというコミュニティを立ち上げから運用までを行っています。

その中でいかに、また来たいと思ってもらえるような体験をデザイン(設計)できるかを考えるべきだと感じました。

具体的には、オフラインでも話す・聞くだけではなく、ネクトアクションを促せるような仕組みを作らなければいけないと思いました。

デザインの考え方は、技術だけでなく、コミュニティ運営やプロダクト開発においても非常に有効であることを実感しました。

### エンジニアとして
もともと、toBや業務・開発効率化といった領域が好きなのですが、業務フローから実際に使ってもらうためのケーススタディや達成したい目標などを洗い出し、プロダクトまで落とし込むことで、実際にユーザに使われるサービスや使い続けてもらえる仕組みを作ることが重要であり考えるべきことなのではないかと考えました。　

以前働いていたインターンシップで、フロントエンドツールの導入やデザインシステムの導入検討などを進めていたのですが、今回のイベントに参加してみて、作ったあといかに使ってもらえる仕組みを作るかが、導入することよりも重要だと改めて考える機会になりました。

導入するのは簡単ですが、導入後誰がメンテナンスするのか、属人的にならないのか、ツール自体がアップデートされているのか(コミュニティが大きいか)などを踏まえた上の技術選定を考える必要があることも再認識しました。

## まとめ
- とりあえずめっちゃ楽しかった
- エンジニアとしても活かせるところがたくさんあった
- デザインの考え方(デザイン思考？)は、あらゆるものに応用できる
- 畑が違うイベントにも行ってみよう
HTMLとCSS：ウェブページ作成の基本

# HTMLとCSS：ウェブページ作成の基本

**ウェブページを作るためには、HTMLとCSSという二つの重要な要素があります。**
これらはウェブサイトを建てる際の骨組みと装飾に例えることができます。

## HTMLって何？

HTMLは、ウェブページの構造を作る言語です。
本の骨組みのようなもので、タイトル、見出し、段落など、ページの各部分を定義します。
HTMLは「HyperText Markup Language」の略で、単純なテキストに「タグ」と呼ばれる特別なラベルを使用して、ブラウザにどのようにコンテンツを表示するかを伝えます。

たとえば、`<h1>`は一番大きな見出しを意味し、`<p>`は段落を示します。以下のコードは、HTMLを使って簡単なウェブページの一部をどのように作るかを示しています：

```html
<h1>私の趣味</h1>
<p>私は読書が好きです。</p>
```

このコードは、大きな見出し「私の趣味」というテキストと、その下に「私は読書が好きです。」という小さなテキストの段落を作ります。

## CSSとは何か？

CSSは、HTMLで作った骨組みに色やデザインを加える言語です。
これは「Cascading Style Sheets」の略で、ウェブページの見た目を美しく整えるためのスタイリング指示を書きます。たとえば、CSSを使ってテキストの色を変えたり、背景に画像を設定したりすることができます。

以下のCSSコードは、HTMLの要素にどのようにスタイルを適用するかを示す例です：

```css
h1 {
  color: blue;
  font-size: 24px;
}

p {
  color: gray;
  font-size: 16px;
}
```

このスタイルは、見出しを青色と大きめの文字で表示し、段落を灰色と標準サイズの文字で表示するようにブラウザに指示します。

## HTMLとCSSはどう関係しているの？

HTMLとCSSは手を取り合って働きます。HTMLが「何を表示するか」を定義し、CSSが「それをどのように美しく見せるか」を決めるわけです。ウェブページにおいて、HTMLは骨組みとなる内容をし作成し、CSSはその骨組みを装飾します。

例えば、お店のウェブサイトを作るとき、HTMLでメニューのリストを作り、CSSでそのリストをお店のブランドカラーやフォントで美しく装飾することができます。

---

**このようにHTMLとCSSは、ウェブページを作るために連携して機能します。
HTMLで基本的な構造を作り、CSSでスタイルを加えることによって、機能的で魅力的なウェブページが出来上がります。**
【JavaScript】エラーの種類で処理を分ける方法

以下のように`instanceof`を使用することでエラーの種類によって処理を分けることができます。

```js
try {
  throw new TypeError()
} catch (err) {
  if (err instanceof TypeError) {
    // TypeErrorの場合の処理
  } else {
    console.log('その他')
  }
}
```
ApacheとNginxを共存させるメモ

# はじめに
本来共存させることは推奨されないはずなので、これを参考にしてやる場合はクローズドな環境でお試しすることを推奨致します。
因みに、今回完全ローカル環境で構築したためファイアウォールは未設定です。

## 本題
インストール前に`sudo apt update`をお忘れなく。
まず先に、Apacheをインストールします。
この際サービスを止めることを忘れないでください。
```console
$ sudo apt install -y apache2
$ sudo systemctl stop apache2
```
次に、Nginxをインストールします。こちらも同様にサービスを停止させてください。
```console
$ sudo apt install -y nginx
$ sudo systemctl stop nginx
```
\
そうしましたら、ポートを変更したい方のconfig を変更します。
今回はNginxの80番ポートを8080番ポートへ変更しています。また、indexの優先度も変更します。
```c:/etc/nginx/sites-enabled/default
#22行目付近
#listen 80 default_server;
#listen [::]:80 default_server;
listen 8080 default_server;
listen [::]:8080 default_server;

#46行目付近
#index index.html index.htm index.nginx-debian.html;
index index.nginx-debian.html index.html index.htm;
```
\
ここまで来ましたら確認です。サービスの再起動を行い。
```console
$ sudo systemctl start apach2 nginx
```
**http**://[IP ADDR]:80　と　**http**://[IP ADDR]:8080　で接続テストです。
それぞれのデフォルトページが出れば成功です。

## 使いやすさ向上のための設定
さて、ここまで来れば基本は終了です。ここから先は使いやすさ向上のための設定です。
まず好きなところにApacheとNginxそれぞれのディレクトリを作成し、indexファイルをコピーしてください。
そしたらドキュメントルートの変更を行います。
- Apache
```console:/etc/apache2/apache2.conf
#170 行目付近
<Directory /var/www/>
    Options Indexes FollowSymLinks
    AllowOverrride None
    Require all granted
</Directory>
↓
<Directory "作成したディレクトリ名">
    Options Indexes FollowSymLinks
    AllowOverrride None
    Require all granted
</Directory>
```
```cosole:/etc/apache2/sites-available/000-defaulut.conf
DocumentRoot /var/www/html
↓
DocumentRoot "作成したディレクトリ名"
```
- Nginx
```console:/etc/nginx/sites-enabled/default
#43行目
root /var/www/html;
↓
root "作成したディレクトリ名"
```
以上です。
最後にサービスの再起動を行い、
```console
$ sudo systemctl start apach2 nginx
```
**http**://[IP ADDR]:80　と　**http**://[IP ADDR]:8080　で接続テスト行って、
それぞれのデフォルトページが出れば成功です。

これ以降はそれぞれのディレクトリで管理できるようになりました。

## 締め
初めての記事作成で至らない点があるかもしれませんが、ご参考になれば幸いです。
以下に着想を得たサイトを置いておきます。

---
参考にしたサイト

https://yoshoku.hatenablog.com/entry/2017/03/12/011701
ST7789V2でキャラクター文字を表示する。(ESP32)(Adafruit_ST7789)


目的
テスト


https://qiita.com/caa45040/items/3c57c159be0fd0f7a718


https://qiita.com/caa45040/items/8935036eab45af3b08d0


https://qiita.com/caa45040/items/285a406d1a033a3ddc59


![o_cop783.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/e5cdd46c-2a05-ae33-9179-3aa0ab90e185.jpeg)

TFT_CS 14
TFT_RST 15
TFT_DC 32

CLK-18
MOSI-23

```c++


//st7789_text_test1_esp32

//インクルド
#include <Adafruit_GFX.h>    // Core graphics library
#include <Adafruit_ST7789.h> // Hardware-specific library for ST7789
#include <SPI.h>

//ピン定義
//#if defined(ARDUINO_FEATHER_ESP32) // Feather Huzzah32
  #define TFT_CS         14
  #define TFT_RST        15
  #define TFT_DC         32

//画面の定義
// OPTION 1 (recommended) is to use the HARDWARE SPI pins, which are unique
// to each board and not reassignable. For Arduino Uno: MOSI = pin 11 and
// SCLK = pin 13. This is the fastest mode of operation and is required if
// using the breakout board's microSD card.

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);


//初期化
void setup(void) {

  //画面の初期化
  // Use this initializer (uncomment) if using a 1.3" or 1.54" 240x240 TFT:
  tft.init(240, 240);           // Init ST7789 240x240

  //画面のクリア
  tft.fillScreen(ST77XX_BLACK);

  // テキストサイズを設定
  tft.setTextSize(3);
  // テキスト色を設定
  tft.setTextColor(ST77XX_WHITE);
  // テキストの開始位置を設定
  tft.setCursor(0, 10);

  // 1行目にUNOを表示
  tft.println("ST7789");

} //setup


//メインルーチン
void loop() {
  delay(1);
} //loop

```
[小ネタ]PHPで数値を先頭空白埋め・右揃え・桁区切りして表示したい

### やりたいこと ###
要は、数値をこうやって(↓)出力したいってことです。
sprintf関数を使って何とかできないか、ググったり試行錯誤しましたが、（ニーズはあるはずやのに）なかなかしっくりくる答えは見つからず・・・:frowning2:
```
入力件数      ：  12,000件
エラー件数    ：   1,000件
スキップ件数  ：     200件
出力件数      ：  10,800件
```
***
### 何てことなかった ###
が、そのうちひらめきました。
Max百万台を表示する例です。
``` php
echo "入力件数      ：" . sprintf("%9s", number_format($cnt_inrec, 0)) . "件";
```
sprintfで文字列フォーマット指定するのがミソでしょうか。
Smartyで対応する場合は、左から右にオプションが評価されるので、次のようになります。
```
入力件数      ：{$cnt_inrec|number_format|string_format:"%9s"}件
```
C#で対数積分関数li(x)を自前で計算する(x≧2)

$$\text{li}(x):=\lim_{\epsilon\to 0+}\left(\int_0^{1-\epsilon}\frac{dt}{\ln t}+\int_{1+\epsilon}^x\frac{dt}{\ln t}\right)\ \ \ \ \ (x>1)$$

を計算するプログラムを書いてみた。

https://mathworld.wolfram.com/LogarithmicIntegral.html

上記で紹介されているラマヌジャンの式を使うと高速に収束するとのことなので、これを用いる。
$$\text{li}(x)=\gamma+\ln\ln x + \sqrt{x}\sum_{n=1}^\infty\frac{(-1)^{n-1}(\ln x)^n}{n!2^{n-1}}\sum_{k=0}^{\lfloor(n-1)/2\rfloor}\frac{1}{2k+1}$$

```c#:li.cs

using System;

class LiFunc
{
    static double gamma_constant = 0.57721566490153286061;

    static double Li(double x)
    {
        double lnX = Math.Log(x);
        double a = gamma_constant + Math.Log(lnX);
        double sum1=0;
        double prevSum1=0;
        double sum2=0;
        double factor = lnX;
        int prevK = -1;
        int endK;
        for(int n=1;n<=100000;n++)
        {
            if (n>1)
            {
                factor *= -lnX*0.5/n;
            }
            endK = (n-1)/2;
            for(int k=prevK+1;k<=endK;k++)
            {
                sum2 += 1.0/(2*k+1);
            }
            prevK = endK;

            sum1 += factor*sum2;
            if (prevSum1 == sum1)
            {
                // doubleの範囲で値が変化しなくなったときのnを出力(参考用)
                Console.Write("exit at n=");
                Console.WriteLine(n);
                break;
            }
            prevSum1 = sum1;
        }
        return a + sum1*Math.Sqrt(x);
    }

    [STAThread]
    static void Main(string[] args)
    {
        Console.WriteLine(Li(2));
        Console.WriteLine(Li(1.1));
        Console.WriteLine(Li(1.4513692348)); // 計算結果が 0 に近いため計算誤差が累積する。
        Console.WriteLine(Li(10000000000000));
    }
}

```

```text:出力結果
exit at n=14
1.04516378011749
exit at n=10
-1.6757728303192
exit at n=12
-2.23837337554045E-10
exit at n=61
346065645810.05
```

# python (mpmath)で検算

```python:calc_li.py

import mpmath
mpmath.mp.dps = 17

for x in [
    2,
    1.1,
    1.4513692348,
    10000000000000,
    ]:
    print(mpmath.li(x))

```

```text:出力結果
1.0451637801174928
-1.6757728303191988
-2.2383724226679356e-10
346065645810.05034
```

x=1.4513692348
以外の例はdoubleの桁数の範囲でmpmathの計算結果を丸めたものと一致しているようなので、$x\geq 2$のときはわりと実用的に使えるレベルかなと。