OmniAICreator/Qiita-1.07M huggingface dataset:
【自分用メモ】FlaskでPOSTを受け取る~入力した日付から曜日を取得するAPIを作成~

投稿日：2022/12/08
## はじめに
　今回、webサーバーを作る勉強として、Flaskを利用したAPIの作成を行いました。
勉強したことを自分用メモとして記事にまとめました。
間違い等、お気づきの場合はご指摘いただけると幸いです。

## APIの作成
入力した日付から曜日を取得するAPIを作成していきます。
```python:app.py
from datetime import datetime
from flask import Flask, request
import pytz

# Flaskのインスタンスをappという名前で作成
app = Flask(__name__)

# Flaskでpostを受けとるにはrouteの第二引数に methods=['post'] を指定
# localhost:5000/dateへPOSTメソッドでリクエストを受信したら、関数「week_caluculation」を実行する
@app.route('/date', methods=['POST'])
def week_caluculation():

    # 曜日情報のリストを作成
    week_list = ['月', '火', '水', '木', '金', '土', '日']

    # request.form.get は POST送信 された値を取得するプロパティ
    # ('days')は、送信されたデータのキーを指定しており、このキーで送信された値を取得する
    input_date = request.form.get('days')

    # 受け取った文字を日付に変換する
    date = datetime.strptime(input_date, '%Y-%m-%d')

    # 日付を曜日に変換する
    # date オブジェクトは曜日情報を0から6の整数で保持
    week = date.weekday()

    return f'{date}は{week_list[week]}曜日です'


if __name__ == "main":
    app.run()
```

### Python 曜日情報を取得
```python
    # 受け取った文字を日付に変換する
    date = datetime.strptime(input_date, '%Y-%m-%d')
```
strptime(): 文字列から日付、時間への変換

https://www.javadrive.jp/python/date/index5.html

```python
    # 日付を曜日に変換する
    week = date.weekday()
```

datetimeモジュールにあるdateオブジェクトのweekdayメソッドを使用

date オブジェクトは曜日情報を0から6の整数で保持。
0なら月曜日、1なら火曜日と順番に並んで最後の6が日曜日になる。


## curlコマンドでPOSTする
**curlコマンド**
サーバーとデータを送受信するコマンド
``` Linux
$ curl -X POST -d 'days=2022-12-08' http://localhost:5000/date
```
- **-X POST** : POSTリクエストを送る
- **-d** : POSTする際、何らかのパラメータやデータを付与してリクエストする(--dataの省略形)
指定された文字列データをそのまま送信(days=2022-12-08という文字列が渡される)
オプションに渡す値の形としては **変数名=値** の形式で値を指定する。
- http://localhost:5000/date : エンドポイントのURLを指定

## ターミナルでサーバーを立ち上げて動作確認
プロジェクトのディレクトリへ移動
```:virtualenvによるPythonの仮想環境を有効化
$ source env/bin/activate
```
```:下記のコマンドでサーバーを立ち上げ
$ flask run
```
↓サーバーを立ち上げたターミナルとは別に、新しくターミナルを表示
```:ターミナルからcurlコマンドでリクエストを送信
$ curl -X POST -d 'days=2022-12-08' http://localhost:5000/date
>> 2022-12-08 00:00:00は木曜日です
```
成功です。

## 参考文献
以下のサイト、記事を参考にさせていただきました。

https://www.mathpython.com/flask-post

https://shigeblog221.com/flask-get-post/

https://weblabo.oscasierra.net/curl-post/

https://daeudaeu.com/curl-command/

https://qiita.com/yasuhiroki/items/a569d3371a66e365316f

https://leben.mobi/blog/python_day_of_the_week/python/
Azure AppServiceでPythonのrequirement.txtの場所を変えたい

Azure AppServiceに配置するPythonのプロジェクトについて
同じプロジェクトでフロントエンドとバックエンドの資材を扱いたい場合とか
requirement.txtの場所を変えたい時がある。

例）
root
┗backend：バックエンド側資材。こっちにrequirement.txtを入れたい。
　┗requirement.txt
┗frontend：フロント側資材

対応：以下2点を実施
①アプリケーション設定で「CUSTOM_REQUIREMENTSTXT_PATH」変数にrequirements.txtのパスを設定する。設定値はrootからのパス。
②アプリケーション設定で「SCM_DO_BUILD_DURING_DEPLOYMENT」変数に1を設定する（trueでもよい）

上記構成だと、設定値は以下となる
CUSTOM_REQUIREMENTSTXT_PATH=backend/requirement.txt
SCM_DO_BUILD_DURING_DEPLOYMENT=1

これでOK。

##### 解決まで長かったので経緯

以下を参照すると、
https://github.com/microsoft/Oryx/blob/main/doc/configuration.md
アプリケーション設定で「CUSTOM_REQUIREMENTSTXT_PATH」変数を用いてrequirements.txtの場所をカスタマイズできる、と読み取れる

…なぜかエラーになる。
ログを読み取ると「Could not find setup.py or requirements.txt;」と記載されているのでrequirements.txtが読めていないっぽい。
requirements.txtをroot直下に持っていくと稼働するので、どうもこの記載のとおり設定しても動かないっぽい。

なので、サポートに問い合わせる。
サ：CUSTOM_REQUIREMENTSTXT_PATHだけでなく、SCM_DO_BUILD_DURING_DEPLOYMENT=1も設定する必要があるよ

設定する。変わらない。

サ：確認するからちょっとまってー
：
ここから、なんと3か月待たされた。
どうやら不具合だったらしい。
途中で不具合だったとか、今直してますとか、状況教えてくれたらいいんだけどねえ。
NameError uninitialized constant User・コンフリクトなどの一連のエラーへの対処

# エラー内容
・`NameError uninitialized constant User`　というエラーが表示された。
この後も色々エラーに出くわしたので、解決までのメモを残しておきます。

![NameError uninitialized constant User.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/731c2b98-c242-83ac-5c61-a0e0508f8057.png)

1. 以下4行目の追加したら解決した（と思っていた）

![image35.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/a2e6d444-f38a-52a4-6fa7-53dc30309ab3.png)

2.　ちょっと作業していると、次なるエラー`NameError in Rooms#new`が発生。
　　　　　　
![NameError in Rooms#new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/54c472f2-5d1d-ff7a-b744-0a79caa767bf.png)

3.　ソースコードを確認すると、`devise_create_user.rb`のファイル名に取り消し線が入っており、何らかの影響でこの辺のテーブルファイルが破損？している可能性があることに気づく。

4.　Gitでブランチを切るタイミングを間違えていたことが発覚。（＝マスターファイルをマージした場合は必ずプルリクエストを行い、そのファイルからブランチを切るようにしなくてはならない！！）。一度マスターブランチにして、履歴確認。
`choose  ~~branch to merge into…`
を押すと、コンフリクトが起きてる場所がわかるので、それを一つずつ確認。
今回の場合は、deviseが一部分うまく保存されていないのが原因だった。３つほどコンフリクトを確認。VScode上で相違点を編集する。
とほほ、コンフリクトのせいだったのね...。

5.　また次なるエラーに出くわす。今度はRouting Errorじゃと！？
`Routing Error No route matches[GET] "/rooms/new"`
![Routing Error No route matches[GET] rooms new.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2710373/2ad66d0c-07ae-7bae-3252-1453176cbf6c.png)

6.　deviseを追記した後、`bundle install`と`install devise`を実施するが、そのあとに`rails s`を再起動。
ただし、terminalの別セッションでrails sをしていたため、再起動になっておらず、上記の通りルーティングエラーとなった。
必ず全てのタブでサーバーが停止したかを確認する必要があります。。。
Java Bronzeをオンラインで受験してみた

# Java Bronzeをオンラインで受験してみました
Java Bronzeは、SilverやGoldとは違い、唯一オンラインでも受験可能な試験です。

試験前にJava Bronzeについて色々調べてみましたが多くの記事には「__オンライン受験はできるが、英語での試験になる__」と書かれていました。

__実際はしっかり日本語でも対応していましたのでご安心ください__

## 受験準備
私は受験しよう！と決めた日の前日に準備し始めました。

試験チケットのようなものがメールで発行されて、チケット番号を入れると試験が受けられる、という流れでした。

いざチケットを買って送られてきたメールを見ると、英語で「もしかしたらチケット発行まで３日かかるかも⭐︎」と書かれていて「え…明日受けられないかもしれない泣」と落ち込みましたが、1時間後くらいにちゃんとチケット発行のメールが届きました😅

## いざ受験！…とその前に
オンライン試験は、時間も指定できますのでお好きな時間に受けちゃってください！

でもその前に、、、カンニングできないような環境を作れと案内を受けます。

どうするかというと、
- スマホや参考書、ノートなど怪しいものを机から手が届かない範囲に置く。
- カメラで机の前後左右を撮影して机の周りに怪しいものはないという証拠を送る。

アングルが悪いとか、まだ物がある、とかだと「もう一度」と指示があります。

受験前にバタバタしてました笑

机の前後左右の撮影した写真が合格すれば、試験を開始できます。

ちなみに、受験後に試験レポート（合格か不合格かが書かれていて、正解率が記載されているもの）用に顔写真を取られますので、オンラインだからって身だしなみはきちんとした方がいいと思いました😄

## 受験中
受験中は、カメラをオンにして自分の上半身（肩が全部カメラに収まるように）を映しながら受験します。

少しでも見切れると「上半身をしっかり写してください」とチャットが飛んできて怒られます😅

例えば、文字が小さくて画面に近づいて問題を見ている時とか、問題を考えている時に頬杖をついてうっかりカメラから見切れたりした時にチャットが飛んできました。
（しっかり監視されているようです）

## 受験後
なんだかんだあり、受験後に「受験終了」ボタンを押すとそのまま点数がすぐに出て、合格か不合格かがわかります。

## 受験の注意点
一番知っていた方がいいと思ったのが、試験アプリの動作の重さです。

私が試験で使用したのは、MacBook Air2020でM1チップのものですが、アプリが非常に重く、どんなに素早く問題を解いても次の問題の画面に遷移するのに5秒は待ったかな、と思います😅

# まとめ
以上のように、オンラインですがほとんどカンニングする隙はない、と考えていて良いです。（どこかの記事で「Bronzeはオンラインだからカンニングできる」と書かれていましたが、そんなことありません！笑そもそもカンニングありきで受験しちゃだめです😌）
また、試験時間に対して問題数が多く、カンニングする時間を取ろうとしても全問解けない可能性が高いので変な小細工はせずに正々堂々受験しましょう。

チケット発行されるタイミングとか、部屋の片付けを事前にしておくとか、こんな感じで受験するというのを受験前に把握しているだけでもスムーズに試験に入れるかな、と思って記事にしてみました。どこかでお役に立てたら幸いです😊
リポジトリ層

[Next.js + サーバーサイドTypeScript + 関数フレーバーでクリーンなアプリを作ったので実装意図とか書く Advent Calendar 2022](https://qiita.com/advent-calendar/2022/shwld)
の**11日目**。[株式会社mofmof](https://www.mof-mof.co.jp/)に生息している[shwld](https://twitter.com/shwld)です。

前日は[エンティティバリデーション]()について書きました
# リポジトリ層
ORMとして[Prisma](https://www.prisma.io/)を使い、モデルの状態を永続化するため、モデルの状態ごとに永続化関数を書いています。

```ts:/infrastructures/db/src/repositories/account/account-create.ts
import { tryCatch } from 'core-domain';
import type { Aggregates } from 'core-domain';
import { db, handleError } from '../../lib/db';
import { convertToEntity } from './account-record';
import { picker } from '../../lib/picker';

// core-domainから集約のインタフェースを引っぱってきて型をつけます。
export const create: Aggregates['account']['create'] = input => {
  const { id, createdById, ...columns } = input;
  return tryCatch(
    () =>
      db.account
        .create({
          data: {
            id,
            ...columns,
            createdBy: {
              connect: {
                id: createdById,
              },
            },
            accountMemberships: {
              create: {
                role: 'OWNER',
                user: {
                  connect: {
                    id: createdById,
                  },
                },
              },
            },
          },
        })
        .then(convertToEntity),
    handleError
  );
};
```
[/infrastructures/db/src/repositories/account/account-create.ts](https://github.com/shwld/uzumaki/blob/advent-calendar/infrastructures/db/src/repositories/account/account-create.ts)

インタフェースはこんな感じになっています。

```ts:/domain/core/src/aggregates/repository-interfaces/account-repository.ts
create(attributes: Account_BuiltAttributes): Result<RuntimeError, AccountEntity>;
```
[/domain/core/src/aggregates/repository-interfaces/account-repository.ts](https://github.com/shwld/uzumaki/blob/advent-calendar/domain/core/src/aggregates/repository-interfaces/account-repository.ts)

PrismaはActiveRecordパターンではないので、慣れないRepositoryパターンを採用することになりましたが、一長一短あるなと感じつつも、レイヤーを分けるメリットはあるなと感じます。

結局テストの際にDBを入れずにテストしてもあまり意味があると思えないので、結局結合してテストしていて、あんま切り離す意味ないなーなどと感じなくもないですが、これは多分設計がイケてなくて、もっとリポジトリがコレクションを扱うことに徹するのが理想なんだろうか。

# 次回予告
明日は[GraphQLサーバーを構成する要素](https://qiita.com/shwld/items/0d2cb0802918030d6350)について書きます。
エンティティのバリデーション

[Next.js + サーバーサイドTypeScript + 関数フレーバーでクリーンなアプリを作ったので実装意図とか書く Advent Calendar 2022](https://qiita.com/advent-calendar/2022/shwld)
の**10日目**。[株式会社mofmof](https://www.mof-mof.co.jp/)に生息している[shwld](https://twitter.com/shwld)です。

前日は[エンティティの状態遷移]()について書きました
# エンティティのバリデーション
入力データの検証は[zod](https://github.com/colinhacks/zod)を使います。

https://github.com/colinhacks/zod

```ts
export const validationSchema = z
  .object({
    ...AccountValidator.validators,
    createdById: genericValidator.id,
  })
  .strict();
```

[/domain/core/src/models/account/mutations/build-account.ts#L27-L32](https://github.com/shwld/uzumaki/blob/main/domain/core/src/models/account/mutations/build-account.ts#L27-L32)

zodのschemaはそのまま活用できるようにexportしています。

以下のように、`Result型`(このカレンダー内の別記事参照)を利用するためのヘルパーを作っており、zodのschemaを渡すことで機能します。

```ts
export const validateWith =
  <TOutput, TDef extends ZodTypeDef, TInput = TOutput>(
    schema: ZodSchema<TOutput, TDef, TInput>
  ) =>
  (input: TInput): Result<InvalidAttributesError, TOutput> => {
    const parsedInput = schema.safeParse(input);

    return toResult(
      !parsedInput.success
        ? Either.left(InvalidAttributesError.from(parsedInput.error))
        : Either.right(parsedInput.data)
    );
  };
```
[/domain/core/src/shared/validator.ts#L24-L36](https://github.com/shwld/uzumaki/blob/main/domain/core/src/shared/validator.ts#L24-L36)

このヘルパーは、zod schemaを受け取り、バリデーションメソッドを返します。
バリデーションメソッドは入力を検証しResult型を返します。
また、バリデーションの結果、型が変わる場合それが戻り値に反映もされます。

```ts
const validate = validateWith(validationSchema)
const result = validate(input)
// result is Result<InvalidAttributesError, ValidAttributes>
```

実際にこういうふうに使っています。

```ts
export const build = (
  input: Account_BuildInput
): Result<InvalidAttributesError, Account_BuiltAttributes> => {
  return pipe(
    {
      ...input,
      createdAt: new Date(),
      updatedAt: new Date(),
    },
    validateWith(validationSchema),
    map(v => ({
      ...v,
      __state: STATE_IS_BUILT,
    }))
  );
};
```

# 次回予告
明日は[リポジトリ層](https://qiita.com/shwld/items/b4de03555f0e91a4f3ca)について書きます。
selenium備忘録

スクレイピングするときのメモ程度なので、読んでも役に立ちません。
## 最初の設定
### webdriver.Chtomeoptions()
```Python
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument('--no-sandbox')
options.add_argument('--disable-dev-shm-usage')
```
options.add_argumentでオプションを追加していく
* --headless
    * バックグラウンドモードでの実行
* --no-sandbox
    * sandboxモード(セキュリティ？)の解除
* --disable-dev-shm-usage
    * /dev/shmパーティションの使用を禁止し、パーティションが小さすぎることによる、クラッシュを回避する。
    * よくわからん

```python
# Chromeの起動
driver = webdriver.Chrome('chromedriver',options=options)
# 要素がリロードされるまで、最大10秒待つ。この場合はChrome
driver.implicitly_wait(10)
```


## webサイトの操作
### サイト読み込み
以下のようにサイトに飛ぶことができる。
```python
url = 'https://**************.***' #サイトのURL
browser.get(url) #サイトにアクセス
```

### 要素の抽出
要素を検索して抽出することができる。
```python
browser.find_element() #最初に見つかった1つのみ
browser.find_elements() #全てに要素
```
要素の指定は以下のようにByというライブラリを使用する。
```python
#.find.elementで使う定数を定義
from selenium.webdriver.common.by import By

name_elements = browser.find_elements(By.CLASS_NAME,'name')
name_element = browser.find_elements(By.CLASS_NAME,'name')[0] #ひとつだけ。find_elementと同じ結果になる
```
Byによって指定できる要素は以下の通り。
```
CLASS_NAME ：クラス名
CSS_SELECTOR ：CSSセレクタ
ID ：id属性
LINK_TEXT ：リンクが設定されているテキスト
NAME ：name属性
PARTIAL_LINK_TEXT ：リンクが設定されているテキストの一部
TAG_NAME ：タグ名
XPATH ：XPATH（HTMLの階層をファイルパスみたいに書く）
```
Delta Live Tablesのベストプラクティス

[Delta Live Tables best practices \| Databricks on AWS](https://docs.databricks.com/workflows/delta-live-tables/delta-live-tables-best-practices.html) [2022/11/24時点]の翻訳です。

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

本書では、Delta Live Tablesパイプラインを開発、デプロイ、管理する際のベストプラクティスを説明します。

# テーブルとビューの選択基準

パイプラインが効率的かつメンテナンスしやすくなる様に、パイプラインのクエリーを実装する際に、テーブルかビューかベストなデータセットタイプを選択する様にしましょう。

以下のケースではビューの使用を検討してください:

- 管理しやすいクエリーに分割したいと考える大規模かつ複雑なクエリーである場合。
- エクスペクテーションを用いて中間結果を検証したい場合。
- ストレージコスト、計算コストを削減したいと考えており、クエリー結果のマテリアライゼーションが不要な場合。テーブルはマテリアライゼーションされるので、計算コストとストレージリソースを必要とします。

以下のケースではテーブルの使用を検討してください:

- 複数の後段のクエリーがテーブルを使用する場合。ビューはオンデマンドで計算されるので、クエリーされるたびにビューは再計算されます。
- 開発中にクエリーの結果を参照したい場合。テーブルはマテリアライズされるので、パイプラインの外で参照、クエリーすることができ、開発中にテーブルを用いることは、計算処理の適切性の検証の役に立ちます。検証後に、マテリアライゼーションが不要なクエリーをビューに変換します。

# パイプライン設定でSparkバージョンを上書きしないでください

Delta Live TablesのクラスターではカスタムバージョンのDatabricksランタイムを実行しているので、クラスター設定で手動でSparkバージョンを設定することはできません。手動でバージョンを設定するとパイプラインは失敗します。

# 注意深くパイプラインの境界を選びましょう

パイプラインをどの様に分割するのかを決定する際、以下の点を検討してください。

以下のケースでは大規模パイプラインにしてください:

- クラスターリソースをより効率的に活用したい。
- ワークスペースのパイプライン数を削減したい。
- ワークフローのオーケストレーションの複雑性を削減したい。

以下のケースでは複数のパイプラインにしてください。

- チーム境界で機能を分割したい場合。例えば、あなたのデータチームではデータを変換するためのパイプラインを維持管理し、データアナリストは変換データを分析するパイプラインを維持管理する場合。
- 結合度を削減し、共通機能の再利用を促進するために、アプリケーション固有の境界で機能を分割する場合。

# 効率を高め、リソース使用量を削減するためにオートスケーリングを活用しましょう

パイプラインにおけるクラスターの使用率を最適化するために、[強化オートスケーリング](https://qiita.com/taka_yayoi/items/80ee29197d26e177bbeb#databricks%E3%81%AE%E5%BC%B7%E5%8C%96%E3%82%AA%E3%83%BC%E3%83%88%E3%82%B9%E3%82%B1%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0)を使いましょう。強化オートスケーリングは、リソースの追加によってパイプラインの処理スピードを改善するとシステムが判断した時のみリソースを追加します。不要になるとすぐにこれらのリソースは解放され、すべてのパイプラインのアップデートが完了するとクラスターはシャットダウンします。

プロダクションパイプラインで強化オートスケーリングを設定する際には、以下のガイドラインを使用してください。

- `Min workers`の設定はデフォルトのままにしてください。
- 予算とパイプラインの優先度に基づいて、`Max workers`を設定してください。
- Delta Live Tablesランタイムが、ワークロードにベストなインスタンスタイプを選択できる様に、インスタンスタイプは未設定の状態にしてください。

### Databricks 無料トライアル

[Databricks 無料トライアル](https://databricks.com/jp/try-databricks)
【UiPath】キャンセルスコープ (Cancellation Scope) の使い方

「**キャンセルスコープ**」アクティビティの使い方を紹介します。
公式ドキュメントは以下をご参照ください。

https://docs.uipath.com/activities/lang-ja/docs/cancellation-scope

### 仕様
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/883c0ff8-ed39-701e-3fa0-4db055a784d4.png)
Bodyセクション内のアクティビティを実行中にキャンセル（UiPathの実行を停止）された場合、
CancellationHandlerセクション内のアクティビティを実行して処理を終了します。

### 実際に動かす
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/8edf74f2-1f92-3ba5-31ee-2f1b9120bf5b.png)
Bodyセクション内にDelayアクティビティを置き、ここでキャンセル操作を行います。
検証のため、CancellationHandler内とキャンセルスコープを抜けた先にログ出力を置いています。

#### 実行結果（キャンセルした場合）
![メディア1.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/dd60cd34-481c-0cfe-536a-3cd0da662c67.gif)
CancellationHandleセクション内のログは出力されていますが、
キャンセルスコープを抜けた先のログは出ていません。

#### 実行結果（キャンセルしなかった場合）
![メディア2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/8450df28-286c-9b53-3147-a894561b0139.gif)
CancellationHandleセクション内のログは出力されていませんが、
キャンセルスコープを抜けた先のログは出ています。
キャンセルした場合と逆ですね。

### Finally（TryCatch）との比較
ちなみにキャンセルされた場合の動作は「トライキャッチ」アクティビティのFinallyセクションと同じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/b733d3ac-ed24-4071-daaf-f43b4fb42bea.png)
![メディア3.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/578020/b2eb45ff-a528-5a29-1582-1ee32520965b.gif)

キャンセルされた場合の動作は同じですが、
Finallyは**キャンセルされなかった場合も実行される**のに対して、
キャンセルスコープは**キャンセルされなかった場合は実行されない**という違いがあります。
用途によって使い分けましょう。

## 動作環境
UiPath.System.Activities 22.10.3
paiza.ioでelixir その131

# 概要
paiza.ioでelixirやってみた。
練習問題やってみた。

# 練習問題
アセンブラでzundokoをやってみて。

# サンプルコード

```
File.write "hello.s", """

.code64
.text
.global main
main:
	mov	 	$0, %rdx
	mov	 	$234, %al
loop:
    cmp     $4, %rdx
    je      printkiyosi
	mov	 	$5, %cl
	mul	 	%cl
	add	 	$1, %al
	cmp	 	$120, %al
	jb      printdoko
printzun:
    push    %rax
    push    %rdx
    mov   	$1, %rax;
	mov   	$1, %rdi;
	mov   	$zun, %rsi;
	mov   	$4, %rdx;
	syscall;
	pop     %rdx
	pop     %rax
	add     $1, %rdx
	jmp	 	loop
printdoko:
    push    %rax
    push    %rdx
    mov   	$1, %rax;
	mov   	$1, %rdi;
	mov   	$doko, %rsi;
	mov   	$5, %rdx;
	syscall;
	pop     %rdx
	pop     %rax
	mov     $0, %rdx
	jmp	 	loop
printkiyosi:
	mov   	$1, %rax;
	mov   	$1, %rdi;
	mov   	$kiyosi, %rsi;
	mov   	$13, %rdx;
	syscall;
	mov   	$0, %rax;
	syscall;
.data
zun:
	.asciz "zun "
doko:
	.asciz "doko "
kiyosi:
	.asciz "doko kiyosi!!"  

"""

{result, 0} = System.shell("gcc -no-pie hello.s")
IO.puts result

{result, 0} = System.shell("./a.out")
IO.puts result



```

# 実行結果

```

zun zun doko zun zun zun doko doko zun doko zun zun doko doko doko doko zun zun doko doko zun doko doko zun zun doko doko doko doko doko zun zun zun zun doko kiyosi!!
```

# 成果物

https://paiza.io/projects/skTkAEsJySQbfP8SmGG4Yg?language=elixir


以上。
[やっぱり対話] エンジニアこそノンバーバルコミュニケーションを大切にしよう！！！

 ## 概要
相手に物事を伝える場面で意識すべきことはノンバーバルコミュニケーションである

## 目的
読んだ人がエンジニアもチャットツールだけじゃなくて、もっと身振り手振りで表現しようぜって気持ちになるため

## そもそもノンバーバルコミュニケーションって何？
- **non-verbal**、つまり非言語、言葉を使わないコミュニケーションのこと
- 具体的には顔の表情や視線、声のトーン、大きさ、抑揚など人の五感で感じ取ることのできる意思疎通のこと
## 第一印象は五感の操作によって決まる
- 結局、人が五感によって受け取るイメージってのは人間の第一印象に大きく影響すると言われているで

<img width="715" alt="スクリーンショット 2022-08-18 20.24.13.png (162.1 kB)" src="https://img.esa.io/uploads/production/attachments/14274/2022/08/18/126296/071662e2-35b3-4bd3-a8a2-741e8935315a.png">

ここでメラビアンの法則を紹介しましょかい
## メラビアンの法則（7-38-55ルール）

<img width="596" alt="image.png (42.7 kB)" src="https://img.esa.io/uploads/production/attachments/14274/2022/08/18/126296/e036e23b-ed47-41f1-8b3c-e43d51b835d8.png">

- これは人がコミュニケーションの際に受け取る情報を１００とした場合、``７％``が言語情報、``９３％``が非言語情報というもの
- ９３％の内訳は見た目や表情、身だしなみなどの視覚情報が``５５％``
- 声のトーン、大きさ、抑揚、話し方などの聴覚情報が``３８％``
- せっかく用意した説明資料も結局非言語の方が重要ってことで
- そう思えば、少しは資料準備の肩の荷が降りるかな？

## ノンバーバルコミュニケーションの重要性
- 発した言語情報を補完できる
- 信頼関係を構築できる
- 相手の気持ちや状況を理解できる

## まとめ
話す内容を考える前に雰囲気良く身体中動かしながら話そうぜ！！（くねくねグルングルン）

## 所感
- 社会人になって自分の考えを言語化するのが上手だなって思える人を多く見てきたけど、表情が固く、トーンが一辺倒で何を伝えたいのか分かりにくい人もいる。非常に勿体無い
- 大事なのは非言語情報
- あと、この人話がうまいな、とか仕事ができそうとか勝手に第一印象で思ってしまう人は身だしなみやあいさつなどがしっかりできている気がするね。
- 話す内容とかはどうでもよくてやっぱり日々の言動、身だしなみが重要だね

## 参考（引用もさせていただいています）
- [ノンバーバルコミュニケーションを活用するには](https://www.cydas.com/peoplelabo/non-verbal-communication/#:~:text=%E3%80%8C%sE3%83%8E%E3%83%B3%E3%83%90%E3%83%BC%E3%83%90%E3%83%AB%E3%80%8D%E3%81%AB%E3%81%AF%E3%80%81%E3%80%8C,%E3%82%B3%E3%83%9F%E3%83%A5%E3%83%8B%E3%82%B1%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3%E3%81%8C%E8%A9%B2%E5%BD%93%E3%81%97%E3%81%BE%E3%81%99%E3%80%82)
- [メラビアンの法則とは？](https://www.kaonavi.jp/dictionary/melabians-law/)
【基本情報】論理演算

# 論理演算
|用途|記号|MIL記号|
|---|---|---|
|**論理和(OR)**|**A + B<br>A∧B**|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/101a25d5-9d60-92be-4654-9d294f81065d.png)|
|**論理積(AND)**|**A ・ B<br>A∧B**|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/e02364cf-7eef-0823-9914-2e812e7b74f0.png)
|**否定(NOT)**|**$\bar{A}\hspace{5mm}$**|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/ef72d72c-fa1d-fa9f-20fa-09f8d52cd09c.png)|
|**排他的論理和(XOR)**|** **|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/6e1cc4c8-affd-d2b5-5a22-867675addcb5.png)|
|**否定論理和(NOR)**|** **|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/afc74cba-c550-93c8-60e5-41cbebc03720.png)|
|**否定論理積(NAND)**|** **|![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/9d87b321-5d0c-0003-5c96-57d10d254760.png)|

# 論理和

## ペン図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954863/1d2bdda1-111a-9d74-d87b-c3e2e3ed0360.png)
## 真理値表
|入力A|入力B|結果|
|---|---|---|
|**0**|**0**|偽|
|**1**|**0**|真|
|**0**|**1**|真|
|**1**|**1**|真|







| 書式| 表示$\hspace{10mm}$ | 備考 |
|:-----------:|:------------:|:------------|
|\bar{x}|$\bar{x}\hspace{5mm}$|`\overline{xy}` $\hspace{2mm}\Rightarrow\overline{xy}$$\hspace{2mm} 、\hspace{2mm}$ `\underline{xy}` $\hspace{2mm}\Rightarrow\underline{xy}$|
ansibleでソフトウェアアップデート

全然記事を投稿していないので、しばらくは自分が作成したスクリプト系を紹介するだけの記事を投稿します。

# 背景
セキュリティ対策として定期的なシステムアップデートなどが必要と思いますが、自分で管理しているサーバの台数がちらほらと増えてきて、また思いついたときに実行しているくらいだったのでcronで設定したいと思ってました。
我が家にはサーバのcronマネージャのような立ち位置でAWXくんがいるのですが、そいつに任せればいいじゃないか！ということでシステムアップデート用のansible-playbookを作成してますのでそれの紹介です。

# 要件

- Windows ServerとRedHat系のシステムアップデートしたい
- playbookは一つにまとめたい


# playbook

```yml
- hosts: all
  gather_facts: true

  tasks:
    - name: OS family display
      debug: var=ansible_os_family
    
    - name: Redhat update(yum)
      become: yes
      yum:
        name: '*'
        state: latest
      register: update_result
      when:
        - ansible_os_family== "RedHat" 
    
    - name: Windows Update
      win_updates:
        category_names:
          - Application
          - Connectors
          - CriticalUpdates
          - DefinitionUpdates
          - DeveloperKits
          - FeaturePacks
          - Guidance
          - SecurityUpdates
          - ServicePacks
          - Tools
          - UpdateRollups
          - Updates
        state: installed
        reboot: yes
        reboot_timeout: 6000
      register: update_result
      when:
        - ansible_os_family== "Windows" 
    
    - name: Update results
      debug: var=update_result
```

# ざっくり要点説明

- `gather_facts`は`true`必須です。ここでOSファミリー情報を取得して、実行するモジュールを`when`で使い分けます
    - 自分はRedHat系とWindows Serverで試したかったので、Debian系を使用している人は別のタスクを追加してください
- Windows Updateについては、`category_names`にすべてのカテゴリーを書いたつもりですが、`*`でも大丈夫らしいです。ただ自分が実施したときに一部当てられないパッチがあった気がしたので指定してます。（おいおい気づいたのですが、インストール済みだけどWindowsのコンソール上は終わってないように見えていただけの節がありますが細かく検証してないです）
- Windowsについては必要に応じてリブートするようにしてます。そのため自分はAWXでワークフロージョブとしてこのplaybook前後に正常性確認のplaybookを指定してます。それは別の機会に紹介します。
自己紹介

マイコンボード、プログラミング、数学が好きな人と手話で交流したいDeafBearです。
よろしくお願いします!

### 職歴
- 計測機器開発会社
　Winアプリ開発、組込みソフト開発
- 半導体開発会社
　RTL設計&検証、自動化ツール開発、IoT機器システム開発、生産データの解析

### 業務でのプログラミング言語(2022年度現在)
- EXCEL VBA
- RPA(UiPath)
- JMP
- プリザンター
- その他

### 好きなこと
- 走ること
- 海をぼーっと眺めること
- 水族館に行くこと

### 好きなソフト言語
- Python

### 書きたい記事
* エンジニアとしての勉強記録
    * ソフトウェア
    * マイコンボード(RaspberryPi、Arduino、Microbit)
    * 数学(力学系)/統計
* 聞こえないエンジニアとして思うこと

### 将来の夢
- 島で暮らすこと
- 月か火星で暮らすこと
- 生涯エンジニア
入力内容に応じて動作を変更する

# クリックされたボタンの結果を変数に保存する
```js
  <script>
      'use strict';
    let answer = window.prompt('ヘルプを見ますか？');
    console.log(answer);
  </script>
```
### 気づき
メッセージを入力するとその値が変数answerに代入されるからコンソールに入力した値が入力されるのか。

### window.prompt()とは？
ユーザーにテキストの入力を求めるオプションの```メッセージを含むダイアログ```を表示し、```ユーザーがテキストを送信```するかダイアログをキャンセルするまで待機するようブラウザに指示します。

#### 出典
https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt

```js
<script>
  var name = prompt("名前を入力してください","キラメキタロウ");
  document.write(name);
</script>
```
```prompt()```の第２引数には初期値を入れることができる。
#### 出典
https://magazine.techacademy.jp/magazine/5488

### 変数の内容も変更される
```js
  <script>
      'use strict';
    let answer = window.prompt('ヘルプを見ますか？');
    console.log(answer);
    answer = 'no';
    console.log(answer);
  </script>
```
これもプロゲートで学んだな。
変数の上書き
上書きするときは```let```がいらない。

# 定数を使ってデータを書き換えられないようにする
```js
  <script>
      'use strict';
    const answer = window.prompt('ヘルプを見ますか？');
    console.log(answer);
    answer = 'no';
    console.log(answer);
  </script>
```
### エラー
```Uncaught TypeError: Assignment to constant variable.```
定数が定義されたら後から上書きされることがない。

### 気づき
```const```の性質は使えそうだ。

# 保存された内容で動作の切り替える
```js
  <script>
      'use strict';
    const answer = window.prompt('ヘルプを見ますか？');
    if(answer === 'yes') {
        window.alert('タップでジャンプ、障害物を避けます。');
    }
  </script>
```
'yes'を入力したときだけあらーどダイアログボックスが表示される。
### 比較演算子```===```
```===```は左と右がどう見ても同じでない限り、全体の評価結果をtrueにしない（データ型を変換しないで、左右を比べる)

#### 参考
https://qiita.com/PianoScoreJP/items/e43d70ec188c6fed73ed

# 出典
https://www.sbcr.jp/product/4815601577/
Box CLIでファイルバージョンを更新する

# Box CLIでファイルをアップロードしたい
Box CLIを使えばbatなどから簡単にアップロードが可能です。
しかし、`Box files:upload`では、同名ファイルをアップロードすると`409 conflict item_name_in_use`なるエラーが発生します。
どうも同名ファイルはそのままではアップロードできないみたいで、色々調べて解決できたのでメモしておきます。

# 解決法
`box files:versions:upload FILEID PATH`を使うだけで解決できました。


いろいろググっても出てこなかったのですが、Git Hubのページを見たら書いてありました。
https://github.com/box/boxcli/blob/main/docs/files.md

色々検索しても出てこない時は、公式ドキュメントを見るのが一番ですね…。
誰かの参考になれば幸いです。
iOS14でTextFieldにdidBecomeFirstResponderを設定する


```swift:CustomTextField.swift
struct CustomTextField: UIViewRepresentable {
  @Binding var text: String
  var font: UIFont = .init()
  var textAlignment: NSTextAlignment = .left

  var isFirstResponder: Bool

  init(text: Binding<String>, isFirstResponder: Bool = false) {
    self._text = text
    self.isFirstResponder = isFirstResponder
  }

  func makeUIView(context: UIViewRepresentableContext<CustomTextField>) -> UITextField {
    let textField = UITextField(frame: .zero)
    textField.font = font
    textField.textAlignment = textAlignment
    textField.delegate = context.coordinator
    textField.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)

    return textField
  }

  func updateUIView(_ uiView: UITextField, context: UIViewRepresentableContext<CustomTextField>) {
    uiView.text = text

    if isFirstResponder && !context.coordinator.didBecomeFirstResponder {
      uiView.becomeFirstResponder()
      context.coordinator.didBecomeFirstResponder = true
    }
  }
}

extension CustomTextField {
  func makeCoordinator() -> CustomTextField.Coordinator {
    Coordinator(text: $text)
  }

  class Coordinator: NSObject, UITextFieldDelegate {
    @Binding var text: String
    var didBecomeFirstResponder = false

    init(text: Binding<String>) {
      _text = text
    }

    func textFieldDidChangeSelection(_ textField: UITextField) {
      text = textField.text ?? ""
    }
  }
}

extension CustomTextField {
  public func font(_ font: UIFont) -> CustomTextField {
    var view = self
    view.font = font
    return view
  }

  public func textAlignment(_ alignment: NSTextAlignment) -> CustomTextField {
    var view = self
    view.textAlignment = alignment
    return view
  }
}
```


```swift:Content.swift
struct ContentView : View {
  @State var text: String = ""

  var body: some View {
    CustomTextField(text: $text, isFirstResponder: true)
      .borderStyle(.roundedRect)
      .frame(width: 200, height: 40)
      .background(Color.red)
  }
}
```


iOS15以降は`@FocusState`を使う

参考にしたのは[こちら](https://stackoverflow.com/questions/56507839/swiftui-how-to-make-textfield-become-first-responder)
Library not loaded: /usr/local/opt/postgresql/lib/libpq.5.dylib (LoadError)

> あまりに嬉しかったのでQiitaに投稿

## 今回の概要
- [qiita-markdown](https://rubygems.org/gems/qiita-markdown)をインストールしようとしてアプリが動かなくなってしもた。
   - 開発中のrailsアプリが全て同じエラーで動かなくなってしまいました。
- 原因は自分でもよくわからないコマンドを打ってしもたから。
   - 打ったコマンド
      - `$ brew install icu4c cmake`
   - [参考にした記事](https://zenn.dev/noraworld/articles/installation-of-charlock-holmes-on-macos)
- その結果発生したエラーは以下の通りです
```
.
.
.
Library not loaded: /usr/local/opt/postgresql/lib/libpq.5.dylib (LoadError)
.
.
.
```

## 具体的な解決方法
### まずはエラーの原因を発見
```
Library not loaded: /usr/local/opt/postgresql/lib/libpq.5.dylib (LoadError)
```
- `libpq.5.dylib`
- っていうファイルが見つからないらしい

### 次に見つからないファイルを検索
```
ls /usr/local/opt/postgresql/lib
```

- このコマンドで`lib`の中に`postgresql@14`とかいうディレクトリを発見
- `postgresql@14`の中も覗いてみる

```
ls /usr/local/opt/postgresql/lib/postgresql@14
```

- そうすると`libpq.5.dylib`を発見！
- ここにおったんか君は。

### ファイルのパスを変更？
> 正直ここはよくわかってない

```
ln -s /usr/local/opt/postgresql/lib/postgresql@14/libpq.5.dylib /usr/local/opt/postgresql/lib/libpq.5.dylib
```

- シンボリックリンクを作成しなおしたっぽいです
   - シンボリックリンクとは、ファイルの別名みたいなもの。
   - 今回だと、AというパスでBというファイルが読み込めないことが原因のようでした
      - `Library not loaded: /usr/local/opt/postgresql/lib/libpq.5.dylib (LoadError)`
   - そこで、AというファイルでBというファイルにアクセスできるようにAというパスの参照先を強制的に変更した
      - `ln -s /usr/local/opt/postgresql/lib/postgresql@14/libpq.5.dylib /usr/local/opt/postgresql/lib/libpq.5.dylib`を打つことで
         - `/usr/local/opt/postgresql/lib/libpq.5.dylib`
         - を
         - `/usr/local/opt/postgresql/lib/postgresql@14/libpq.5.dylib`
         - に変えたんだと思う
   - みたいな認識です
- [シンボリックリンクについての参考記事](https://atmarkit.itmedia.co.jp/ait/articles/1605/30/news022.html)


## 参考にした記事
- https://qiita.com/ymdarudy/items/2ff4d5f96e6e6982c5fb
[Rails]Indexを条件を指定して並び替える

## 行いたいこと
本の一覧を条件を指定して並び替える
今回の条件
- 投稿日の新しい順
- 投稿日の古い順
- 評価の高い順

![スクリーンショット 2022-12-08 16.48.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2950107/9f685859-596a-70aa-923e-fa737ae7c708.png)


## 環境
- Ruby3.1.2
- Rails6.1.7
- Bookモデル作成済み
- 評価機能作成済み(並び替えで使用しているだけなので必須ではない)

# 1.並び替える方法
`order`を用いてデータを並び替える
```
Book.order(条件: :並び順)
Book.order(created_at: :desc) created_at:は作成日時。　:descは降順
Book.order(created_at: :asc) created_at:は作成日時。　:ascは昇順
Book.order(rating: :desc) ratingは評価の値が入っているカラム名
```
勿論このまま書いてもいいが、コントローラーをスッキリさせるため`scope`を用いて簡潔にする
```models/book.rb
  scope :sort_rate, ->{order(rating: :desc)}
  scope :sort_new, ->{order(created_at: :desc)}
  scope :sort_old, ->{order(created_at: :asc)}
```
# 2.viewでのリンクの作成
view各検索方法へとアクセスするリンクを作成する
```views/books/index.erb
~省略~
 <h2>Books</h2>
 <p><%= link_to '新しい順', books_path(new:new)%> | 
<%= link_to '古い順', books_path(old:old)%> | 
<%= link_to '評価の高い順', books_path(rate:rate)%></p>
~省略~
```
ここでの`books_path(new:"new")`、`books_path(old:"old")`、`books_path(rate:"rate")`
は送信先は全てindexになるが、さらに( )の中の値を一緒に送信している
例：`books_path(new:"new")`なら`new:`という項目に`new`という値を付与
この(　)の値は任意のもので良い。後述するコントローラーでの分岐に必要になる

# 3.コントローラーでの分岐処理
indexアクションを以下のように変更
```controller/books_controller.rb
  def index
    if params[:rate].present?
      @books = Book.sort_rate
    elsif params[:new].present?
      @books = Book.sort_new
    elsif params[:old].present?
      @books = Book.sort_old      
    else
      @books = Book.all
    end
    @book = Book.new
  end
```
ここで仮に「新しい順」を押した時に送られる値を確認してみる
```
[1] pry(#<BooksController>)> params
=> #<ActionController::Parameters {"new"=>"new", "controller"=>"books", "action"=>"index"} permitted: false>
```
`"new"=>"new"`という値が送られてきているのがわかる。
あとは**if params[:~~].present?** でその値が有るかを確認し、
合致する場所の処理を、１で設定した`scope`を用いて記述していく
※**present?** はその要素が存在していれば`true`、なければ`false`を返す。

これで完成！
## 参考にした記事
https://qiita.com/kcl215/items/c0222befe4a6b270986a
POSTリクエストのパラメータの話

# 背景
こんなAPIのControllerがあった。
(Java/Spring Boot)

```java
@PostMapping("/hoge")
public ResponseEntity<Resource> postHoge(@RequestParam("fuga") String fuga) {
  // ~~~
}
```

それに対してフロントエンドから`axios`を使ってこんなリクエストをした。

```typescript
const requestHoge = async (fuga: string): Promise<void> => {
    await axios.post('/hoge', { fuga: fuga })
}
```

すると、`400 Bad Request`が返ってきた。

# 原因
APIはパラメータを`リクエストパラメータ`（フォームデータ）で待っていたのに対し、
フロントエンドは`リクエストボディ`で送ってしまっていた。

# 対処
axiosのPOSTリクエストでフォームデータを送るには、
一旦`FormData`インスタンスに`append`して、
それを`axios.post`の第二引数に含めてあげる必要がある。

```typescript
const requestHoge = async (fuga: string): Promise<void> => {
    const formData = new FormData()
    formData.append('fuga', fuga)
    await axios.post('/hoge', formData)
}
```

# 結論
APIが`リクエストパラメータ`か`リクエストボディ`どちらを引数に取っているか
確認して実装すること。
CKA/CKADの資格更新をした際のTips

## 記事の概要
2022年9月にCKA/CKADの資格更新の試験を受けました。
その際に戸惑った点や3年前と試験と変わった点などをまとめてみました。
**試験内容に関する技術的な内容は一切書いておりません。**

## 受験の申込み場所が前回と違った(誤解の可能性あり)
受験する際には日時を決めてTraining&Certificationのサイトで申込むのですが、その場所が最初に受験した場所と変わってると思います(前回が3年前なのでうろ覚えなのですが)

確かまだ受けていない試験&コースが選択できるタブがあり、そこから申し込めたのですが更新時はそこにCKA/CKADがありません。
ではどこから申し込んだかと言うと、「Course&Completed」タブの、該当資格の「View Certification」から申し込めます。
ここは前回の試験時の日時や結果が表示されるのですが、新しく受験資格を購入すると次回の申込みページになる模様です。
(スクリーンショットは合格後に撮ったので細かい点が違うかもしれません)
![Training&Certificationの画面](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3036813/0743e6e1-4df0-13a8-412c-f884a73af185.png)

# 試験場所のカメラチェック
試験前にビデオによる試験環境周囲の環境チェックがありますが、今回受けたCKADでは追加でスマートフォンの場所の確認がありました。
私は別室に置いてあったのでそれを取りに行き見せてpassしました。CKAではなかったので試験官によるのかもしれません。
多分ですが、スマートフォンを隠し持ってないことの確認と思われます。ですが複数端末持ってる人への対策にはならない気がします・・・

## 試験環境がPSIセキュアブラウザに変更
2022年6月より、従来のChrome+extensionから[PSIセキュアブラウザ](https://training.linuxfoundation.org/ja/bridge-migration-2021/ "Linux Foundation Proctoring Platform –PSIブリッジへの移行")というものに変更されました。
まずブラウザ自体が独自になるため使用できる環境が変わります。Windows/Mac/Linuxとなり、従来は使用できたChromebookが使えなくなっています🥺
私はカメラ付き端末がChromebookだけだったので急遽許可をとり会社PCで受けました。

また翻訳機能がありません。Chromeが使えてた時はブラウザの翻訳機能が使えたのですが今回は該当機能は全くありません・・・
試験自体は英語/日本語/中国語を随時切り替えられるので問題ありませんが、試験官のチャットで難しい英単語が出たときに困る気がします。(これは日本語版試験を受ければ問題ないのかもしれませんｗ)

それとPSIセキュアブラウザの影響かは不明ですが、試験で実際に操作するLinux端末のウインドウがとても狭いです。
解像度は変更できたのかもしれませんが、下手に触って怒られる＆動かなくなるのも怖かったので今回は狭いまま受けました。
どの程度の狭さかというと、ターミナルをデフォルトサイズで上下に2つ重ねず並べられない程度です。
1ターミナルで足りる人であれば問題ないかもしれませんが、私はログ確認等で2ターミナル使うのでなかな苦労しました・

## 次の資格期限が合格日になる
些細な話ですが、更新試験なので期限は1回目の受験時の期限になってほしかったと思います。
日がずれるのが嫌ならギリギリに受ければいいのではと思われるかもしれませんが、CKA/CKAD等は1度不合格になっても再度受験できます。
それを考えると再スケジューリングのラグを考えると、やはり数日前には1回目を受けたくなります。

また更新試験とは言え、新しく取る場合と同じ試験&費用なことを考えると期限が切れた後に再度受けてもいいかもしれません。
ただその際はCertificate IDが変更される気がします。(期限内に更新するとIDは変更されません)

## 合格後のCredlyバッジが更新されない事がある
合格したら数日後にCredlyからメールが来てバッジの更新がされる。はずなのですが、CKA/CKADともにこれが来ませんでした(passしたよ！メールは試験完了後24時間で来ました)
前回の期限が来たら更新されるのかなぁ。とのんびり構えていたのですが実際にその日を超えても更新されず、「expire」となっていました。
これはさすがにダメだと思い、ちょっとぐぐると[同様の事象に合われた方](https://ngoktanio.hatenablog.com/entry/2021/10/24/192339 "おけぽよの日記-CKA更新時のトラブル")がおられました。
なので早速私もサポートに連絡し、無事数日後にバッジも更新されました。(サポートも慣れてる感じで、追加の情報など必要なくバッジ更新→サポートクローズとなりました)

## 最後に
更新試験だからすんなり行くだろう'`,､('∀`) '`,､とか思っていたらそんなこともなかったので記事にしてみました。
皆様が何も慌てずに受験できるように祈っております。
DockerでGo+MySQLの開発環境をつくりたい

# はじめに
Dockerで開発環境を作るアウトプットとして簡単にまとめてみます
goの始め方もまとめていますが、公式ドキュメントを参考にしてください

https://go.dev/doc/tutorial/getting-started

## ファイル構成
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2889192/b840244d-3860-e641-6d69-f52f94f25799.png)

.envはdbの環境変数、my.cnfはdbの設定項目に関するファイルになります


# やりかた
以下のファイルを作成して、上画像のファイル構成にします

```Dockerfile
FROM golang:1.18.0
RUN apt-get update && apt-get install -y build-essential make

# vscodeの拡張機能のためにインストール
RUN go install golang.org/x/tools/gopls@latest
RUN go install github.com/ramya-rao-a/go-outline@latest
RUN go install github.com/cosmtrek/air@latest
RUN wget -O ~/vsls-reqs https://aka.ms/vsls-linux-prereq-script && chmod +x ~/vsls-reqs && ~/vsls-reqs

WORKDIR /go/src
```

```docker-compose.yml
version: "3"
services:
  db:
    image: mysql:8.0
    environment:
      MYSQL_ROOT_USER: ${ROOTUSER}
      MYSQL_ROOT_PASSWORD: ${ROOTPASS}
      MYSQL_DATABASE: ${DATABASE}
      MYSQL_USER: ${USERNAME}
      MYSQL_PASSWORD: ${USERPASS}
      TZ: "Asia/Tokyo"
    volumes:
      - ./my.cnf:/etc/mysql/conf.d/my.cnf
    env_file:
      - .env
    container_name: sample_db
    ports:
      - 3306:3306

  go:
    build: ./
    volumes:
      - ./go/src:/go/src
    container_name: sample_go
    tty: true
    ports:
      - "8000:8000"
    depends_on:
      - db
```

```.env
ROOTUSER=root
ROOTPASS=password
DATABASE=db
USERNAME=docker
USERPASS=docker
```

```my.cnf
[mysqld]
character-set-server = utf8

[client]
default-character-set=utf8
```

Dockerイメージの作成とコンテナの起動を行います
```
$ docker-compose build
$ docker-compose up
```

Dockerfileでgo/srcをワーキングディレクトリにしているのでsrcファイルを含むgoフォルダが作成されます


まずdbのコンテナに入り、db接続を確認します
```
$ docker exec -it sample_db sh
```

```
// passwordはpassword(.envのROOTPASS)
$ mysql -u root -p
```

次にgoのコンテナに入ります

```
$ docker exec -it sample_go sh
```

go.modファイルを作成するために以下を実行します

```
// sample_goというモジュール名で作成
# go mod init sample_go
```

go/srcにmain.goファイルを以下の内容で作成します

```main.go
package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

```

以下を実行し、コンソール上にHello, World!が表示されたらOK
```
# go run main.go
```


# おわりに
開発環境をつくる際に同じことを調べたりすることがあったので、まとめました。
今後誰かに教える際にも使えるので、その際はこの記事が役立てば良いなと思います。
タイプミス矯正

# ミスタイプって、よくありますか？
これをご覧になられている皆様におかれましては、Linuxのコマンドライン操作に当たってファイル、ディレクトリの一覧を見るために以下のようにコマンドを実行されているものと思います。
```
ls
```
これを間違えて、
```
sl
```
などと打ってしまうようなことはないものと思いますが、それでも間違いは起こります。
そこで、今回はミスタイプを矯正するためのツールをインストールしたいと思います。何番煎じなんでしょうね。

# ソースコードのダウンロード
ソースコードがGitHubで公開されているので、リポジトリをクローンで取得します。
```
git clone https://github.com/mtoyoda/sl
cd sl
```
コンパイルする前に、makeの設定を確認します。
` cat Makefile`
```
#==========================================
#    Makefile: makefile for sl 5.1
#       Copyright 1993, 1998, 2014
#                 Toyoda Masashi
#                 (mtoyoda@acm.org)
#       Last Modified: 2014/03/31
#==========================================

CC=gcc
CFLAGS=-O -Wall

all: sl

sl: sl.c sl.h
        $(CC) $(CFLAGS) -o sl sl.c -lncurses

clean:
        rm -f sl

distclean: clean
```
"make all"でコンパイルできそうですね。

で、早速コンパイル
`make all`

```
gcc -O -Wall -o sl sl.c -lncurses
sl.c:41:10: fatal error: curses.h: No such file or directory
   41 | #include <curses.h>
      |          ^~~~~~~~~~
compilation terminated.
make: *** [Makefile:15: sl] Error 1
```
curses.h が無いと怒られました…（.hはヘッダファイルの拡張子です。詳細は割愛します）
ですので、curses.hを含んだ開発ライブラリをインストールします。
```
sudo apt-get install libncurses5-dev
```

気を取り直してリトライします。
```
make all
```

エラーは出なかったので試しに実行してみましょう。
```
./sl
                       (@@) (  ) (@)  ( )  @@    ()    @     O     @     O      @
                  (   )
              (@@@@)
           (    )
         (@@@)
         ====        ________                ___________
     _D _|  |_______/        \__I_I_____===__|_________|
      |(_)---  |   H\________/ |   |        =|___ ___|      _________________
      /     |  |   H  |  |     |   |         ||_| |_||     _|                \_____A
     |      |  |   H  |__--------------------| [___] |   =|                        |
     | ________|___H__/__|_____/[][]~\_______|       |   -|                        |
     |/ |   |-----------I_____I [][] []  D   |=======|____|________________________|_
   __/ =| o |=-~~\  /~~\  /~~\  /~~\ ____Y___________|__|__________________________|_
    |/-=|___|=    ||    ||    ||    |_____/~\___/          |_D__D__D_|  |_D__D__D_|
     \_/      \O=====O=====O=====O_/      \_/               \_/   \_/    \_/   \_/


```
はいOK！
後は、コマンドのパスを通すだけなのですが、今回はlsと同じディレクトリにシンボリックリンクを貼って対応します。
```
cd /usr/bin/
sudo ln -s ~user001/sl/sl
```

これで、打ち間違えたらいちいちSLが走ります。
落ち着いて正確なタイピングを心掛けましょう。そのうち、lsをslと打ち間違えることもなくなるでしょう。

後、slにはいくつかオプション（-a、-l、-F、-c）があります。興味がありましたらお試しください。では。
それっぽく設定するCloudWatch Alarms

[Amazon CloudWatch](https://docs.aws.amazon.com/cloudwatch/index.html)にて、最小限の労力でもそれっぽく監視したいんだよな〜という……。

* そもそも動くことすらできていない「スロットル」は要監視である。動かなければお話にならないので
* レスポンス`5XX`、`4XX`、`3XX`、`2XX`については一部だけ記載してある。状況に合わせて適宜監視するとよい
* 最小限にしつつもおすすめは、「いわゆるERROR」（≒障害）用のアラームと、「いわゆるWARN」（障害ではないが気になる挙動）用のアラームを作ってみること。そうすると、構築したサービスの挙動傾向が掴みやすく、結果として安寧が得られる

## ALB

* ロードバランサー5XX系エラー回数
  * `HTTPCode_ELB_5XX_Count Sum`
  * クライアントにサーバーエラーを返しているようだ
* ターゲット5XX系エラー回数
  * `HTTPCode_Target_5XX_Count Sum`
  * ターゲットがサーバーエラーを返しているようだ
* ターゲットのヘルシー率（レート）
  * `UnHealthyHostCount / (HealthyHostCount + UnHealthyHostCount)`
  * オートヒールする作りにしてあるとはいえ、意外とダウンしている？
    * ターゲットの単純な起動エラーによる無限立ち上げループの危険性も

## API Gateway

* レイテンシー
  * `Latency p99`
  * 対クライアントがなにやら重い？
* インテグレーションレイテンシー
  * `IntegrationLatency p99`
  * バックエンドがなにやら重い？
* 5XX系エラー率（レート）
  * `5XXError Average`
  * サーバー側でなにやらあったようだ
    * AWSサービス自体の内部エラーという場合もある。その場合は[AWS Health](https://docs.aws.amazon.com/health/index.html)に通知が来たりもする
* 5XX系エラー回数
  * `5XXError Sum`
  * 単純な回数も把握しておこう
* 4XX系エラー率（レート）
  * `4XXError Average`
  * あまりに高まってきているなら不穏…
    * アタックにより発生している危険性も
    * サーバー側コードのバグにより発生している危険性も
    * クライアントが自アプリなら、アプリコードのバグにより発生している危険性も
* 429エラー回数
  * `(MetricFilter) 429Error Sum`
  * スロットルされている！
    * 自前でメトリクスを生成しておくと分かり易い

## Cognito

* サインインスロットル回数
  * `SignInThrottles Sum`
  * スロットルされている！

## ECS

* CPU利用率
  * `CPUUtilization Average`
  * 意外とぶん回している？
* メモリー利用率
  * `MemoryUtilization Average`
  * 意外と食っている？

## Lambda

* 実行時間
  * `Duration p99`
  * なにやら重い？
* 最大並列実行数
  * `ConcurrentExecutions Maximum`
  * 並列実行数が想定より増えている？
* 実行回数
  * `Invocations Sum`
  * 定期的に動かしているつもりが…動いていない説？
* エラー率（レート）
  * `Errors / Invocations`
  * リトライで解消する作りにしてあるとはいえ、意外とエラーになっている？
* エラー回数
  * `Errors Sum`
  * 単純な回数も把握しておこう
* スロットル回数
  * `Throttles Sum`
  * スロットルされている！

## SQS

* DLQメッセージ数
  * `ApproximateNumberOfMessagesVisible Maximum`
  * DLQ落ちが発生しておりいと悲し
* DLQメッセージ数増減差分
  * `RATE(ApproximateNumberOfMessagesVisible) * PERIOD(ApproximateNumberOfMessagesVisible)`
  * DLQメッセージ数がどんどん増えているぞ……！

## Step Functions

* 実行時間
  * `ExecutionTime p99`
  * なにやら重い？
* ステートマシン実行失敗数
  * `ExecutionsFailed Sum`
  * リトライもなんのその、完敗している
* スロットル回数
  * `ExecutionThrottled Sum`
  * スロットルされている！

## WAF

* ブロック率（レート）
  * `BlockedRequests / (AllowedRequests + BlockedRequests)`
  * 意外とブロックされているようだ。ルールがよろしくないのかも？
確認ダイアログボックスを表示する

# 確認ダイアログボックスを使ってみよう
```js
  <script>
    'use strict';
    console.log(window.confirm('ゲームスタート！準備はいい？'));
  </script>
```
```window```オブジェクトに確認ダイアログボックスが表示される。
その中は、パラメータとキャンセルとOKが表示される。
キャンセルをクリックするとコンソールにfalse
OKをクリックするとコンソールにtrueが表示される。

### 気づき
```js
console.log(window.confirm('ゲームスタート！準備はいい？'));
```
パラメータでtrueかfalseになる。
それが```console```オブジェクトに表示される。

#### ```.confirm```
window.confirm()オプションのメッセージを含むダイアログを表示し、ユーザーがダイアログを```確認またはキャンセルするまで待機```するようブラウザに指示します。

##### 戻り値
```OK(true)``` または```キャンセル(false)``` が選択された かどうかを示すブール値。ブラウザがページ内ダイアログを```無視している場合、返される値は常にfalse```です。
###### 出典
https://developer.mozilla.org/en-US/docs/Web/API/Window/confirm

# クリックされたボタンでメッセージを変える
```js
  <script>
      'use strict';
    if(window.confirm('ゲームスタート！準備はいい？')) {
        console.log(`ゲームを開始します。`);
    } else {
        console.log(`ゲームを終了します。`);
      };
  </script>
```
```true```の時は
```js
console.log(`ゲームを開始します。`);
```
```false```の時は
```js
console.log(`ゲームを終了します。`);
```
の処理が行われる。

### 気づき
やっとプロゲートで学習したif文を使うことができた。
こうやって使うんだな。

## elseがない場合
```js
  <script>
      'use strict';
    if(window.confirm('ゲームスタート！準備はいい？')) {
        console.log(`ゲームを開始します。`);
    };
  </script>
```
キャンセルをクリックした時```false```が返されるので、コンソールには何も表示されない。
表示させたい時は
```js
console.log(window.confirm('ゲームスタート！準備はいい？'));
```
のように直接```console```オブジェクトにif文を書くか、elseに```console.log```をして表示させるようにする。

# 出典
https://www.sbcr.jp/product/4815601577/
【CommonLisp】クラス以外でもdefmethodが使える件


## 前書き

* 上級Lisperが得るものは何一つない記事です
* 処理系はSBCLです

## 内容

他の言語だとメソッドというものはクラスの専売特許であることが多いので、CommonLispもそうなんだろうなと勝手に思っていたが、普通に構造体などでもメソッドが利用できた。

```common-lisp
(defstruct hoge)
(defstruct (fuga (:include hoge)))

(defparameter *hoge* (make-hoge))
(defparameter *fuga* (make-fuga))

(defmethod show ((x hoge))
  (format t "hoge~%"))

(defmethod show ((x fuga))
  (format t "fuga~%"))

(defmethod show ((x integer))
  (format t "integer~%"))

(defmethod show ((x string))
  (format t "string~%"))

(defun main ()
  (show *hoge*) ; -> hoge
  (show *fuga*) ; -> fuga
  (show 123)    ; -> integer
  (show "なごなご") ; -> string
  )
```

（クラス使うメリットある？多重継承はできるけど…）
【Unity】SkyBoxを変更したらオブジェクトの色がおかしくなった

## この記事について
Window＞rendering＞Lighting＞Skybox MaterialからSkyBoxを変更したら、空間上に表示しているオブジェクトが影響を受け、色合いがおかしくなりました。

[こちらの記事](https://qiita.com/noma_tongull/items/a49289f33787818a88a4)で書いた方法を試してみましたが、影がなくなってしまったり改善しなかったため、別の方法を紹介します。

Unity Version：`2021.3.6f1 LTS`

## 原因
影響を受ける原因は、Window＞rendering＞Lighting＞Environment＞Environment LightingにSkyboxが設定されているからです。

つまり、設定したSkyboxに合った色合いが環境光として表現されてしまっているということです。

## 対処法
1. Window＞rendering＞Lighting＞Environment＞Skybox Materialから、追加しているMaterialを削除


2. MainカメラにSkyboxコンポーネントを追加してMaterialを設定
【merge】Databricks の Delta 形式のテーブルでは自由度の高いテーブル更新、削除、追加ができる話

# はじめに
本記事では Databricks 上で merge 機能を使用して Delta 形式のテーブルに対して更新、削除、追加する方法を紹介していきます。
Databricks の基本的な使い方や Delta 形式のテーブルについてある程度理解しているという前提のもとで進めていきます。
# 本記事のゴール
- merge とは何かを理解する
- merge のコード記述方法を理解する(SQL)
# 作業環境や必要な準備物
- Databricks 環境
- 本記事ではコードに SQL 使用(他言語でも可能)
- 任意のDelta 形式のテーブル
- 上記とテーブル構造が同じである更新データ及び追加データ
# merge の解説
## merge とは何か
merge は直訳すると融合するというような意味を持ちます。
Databricks では Delta 形式のテーブルに対してのみ、merge を使用したテーブルの削除及び upsert(更新と追加の総称)が可能になります。
もちろん merge を使用せずとも insert や delete などを直接叩いてテーブルを変更させることも可能です。
ですが、merge を使用することによって以下のようなメリットが挙げられます。
- テーブル読み込みの効率化
ほとんどのユースケースではテーブルの一部分のみに変更を加えると思います。
その一部分の変更のためだけにテーブルの全体を読み込んだり再書き込みを行ってしまうと、変更したい部分以外にも無駄な工数が発生することになります。
merge では条件式を加えることにより、その条件に合った部分、またその条件外の部分にのみ変更を加えるといった操作が行えます。
つまり、merge の条件式に関係のない部分はデータの検索を行わない(データスキッピングと呼ばれる)のでクエリ処理を高速化させます。
条件式によって変更部分の指定方法に自由度が増し、さらにクエリ処理を効率的に行えるのがメリットとなります。

説明だけだとわかりにくいかとは思いますので実際に簡単なコード例を見ていきましょう。
## merge のコード例
SQL 文で書くと以下のような構造になります。
もちろん細かい部分でカスタマイズは可能です。詳細は[こちらの公式ドキュメント](https://docs.databricks.com/sql/language-manual/delta-merge-into.html)をご覧ください。
```sql
MERGE INTO target_data
USING update_data
ON target_data.column1 = update_data.column2
WHEN MATCHED THEN
      UPDATE SET *
     (DELETE)
WHEN NOT MATCHED THEN
      INSERT *
```
|変数|説明|
|:--|:--|
|target_data|変更が加えられる Delta 形式のテーブル|
|update_data|変更内容に影響を与えるテーブル|
|column1|変更する条件に影響を与える target_table のカラム|
|column2|変更する条件に影響を与える update_table のカラム|

1. MERGE INTO で変更するテーブルを指定する
1. USING で上記テーブルの変更に影響するテーブルを選択する
1. ON で条件を指定する
1. WHEN MATCHED では上記の条件を満たす場合、更新または削除を指示する
1. WHEN NOT MATCHED では上記の条件を満たさない場合、追加を支持する

ただ単にテーブルに変更を加えるのではなく、変更のバリエーションが広がりますね。
# まとめ
merge 機能について紹介しました。
変更箇所のみ効率よく変更できることによってテーブルが大きければ大きいほどクエリパフォーマンスは上がりそうですね。
ぜひ使ってみてください。
【TIPS】Gitのプロジェクトを最新化（一括リセット）する

複数のGitプロジェクトをcloneしていると、「ブランチが最新じゃなかった！」が原因で、想定外の動作をしていた…という場面がありました。また、マイクロサービスアーキテクチャを採用していた場合、プロジェクト数が多くなる可能性[^1]があり、各プロジェクトの状態確認の時間がとても手間です。

[^1]: 「1つのGitプロジェクトに複数サービス入れれば良いのでは？」という提案もあると思います。各サービスのバージョン管理の方針次第ですが、分割しておいた方が柔軟性があるため、案件プロジェクトによって選ぶと良いと思います。


* 動作が担保されているブランチに切り替えられれば良い
* ローカルのブランチを一括で綺麗にしたい

案外簡単にできるかな…と思っていたのですが、少し嵌ったことがあるのでまとめておきたいと思います。

# 前提
* shell で実行できる
    - PowerShell でも同じことができると思います（やりたいコマンドをps用に書き換える必要あり）
* 「#bin/bash」や「現在ディレクトリの変数化」等のお作法は記載しません


# 結論

```bash
checkoutBranch='develop'
projectDirs=(
'Gitプロジェクトまでのディレクトリパス' 'Gitプロジェクトまでのディレクトリパス'
'Gitプロジェクトまでのディレクトリパス' '...'
)

for projectDir in ${projectDirs[@]};do
  cd $projectDir

  git fetch --prune
  git checkout $checkoutBranch
  git pull origin $checkoutBranch

  featureBranches=$(git for-each-ref --format="%(refname)" | grep "^refs/heads/" | sed -e "s/refs\/heads\///" | grep -v "$checkoutBranch")
  if [[ $featureBranches != "" ]]; then
    git beanch -D $featureBranches
  fi
done
```

# 紐解く

大まかな処理の構成は下記となります。

1. 「Gitプロジェクトのディレクトリパスを一覧で取得」
2. 「1 で取得したGitプロジェクトごとに処理を実行する」
    2-1. 「Gitプロジェクトに移動」
    2-2. 「ローカルのGitプロジェクトの最新化」
    2-3. 「ローカルのブランチの一覧取得」
    2-4. 「2-3 で取得したブランチの一覧から、切り替えたいブランチ以外を絞り込む」
    2-5. 「2-4 のブランチを削除する」

コメントを含めた形にするとこうなります。

```bash
checkoutBranch='develop'
# 1
projectDirs=(
'Gitプロジェクトまでのディレクトリパス' 'Gitプロジェクトまでのディレクトリパス'
'Gitプロジェクトまでのディレクトリパス' '...'
)

# 2
for projectDir in ${projectDirs[@]};do
  # 2-1
  cd $projectDir
  # 2-2
  git fetch --prune
  git checkout $checkoutBranch
  git pull origin $checkoutBranch
  # 2-3, 2-4
  featureBranches=$(git for-each-ref --format="%(refname)" | grep "^refs/heads/" | sed -e "s/refs\/heads\///" | grep -v "$checkoutBranch")
  if [[ $featureBranches != "" ]]; then
    # 2-5
    git beanch -D $featureBranches
  fi
done
```

## 嵌った部分

このシェルの重要な部分は、『2-3. 「ローカルのブランチの一覧取得」』です。
そして、その部分に嵌りました…。

「Git のブランチの一覧表示」といえば、 `$ git branch` かと思います。
ただ、これだと個人的にはうまくできなかったです。

やりたいことは、「ブランチ名を取得してアレコレしたい…」だったので調べたところ、 for-each-ref を見つけ解決しました。

https://git-scm.com/docs/git-for-each-ref

あとは、取得できた文字列を良い感じに削除用の文字列に変換をしたり絞り込みをして実現しました。

## 注意点

`git branch -D` を利用しています。一度リセットをする目的のために `-d` ではなく、 `-D` を使っていますので、作業中のブランチがあった場合は削除されてしまいます。
もしも誤って削除してしまった場合は、 `git reflog` を実行し復元したい状態を確認し、 `git branch ブランチ名 HEAD@{ログ番号}` で元に戻しましょう。

# 最後に

「結論」として最小限のシェルをまとめました。ただ、このまま利用すると想定外のミス（削除したくないものまで削除してしまった…）や、少しの手間や無駄なログが表示されるといった、微妙な状態となっています。

1. 不要な出力を /dev/null に流して、出力を抑える
1. 処理中のプロジェクトを表示する
1. 削除対象のブランチが何かを表示する
1. 削除前に、削除して良いかのチェック処理を入れる
1. 削除開始と削除完了後を表示する
1. シェルファイルを配備したら、そのファイル直下の全てのディレクトリを対象としてくれるようにする
1. ディレクトリを指定したら、そのディレクトリ直下の全てのディレクトリを対象としてくれるようにする
1. etc...

実際に使う場合は、こういったことを意識して改造をすると良いと思います。
「こういう風なシェルに改造したら使いやすかったですよ！」というようなアイデアは、コメントに頂けると嬉しいです。

面倒な作業が少しでも減らせられれば幸いです。それでは。