OmniAICreator/Qiita-1.07M huggingface dataset:
コメント駆動開発(コメントドリブン)という考え方

## はじめに

新人プログラマ応援イベントの参加記事です。

https://qiita.com/official-events/3f21c92121aa125807b4

この記事は、James Edwards氏のプログラミング方法論を参考にしています。

https://www.sitepoint.com/comment-driven-development/

また、この記事には私の独断と偏見も含まれています。

## コメント駆動開発（コメントドリブン）とは

コメント駆動開発とは、コードを書き始める前に、実装するべき処理を先にコメントとして書くことで、
必要なロジックを明確化し整理する手法です。

:::note warn
・説明するのは簡単だが、コードで表現するのが難しい処理。
・コードで表現するのは簡単だが、説明するのが難しい処理。
:::

このような問題を解決するためのアプローチとしても有効です。

例えば、

モグラたたきで、モグラを叩いた時のプログラムを作成する例
先に必要と思われるであろう処理をつらつらとコメントとして書いていきます。

```JavaScript
// HTMLからモグラの要素を取得

// モグラがクリックされた時の処理

// モグラが穴に隠れていなければ、

// パスを指定し、モグラが叩かれているときに表示する画像を取得

// モグラの画像を入れ替える
```

このようにコメントを書いた後、そのコメント通りにコードを書いていきます。

上記の例は非常に簡単なものなので、逆に冗長に見えてしまうかもしれませんが、
事前に要件を細分化して文字として残しておくことで、
コードも書きやすくなるかと思います。

IF仕様書の処理概要を先にコメントで書くようなイメージかもしれません。

個人的には、[BDD(ビヘイビア駆動開発)](https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%98%E3%82%A4%E3%83%93%E3%82%A2%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA)の[TDD(テスト駆動開発)](https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA)要素を除いて、
コーディングに焦点を当てた感じのものだと考えています。


## 注意点
プログラミングにおけるコメント論にも様々な議論がありますが、
コードとコメントの不一致により、プログラムの可読性が低下し混乱が生じる可能性があります。

## まとめ
これはあくまでコーディングのみに焦点を当てたプログラミング方法論であるので、
比較的取っ付きやすい反面、
別途テストコードを用いる等、コードの正確性は担保できるようにするのが良いでしょう。

また、ティーチングテクニックとして有名な、
[ラバーダッキング法](https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%90%E3%83%BC%E3%83%80%E3%83%83%E3%82%AF%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0)(アヒルに向かって問題を説明することで自身の考えを整理する)にも通ずるので、
プログラミング初心者の方にもオススメできる方法ではないでしょうか。

少しでも参考になれば幸いです。

## 参考
https://www.sitepoint.com/comment-driven-development/

https://ja.wikipedia.org/wiki/%E3%83%93%E3%83%98%E3%82%A4%E3%83%93%E3%82%A2%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA

https://ja.wikipedia.org/wiki/%E3%83%86%E3%82%B9%E3%83%88%E9%A7%86%E5%8B%95%E9%96%8B%E7%99%BA

https://ja.wikipedia.org/wiki/%E3%83%A9%E3%83%90%E3%83%BC%E3%83%80%E3%83%83%E3%82%AF%E3%83%BB%E3%83%87%E3%83%90%E3%83%83%E3%82%B0
<iframe>の意図しないループを解消する

# `<iframe>`タグで混乱！
`<iframe>`タグで読み込んでいたiframe.htmlの要素をクリックした際に、
 **iframe.htmlの中にiframe.htmlが出るというループが発生** した。
ブラウザの検証（Ctrl+Shift+C / ⌘+Shift+C）でエラー元を確認するも、
Cookieに問題があると言われたりモール共通のとあるjsファイルがおかしいなんて言われる。
<details><summary>iframe内のhtmlファイルについて</summary>

Webサイト制作ではあまり使うことはない`<iframe>`タグ。
WordPressでの制作でPHPファイルをいじくるときにそれっぽいことをするが、
`<iframe>`タグの扱い方を知らないとエラーが混乱を招く気がした。
</details>

※`<iframe>`タグはインラインフレームと呼ばれ、src属性で指定したURL（別ページ）の内容を読み込み、
　**`<iframe>`タグを設置した箇所に（埋め込む形で）表示する** もの。

# この記事を呼んでもらいたい人
1.ECモールでショップを運営・管理している人
2.HTML初心者や少し触ったことがある程度の人
3.`<iframe>`で意図しないループが起きた人

# 解決方法
iframe.html内の **`<a>`タグに`target="_blank"`を追加することで解決** した。
<details><summary>サンプル</summary>

```html:index.html
<iframe id="error" src="https://www.~/index.html"></iframe>
```
↓修正後
```html:index.html
<iframe id="success" src="https://www.~/index.html" target="_blank"></iframe>
```
たったこれだけです💦
</details>

### 解決までの道のり
Firefoxを愛用する私は、エラー発生時もFirefoxで検証していたのだが、
`<iframe>`タグないのirame.html要素をクリックした際に、
何度か「`<iframe>`など外部読み込みタグを検知すると警戒しちゃうから、
ブラウザの別タブで開くことをオススメするよ」と表示されていた。

既にブラウザが答え教えてくれてた🥰🥰🥰

エラー出た際に「iframe ループ」で検索したが、ループさせる表示方法ばかりが出てきた。
1つだけ「iframeでバグる時あるから注意して」的なサイトがあったが、
英文を無理やり翻訳かけたような内容だった上、`taeget="_blank"`についての記述はなかった。

### 【余談】エラーの経緯
私の場合、某ECモールで管理しているショップのヘッダーで読み込ませていたindex.html内で、
別のhtmlファイルを読み込ませる必要が出たので、ifare.htmlを作成し`<iframe>`タグで呼んでいた。
私が現在の会社に所属する前に契約していたコンサル会社が管理していたものだったので、
余計なコードを整理していた流れで発生した。
「なんでわざわざ別タブ指定させんねん」という考えで消したわけだが、ちゃんと意味はあったのだ。
コンサルだからって疑っちゃいけない。
ごめん、元コンサル...

# 結論
私のようにECショップ運営者は特に気を付けて欲しい。
HTMLよく分からない人だと原因追及は不可能だと思うので、
初心者がエラーにぶつかった際にこの記事に辿り着いて貰えると幸いです。
装備品の性能を取り除いた数値

定期的に質問を見る気がするので記事にしました。

装備品の影響を無視し、キャラクターの元々の腕力などをダメージ計算に使いたい場合の話です。

アクターの数値は以下の方法で計算されます。
**value= (actor.paramBase(paramId) + actor.paramPlus(paramId) )* actor.paramRate(paramId) * actor.paramBuffRate(paramId)**

paramIdは能力値の番号を示します。
最大HP,最大MP,攻撃力…の順に並んでおり、攻撃力を取得したいのであれば、actor.paramBase(2)といった指定にします。
| 関数名 | 対応する数値 | 備考 |
|:-:|:-:|:-:|
| paramBase()| アクターの職業依存の数値  | レベルアップによる変動の影響を含む  |
| paramPlus() | 装備品による影響<br>アイテムなどによる成長効果  | 2つを切り離すことはできない  |
| paramRate() | 特徴の通常能力値による乗算  |   |
| paramBuffRate() | 1段階に付き25%  |  スキルやアイテムによって発生する効果 |


装備品による数値のみを取得する関数はありません。
装備品による加算値は全ての装備品の合計で計算されます。
攻撃力をアップする武器以外の装備品がある場合、その数値も取得します。
二刀流によって複数の武器を装備している場合、その合計値を取得します。

以下はダメージ式の欄へコピペで使えるサンプルです。
要望があればサンプルは追加していきます。

```js
Math.pow(a.paramBase(2) ,2) * a.paramPlus(2) //アクターの腕力^2 * 武器攻撃力
```
qittaメールアドレス認証できない


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2644633/4535b405-c0d5-00f8-fbab-3319a6f14fe0.png)
上記の青い部分をクリックしてください
すると登録しているメールアドレスに認証メールが届きます。
複数回押してしまった場合は一つ目のメールを開いてください。
その後、そのメールから認証設定をすれば完了です。
Unity + Visual Studio で Null 条件演算子がエラー表示されない問題

Unity の `UnityEngine.Object` は、Null 条件演算子（`?.`)、Null 合体演算子（`??`)、Null 合体割り当て演算子（`??=`）は使わないほうが良いモノです。


<!--
https://qiita.com/sator_imaging/items/eb774dd953a958833090
-->


Visual Studio ならしれっと「提案」としてその旨が表示されますが、状況によってはエラーが出ます。


<img src="https://dl.dropbox.com/s/82i98pkko60hkjh/UnityObjectNullHandling_ShouldNotUse.jpg" />


状況によっては、というのが厄介で以下のコードだと期待通りに機能します。


```csharp
GUIContent guiContentIsNull = null;
GameObject unityObjectIsNull = null;

Debug.Log(guiContentIsNull?.text);
Debug.Log(unityObjectIsNull?.name);
```

自分のプロジェクトで出たエラーも再現性は無くはないだろうけど、、、というもの。必ずエラーが出るわけではないのが困りもの。


もう一つ厄介な問題として、Unity 由来のクラスだとしても `GUIContent` のように `UnityEngine.Object` を継承していないクラスでは Null 関連の演算子が問題なく使えるという所ですね。

提案の表示も薄いのでそのまま流れで使ってしまう感じ。



## 警告やエラーが出るようにする。


「状況によってはエラーが出る」ということで提案なのは分からなくもない、って感じですがあえて問題になり得るものを抱えておく必要もないですよね。

提案表示のポップアップからそのまま扱いを「警告」や「エラー」に格上げすれば全部対処できるんですが、調べた限りでは `.editorconfig` はソリューション単位でしか機能しないようで、全プロジェクトで共通の格上げは出来ないっぽいです。

これまた厄介ですね。


※ 格上げ対象は `UNT0007`、`UNT0008`、`UNT0023`

<img src="https://dl.dropbox.com/s/7f78g9j94qxtg1a/UnityObjectNullHandling_ChangeSeverity.jpg" />



--


みんな忘れずに新規プロジェクトを作るたびに重要度の格上げしてるんですかね？？ それともエラーに出くわさない？

個人的にはデフォルトで警告にするのが良いんじゃないかなーって事で以下を投げてみました。Good 等して後押しして頂けると幸い。


https://github.com/microsoft/Microsoft.Unity.Analyzers/issues/217


以上です。お疲れ様でした。
商品開発プロセスを改善するStorybookのベストプラクティス

[UXPinとStorybookの統合](https://www.uxpin.com/jp/merge/storybook-integration)により、あなたやあなたのチームメンバーは、承認されたインタラクティブなコンポーネントのUIライブラリからデジタル製品をこれまで以上に簡単に構築できるようになります。統合後は、ワークフローが改善され、より効果的な製品開発が期待できます。しかし、単に2つのツールを統合しただけでは、すべてのメリットが得られるわけではありません。以下のStorybookのベストプラクティスを参考に、製品開発プロセスをより効果的なものにしてください。
まだStorybookとUXPinのMerge技術を統合していない場合は、今すぐ[チュートリアル](https://uxpin-jp.notion.site/UXPin-Merge-7153e34032f548929321dbbd2878ac56)にアクセスして始めましょう。プロセスはわずか1分で完了します。
# 誰もがコンポーネントを見つけやすい命名規則を見つける
Storybookには検索機能があり、新しいプロジェクトに追加したいストーリーやコンポーネントを見つけるのに役立ちます。しかし、この検索機能は、探したいものの名前を覚えているかどうかにかかっています。完璧に覚えている必要はありませんが、かなり近いものが必要です。そうしないと、必要なアセットにたどり着くまで、延々とファイルを見続けることになってしまいます。

この問題を解消するために、命名規則を選択してください。現実的には、どのような命名規則を選んでも問題ありません。[ComponentName].stories.[js|jsx|tsx]は、多くのチームでうまく機能しています。しかし、あなたにとってはうまくいかないかもしれません。

最も重要なことは、一つの命名規則を選び、全員がそれを使うことを義務付けることです。デザインシステムの隅々にまで不正なコンポーネントが存在しないようにするためです。

# StorybookのCSFフォーマットにこだわる
Storybookからコンポーネントをエクスポートする際、ファイルはデフォルトでCSFフォーマットになっています。デザイナーや開発者の中には、自分の編集ソフトに合わせてフォーマットを変更したくなる人がいます。しかし、それは決して良いことではありません。CSFフォーマットは、ファイルを他の環境に移動させても、メタデータが確実に残るようになっています。

# 一度にひとつのストーリーに取り組む
クライアントはすぐに結果を求めます。それがデジタル製品を作るということの本質です。鳴り止まないメールに対して、マルチタスクで対応する人もいます。するとどうでしょう。問題を解決したり、プロジェクト間で生じた混乱を整理したりするのに多くの時間を費やすことになります。

そのためには、1つのストーリーに集中して取り組むことが大切です。そうすれば、プロジェクトのあらゆる側面を整理することができ、より良い結果が得られ、より早くマイルストーンに到達することができるでしょう。

ストーリーに着手したら、区切りのよいところまで整理してコンポーネントの追加とテストを続けます。そうすることで、すべてのコンポーネントが適切なストーリーに配置され、プロジェクトの進捗状況を正確に把握することができます。

もちろん、1つのプロジェクトを完成させるまで、1つの作業しかできないというわけではありません。ただ、一度に一つのストーリーに集中するように、一日のスケジュールを組む必要があります。

順序立てて進める。StorybookとMergeはコードベースのデザインアプローチを採用しているので、チームの時間を大幅に節約できるツールがすでに用意されています。急ぐ必要はありません。

# カスタムドキュメントが必要かどうかは、開発チームと相談する
Storybookにデフォルトで搭載されているDocsPageを使うべきなのか、それとも独自のドキュメントを作成するべきなのか。この質問には、普遍的な正解はありません。しかし、あなたのチームが開発する製品の種類に応じて、一つの選択肢があると思います。

あなたがJavaScriptの経験が豊富でない限り、コンポーネントをドキュメント化する最善の方法については、開発チームと話し合う必要があります。どちらの方法がデザインや開発のニーズに合っているかは、専門家の意見を参考にしてください。

# Storybookで遊ぶ時間を作る
Storybookには、クリエイティブなリスクを冒しても、ストーリーの他のコンポーネントに影響を与えないためのサンドボックスがあります。これはStorybookの最も優れた点のひとつですから、ぜひ活用してください。

遊ぶことは時間の無駄ではありません。あるツールがどのように機能するのか（機能しないのか）を学ぶ最も効果的な方法のひとつです。今、探索に費やす時間は、将来的にStorybookのより良いユーザーになるためのものです。練習だと思ってやってみてください。でも、楽しみながらやってくださいね！

# Storybookのコミュニティに参加する
Storybookにはたくさんのチュートリアルがあり、UIコンポーネントライブラリやデザインシステムを作るための効果的な方法を見つけることができます。しかし、すべての質問にチュートリアルが答えてくれるわけではありません。

そこで、[Storybookのコミュニティ](https://storybook.js.org/community)の出番です。他のオープンソースツールと同様に、Storybookにもユーザーや開発者の活発なコミュニティがあります。コミュニティに参加すれば、他のユーザーと知見やヒントを交換することができます。

また、コミュニティに参加することで、Storybookのアップデート情報や、それがデザインプロセスにどのような影響を与えるかを常に知ることができます。
*    *    *
__[UXPin](https://www.uxpin.com/jp/merge) は、世界中の製品チームがアイデアをより早く製品にするためのデザインプロセスツールです。__																									
__UXPinの革新的なテクノロジーである[Merge](https://uxpin-jp.notion.site/UXPin-Merge-7153e34032f548929321dbbd2878ac56)により、DesignOpsの課題を簡単に解決することができます。UXPin Mergeでは、Reactコンポーネントを使ってデザインし、最終製品と完全な一貫性を持ったプロトタイプを実現することができます。__																									
__さあ、今すぐ[無料トライアル](https://www.uxpin.com/jp/sign-up)を！__																									
![スクリーンショット 2022-04-12 11.30.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1037046/1d0d129d-4194-7dae-5c5d-966870c4441f.png)
Flutter 画像がぼやける

## 事象： Flutterで画像を追加するとぼやける
アプリ内で自前の画像を入れて固定サイズで表示したいときに、表示するサイズと同じサイズの画像を入れるとぼやけてしまう

## 対応
現状、私は表示するサイズの3倍の大きさの画像を入れています
mecab 辞書ディレクトリが見つからない場合

## mecab インストール後に辞書ディレクトリが見つからずmecabが起動できない場合

```
# mecab
param.cpp(69) [ifs] no such file or directory: /usr/lib/mecab/dic/ipadic/dicrc
```

lib64の方を見に行けてないのが原因
/etc/mecabrc 内の辞書ディレクトリを変更

```
;dicdir =  /usr/lib/mecab/dic/ipadic
dicdir = /usr/lib64/mecab/dic/ipadic
```

ちなみにインストールは

```
tar xvzf mecab-0.996.tar.gz 
cd mecab-
cd mecab-0.996
 ./configure --enable-utf8-only --enable-mutex --prefix=/usr
make
make install
```

辞書

```
tar xvzf mecab-ipadic-2.7.0-20070801.tar.gz 
cd mecab-ipadic-2.7.0-20070801
./configure --with-charset=utf8 --prefix=/usr
make install
```

辞書のアップデート  CSVファイルを配置した後に

```
make clean all
./configure --with-charset=utf8 --prefix=/usr
make install
```
Excelですべてのシートのカーソルを"A1"に揃えるマクロ

提出前の整形にご使用ください。

```VB
Sub CursorA1()
'
' CursorA1 Macro
'
    Dim Ws As Worksheet
    For Each Ws In Worksheets
        Ws.Activate
        Range("A1").Select
    Next Ws
    Worksheets(1).Activate
    ActiveWorkbook.Save
End Sub
```
APIでコンフルエンスのグループを取得してExcelに書き出す

# はじめに
コンフルエンスのグループ情報を取得してExcelに書き出す処理の実装です。
実務で地味に使ってるので記事にしました。

その内Githubに集約していきます。

数年前に書いたモノなので恥ずかしいコードになってるのはご容赦ください。

---

## ライブラリ
openpyxlはpipで追加インストール

requests、json、astは標準ライブラリです。


## コード
```getgroups.py
import openpyxl
import requests
import json
import ast

auth = ("hogehoge@hoge.co.jp", "APIキー情報")

def GetGroups():
    wb = openpyxl.load_workbook("test.xlsx")
    sht = wb['Sheet1']
    url = "https://xxxx.atlassian.net/wiki/rest/api/group"

    headers = {
        "Accept": "application/json"
    }

    query = {
    'limit': 500 #500 #取得するグループのリミット数
    }

    response = requests.request(
        "GET",
        url,
        auth=auth,
        headers=headers,
        params=query
    )

    parse_response = json.dumps(json.loads(response.text), sort_keys=True, indent=4, separators=(",", ": "))

    group_name_dict = {}

    dict_response = json.loads(parse_response)

    dict_convert_lists = dict_response['results']

    i = 0

    for value in dict_convert_lists:

        con_dict_value = ast.literal_eval(str(value))

        group_name_dict[i] = con_dict_value['name']
        print(con_dict_value['name'])

        i += 1

        sht.cell(i, 1).value = con_dict_value['name']

    wb.save("test.xlsx")
```

こんな感じに出力されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184018/914aeda3-4ab6-0187-50fc-75ecaeca84ce.png)

---
### 詳細

```
コンフルでAPIキーを作成して認証情報を組み込みます
auth = ("hogehoge@hoge.co.jp", "APIキー情報")

def GetGroups():
　　書き出すExcelファイルとシートを記述
    wb = openpyxl.load_workbook("test.xlsx")
    sht = wb['Sheet1']

　　confluence urlを記述
　　url = "https://xxxx.atlassian.net/wiki/rest/api/group"
```
plunkerでshadertoy sandbox その 3

# 概要
plunkerでshadertoyのglsl動かしてみた。
iDate、実装してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/cd13d773-a058-f5f6-9a0b-8d17c2e080b8.png)

# 成果物

https://embed.plnkr.co/plunk/vNaqCXeXRovZJnZ2


以上。
名所と名言、動的に変化させ表示させる(JavaScript)

# はじめに
絶景と名言が好きなので、まとめて表示してみようと思います。（"絶景を見ながら偉人の名言を"、という本は、たくさん出版されていますが、それと同類のものです）

# 内容
- Webサイトに写真を表示し、そこに文字を入れる（写真＝自分で撮影した世界の名所、文字＝名言集）
- アクセスする度に、写真も文字も動的に変化させる
- 写真のリスト、名言のリストはGoogleスプレッドシートに用意してAPI連携する

##### 使用する技術
- Javascript / GoogleスプレッドシートAPI連携
- bootstrap(v5)のimage-overlays
https://getbootstrap.jp/docs/5.0/components/card/#image-overlays

# サイト
[作成したサイト](https://anotherskyjp.site/devapps/otherpg/08_pic_proverb/pic_proverb1.html)　
![Screenshot_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/d6b76364-feff-c743-79d3-e70de89de126.png)

# 用意したデータ
Googleスプレッドシート
- 写真リスト
![Screenshot_3.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/9f674c79-3696-8278-6b2d-0c71b7256e7d.png)

- 名言リスト
![Screenshot_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/167772/9f09e8d6-9ea7-6602-c11d-9e058726bd55.png)

# コードのポイント
- Googleスプレッドシートの読み込み
[こちらの記事](https://qiita.com/yoshi_yast/items/44ef9da9bc136e455950)を参照

- HTMLの表示部分
```sample.html
  <div class="container">
    <h3>世界の名所と名言と</h3>
    <div class="container">
      <div class="row row-cols-1 row-cols-sm-1 row-cols-md-1 row-cols-lg-2">
        <div class="col"><div id="set0" class="card text-white fs-4"></div></div>
        <div class="col"><div id="set1" class="card text-white fs-4"></div></div>
        <div class="col"><div id="set2" class="card text-white fs-4"></div></div>
        <div class="col"><div id="set3" class="card text-white fs-4"></div></div>
        <div class="col"><div id="set4" class="card text-white fs-4"></div></div>
        <div class="col"><div id="set5" class="card text-white fs-4"></div></div>
        <div class="col"><div id="set6" class="card text-white fs-4"></div></div>
        <div class="col"><div id="set7" class="card text-white fs-4"></div></div>
      </div>
    </div>
  </div>
```

- 読み込んだリストのシャッフル
配列のシャッフルには、[JavaScriptでシャッフルする(Qiita)](https://qiita.com/pure-adachi/items/77fdf665ff6e5ea22128
)を参照させていただきました（感謝）

```sample.html
<script>
  //シャッフルアルゴリズム
  function shuffleData(data) {
    for (i = data.length; 1 < i; i--) {
      var k = Math.floor(Math.random() * i);
      [data[k], data[i - 1]] = [data[i - 1], data[k]];
    }
    return data;
  };
</script>
```
##### ※コメントをいただき追記
今回はリストにあるデータすべてを表示するわけではないので（作成したサイトでは8個）、全データをシャッフルするのは無駄であるため、全データ中のランダムな位置のデータを取り出すように修正。（取り出し方法は、コメントを参照）


- 文字数の確認（多すぎる文字数は表示しない）
名言の中には文字数が多すぎるものがあり、写真からはみ出してしまうケースがあるので、文字数は85までとしました。除去は、filterを使用しました。

```sample.html
<script>
  // 85文字以下のものは除去
  var result = shuffleTexts.filter((shuffleText) => {
    return (Number(shuffleText.len) < 85);
  });
</script>
```

# まとめ
- Bootstrap、データリスト(Googleスレッドシート)との連携で簡単にデータをシャッフルしてWEB表示することができました。
plunkerでshadertoy sandbox その 2

# 概要
plunkerでshadertoyのglsl動かしてみた。
debug printやってみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/b9715551-c531-a55d-09d8-9b28f268455c.png)


# サンプルコード

```
precision mediump float;
uniform vec2 iResolution;
uniform float iTime;

float DigitBin(const int x) {
	return x == 0 ? 480599.0 :
		x == 1 ? 139810.0 :
		x == 2 ? 476951.0 :
		x == 3 ? 476999.0 :
		x == 4 ? 350020.0 :
		x == 5 ? 464711.0 :
		x == 6 ? 464727.0 :
		x == 7 ? 476228.0 :
		x == 8 ? 481111.0 :
		x == 9 ? 481095.0 : 0.0;
}
float PrintValue(vec2 vStringCoords, float fValue, float fMaxDigits, float fDecimalPlaces) {
	if ((vStringCoords.y < 0.0) || (vStringCoords.y >= 1.0))
		return 0.0;
	bool bNeg = (fValue < 0.0);
	fValue = abs(fValue);
	float fLog10Value = log2(abs(fValue)) / log2(10.0);
	float fBiggestIndex = max(floor(fLog10Value), 0.0);
	float fDigitIndex = fMaxDigits - floor(vStringCoords.x);
	float fCharBin = 0.0;
	if (fDigitIndex > (-fDecimalPlaces - 1.01))
	{
		if (fDigitIndex > fBiggestIndex)
		{
			if ((bNeg) && (fDigitIndex < (fBiggestIndex + 1.5)))
				fCharBin = 1792.0;
		}
		else
		{
			if (fDigitIndex == -1.0)
			{
				if (fDecimalPlaces > 0.0)
					fCharBin = 2.0;
			}
			else
			{
				float fReducedRangeValue = fValue;
				if (fDigitIndex < 0.0)
				{
					fReducedRangeValue = fract(fValue);
					fDigitIndex += 1.0;
				}
				float fDigitValue = (abs(fReducedRangeValue / (pow(10.0, fDigitIndex))));
				fCharBin = DigitBin(int(floor(mod(fDigitValue, 10.0))));
			}
		}
	}
	return floor(mod((fCharBin / pow(2.0, floor(fract(vStringCoords.x) * 4.0) + (floor(vStringCoords.y * 5.0) * 4.0))), 2.0));
}
void mainImage(out vec4 fragColor, in vec2 fragCoord) {
	vec3 vColour = vec3(0);
	vec2 vFontSize = vec2(8.0, 15.0);
	vColour = mix(vColour, vec3(1.0, 0.0, 1.0), PrintValue((fragCoord - vec2(100.0, 205.0)) / vFontSize, mod(iTime, 60.0), 2.0, 0.0));	
	fragColor = vec4(vColour, 1);
}
void main() {
  vec4 color;
  mainImage(color, gl_FragCoord.xy);
  color.w = 1.0;
  gl_FragColor = color;
}   
```

# 成果物

https://embed.plnkr.co/plunk/RsZliK2hZsqEM7sZ

以上。
Android Studio エミュレーターでのエラー Qt platform plugin could be initialized ... 【備忘録】

## ■事象
Android StudioでADV Managerからエミュレーターを指定して、起動した時にエラーが出てきた

## ■エラー文
「This application failed to start because no Qt platform plugin could be initialized. Reinsalling the application may fix this problem」

## ■原因を探ってみる
グーグル検索したところ、他のソフトウェアで定義された環境変数がアプリケーションと競合するために発生しているので、アプリケーションを起動する前に、現在の環境から以下の変数を削除してください。とのことだったので、環境変数を見てみたが以下の環境変数は設定していない。なぜ？
・QT_PLUGIN_PATH
・QML2_IMPORT_PATH

## ■本当の原因
どうやら、C:\Users\{username}直下のAndroidStudioのSDKやら何やらにアクセスできないため発生していたらしい

usenamerフォルダ以下の、「読取り専用」「隠しフォルダ」の属性のチェックを外したら無事に起動するようになった。
そんなバカな
Failed to set locale, defaulting to C.UTF-8 対策

## Failed to set locale, defaulting to C.UTF-8 が出てしまう場合
何かのコマンドを打つたびにこんなメッセージが出てしまう場合

```
Failed to set locale, defaulting to C.UTF-8
```

日本語向けパッケージがインストールされてないからっぽい。

```
# dnf -y install langpacks-ja
```

ロケールをセット

```
# localectl set-locale LANG=ja_JP.UTF-8
```

同じコマンドを打って確認

```
# dnf -y install langpacks-ja
メタデータの期限切れの最終確認: 0:10:14 時間前の 2022年04月27日 10時33分16秒 に実施しました。
パッケージ langpacks-ja-1.0-12.el8.noarch は既にインストールされています。
依存関係が解決しました。
行うべきことはありません。
完了しました!
```
Twitterクローンを作ります #35 通知(3)

未読の通知件数の取得は、ページ遷移のタイミングで行うことにしましょう。

```javascript:client/src/main.js
import UIkit from "uikit";
import Icons from "uikit/dist/js/uikit-icons";
import { createApp } from "vue";

import App from "./App.vue";
import router from "./router";
import store from "./store";

import "uikit/dist/css/uikit.min.css";
UIkit.use(Icons);

router.beforeEach(async (to, from, next) => {
  if (to.matched.some((record) => record.meta.loginRequired)) {
    let user = store.state.userLoggedIn;
    if (user && user._id) {
      store.dispatch("loadUnreadNotifications");
      next();
    } else {
      await store.dispatch("loginCheck").catch(() => {
        // noop
      });
      user = store.state.userLoggedIn;
      if (user && user._id) {
        store.dispatch("loadUnreadNotifications");
        next();
      } else {
        next({ path: "/login" });
      }
    }
  } else {
    next();
  }
});

createApp(App).use(store).use(router).mount("#app");
```

メニューに表示します。

```vue:client/src/components/SideNav.vue
<template>
  <ul class="uk-iconnav uk-iconnav-vertical uk-padding">
    <li>
      <router-link
        to="/"
        uk-icon="icon: home; ratio: 2"
        uk-tooltip="title: ホーム; pos: right"
      ></router-link>
    </li>
    <li>
      <router-link
        to="/search"
        uk-icon="icon: search; ratio: 2"
        uk-tooltip="title: 検索; pos: right"
      ></router-link>
    </li>
    <li class="uk-inline">
      <router-link
        to="/notifications"
        uk-icon="icon: bell; ratio: 2"
        uk-tooltip="title: 通知; pos: right"
      ></router-link>
      <span
        class="uk-badge uk-position-top-right uk-margin-small-top"
        v-if="unreadNotificationCount"
      >
        {{ unreadNotificationCount }}
      </span>
    </li>
    <li>
      <router-link
        to="/messages"
        uk-icon="icon: mail; ratio: 2"
        uk-tooltip="title: メッセージ; pos: right"
      ></router-link>
    </li>
    <li>
      <router-link
        to="/profile"
        uk-icon="icon: user; ratio: 2"
        uk-tooltip="title: プロフィール; pos: right"
      ></router-link>
    </li>
    <li>
      <a
        @click="logout"
        uk-icon="icon: sign-out; ratio: 2"
        uk-tooltip="title: ログアウト; pos: right"
      ></a>
    </li>
  </ul>
</template>

<script>
import UIkit from "uikit";
import { computed } from "vue";
import { useRouter } from "vue-router";
import { useStore } from "vuex";

export default {
  setup() {
    const store = useStore();
    const router = useRouter();

    const logout = () => {
      store
        .dispatch("logout")
        .then(() => {
          router.push("/login");
        })
        .catch((error) => {
          UIkit.notification(error.response.data.error.message, {
            status: "danger",
          });
        });
    };

    const unreadNotificationCount = computed(() => {
      return store.state.unreadNotificationCount;
    });

    return {
      logout,
      unreadNotificationCount,
    };
  },
};
</script>

```

![スクリーンショット 2022-03-27 11.06.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2536525/d30c4971-5c38-9402-b4c9-97a41a71dda9.png)

よさそうですね。
VBAマクロにて日付入力の手間を省くプログラムを作ってみた！　~PART2~

さて、前回のPART1ではプログラム全体を掲載しただけになりましたが、今回は各コードの役割を解説していきます。

①画面処理の簡略化
```vb
Sub 月日入力()

'    Yes/No判定及び画面処理の省略

    Application.ScreenUpdating = False  //画面一つ一つの処理の動きを省略
    Application.DisplayAlerts = False　 //処理中のYes/No判定を省略

```

②変数を定義しています。（変数名はテキトーです。すみません！！！）
```vb
    
'    変数の定義

        Dim nen As Long
        Dim tsuki1 As String
        Dim hantei1 As String
        Dim box As Date
        Dim y As Long
```
③次月初日の日付取得とコメントにありますが、任意の日付から1ヶ月を想定しております。
```vb
'    次月初日の日付取得

        box = Application.InputBox _
            (prompt:="日付を入力してください", Title:="日付入力", Type:=1)

///インプットボックスを呼び出し、任意の日付を入力し値を取得
```
④月ごとの日数判定（30日、31日、28日、29日など）
```vb
'    月ごとの日数判定のための変数に、月の値を格納

        hantei1 = Mid(Str(box), 7, 2)
///ExcelでもおなじみMid関数を使用し、月の値をhantei1に格納
```

⑤コメントの通りです。
```vb
'    西暦及び該当月を取得し、D2セルに表示
        
        nen = year(box)
        Sheets("家計簿").Range("D2").Value = nen & "年" & hantei1 & "月"
        y = Day(DateSerial(nen, 3, 1) - 1)　///うるう年対応
```
⑥条件分岐により、1月分の日付をオートフィル（Select Case使用）
```vb
'    月日入力及び月末までオートフィル
        
        Select Case hantei1
        
        
'       インプットボックスを閉じるまたはキャンセルボタン押下
        
            Case False
            
            End
            
            
'       2月の場合
            
            Case Is = "02"
            
                If y = 29 Then

                    Sheets("家計簿").Range("B9").Value = box
                    Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B37"), xlFillValues)
                    Sheets("家計簿").Range("B38:B39").Value = ""
                    
                Else
                  
                    Sheets("家計簿").Range("B9").Value = box
                    Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B36"), xlFillValues)
                    Sheets("家計簿").Range("B37:B39").Value = ""
                
                End If
                
            End
            
            
'       30日の月の場合
            
            Case Is = "04", "06", "09", "11"
            
                Sheets("家計簿").Range("B9").Value = box
                Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B38"), xlFillValues)
                Sheets("家計簿").Range("B39").Value = ""
                
                
            End
            
            
            Case Else
            
                Sheets("家計簿").Range("B9").Value = box
                Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B39"), xlFillValues)
                
            End
            
            
        End Select
        
        
End Sub
```

以上となります。これを参考に日付入力の呪縛から解放されていただければ幸いです！
plunkerでshadertoy sandbox

# 概要

plunkerでshadertoyのglsl動かしてみた。
iMouseを実装してみた。

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/2bb7b3f6-f20e-1b16-d9f9-7fb3f3304ea2.png)


# 成果物

https://embed.plnkr.co/plunk/jSEoG0AeM0c8SH4P

以上。
plunkerでPixelArtGeometry

# 概要

plunkerでPixelArtGeometryやってみた。

# 参考にしたページ

https://qiita.com/Urushibara01/items/1362e5ca6b519fb7963f

# 写真

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/99e05952-35c5-c6af-4ffa-eae47c480aea.png)


# 成果物

https://embed.plnkr.co/plunk/KgTGmkGCzWGNvH6b

以上。
LaravelのクエリビルダとEloquent

# クエリビルダとEloquent
***クエリビルダはSQLを作成し、実行***します。
戻り値はDBの取得値をコレクションにしたものみたいです。

***Eloquentの戻り値はEloquentモデルオブジェクト***みたいです。

# 両者の書き方


⚫︎***クエリビルダ書き方***
```FolderController.php
public function index()
    {
$folder = DB::table('folders')->where('id',1)->first();
        return $folder->id;
}
```
whereの書き方も参考にしてください。

⚫︎***Eloquent***
```FolderController.php
public function index()
    {
     $folder = Folder::where("user_id", "=",11)->first();
     return $folder->id;
}
```

出力は両者とも***１***です。



どういうデータが入っているのか

```FolderController.php
public function index(){
$folders = Folder::get();//データを全取得
return view('folder.index', ['folders' => $folders]);
}
```

```folder/index.blade.php
#都合により省略
            
{{-- <html> --}}
<head>
<title>フォルダ一覧</title>
</head>
 <table border = "1"> 
    <tr>
        <th>id</th>
        <th>user_id</th>
        <th>title</th>
        <th>created_at</th>
        <th>updated_at</th>
    </tr>
    
    @foreach($folders  as $folder) 
    <tr>
        <td>{{$folder->id }}</td>  
        <td>{{$folder->user_id}}</td>
        <td>{{$folder->title}}</td>
         <td>{{$folder->updated_at}}</td>
        <td>{{$folder->created_at}}</td> 
    </tr> 
      @endforeach
</table>

{{-- </html> --}}

```
![スクリーンショット 2022-04-27 9.58.45.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1748789/f615d2eb-a18b-9882-5e0d-1519373919a0.png)



# 資料

https://cloudsmith.co.jp/blog/backend/laravel/2021/06/1817294.html

https://qiita.com/shosho/items/5ca6bdb880b130260586


https://cloudsmith.co.jp/blog/backend/laravel/2021/06/1817294.html
Cannot connect to the Docker daemon 再起動後は気をつけよう

超初歩的ミスの備忘録です。

普段通り、dockerのコンテナを起動しようとしたら起動しないというハプニングが起きました。
```
$ docker compose up -d
Cannot connect to the Docker daemon at unix:///var/run/docker.sock. Is the docker daemon running?
```
# 結論

原因はdocker Desctopが立ち上がっていないというオチでした。
些細な事ですが、パソコン再起動の後は気をつけようと思います。。笑
大規模データ分析基盤の個別相談受付中です！　

![R2_Sales Strategy_25apr2022.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2634867/fb4ed027-7dc3-3061-c395-ea73ec23cd3a.jpeg)
おはようございます。
今までは、GraalVMの機能を中心に記事を書いていたのですが、「具体的な実装方法」に関しても、今後は書いていきたいと思います。
今回は、GraalVMの「最適化されたJITコンパイラー機能」（主要３機能の内の１つ）を活用して、大規模データ分析基盤を、コスト削減しながら、より高速に動かす実装方法に関して、議論します。

＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝＝
リアルタイムデータ処理システムにおいても、Graal VMの「最適化されたJITコンパイラ機能」が威力を発揮致します。

■　GraalVMカタログ（P7)
https://www.oracle.com/a/ocom/docs/graalvm-enterprise-white-paper.pdf

>While there are many sophisticated performance tuning options and techniques available in Apache Spark, one of the easiest ways to improve overall performance is to run it on GraalVM Enterprise.

■ Facebook社様が、GraalVMを使用して、Apache Sparkを高速化させた事例　
https://medium.com/graalvm/graalvm-at-facebook-af09338ac519

＞The Facebook team used GraalVM Community as a replacement of OpenJDK. In this scenario, migration to GraalVM is very easy — it’s just a matter of switching runtime, with no changes required for the application code.
＞GraalVM can significantly speed up Spark workloads. The Renaissance benchmark suite’s Apache Spark benchmarks show an average speedup 1.1x for Community and of 1.42x for Enterprise, with some benchmarks running up to 4.84x faster.

■ Apache SparkをGraalVM上で動くと、メモリー消費を抑えつつ高速化する実証データ
https://blogs.oracle.com/java/post/apache-sparklightning-fast-on-graalvm-enterprise

>As you can see, for a range of benchmarks Apache Spark consumes less memory and runs faster on GraalVM Enterprise than on OpenJDK. If you’re running Apache Spark in production and would like to use fewer compute resources while improving throughput it’s as easy as switching to GraalVM Enterprise. To try it out for yourself simply install GraalVM Enterprise, set your JAVA_HOME, and go! Download GraalVM Enterprise today.
【rails】image_tagで超簡単に画像を丸く(円形に)くり抜いて表示する方法

久々に、railsの`erb`を使う機会があり、画像を丸く(円形に)くり抜いて表示する要件があったので調べました。



左の画像を、アスペクト比を崩さずに右のように円形にくり抜いて表示したいです。

<img width="250" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425910/243934af-0647-528a-b0ef-23b33184b469.png"> 
<img width="200" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/425910/22041a51-ad87-9c32-0175-50d7ae6c16d4.png">



結論
-
```erb
<%= image_tag "画像パス or URL", style: "border-radius: 50%; width: 200px; height: 200px; object-fit:cover;" %>
```
※ `width`と`heihgt`は同じ値にしてください。
※ cssは都合上インラインスタイルでやってます。一般的にはcssファイルに分けた方がよいそうです。


参考
-

https://developer.mozilla.org/ja/docs/Web/CSS/object-fit
PHP　sprintf　フォーマットに沿って文字や数字を代入・先頭に0を追加する

## 用途
文字や数字をフォーマットに沿って代入したいときに使う。
先頭に0を追加したいときに使う。

## 使用方法
```php:書き方
sprintf(表示したい文字列のフォーマット, 表示したい文字１, 表示したい文字２, ....)
```
### フォーマットについて（記述したもの以外にもあります）
`%s` には文字列、`%d` には数値を代入できる。

例
「〇〇くんは、おもちゃを〇個持っています。」という文に代入する場合は下記のフォーマットになる。
```
%s くんは、おもちゃを %d 個もっています。
```

「田中くんは、おもちゃを3個持っています。」という文を作る場合は下記のようになる。
```php:
sprintf("%sくんは、おもちゃを%d個もっています。", "田中", "3")
```
※表示したい文字には変数を入れることもできます。
```php:
$name = "田中";
$number = "3";
sprintf("%sくんは、おもちゃを%d個もっています。", $name, $number)
```

### 先頭に0を追加する
```php: 
$hoge = "5"
echo  sprintf("%02s", $hoge).'<br>'; // 05
echo  sprintf("%03s", $hoge).'<br>'; // 005
echo  sprintf("%04s", $hoge).'<br>'; // 0005
echo  sprintf("%05s", $hoge).'<br>'; // 00005
```
`%02d` が先頭に0を１つ追加する。数によって追加される0の数が変わってくる。
VBAマクロにて日付入力の手間を省くプログラムを作ってみた！　~PART1~

今回はVBAにて日付入力の手間を省くプログラムについてご紹介いたします。

皆さんはこんな経験ございませんか？月の1日を入力し、フィルハンドルを使って日付をコピーするという作業です。これって面倒ですよね！？今回はマクロボタンをポチッと押すだけで、各月の1日を入力すれば日付が自動で反映されるプログラムを紹介いたします。

フィルハンドルを使用
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/079340e7-9de4-4016-a3a8-8ff1d4fe2f38.png)

このマクロにて簡略化
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/ceecc086-13c3-857d-2fa1-8acf928df37e.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2631873/206c9726-ff77-0857-d8d8-3e83676fceb8.png)
画面右上の"月日入力"ボタンを押して、任意の月の1日の日付を入力するとその月の日付がすべて入力される仕様となっております。そのコードを下に記載します。

```vb
Sub 月日入力()

'    Yes/No判定及び画面処理の省略

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False
    
    
'    変数の定義

        Dim nen As Long
        Dim tsuki1 As String
        Dim hantei1 As String
        Dim box As Date
        Dim y As Long
        
               
'    次月初日の日付取得

        box = Application.InputBox _
            (prompt:="日付を入力してください", Title:="日付入力", Type:=1)
            
    
'    月ごとの日数判定のための変数に、月の値を格納

        hantei1 = Mid(Str(box), 7, 2)
        
             
'    西暦及び該当月を取得し、D2セルに表示
        
        nen = year(box)
        Sheets("家計簿").Range("D2").Value = nen & "年" & hantei1 & "月"
        y = Day(DateSerial(nen, 3, 1) - 1)
        
            
'    月日入力及び月末までオートフィル
        
        Select Case hantei1
        
        
'       インプットボックスを閉じるまたはキャンセルボタン押下
        
            Case False
            
            End
            
            
'       2月の場合
            
            Case Is = "02"
            
                If y = 29 Then

                    Sheets("家計簿").Range("B9").Value = box
                    Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B37"), xlFillValues)
                    Sheets("家計簿").Range("B38:B39").Value = ""
                    
                Else
                  
                    Sheets("家計簿").Range("B9").Value = box
                    Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B36"), xlFillValues)
                    Sheets("家計簿").Range("B37:B39").Value = ""
                
                End If
                
            End
            
            
'       30日の月の場合
            
            Case Is = "04", "06", "09", "11"
            
                Sheets("家計簿").Range("B9").Value = box
                Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B38"), xlFillValues)
                Sheets("家計簿").Range("B39").Value = ""
                
                
            End
            
            
            Case Else
            
                Sheets("家計簿").Range("B9").Value = box
                Call Sheets("家計簿").Range("B9").AutoFill(Range("B9:B39"), xlFillValues)
                
            End
            
            
        End Select
        
        
End Sub
```

これが、一連のコードの流れになります。コメントも記載しておりますので、プログラムコードの意味は理解できるかと思いますが、次回解説も入れたいと思います。
StoryboardでUITableViewControllerをembedしたいとき

# 前提
xcode : 13.2.1
Swift : 5.5.2

# 事象
viewController内にcontainerViewを生成すると、自動的に新しいviewControllerがembedされた状態で生成されるが、viewControllerの上にTableViewを乗せたところ以下のエラーが発生:warning:

`error: Illegal Configuration: Static table views are only valid when embedded in UITableViewController instances`

![スクリーンショット 2022-04-26 15.59.22.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629280/34655e1b-1661-f767-9746-fb0e8631199a.png)



え、、、。
でもviewController自動的に生成されてるし、どうやってUITableViewController作るん、、:thinking:

# 解決方法
生成されたviewControllerを削除し、新しくUITableViewControllerを選択
![スクリーンショット 2022-04-26 16.23.13.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629280/02e83605-0727-2c72-da43-b626b9527efe.png)

先程生成したcontainerViewからUITableViewControllerまでcontrolボタンを押しながら、ドラッグする
そして、Segue選択メニューが開くのでEmbedを選択
![スクリーンショット 2022-04-26 16.23.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629280/0c5e7e3c-33c8-4893-ef68-8f20449d6d45.png)

buildすると無事エラーが解消:raised_hands_tone2:

![スクリーンショット 2022-04-26 16.26.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2629280/45c86761-9f5c-5e14-e1c9-a7a1f87b6478.png)

# 感想
自動でviewControllerが生成されてしまうので、一旦削除するという方法をなかなか思い浮かぶことができず苦戦したため、今回記事にしてみました。
「トートロジー」と「矛盾」の論理回路はやっぱりNANDから作れる

![スクリーンショット 2022-04-27 9.02.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380862/043ff5a6-ae2d-194a-e12d-cd14f0921d49.png)
結論：上がトートロジー、下が矛盾です。

Wikipediaの真理値表を眺めていると入力にかかわらず常に真、常に偽である項目があることに気づきました。
これがトートロジーと矛盾です。
![スクリーンショット 2022-04-27 9.04.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2380862/135059c4-bc25-153b-7352-501eb2e5de95.png)
Nand2TetrisによるとNAND素子で全ての演算ができるということだったので、トートロジーと矛盾もNANDから導出できないか考えてみました。
で、できたのが冒頭の図です。
NOT、OR、ANDしか使っていないので、これはやはりNANDから導けるということですね。
この回路に使用価値があるのかといわれると微妙ですが（VDD、GNDの方がシンプル）、NANDの完全性を確かめられた気がします。
VScodeのプラグインBracket Pair Colorizer 2が非推奨になってた件について

# Bracket Pair Colorizer 2ってなに？
Bracket Pair Colorizer 2はコード内の括弧を階層別に色違いにできる拡張機能でコードの視認性が向上するというモノでした

詳しくは以下の公式からご確認ください↓

https://marketplace.visualstudio.com/items?itemName=CoenraadS.bracket-pair-colorizer-2

# Bracket Pair Colorizer 2メンテ終了のお知らせ
先日ふとVScodeのプラグインを整理していたらこんな表示が
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935471/85bcb339-555a-2fee-6299-28d88b946726.png)

うん？[Depreciated]とな？
Depreciated、直訳すると「非推奨」とか「廃止」という意味



そう！いつのまにかメンテが終了していたのだ！~~便利だったのにどうして・・・~~

というわけで早速代替手段を探します

# VScodeの標準機能になってた件

https://dev.classmethod.jp/articles/replace-bracket-pair-colorizer-2-to-vscode/

検索してみるとどうやらVS Code 1.60からBracket Pair Colorizer 2の機能が標準搭載されていた模様~~パッチノートはキチンと見よう！~~

つまり公式で搭載されたからわざわざプラグイン使わなくても良いよねと言うことらしいです

というわけで早速設定していきます

# 設定方法
Bracket Pair Colorizer 2 はアンインストールしましょう
無効化でも構いません

設定から``bracket``と検索すると簡単に見つかります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935471/82db5320-dde2-24b0-c7ef-9f60d4971929.png)

デフォルトで無効化されているので以下の部分のチェックボックスから有効化します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/935471/ce5e5a08-494b-1946-0f06-04893097ea71.png)

以上で設定完了です

# おわりに
カスタマイズ性はBracket Pair Colorizer 2のほうが上らしいですが個人的には色分けさえできてればよかったので満足です

Twitterもやっています良かったらフォローお願いします→[@mzsn53](https://twitter.com/mzsn53 "Twitter@mzsn53")
100日後くらいに個人開発するぞ！day009

## 今日はトップ部分を作ってみた！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/50a239de-db3d-46ac-1558-de97880b7651.png)

## 今日の作品

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2632394/552e87b8-a17e-a4cb-b1fe-17c91e1b0485.png)


## 今日の学び

### 背景画像を指定する方法
- CSSで背景画像を指定するにはbackground-imageプロパティを用いる
    - 定型文：`background-image: url(画像のURL);`

### 背景画像の大きさを指定する方法
- background-imageで指定された背景画像は表示範囲を埋め尽くすまで繰り返し表示される性質がある
- `background-size: cover;`を指定すると1枚の画像で表示範囲を埋め尽くすように画像の大きさが拡大縮小する


### 要素を中央に配置する方法
- 中央に配置するためにはmarginの左右にautoを指定する必要がある
    - 例：`margin:0 auto;`
- marginにautoを指定する場合は必ずwidthを併せて指定する
- 上下のmarginにautoを指定することはできない

### 要素を透過させる方法
- 要素を透明にするにはopacityプロパティを使う
    - 例：`opacity:0.5;`
- 透明度は完全に透明「0.0」から完全に不透明「1.0」の間で指定します。


### 文字の間隔を指定する方法
- letter-spacingプロパティを用いることで文字の間隔を指定できる
    - 例：`letter-spacing：10px；`

### インライン要素でwidthやheightを指定する方法
- `<a>`タグなどインライン要素はwidth/height/marginを指定できない
- インラインブロック要素を用いるとインライン要素でもwidth/height/marginを指定できる
- displayプロパティを使うとインラインブロック要素に変更できる
    - 例：`display:inline-block;`
- displayプロパティでは他の要素を指定することができる
    - block（ブロック要素）
    - inline-block（インラインブロック要素）
    - inline（インライン要素）

### 複数のクラスを指定する方法
- 複数のクラスを細かく指定したい場合はクラス名を半角スペースで区切ることで指定することができる
    - 例：クラス名を半角スペースで区切る（HTML）
        - `<div class="button blue"></div>`
        - `<div class="button red"></div>`
    - 例：区切られたクラス名を一部だけ指定する（CSS）
        - `.button{font-size:10px;}`
        - `.blue{color:blue;}`
        - `.red{color:red;}`
Nimでインスタンスから型を取得して引数に設定　ー　typedesc型引数の設定

# １．「型」自体を引数にするためtypedescを利用

コードは以下。

```nim:main.nim
# 型に関する情報を取得するモジュールを読み込む
import std/typetraits

# 型名を表示するプロシージャ
# typedesc型で型を受ける
proc showTypeName(varType: typedesc) =
  echo varType.name

# 実行
when isMainModule:

  # フィールドなしの型を作成
  type Sample = object

  # 型を引数に設定し実行
  showTypeName(Sample)


```

# ２．インスタンスから型を取得し、typedescの引数に設定

以下は、前掲のコードの一部を修正したもの。
プロシージャの呼び出し部分のみ。
ポイントは、「typedesc[インスタンス.type]」の部分。

```nim:main.nim

when isMainModule:
  
  # フィールドなしの型を作成
  type Sample = object

  # インスタンス化
  var sam = Sample()

  # インスタンスから型を取得し、typedescを設定
  showTypeName(typedesc[sam.type])

```
アドレスのホスト名とドメイン名の違い

# ドメインについて

## なぜ、ユーザはIPアドレスを叩かなくても任意のサイトにアクセスできるのか？

ドメイン名**とIPアドレスが対応づけられているため**

そのドメイン名とIPアドレスの紐付けを効率よく行なっているシステムがDNS(Domain Name System)

DNSでは、rootからTLD(Top Level Domain)、SLD(Second Level Domain)と階層構造=木構造となっている。TLDの管理はICANNという組織が担っている。

## FQDNとは?

完全修飾ドメイン名と呼ばれる、ホスト名とドメイン名を含むもの。また、DNSのrootからノードまでの全てのルートをまとめたラベルのこと

例えば、root→jp→co→hogehoge→wwwなら、www.hogehoge.co.jpとなる。

**ホスト名**

- ネットワークに接続されたデバイスやコンピュータの名前
- 例：www

**ドメイン名**

- ウェブサイトにユーザがアクセスするために用いられるウェブサイトのアドレスの名前
- 例：hogehoge.co.jp

## 代表的なTLDの種類


- ccTLD(country code TLD)
    - 国コードトップレベルドメイン、国ごとに割り当てられたトップレベルドメイン
    - ツバル(tv)はテレビの略称と同じなので、民間に売り出している。
- gTLD(generic TLD)
    - 分野別トップレベルドメイン

ICANNによってccTLDとgTLDがそれぞれの各TLDの管理組織に委任を行なっている。

## 参考サイト

[https://www.nic.ad.jp/ja/basics/terms/ccTLD.html](https://www.nic.ad.jp/ja/basics/terms/ccTLD.html)

[https://jprs.jp/related-info/about/type/#:~:text=トップレベルドメインには,Top Level Domain）があります。](https://jprs.jp/related-info/about/type/#:~:text=%E3%83%88%E3%83%83%E3%83%97%E3%83%AC%E3%83%99%E3%83%AB%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%AB%E3%81%AF,Top%20Level%20Domain%EF%BC%89%E3%81%8C%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)

[https://qiita.com/bezeklik/items/963f4f4630607a42d509](https://qiita.com/bezeklik/items/963f4f4630607a42d509)

[http://www.differencebetween.net/technology/difference-between-hostname-and-domain-name/](http://www.differencebetween.net/technology/difference-between-hostname-and-domain-name/)
boto3を使って、さくらのオブジェクトストレージにファイルをアップしてみる

# はじめに
最近になって、さくらのクラウドを触り始めた初心者（筆者）が四苦八苦しながら
オブジェクトストレージにファイルをアップロードしてみたのが前回の内容。

https://qiita.com/nkmr_RL/items/9b15c2eaddb97a830887

上記のアップロードができるようになったら
**「なんかPythonから操作できる気がしてきたわ...」**
と思い立ったので、Pythonから操作してみるのが今回の内容。

あと、先に言っておきますが、**AWS公式ライブラリboto3を使った方法**になるので
**さくらインターネットの公式サポート対象外のやり方**です。（多分）

だから、1年後には使えなくなっているかもしれない。（バナージ...悲しいね）

# 予想される検索ワード
以下、この記事を求めているであろう方が入力しそうな
（というか実際に私が必死で検索した）検索ワードです。

さくらのクラウド, オブジェクトストレージ, アップロード方法, Python, boto3

# 実行環境
- ubuntu 18.04（Dockerで構築）
- Python 3.7
- boto3 1.22.0

# 手順
## オブジェクトストレージにてバケットを作成する
前回記事同様、以下のマニュアル通りなので多分ハマらないです。
（サイト作成時のアクセスキーIDとシークレットアクセスキーのメモは忘れずに！）

https://manual.sakura.ad.jp/cloud/objectstorage/about.html#id8

## boto3をインストール
pipでboto3をインストールします。

```console
$ pip install boto3
```

## オブジェクトストレージへのアクセス確認
boto3からさくらのオブジェクトストレージ内のバケット一覧が取得できるか確認します。

1. test_boto3.pyを作成します。（場所は多分どこでもOK）

    ```console
    $ vi test_boto3.py
    ```

    test_boto3.pyの中身はこんな感じ。

    ```test_boto3.py
    import boto3

    s3 = boto3.resource('s3',
        endpoint_url = "https://s3.isk01.sakurastorage.jp",
        aws_access_key_id = [サイト作成時のアクセスキー],
        aws_secret_access_key = [サイト作成時のシークレットアクセスキー],
        region_name = 'jp-north-1'
    )

    for bucket in s3.buckets.all():
        print(bucket)
    ```

1. test_boto3.pyを実行して、作成したテストバケットが表示されるか確認します。

    ```console
    $ python test_boto3.py
    ```

## オブジェクトストレージにファイルをアップする

ubuntu上にあるtest_file_py.txtをオブジェクトストレージにアップしてみます。

1. /tmpフォルダ直下にtest_file_py.txtを用意しておきます。

    ```console
    $ vi /tmp/test_file_py.txt
    （中身は適当に記述して保存しておきます）
    ```

1. test_boto3.pyに以下の記述を追加します。

    ```python:test_boto3.py
    # アップロード先のバケット名
    bucket_name = "test-bucketxxxx"
    
    # アップロードするファイル
    upload_file = "/tmp/test_file_py.txt"
    
    # オブジェクトストレージ上で表示されるファイル名
    obj_name = "test_file_py.txt"
    
    # ファイルのアップロード
    s3.Bucket(bucket_name).upload_file(upload_file, obj_name)
    ```

1. test_boto3.pyを実行します。

    ```console
    $ python test_boto3.py
    ```

1. Webブラウザでオブジェクトストレージにファイルがアップされているか確認します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/6bc5c910-4f65-1611-4cfc-758ecba5d43c.png)

# 補足というか余談
boto3を使用する際、boto3.client()とboto3.resource()があって混乱しました。

どうやらboto3.client()は低レイヤーサービスへのアクセス（辞書型データが返ってくる）
boto3.resource()は高レイヤーサービスへのアクセス（s3オブジェクトが返ってくる）
という感じのようです。

boto3.resource()の方がコードの可読性が高くなるので
基本的にboto3.resource()を使っておくのが正解のようです。

# おわりに
AWS様の力をお借りしつつ、Pythonを使って
さくらのオブジェクトストレージにファイルをアップすることができました。

いつ使用できなくなるのか若干の不安はありますが、
Python上から操作できるのは、やっぱり便利ですね。

今後も「Python × さくらのクラウド」な小技を見つけたら
記事に残したいなと（現時点では）思っています。

# 参考記事など
- [Python boto3 でAWSを自在に操ろう ~入門編~](https://qiita.com/kimihiro_n/items/f3ce86472152b2676004)
- [boto3でのendpoint_url=Noneの指定](https://qiita.com/takanattie/items/7c6ec6bfcfbe7926f9e9)
- [Boto3 ClientsとResourcesの違いについて](https://note.com/gota_morishita/n/ncd2c26e0c5ae)
【WSL2】Win11でUbuntu環境を整えようとしたら結構失敗した話

## はじめに
* シェル芸を練習しようとしてUbuntu環境を整えようと思い立った。
* Linuxなにもわからんけどとにかくやってみる
* 最終的にはWSLインストールできました。うまくいった方法は③を参照ください。
* WSL2のインストール方法が書いてあるブログはいっぱいあったけど、起動後の感じが書かれていなくてインストール前はどきどきした
（いまのWindowsOSがLinuxOSに置き変わっちゃうんじゃないかと思ってどきどきしてた（そうはならなかった））

## 試したこと①公式ドキュメントを見た
https://docs.microsoft.com/ja-jp/windows/wsl/install

公式ドキュメントを見ながら下記コマンドを打った。
インストールがある程度の％で止まってしまい、進まなくなってしまった。
```言語:
wsl --install
```

## 試したこと②Windows StoreからUbuntuをダウンロードする
https://ygkb.jp/7291

```言語:
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
```
管理者モードのPowerShellで上記コマンドを実行しても、ファイルを開く画面が出てきて（？）うまくいかなかった。
『プログラムと機能』からも設定できるということで設定して次へ進む。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692485/df8f5cb6-bd70-204a-bcfa-0f10e34ecf3f.png)

いけそうだぞ！！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692485/c9c5f10c-8e27-7366-df05-bc1bef7196f1.png)

なかなかインストール終わらないな……。
あっ▽押したらメッセージ見れそう。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692485/d2a50733-22a7-8df7-6493-0ea1795f461c.png)

ウワァーやっぱりダメそう。

```言語:
The Windows Subsystem for Linux optional component is not enabled. Please enable it and try again.

See https://aka.ms/wslinstall for details.

Press any key to continue...
```
optional componentがnot enabledと言われている。
オプション設定が何か足りないっぽい……。
貼られてるリンクは①で参照したページだ……。

## 試したこと③Windows StoreからUbuntuをダウンロードする
https://www.kkaneko.jp/tools/wsl/wsl2.html#S1

手順通りに進めようとするけど、まず「Windows の機能の有効化または無効化」に「Hyper-V」の項目がない。
まあ一応次に進むか……。
記事の通りに設定していって、最後にwslインストールコマンドを叩く。

```言語:
wsl --install -d Ubuntu-20.04
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692485/6105b5db-93de-d534-f738-fa58409914ba.png)
オッ？

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692485/8ca3aa2d-a523-e60a-c077-e7df5c6b87d8.png)
いけそうだぞ！！！！
Usernameとpasswordを適当に設定する。

ヤッター！！！！！！

## 起動できた
https://gihyo.jp/book/2021/978-4-297-12267-6

シェル・ワンライナー本の1つ目のコマンドを叩いてみるぞ！！
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/692485/422cb399-164b-dc55-e0b8-14674e9d3d51.png)

```言語:
akami@MyComputer:~$ echo $0 　// bash もしくは-bashが返るはず
-bash
```

ヤッターーーーー！！！！！！

起動した感じはTerminalっぽい。パソコンを動かすOS自体がLinuxになっちゃわなくてよかった……。

## 終わり
あきらめない心が大事
NVMe SSDの寿命消費率(Percentage Used)が増えたので調べてみた（その2）

# はじめに
　以前[この記事](https://qiita.com/ken-yossy/items/5454c1e02a0b890448d4)で、私が日々の仕事で使用しているノートPCに搭載されたNVMe SSDのPercentage Usedという統計情報が増えたことをご紹介しました。

　この"Percentage Used"とは、NVMe仕様<sup>[1]</sup>が定めるSelf-Monitoring Analysis and Reporting Technology (S.M.A.R.T.)情報のひとつで、日本語では「寿命消費率」と言えるような数値です（[以前の記事](https://qiita.com/ken-yossy/items/4d1f84f3c783caccc336)参照）。

　前回この数値が増えたのは2021年8月のことでしたが、先日またこの数値が増えました！

　具体的には14 (%)から15 (%)に増えました。

　そこで前回数値が変化してから今回再度数値が変化するまでの状況をまとめ、考察します。

　なお、「寿命消費率」という呼びかたは"Percentage Used"に対して私が勝手に付けたものであり、公式な呼びかた（日本語訳）ではありません。

# まとめ
* Percentage Usedは、NVMe仕様に規定された「メーカー保証寿命に対する消費率(%)」で、計算方法はメーカー依存
* Percentage Usedの増加（寿命消費の進行度合い）を見る限り、引き続き、TBW算出に用いられた「使いかた」よりも「優しい使いかた」をしている模様

# おさらい：寿命消費率(Percentage Used)とは
　NVMe仕様のSelf-Monitoring Analysis and Reporting Technology (S.M.A.R.T.)情報における「寿命消費率(Percentage Used)」とは **メーカー依存の寿命使用度見積もり（百分率）** です。

　この「寿命消費率」は、NVMe仕様で規定された標準項目中で唯一寿命を直接的に表現した数値で、メーカー基準の保証寿命を使い尽くした状態が100 (%)になるように現在の使用状況を正規化した値です。

　なおこの"Percentage Used"は100を超えることもあり得ます（100を超えることを仕様として許容している）。これは、メーカー基準の保証寿命と実際のSSDの寿命に差がある（後者のほうが長い）ためです。

　詳細は[以前の記事](https://qiita.com/ken-yossy/items/5454c1e02a0b890448d4)をご覧ください。

# 以前からこれまでのホストからの書き込み量推移
　今回、Percentage Usedが14から15に増えました。

　このPC (SSD)の通算使用期間は3年と約3か月です。つまり約3.25年経過してメーカー保証寿命の15%を消費した、ということになります。

　昨年（2021年）13から14に増えた時から、今回14から15に増えるまでの累積書き込み量の様子は、SSDから取得したS.M.A.R.T.情報によると以下のようになります。

![前回Percentage Usedが増えてからのホストからSSDへの累積データ書き込み量](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/439683/a9f40c8b-8133-378d-74d1-d3605550ebdb.png "前回Percentage Usedが増えてからのホストからSSDへの累積データ書き込み量")
図：前回Percentage Usedが増えてからのホストからSSDへの累積データ書き込み量

　前回Percentage Usedが13から14に増えるまでは約4.8 TB書き込んでいました。同様に調べると、今回Percentage Usedが増えるまでに約5.9 TB（約5.5 TiB）書き込んでいました。

　Percentage Usedが15に変化した時点でのホストからの累積データ書き込み量は約102 TBです。

　このSSDのカタログスペック上のTBWは300 TBですので、同じくS.M.A.R.T.情報のData Units Writtenからの単純計算では34%消費したことになりますが、Percentage Usedはそれよりも低い値を示しています。

　同様にTBWとホストから書き込んだデータ量が一致した時にPercentage Usedが100になると仮定すると、単純計算ではPercentage Usedの1%は3 TBなので3 TB書き込むとPercentage Usedが1増えるはずですが、今回もPercentage Usedが1増える間にそれより多い量のデータを書き込んでいます。

　TBWもこのPercentage Usedも「SSDの使いかた」に依存しますので、この数値の「ずれ」が示すのは「この期間の**私のSSDの使いかたがTBW算出の前提となる使いかたよりもやさしい使いかたである**」ということです。

　逆に言えば、**TBWが「SSDの使いかた」に依存することの証拠**でもあります。

　もちろんこれは測定時点までの過去の話でありPercentage Usedの値が今後も同じペースで増えていくとは限らず、また今後「SSDにやさしくない使いかた」をするとPercentage Usedの増加スピードが上昇する可能性があります。

# まとめ
　今回の記事では、私が実際に使用しているノートPCに搭載されているNVMe SSDの「寿命消費率(Percentage Used)」が増えたことを取り上げて、前回増えた時から今回までのホストからの書き込み量などを調べ、状況を考察しました。

　SSDのS.M.A.R.T.情報をはじめとする統計情報も、他の機器の統計情報と同様に異常値がないか継続的に監視を続けることが重要です。

# References
[1] NVM Express, _"NVM Express Base Specification,"_ Revision 2.0b, Jan. 2022

# ライセンス表記
<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/"><img alt="クリエイティブ・コモンズ・ライセンス" style="border-width:0" src="https://i.creativecommons.org/l/by-sa/4.0/88x31.png" /></a><br />この記事は<a rel="license" href="http://creativecommons.org/licenses/by-sa/4.0/">クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンス</a>の下に提供されています。
ユーザーランドのgpioイベント

たまたま調べていて12-CURRENTの頃にgoogle summer of codeでユーザランドのgpioイベントが実装されている事に気がつきました。

https://wiki.freebsd.org/SummerOfCode2018Projects/UserSpaceGPIOinterrupts

このコードはFreeBSDのいくつかのシステムコールに対応していてINTRNGを使った仕組みのようです。開発時にはarmのSOCで確認していたようですが、mipsでもmediatekはINTRNGに対応しているので使えるのではないかと思いました。

従来はポーリングで状態変化を確認していましたが、あまり起きないイベントの場合、資源の少ないモジュールではコストがばかになりません。またポーリングの間隔によってはイベントを見逃す可能性もあります。

テストコードがtools/test/gpioeventsにあります。

いとしのRT3050(FON2305)用にZRouerでmipselをビルドしてみます。

```
WORLD_SUBDIRS+=tools/test/gpioevents
```

実行してみます。

```
# /usr/bin/gpioevents -f /dev/gpioc0 -s 12 er
time 1140.154975861 pin 12 state 1
```

ボタンを押して離すとプログラムが終了します。このボタンはプルアップされているので、離したときに、0->1の変化になり、それを拾います。

![gpio_intr.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/104066/e244dc1f-f122-fd99-d49c-d9e951241432.png)

ちゃんと見てないですがmips/mediatekのgpioは私がgpioppsのためにちょっといじっていて、それが効いているのかもしれません。

gpioeventsはshare/examplesに置いても良いように思います。

mrubyのmrbgemsでバインディングしたいな。