OmniAICreator/Qiita-1.07M huggingface dataset:
自動補完SHELL、Fishを使い倒す

# 概要

コマンドの自動補完をしてくれるFish Shellというものがある。
そのインストール方法と使い方を軽く説明します。

# インストール

以下を参考にしながらやっていく。

https://github.com/fish-shell/fish-shell

まずはAPTでインストール。

```bash
> sudo apt-add-repository ppa:fish-shell/release-3
> sudo apt update
> sudo apt install fish
```

インストールできたら起動できるか確認する。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/d0e9082a-cbc7-a7b5-8d39-7ec00de038f9.png)

# ログインSHELLをFishにする

起動SHELLは環境変数`$SHELL`に格納されているため、まずは確認する。
`fish`のPATHを見たのち、`chsh`コマンドでログインSHELLを変更する。

```bash
ayato@ayato-VBox:~/LITE_INC$ echo $SHELL
/bin/bash
ayato@ayato-VBox:~/LITE_INC$ which fish
/usr/bin/fish
ayato@ayato-VBox:~/LITE_INC$ chsh
Password: 
Changing the login shell for ayato
Enter the new value, or press ENTER for the default
	Login Shell [/bin/bash]: /usr/bin/fish
ayato@ayato-VBox:~/LITE_INC$ 
```

ログインしなおしてターミナルを起動すると反映されてます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1523062/ae2fc42d-c169-3857-ee34-b1c7ae52d128.png)

# fishrc

エイリアスとかを格納するファイルの説明。

起動時に何等かのコマンドを実行したい場合には`~/.config/fish/config.fish`を編集します。
具体的にはこんな感じです。

```fish:config.fish
if status is-interactive
	# Commands to run in interactive sessions can go here
	alias c='clear'
end
```

# 諸設定

こんなコマンドを打ち込むとWebブラウザーで設定画面が開かれます。
簡単に設定できる！

```bash
> fish_config
```

# コマンド作成

Fishでは自作のコマンドを設定できる。
`~./config/fish/functions/`以下に`.fish`ファイルを以下の形式で作成する。

```fish:.fish
function <Function_Name> -d "<Explaining about command>"
    <Command>
end
```

例えば、僕はこんな感じで作った。画面をクリアしてからglowを実行する。
Fishでは`alias glow=clear && /snap/bin/glow`が許されていないため、以下のような形になる。

```fish
function clear_glow -d "clear and glow"
    clear
    /snap/bin/glow $argv
end
```

`glow $argv`ではループが起こることに注意！
最後に`~./config/fish/config.fish`にて`alias glow='clear_glow`を書いておけば大丈夫。

# まとめ

補完機能めっちゃあって、なんかいいね！
ECSタスク起動時のstandard_init_linux.go:228: exec user process caused: exec format errorへの対処法

# はじめに
コンテナ初心者の自分がM1 Macを使ってDockerイメージ作成からECSデプロイまで行なった際に発生したエラーとその対処法についてまとめます

# 結論
```
standard_init_linux.go:228: exec user process caused: exec format error
```
ECSのタスク起動時に上のエラーが出て、かつDockerイメージ作成の際にM1 Macを使っているなら`docker build`コマンドにオプションとして`--platform amd64`を追加してあげると解決します。
```
docker build ./ --platform amd64
```

# 経緯

Next.jsをECS Fargateにデプロイしようと思い以下のような手順を取りました
- ローカルでDockerfileからイメージビルド
- ECRのリポジトリにイメージをpush
- pushしたイメージをもとにECS Fargateでタスク起動

### 使用したDockerfile
```Dockerfile:Dockerfile
FROM node:16.14.2-alpine3.15

ENV TZ Asia/Tokyo

WORKDIR /usr/src/app

COPY ./ ./
RUN apk update
RUN npm install
RUN npm run build

EXPOSE 3000

CMD ["npm", "run", "start"]
```

### ECRへのpush
AWSコンソール上で表示される手順に沿って行いました
![スクリーンショット 2022-07-24 9.34.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524155/249d9d12-8a44-0828-ef65-c108039e4a31.png)

### タスク起動
タスクを起動しても即座に停止してしまうためログを確認したところ次のようなエラーが発生していました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524155/927a14f9-78d8-fc58-c3c9-6c022dc06f45.png)

# 原因
上記のエラーはDockerイメージをビルドしたM1 Macと実際にコンテナが動作するFargateのCPUアーキテクチャが違うことが原因で発生するもののようです。そのため結論で書いたように`docker build`の時に`platform`を指定することで解決することができました。

# 結果
無事にNext.jsをFargate上で実行することができました
![スクリーンショット 2022-07-24 9.46.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2524155/8facb529-6236-d7de-d6f9-3e65db73005d.png)
G検定に2週間で受かる方法（2022年第2回）

## 試験を受けた感想
・AIや機械学習の仕組みがなんとなく理解できる
・試験時間は2時間あるが、問題数が約200問のため、時間に余裕がなく難易度が高かった
・約7割ほどで合格した（勉強時間は40時間ほど）

## 前提
・文系
・プログラミングを少し触ったことがある
・人工知能や機械学習はさっぱりわからない

## 受験背景
・とにかく短期間で合格したい
・機械学習を学んでみたかった

## 試験内容
・試験時間は2時間
・選択問題、200問（1秒30問ペース）
・自分のパソコンを用いて自宅で受験
https://www.jdla.org/certificate/general/

## 攻略法
・色々な方の合格体験記を読んでテストの傾向を把握
・公式テキストの内容を網羅する
・当日は自宅試験のためチートシートや検索を駆使する（テキストの内容を頭に入れておいて、わからないところのみ調べる。すべての問題を検索すると到底、試験時間に間に合わない）
### お世話になったチートシート
※誠にありがとうございました

https://qiita.com/juri_engineer/items/a42f28e57a1d6809e43e

https://qiita.com/DS27/items/ea719ba584be9966fd06#ai%E3%83%96%E3%83%BC%E3%83%A0

## 勉強法
・公式テキストを熟読する
・テキストは難解なため、検索やYoutubeを通して、わからない箇所を潰していく

・とにかく模試を解いて、復習すべし！テキストやWebに本番を想定した模試が公開されている。解けなかった問題は、その問題だけでなく、テキストで該当範囲をまるまる復習する

・AIの法律・倫理・社会問題が2割ほど出題されるので、ネットでAI関連の法律を調べて、ある程度、頭に入れておく（海外の事例もそこそこ出題される、AIやデータの著作権に関する問題が多かった）

### 徹底攻略ディープラーニングG検定ジェネラリスト問題集 第2版 (徹底攻略シリーズ)
・通称黒本と言われる問題集
・解説が詳しく載っているのでわかりやすい
・最後に掲載されている模試が必須
・テストの感覚がつかめる
・間違えた問題は確認しておく

### Study-AI
・本番と近い難易度
・問題数が豊富なためこちらも解いておく
https://study-ai.com/generalist/

### DIVE INTO EXAM
・こちらも解いておいて損なし
・本番と近い難易度
https://diver.diveintocode.jp/dive_into_exam/3
cscの作法 その253

# 概要
cscの作法、調べてみた。
base64urlをやってみた。

# 参考にしたページ

https://qiita.com/hukatama024e/items/b1352cabcd85948511c3




# 実行結果

```
>base64url
QmFzZTY0dXJsIOaWh-Wtl-WIl-WkieaPm-OCteODs-ODl-ODqw
Base64url 文字列変換サンプル

>

```

以上。
自分のブログに海外からなんだかご機嫌なコメントが届いた件

# はじめに
試験的に運営している別ブログに謎のコメントがとどいたので思い出に残す

# 海外の方何のために…？
IPとメアドを見るにぱっと見ちゃんとしたコメントっぽいが、、、
内容が薄すぎて心配。
翻訳すると「朝早くから君のブログが楽しみでしょうがないよ！」って言ってるけど
ここしばらくずっと更新してないし、、、何か騙されているのでは…？心配じゃー…
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/8a93350a-bd07-026c-2224-7fdc178328e9.png)

でも承認しておこうと思う。このあと何が起きるのか…。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/947adce9-3627-194e-ac0c-196cd54607e8.png)

ちなみにそ～っと入れてるアクセス解析結果はコチラ。
楽しみにしてると言ってくれてる割にはアクセスしてくれてないような…そんなものなのだろうか。
不安は強い。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/6a91b40a-d6ff-8f3d-a723-a55ede0f0f1b.png)
MS/Azure関連ニュースメモ：Windows Subsystem for AndroidのTips and Tricks


https://blogs.windows.com/windowsdeveloper/2022/07/14/windows-subsystem-for-android/

まだ日本に展開されていないWindows Subsystem for Androidについて以下のTipsが紹介されています。

水平スワイプ

Shiftキーを押しながらスクロールホイールを使用すると、水平方向のスワイプに変換することができます。

2本指のスワイプ

ALTボタンを押しながらマウスでクリックやドラッグをすると、2本指でのタッチやスワイプがアプリケーションに送信されます。

ゲームパッドのサポート

ゲームパッドに対応したアプリで使用することができます。

この記事の内容は以下でも紹介されていました

https://forest.watch.impress.co.jp/docs/news/1426/583/amp.index.html
laravel モデルクラスを使ってfindしようとしたらエラーが出た

# 概要

- モデルクラスを用いてfindしたらエラーが発生したので解決方法をまとめる。

# エラー発生までの経緯

- 下記のような記載をコントローラーの関数内に記載した。

    ```FooController.php
    use App\Models\Content;

    $contentEloquent = Content::find($request->contentId);
    ```

- 当該のモデルクラスは下記のように記載した。

    ```app/Models/Content.php
    <?php
    
    namespace App\Models;
    
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Database\Eloquent\SoftDeletes;
    
    class Content extends Model
    {
        use HasFactory;
        use SoftDeletes;
    
        protected $fillable = [
            'id',
            'content',
        ];
    }
    ```

- 当該のマイグレーションは下記のように記載した。

    ```create_contents_table.php
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    return new class extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('contents', function (Blueprint $table) {
                $table->id();
                $table->string('content', 255)->comment('投稿内容');
                $table->timestamps();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('contents');
        }
    };
    ```

# エラー

- findの処理が実行される部分に差し掛かった時、下記のエラーが発生した。

    ```
    Illuminate\Database\QueryException with message 'SQLSTATE[42S22]: Column not found: 1054 Unknown column 'contents.deleted_at' in 'where clause' (SQL: select * from `contents` where `contents`.`id` = 7 and `contents`.`deleted_at` is null limit 1)'
    ```

# エラー解消までの経緯

- マイグレーションに論理削除系カラムの作成命令を記載していなかった。。（モデルクラスには記載していたのに。。）
- 下記のようにマイグレーションを修正したところエラーは解消した。

    ```create_contents_table.php
    <?php
    
    use Illuminate\Database\Migrations\Migration;
    use Illuminate\Database\Schema\Blueprint;
    use Illuminate\Support\Facades\Schema;
    
    return new class extends Migration
    {
        /**
         * Run the migrations.
         *
         * @return void
         */
        public function up()
        {
            Schema::create('contents', function (Blueprint $table) {
                $table->id();
                $table->string('content', 255)->comment('投稿内容');
                $table->timestamps();
                $table->softDeletes();
            });
        }
    
        /**
         * Reverse the migrations.
         *
         * @return void
         */
        public function down()
        {
            Schema::dropIfExists('contents');
        }
    };
    ```
[× Windows][〇 Unity]で新規ファイルをUTF-8にする

**追記：~~Windows10~~ Unityで新規ファイルをUTF-8にする方法です。**
下記にいくつかやり方を記述していますが、現在は
プロジェクトフォルダ(Assetsフォルダと同じ階層)に
```.editorconfig
root = true

[*.cs]
charset = utf-8-bom

```
を置くのが良いようです。


**追記：注意　この変更を行って不具合が出るようでしたら設定をもとに戻してください。**
自分の場合はBandiCamが起動しなくなりました（設定をもとに戻したら起動するようになりました）

---
いつのころからか、Unityで新規ファイルを作成したときのファイル形式がShiftJisになってしまいました。
UnityにもVisual Studioにも新規ファイルの形式を選ぶ形式がなく、仕方なく[ファイル作成後のPostProcessで無理やりファイルをUTF8に変更していた](https://github.com/sharkattack51/GarageKit_for_Unity/blob/master/UnityProject/Assets/__ProjectName__/Editor/AssetPostprocessUTF8Encode.cs)のですが、Windowsの設定を変えることで対処可能でした。

スタート>設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/d557b4fc-1ec9-2251-0e7e-099b2bd568e9.png)
時刻と言語
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/a385f2b9-678b-19c2-f4f7-18a255b83266.png)
日付、時刻、地域の書式設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/bedd1df6-459e-dbf3-9444-aa57d1124a13.png)
地域>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/4a4e10a2-988d-e5d7-1808-d53f6f9a4ce7.png)
日付、時刻、数値形式の変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/f88dc531-6adf-84d3-0691-575dc13b01b3.png)
管理>システムロケールの変更
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/c89646f6-e40a-d3f8-3447-7c21ee64e62d.png)
ワールドワイド言語サポートでUTF-8を使用>再起動
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/59911/730e3d8f-a839-641f-6e17-af1f946be0ef.png)

これで新規ファイルがUTF-8になりました。
【CSS】OOCSSについて

## はじめに
* [スターバックス](https://www.starbucks.co.jp/)のHPを例に取り上げてます。
* コードの例は記載してません。

## 特徴
* オブジェクト指向を取り入れる
* パーツを使い回してエリアに配置し、サイトを構築していく
* どこのエリアにもパーツは依存しない
* CSSに記述する際にIDセレクタは避け、クラスセレクタを用いる

## メリット
* 拡張性
* 移植性

## デメリット
* オブジェクト指向を理解する必要がある
* 厳格な決まりごとは少なく、命名規則などによる補助が必要
* 構造と見た目の組合せの数が膨大になる
* どこのエリアのパーツか不明

## 利用シーン
* OOCSSを単体で使うことはない
* 小規模な開発くらい
* BEMなどの他の設計手法のベースのため、思想は取り入れられている。

## 原則
1. 構造と見た目の分離
1. コンテナとコンテンツの分離

## 1. 構造と見た目の分離
### メリット
* 拡張性

### 構造と見た目ってなんやねん
* **構造**　：width、heigth、padding、marginなど
* **見た目**：font、color、box-shadowなど

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/a17e89c0-7788-7988-401c-523c0e91cee3.png" width="35%"> <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/d2dd28d6-1a9a-e71b-7d0b-55e7c08540cf.png" width="33%">

### そーゆーことか
実際HTMLでクラス属性には、構造と見た目を設定したらええんやな
ただ、異なる構造を要求されたとき、構造と見た目の組合せの数が膨大になるな。
```html:html
<div class="構造 見た目"></div>
```


## 2. コンテナとコンテンツの分離

### メリット
* 移植性

### コンテナとコンテンツってなんやねん
* **コンテナ**　：大まかなエリア
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/127fc096-5e85-ae74-89ca-1ea6360926a3.png" width="100%">

* **コンテンツ**：パーツ

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/a17e89c0-7788-7988-401c-523c0e91cee3.png" width="35%">

### そーゆーことか
ボタンのクラス名を「.nav-btn」みたいにすると、
ナビゲーションエリアでしか使えんボタンになってまうんや。

はじめから「.btn」だけにしてたら、
どこでも移植しやすいっちゅうわけやな

ただ、どこのボタンやねんてなってまいそう。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1483743/9aae8870-fe0b-2f25-3838-8d5596b83935.png" width="100%">

## 備考
* **パーツのみにフォーカスした設計思想である。**
ブラウザ毎の初期設定の違いや、レイアウトなど、Webサイトを構築するのに必要な材料は他にもあるし、それらを考慮する必要があるよね。
:point_right:**他の設計手法と組み合わせていく。**

* SMACSSやBEMなど他の設計手法はOOCSSを参考にしたものであるため、学んでおくことは重要である。



## 参考文献

https://www.amazon.co.jp/CSS%E8%A8%AD%E8%A8%88%E5%AE%8C%E5%85%A8%E3%82%AC%E3%82%A4%E3%83%89-%E8%A9%B3%E7%B4%B0%E8%A7%A3%E8%AA%AC-%E5%AE%9F%E8%B7%B5%E7%9A%84%E3%83%A2%E3%82%B8%E3%83%A5%E3%83%BC%E3%83%AB%E9%9B%86-%E5%8D%8A%E7%94%B0-%E6%83%87%E5%BF%97/dp/429711173X/ref=tmm_pap_swatch_0?_encoding=UTF8&qid=&sr=

https://www.amazon.co.jp/Web%E5%88%B6%E4%BD%9C%E8%80%85%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AECSS%E8%A8%AD%E8%A8%88%E3%81%AE%E6%95%99%E7%A7%91%E6%9B%B8-%E3%83%A2%E3%83%80%E3%83%B3Web%E9%96%8B%E7%99%BA%E3%81%AB%E6%AC%A0%E3%81%8B%E3%81%9B%E3%81%AA%E3%81%84%E3%80%8C%E4%BF%AE%E6%AD%A3%E3%81%97%E3%82%84%E3%81%99%E3%81%84CSS%E3%80%8D%E3%81%AE%E8%A8%AD%E8%A8%88%E6%89%8B%E6%B3%95-%E8%B0%B7-%E6%8B%93%E6%A8%B9/dp/4844336355/ref=pd_vtp_sccl_3_4/355-0792597-6083124?pd_rd_w=kNOMN&content-id=amzn1.sym.cbb45385-7b99-44b7-a528-bff5ddaa153d&pf_rd_p=cbb45385-7b99-44b7-a528-bff5ddaa153d&pf_rd_r=41823D38PG1Z0DP15CW5&pd_rd_wg=b8vsx&pd_rd_r=614f4aa3-9753-4b1c-a1d5-612dc96d4b81&pd_rd_i=4844336355&psc=1

https://hail2u.net/blog/webdesign/oocss-drawbacks-and-gifts-of-every-declaration-just-once.html#:~:text=OOCSS%E3%81%AE%E6%AC%A0%E7%82%B9%E3%81%AF%E3%81%9D%E3%81%AE,%E3%81%A6%E3%81%AF%E3%81%AA%E3%82%89%E3%81%AA%E3%81%84%E3%81%A8%E3%81%93%E3%82%8D%E3%81%A0%E3%80%82

https://qiita.com/nezurika/items/a964e21d3596b0ee4c9a
Salesforcで数式項目を作成しよう～親オブジェクトの複数の項目値を１つにまとめる方法

Salesforceには数式項目という項目型があります
数式項目でできることはいくつかありますが、今回は「クロスオブジェクト数式項目」についてみていきましょう

なお、「クロスオブジェクト数式項目」詳細は以下のヘルプをご参照ください

クロスオブジェクト数式項目とは、2 つの関連オブジェクトにまたがり、そのオブジェクトで差し込み項目を参照する数式です。クロスオブジェクト数式項目は、オブジェクトが主従関係の従側の場合は主 (「親」) オブジェクトから、差し込み項目を参照できます。クロスオブジェクト数式項目は参照関係にも使用できます。

https://help.salesforce.com/s/articleView?id=sf.customize_cross_object.htm&type=5


分かりやすく言えば、
（商談と取引先は取引先が親、商談が子の参照関係ですが）商談オブジェクトにクロスオブジェクト数式項目を作成し、商談レコードに取引先情報を表示することが可能です。

例として商談に取引先の所有者「姓」項目を表示させる場合、以下となります

 Account.Owner.LastName 
![所有者姓.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/505b34a2-4276-1a55-1e0f-b2e1d721a914.png)

このクロスオブジェクト数式項目ですが、「& 」を設定することにより、親オブジェクトにある項目を複数表示させることも可能です

例として取引先の所有者「姓」と所有者「名」を表示させる項目は以下となります

Account.Owner.LastName  &  Account.Owner.FirstName
![姓名.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531631/78f393b4-8356-88e0-e7ad-3977a90a9291.png)

クロスオブジェクト数式項目は親オブジェクトの項目の値が変更した場合もリアルタイムで値が反映されるので便利です。
ぜひ活用すればよりよいSalesforceの運用が可能になるかと思います。
【Flutter/Dart】import文のas/show/hideって何？

Flutterの開発において（他の言語でもそうですが）、import文を書いて別ファイルやパッケージの読み込みを行うことが出来ます。

```dart
import 'package:myproject/pages/home_page.dart';
import 'package:intl/intl.dart';
```
このimport文の末尾に読み込んだファイルやパッケージに任意の名前を付けることが出来ます。
```dart
import 'package:intl/intl.dart' as intl;
// intl.パッケージ内のクラス名
intl.NumberFormat('#,###', 'en_US')
```
こんな感じでよく使いますね。
## そもそもなんで任意の名前を付けるのか？

例えば、NumberFormatというクラスがあるファイルにintlパッケージをimportし、intlパッケージのNumberFormatの機能を使おうとするとクラス名が重複しているので正しく読み込まれません。この場合、任意の名前を付けることによってこのようなバグを防ぐことが出来ます。

```dart
import 'package:intl/intl.dart' as intl;
// intl.パッケージ内のクラス名
intl.NumberFormat('#,###', 'en_US')
// 上記のNumberFormatはintlパッケージのクラスと認識される
class NumberFormat {
}
```
ではas/show/hideの違いはなんでしょう？


## as/show/hideの違いは何？

<strong>as</strong>を使うと、import先のすべての関数とクラスにアクセスすることができます。
```dart
import 'package:intl/intl.dart' as intl;

// 両方ともアクセス可能
intl.NumberFormat('#,###', 'en_US')
intl.DateFormat('yyyy-MM-dd')
```

<strong>show</strong>を使うと、パッケージ内でアクセス可能なクラスや関数を指定することが出来ます。
```dart
import 'package:intl/intl.dart' show NumberFormat;
// アクセス可能
NumberFormat('#,###', 'en_US')
// showで指定していないのでアクセス不可
DateFormat('yyyy-MM-dd')
```

反対に<strong>hide</strong>を使うと、アクセス不可のクラスを指定することが出来ます。
```dart
import 'package:intl/intl.dart' hide DateFormat;
// アクセス可能
NumberFormat('#,###', 'en_US')
// hideの指定によりアクセス不可
DateFormat('yyyy-MM-dd')
```

また、asとshow、hideを組み合わせることも可能です。
```dart
import 'package:intl/intl.dart' as intl show NumberFormat;
// アクセス可能
intl.NumberFormat('#,###', 'en_US')
// showで指定していないのでアクセス不可
intl.DateFormat('yyyy-MM-dd')
```

基本的にはasを使うで問題ないと思いますが、規模の大きいアプリの場合は名前の衝突を防ぐためにもshowやhideを使い分けることが大事になるかもしれないですね。

## 参考
https://flutteragency.com/primary-difference-between-show-and-as-in-import-statement/
STM32L010でI2C EEPROで遊ぶ4(連続読み込み)


x Mbed2リビジョン125


目的
I2C EEPROMのテスト

通販コード　K-12061

![o_con590.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/840352/7a2b5459-71f1-9381-4334-3a9708c32db8.jpeg)


連続読み取り

```c++


//SER_I2C_EEPROM_read_s_010_1

#include "mbed.h"

I2C i2c(PA_10, PA_9); //010

//#define S5851A 0x48
#define ADDR        ((0x50)<<1)   //  address


//四桁の変換
//#define DIV10(n) (((n*409)+((n*154)>>8))>>12)
int DIV10(int n)
{
    return    (((n*409)+((n*154)>>8))>>12)    ;
}
char data[16];
char *itoa9999(int d)
{

    data[4] = 0;
    data[3] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
    d = DIV10(d);
    data[2] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
    d = DIV10(d);
    data[1] = '0' + (  d - (DIV10(d) * 10)  );  // '0'+(d%10)
    data[0] = '0' +  DIV10(d);                  // '0'+(d/10)

    return (data);

}//itoa99

//仮想シリアルへの一文字出力 9600bps
DigitalOut TX(PA_2);
//DigitalIn  RX(PA_3);
#define UART_DELAY 101 //  1/9600 98-105
int pc_putc(char ch)
{
    TX=1;
    TX=0;//Start
    wait_us(UART_DELAY);

    for(int ii=0; ii<8; ii++) { //Data x 8
        TX=(ch>>ii)&1;
        wait_us(UART_DELAY);
    }; //for

    TX=1;//Stop
    wait_us(UART_DELAY);

    return(0);
} //pc_putc


//文字列の表示 nana_seg
int pc_puts(char *str1)
{
    //文字の中身がゼロか
    while(*str1) {
        pc_putc( *str1 ++);
    } //while

    //戻り値
    return(0);
}//pc_puts


//連続読み セグメントを跨がない事?
void eeprom_read(char *str1, int len1) {

    int ii=0;

    char ad_hl[2];

    //アドレス
    //set address
    ad_hl[0] =    ii >> 8   ;
    ad_hl[1] =    ii & 0xff ;
    //pc_puts( itoa9999(ad_hl[0]) );
    //pc_puts( "#" );
    //pc_puts( itoa9999(ad_hl[1]) );
    //pc_puts( " " );
    i2c.write(ADDR, ad_hl, 2); //addres 0

     //データの読み込み
     // Read temperature register
     i2c.read(ADDR, str1, len1, false);
     //data_read[0] = 123;
     pc_puts( "Read len=" );
     pc_puts( itoa9999(len1) );
     pc_puts("\r\n");


}//eeprom_read

int main()
{

    char data_read[32+1]; //バッファー

    pc_puts("\r\n<START>\r\n");

    //無限ループ
    while(1) {

        eeprom_read( data_read, 10);

        pc_puts("for 0 to 10\r\n");

        for(int ii = 0; ii<10; ii++) {

            pc_puts( itoa9999(data_read[ii]) );
            pc_puts("\r\n");

            //1秒待つ
            wait_ms(1000);

        }//for

    }//while

}//main

//容量削減
void error(const char* format, ...) {}




```
【rails】active_storageに簡単にバリデーションを追加

画像投稿を簡単に導入できるactive_storageというGemがあります。画像投稿は簡単に実装できるようになりますが、PDFなども画像として投稿可能なため、思わぬエラーの原因になり得ます。そこで、バリデーション設定するにアウトプットします。

![スクリーンショット 2022-07-24 7.41.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2707093/525ce0cf-f621-8eeb-f08e-e5622c8fc91c.png)
# 結論
Active Storage ValidationsというGemを導入すると、既存のvalidateと同じような記述でバリデーションを追加できます。もう１つの方法は自身でバリデーションのメソッドを定義する方法ですが、今回こちらは紹介しません。
導入方法
```ruby:gemfile
# Rails 5.2 and Rails 6バージョンのみ利用可能
gem 'active_storage_validations'
#記述後bundle install
```
# やったこと
画像ファイルの拡張子に制限をかけることと、大きすぎる画像は投稿できないようにしました。
```ruby:model
validates :image, content_type: {in:[:png, :jpg, :jpeg], message: "はpng, jpg, jpegいずれかの形式にして下さい"},
  size: { between: 1.kilobyte..4.megabytes , message: '画像容量が大きすぎぃ、4megabytes以下でおなしゃす' }
```
その他設定できるバリデーションは「ファイルの寸法（横幅、縦幅）、アップロードする画像数、画像の縦横比、画像が存在するか否か」があります。
# 参考サイト
https://github.com/igorkasyanchuk/active_storage_validations

https://note.com/emetselch1984/n/ndd472c93ade6
python3 和集合と積集合


# set型を使う
set型を使って和集合と積集合をもとめます。set型を作るときは{}で囲います。
```python
s = {1,2,3}
```
set型の特徴は順番と重複が無視されます。
# 集合演算子
set型に集合演算子を使うと和集合や積集合が求められます。
| 和集合
& 積集合
# コード
まずは和集合から
```python
s = {1,2,3,4,5,5}#重複は無視される
t = {2,3}

union = s|t#集合sとｔの和集合
print(union)
```
出力
```
{1, 2, 3, 4, 5}
```
積集合
```python
s = {1,2,3,4,5,5}#重複は無視される
t = {2,3}

intarsection = s & t#sとtの積集合
print(intarsection)
```
出力
```
{2, 3}
```
ラズパイpicoで信号機プログラム

# はじめに

https://docs.sunfounder.com/projects/thales-kit/en/latest/traffic_light.html

を試した。

# 概略図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/4ab8d6ec-662e-dbbb-daa5-cef08e64f6e9.png)

# 回路図

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/55201edd-d7a8-0530-c66e-0bf1ef6e33b9.png)

# コード
赤→２秒→黄→１秒→青→２秒→赤→…の順序でLEDを点灯させる。
付属のボタンを押すと、押した後の初回の赤LEDは5秒点灯する。

```
import machine
import utime
import _thread

led_red = machine.Pin(15, machine.Pin.OUT)
led_yellow = machine.Pin(14, machine.Pin.OUT)
led_green = machine.Pin(13, machine.Pin.OUT)
button = machine.Pin(16, machine.Pin.IN)

global button_status
button_status = 0

def button_thread():
    global button_status
    while True:
        if button.value() == 1:
            button_status = 1

_thread.start_new_thread(button_thread, ())

while True:
    if button_status == 1:
        led_red.value(1)
        utime.sleep(3)
    global button_status
    button_status = 0

    led_red.value(1)
    utime.sleep(2)
    led_red.value(0)

    led_yellow.value(1)
    utime.sleep(1)
    led_yellow.value(0)

    led_green.value(1)
    utime.sleep(2)
    led_green.value(0)

    led_yellow.value(1)
    utime.sleep(1)
    led_yellow.value(0)

```

# コードのポイント

ボタンを押したときに割り込んでフラグを立てられるように。スレッドを使ってる。
_thread()が使えるとは思ってなかったので驚いた。
_thread.start_new_thread(button_thread, ())で常時待機していて
ボタンが押されたら(button.value() == 1)、button_thread()内の button_status = 1を行う。

あとは、普通なプログラムって感じ。
ラズパイPicoでサーボ回す

# はじめに
ラズパイPicoでサーボを回した時の思い出を残す

# 参考
ここに書いてた。感謝感謝。

https://docs.sunfounder.com/projects/thales-kit/en/latest/swinging_servo.html

# 基本的な構成
構造的には電源(VBUS)と１つのGPIOピン（今回のケースではGP15）とつながっていたらOKのようです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/a652668c-7858-cc9b-30af-fa4a6fb638e9.png)

# 回路図
回路はコチラ。
後で気づいたけど、２つのGNDに配線しているけど、上のGNDにはどこともつながってないので多分いらない。
逆に上のGNDにサーボ側のGNDをつなげるのであれば下のGNDはいらない。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/b122ff5f-4442-33f2-3565-a2ac5375ad0b.png)

# 実装コード
これ書くだけでOK。

```
import machine
import utime

servo = machine.PWM(machine.Pin(15))
servo.freq(50)

def interval_mapping(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min

def servo_write(pin,angle):
    pulse_width=interval_mapping(angle, 0, 180, 0.5,2.5)
    duty=int(interval_mapping(pulse_width, 0, 20, 0,65535))
    pin.duty_u16(duty)
    print('angle={}, pulse_width={}, duty={}'.format(angle,pulse_width,duty)) # ←ココはデバグ用なのでなくても動く

while True:
    print('forward swinging')
    for angle in range(180):
        servo_write(servo,angle)
        utime.sleep_ms(20)
    print('reverse swinging')
    for angle in range(180,-1,-1):
        servo_write(servo,angle)
        utime.sleep_ms(20)
```

実行結果はコチラ。実際に動いている動画は取れなかったけど、ログが取れたのでよかった。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/a9514c79-942c-912b-1b72-241164de1b32.png)

# コードの簡単な解説

servo_write()が実際にサーボを回している箇所。
厳密に言うと、servo_write()内にある、pin.duty_u16()で動いている。

pin（今回のケースでいうとGP15）の情報にduty値を与えたら、サーボは動く。

## dutyはどうやって出すの？
dutyは0~65535の範囲で指定してやる必要がある。
じゃあ、duty値をどうやって導くのか？っていうと、

https://docs.sunfounder.com/projects/thales-kit/en/latest/servo.html#servo

より、↓↓の画像より、サーボは0~180°の範囲で動作する。
で、この動作角度は20msの周期（＝50Hz）に対してPulse widthを0.5ms～2.5msの範囲でONにしたときの時間で決まる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/416263/c7dfea2d-0646-977d-6e86-35c95309817c.png)

なので、、、50Hzのデューティ比を算出して、これを元に0~65535に置き換えたら、duty値が割り出せるって話。

そこで、↑↑の換算式を関数化したものがinterval_mapping()
このモジュールはホントよくできてるので別の場所でも使わせてもらおう。

## で、最終的にはどんな動作をするコード？
関数の説明がおわったのでメイン動作なんだけど、それはこのwhile Trueで無限ループしてるところ。
最初は0→180へ向かって1°ずつ20ms間隔でサーボを動かす。
で、180°まで移動したら、次は180→0へ向かって同様にサーボを動かす。というプログラム。

```
while True:
    print('forward swinging')
    for angle in range(180):
        servo_write(servo,angle)
        utime.sleep_ms(20)
    print('reverse swinging')
    for angle in range(180,-1,-1):
        servo_write(servo,angle)
        utime.sleep_ms(20)
```

# おわりに
今回紹介したサイトは、サーボ以外にもほかのモジュールの使用方法についても説明があって
しかもすごいわかりやすいの今後も参考にしていこう。
Backlog API をUiPathから使ってみる_Wikiの追加

# はじめに
この投稿は、BacklogAPIをUiPathから利用するための手順を
個人的にまとめたものです。
今回はいろいろできるBacklogAPIの中でも、Wikiへのページ追加を例として
UiPathから利用します。

この記事はUiPathブログ発信チャレンジ2022サマーの24日目の記事です。

# 事前準備
## Backlog側での準備_APIキーを発行する
事前準備として、BacklogでAPIキーを発行します。

![1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/3d886f00-bc23-944b-f588-f3c26539535c.png)

「個人設定」
→「API」
→ メモの内容を記入（任意）
→「発行」ボタンをクリック
→「登録されたキー」が追加・表示されればOK

## UiPath側での準備_パッケージをインストールする
UiPathのプロジェクトにも、WebAPIを使用するためのパッケージをインストールします。
* UiPath.WebAPI.Activities

# Uipathのプロジェクト

こんなん作りました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/aa42d0bc-7c38-5510-7b2f-2afeabea5a23.png)

リクエスト投げて、その結果を出力に書くだけです。
（これでもWikiは作れちゃいます）
次から設定するパラメータについて触れていきます。

## 設定するパラメータ
基本的に、BacklogAPIのドキュメントに
* 必須の値
* リクエストパラメータ

が記載されているので、それを使用します。

以下からはUiPathの設定項目に準拠して設定する値について説明していきます。

## オプション
オプション部分で設定するのは以下の項目です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/3e74726f-8778-8d43-81ff-a5f21337bb0c.png)

### パラメータ

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/6b46fa93-1c2a-661b-3554-326d89511e5e.png)

ここの「名前」は必ずBacklogAPIドキュメント内の「パラメータ名」と同じにしてください。（同じにしないとエラーになる）

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/ff9fae89-e8ec-999e-27bd-ec1c99f8e3b5.png)


### ヘッダー

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/ab5e71e6-a685-14f6-b6ce-091eafaee3d2.png)
BacklogAPIドキュメント内の「リクエストパラメータ」を設定します。

## 入力
入力部分で設定するのは以下の項目です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/4e084f74-caf9-1ea7-7c99-1e6973dd9bf5.png)

* 受け入れ方式…「ANY」
* 要求URL
ここで一番ハマるかもしれません。
項目名は「要求URL」なのですが、これは「エンドポイント」の設定です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1846796/c3f71844-90d9-0bb8-847c-be6170aa87f8.png)
「要求URL」の設定を開始すると、ここがEndPointの設定なのか～とわかる。
最初どこにエンドポイント設定したらいいんだ…？とさまよいました。
以下のように設定します。
```
" https://"+ SpaceID +".backlog.com/api/v2/wikis?apiKey="+ APIキー
```
余談ですが、現在はbacklog.jpとbacklog.comが混在している状態だそうです。
将来的には.comに統一するとのことで、現在.jpの方は注意が必要です。
.jpの方は.jpとしてください。

https://backlog.com/ja/blog/backlog-jp-change-domain-backlog-com/

（僕は.comなのに.jpだと思い込んで記述してしまい、めちゃめちゃにハマりました）

* 要求メソッド…「POST」
BacklogAPIの「メソッド」部分を参照して設定します。

# 実際に動かしてみた
動かしてみて、こんな感じのが帰ってきてなければ成功です。
（個人情報もりもりでうまく切り貼りできる自信がなかった。ゆるして）

```
{"errors":[{"message":"error.required : projectIdOrKey","code":7,"moreInfo":""}]
```
これはエラーメッセージの一例なのですが、
こんな感じのではなく、追加したかった情報や自分の名前などが含まれたながーい情報が帰ってくるはずなので、そうでない場合はどこかしらに抜け漏れがあるかと思われます。

エラーメッセージについてもBacklogAPIのドキュメントに載っています。

https://developer.nulab.com/ja/docs/backlog/error-response/#

# 参考文献
https://developer.nulab.com/ja/docs/backlog/#

BacklogAPIのドキュメントです。

# おわりに
初めてこういった取り組み（この記事はUiPathブログ発信チャレンジ2022サマー）
に参加いたしましたが、自分で決めて参加するとえいやと書けるので書きたいけど時間がナ～とか言って延々と書かない自分から脱却できてとてもよかったです。

また参加したいと思います。
ありがとうございました。
スプレッド構文を利用してUI表示をうまく切り替える

# React・VueのUI表示切り替えで使える

フラグで表示の切り替えを行うことって多いかと思います。
その時に使えそうなものがあったので今回紹介します。
大したものではないので、また普段使っている方も多いと思います。
ぜひ、使っていいい感じに切り替えできるといいなと思います。

## スプレッド構文を使う

``` typescript
const list1 = [1, 2];
const list2 = [10, 20];
const result = [...list1, ...list2];
```
これですね。


``` typescript
const list1 = [[], 2];
const list2 = [10, 20];
const result = [...list1, ...list2];
=> [2, 10, 20]
```

空の配列はマージすると消えることを利用したUIの切り替えが使えます。

例えば

``` typescript
const list1 = [
   flag ?
   [
      { title: 'AAA' }
   ]
   :
   [], 
   [{title: 'BBB'}]
];
const list2 = [[{title: 'ZZZ'}], [{title: 'XXX'}]];
const result = [...list1, ...list2];
// 　flag = falseの時
=> [
   [{title: 'BBB'}],
   [{title: 'ZZZ'}], 
   [{title: 'XXX'}],
]
```
になります。

これを利用すれば、UIでリスト表示を条件で切り替えてかつ、余分な空配列は消えるので綺麗に表示できます。
`filter`などで処理することもなくなるのでコードも見やすくなるのではないかと思います。

ぜひこちら利用して、いい感じでUI切り替えできるといいなと思います。

閲覧ありがとうございました。
htmlのtableであれこれ（前回の続き）

## テーブル機能追加
前回の記事で作ったヘッダ固定スクロール表に機能を追加。
+ 見出し列のグルーピングについて、スクロールして表示される範囲の中央に表示。
+ セルをクリックしてテキストボックスを表示（実際の編集処理は省略）

<p class="codepen" data-height="300" data-default-tab="result" data-slug-hash="zYWzyBj" data-user="cfd-ack" style="height: 300px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;">
  <span>See the Pen <a href="https://codepen.io/cfd-ack/pen/zYWzyBj">
  Untitled</a> by cfd-ack (<a href="https://codepen.io/cfd-ack">@cfd-ack</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://cpwebassets.codepen.io/assets/embed/ei.js"></script>

スクロール位置 scrollTop、スクロールボックスの高さ、見出し行 thead の高さより
セルが表示されているか計算。
表示されていればその表示領域の中央になるようにコンテンツの位置を調整する。

## 課題
単純なプロトタイプなのでパフォーマンス的な問題があるかも。
Chromeは問題ないがFireFoxでスクロール時の動きがガタつく。
IntersectionObserver で判定を減らしてもあまり効果なさそう・・・
要素の位置を変えることでリフローが発生している？

セルをクリックした際に、セル全体が表示されるよう scrollIntoView() を呼んでいるが
スムーズスクロールが上方向と左方向にしか効いていない。
FireFoxではセル全体が表示しきれないことがある。
requestAnimationFrame を使ってスムーズスクロールを実装するのもありか。
【Git】commit時の error: There was a problem with the editor 'code --wait'. 解消法

## 状況
`~/.gitconfig`に以下のように設定した上で`git commit`を実行したところエラーが発生しました。
```~/.gitconfig
[core]
  editor = code --wait
```

```:ターミナル
$ git commit 
hint: Waiting for your editor to close the file... code --wait: code: command not found
error: There was a problem with the editor 'code --wait'.
Please supply the message using either -m or -F option.
```

## 解消法
以下の方法でpathを通すことで解消しました。

VSCodeを開き、`cmd` + `shif` + `p`を入力。
「シェルコマンド：PATH内に`code`コマンドをインストールします」を実行。
![スクリーンショット 2022-07-24 午前3.37.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2342443/4183850c-6292-eb7e-53cd-ea674526d6d5.png)
CPUの性能指標

CPUの性能を表すためにの指標値が```クロック周波数```と```CPI（Clock cycles Per Instruction)```、```MIP(Milliion Instrucitons Per Second)```
がある。
クロック周波数は```周期信号の繰り返し数```
CPIは```その信号何周期分で一つの命令を実行```できるか
MIPSは```１秒間に実行できる命令の数```

## 気づき
これらの指標値でCPUの性能が決まるのか。
周期が関係あるみたいだ。
周期を繰り返すのと何周期分で一つの命令を実行の説明はややこしいな。
何周期もしないと命令が実行できないのか。
大変だな。
頑張ろう。

## クロック周波数は頭の回転速度
コンピュータの中にはいろんな装置が入っている。それがバラバラに動いていては動作しない。
なので```クロック```と呼ばれる```周期的信号に合わせて動く```のが決まり。
そうすることで、装置同士がタイミングを同調できるようになっている。
この```周期の時間が短くなればなるほどより多くの処理ができる。```
クロックが１秒間に繰り返される回数のことを```クロック周波数```という。
クロック周波数１GHzのCPUの場合は１秒間に１０億回振動していることになる。

### 気づき
同調することによって他の装置が動くのか。
周期的に機械が動くことは初めて知った。
クロック周波数が大きければCPUの性能もいいのか。
つまり僕のコンピュータは２.3GHzだから１秒間に２,300,000,000回チクタク振動しているのか。
コンピュータは忙しいな。

## １クロックに要する時間
クロック周波数が１GHzのCPUの場合は、```１秒を１０億等分```すればいいので。
10^-9秒になる。１クロックに１ナノ秒かかることになる。
この１クロックあたりの時間を```クロックサイクル時間```と呼ぶ。

### 気づき
これが処理速度に繋がるのか今やっと繋がった。
https://qiita.com/masatom86650860/items/9b116a241050e1598c43#:~:text=%E5%B0%8F%E3%81%95%E3%81%84%E8%A3%9C%E5%8A%A9%E5%8D%98%E4%BD%8D%E3%81%A7%E5%87%A6%E7%90%86%E9%80%9F%E5%BA%A6%E3%82%92%E8%AA%AC%E6%98%8E%E3%81%99%E3%82%8B%E3%81%A8%E3%81%AF%E3%81%A9%E3%81%86%E3%81%84%E3%81%86%E3%81%93%E3%81%A8%E3%81%AA%E3%82%93%E3%81%A0%E3%82%8D%E3%81%86%E3%81%8B%EF%BC%9F

## CPI（Clock cycles Per Instruction)
Clock cycles（クロックサイクル) Per(/) Instruction(命令）
を表している。
１命令あたりの何クロックサイクル必要かを表す。
例えば４クロックサイクルなら４CPIとなる。

### 気づき
クロックサイクルの数が多くなるほど命令があまり実行できないのか。
なおかつ１クロックがまた長いとさらに時間がかかるのか。

## MIPS(Million INstruciton Per Second)
Million INstruciton（百万　命令） Per（/) Second（秒）
```1秒間に実行できる命令の数```を表す。
例として一つの命令に２ナノ秒かかると１秒間に何回できるかを求めるのでそれで割る。
500,000,000個の命令をこなせる。
この値を```必ず１００万単位で表す```。５００MIPSとなる。

## 命令ミックス
命令実行には命令取り出し、命令の解読、命令の読み出し、命令実行の手順があった。
中には対象データ読み出しを必要としない命令がある。
命令の種類によって実行に必要なクロックサイクル数が異なる。
そこで用いられるのが```命令ミックス```だ。```よく使われる命令を一つのセットにしたもの。```
10ナノ秒の処理を60%と5ナノ秒の処理を40%を足して平均命令実行時間は8ナノ秒になる。

１セットを１秒間で何回できるか
1秒を8ナノ秒でわる。１２５MIPSになった。

出典 キタミ式イラストIT塾　基本情報技術者　令和03年

### 気づき
10ナノ秒を０.６で割るのかいまいちピンとこない。
算数・数学の知識がないためだ。
これから頑張りたい。

# 練習問題での気づき
## 疑問　トランザクションとは?

* 「商品を渡して、代金を受け取る」のように「ここからここまでワンセット」な処理単位のこと
```「ここからここまでワンセット」な処理単位```
出典 https://wa3.i-3-i.info/word142.html

* ```相互依存の関係にある複数の処理を1つの処理単位```にまとめて、矛盾なく処理すること。データベースにおいて、処理の一貫性を持たせるために、複数の処理を1つの処理として実行して管理する仕組みで、データの整合性を保つための要素の1つ。
出典　https://www.otsuka-shokai.co.jp/words/transaction-processing.html

### 気づき
とりあえず一連の動作なのか。
これは一度勉強したな。
Webの勉強で。

## 疑問　ステップとは？
ステップを検索したがなかなか出でこなかった。ので
ステップ数が表示されたので調べた。
* プログラムの```規模を測る際の目安```となる指標のひとつ
* ```人間語で書いたプログラムの元ネタ（ソースコード）の行数```のこと
出典 https://wa3.i-3-i.info/word14228.html

### 気づき
問題文は８０万ステップあると記述してあった。
ので多分これのことだと思う。
新たに知ることができた。
プログラムのコードの行数をステップと言うのか。


## 答えに合わせる工夫
桁が合わないなら桁を増やして負の指数を増やすこと
## 落ち着いてとく
自信を持って計算する。
GoでAWSWAF WebACL一覧を取得するサンプル

## ポイント
- CloudFrontにアタッチしているWAFを利用する場合は、us-east-1リージョンを指定しないといけない


## サンプル

```go
package main

import (
	"fmt"
	"os"

	"github.com/aws/aws-sdk-go/aws"
	"github.com/aws/aws-sdk-go/aws/session"
	"github.com/aws/aws-sdk-go/service/wafv2"
)

func main() {

	sess := session.Must(session.NewSessionWithOptions(
		session.Options{
			Profile:           os.Getenv("AWS_PROFILE"),
			SharedConfigState: session.SharedConfigEnable,
		}))

	svc := wafv2.New(sess, sess.Config.WithRegion("us-east-1"))

	params := &wafv2.ListWebACLsInput{
		Limit: aws.Int64(5),
		Scope: aws.String("CLOUDFRONT"),
	}

	resp, err := svc.ListWebACLs(params)
	if err != nil {
		panic(err)
	}
	fmt.Println(resp)
}

```
[Control Surface]ひとつの機能に複数のBankを設定したい

Control Surfaceについてはこちらの記事もどうぞ。
https://qiita.com/paraixo/items/7f13caed8bce368404be
今回は解説といよりかは紹介という形になります。

Control SurfaceにはBank機能というものがあるのですが、これを特定の機能に対して複数のBankを付けたかったのですが、ドキュメント上にそのようなやり方を説明している部分がなくどうしようかと思っていたところDiscussionに同じような質問スレッドが立っておりその中にある回答で実現できました。

https://github.com/tttapa/Control-Surface/discussions/381

この質問者の方はCCPotentiometerに対して2つのBankを設定し、一方にはChannelをもう一方のAddressを変えられるようにしたかったみたいでした。

回答としては↓のクラスを自作し、それを適応させるということでした。
```c++
class DualBankCCPotentiometer : public Bankable::MIDIFilteredAnalog<Bankable::SingleAddressMultipleBanks<2>, ContinuousCCSender> {
  public:
    DualBankCCPotentiometer(const Array<OutputBankableMIDIAddress, 2> &banks, pin_t pin, MIDIAddress address)
        : Bankable::MIDIFilteredAnalog<Bankable::SingleAddressMultipleBanks<2>, ContinuousCCSender>({banks, address}, pin, {}) {}
};

Bank<3> channelbank(1); // 3 modes which offset the channel by +1
Bank<3> addressbank(5); // 3 modes which offset the address by +5

DualBankCCPotentiometer pot {
    {{
        {channelbank, BankType::CHANGE_CHANNEL},
        {addressbank, BankType::CHANGE_ADDRESS},
    }},                // Banks and types
    A0,                // analog input pin
    {0x07, CHANNEL_1}, // base address
};
```
こうすることで、potというCCPotentiometerにchannelbankというBankとaddressbankというBankの２つを適応させることができるみたいでした。


自分の開発の方では特定のCCButtonに対して同様にやりたかったので上記にあるクラスを書き換え↓のようにしました。
```c++
class DualBankButtons : public Bankable::MIDIButton<Bankable::SingleAddressMultipleBanks<2>, DigitalCCSender> {
  public:
    DualBankButtons (const Array<OutputBankableMIDIAddress, 2> &banks, pin_t pin, MIDIAddress address)
      : Bankable::MIDIButton<Bankable::SingleAddressMultipleBanks<2>, DigitalCCSender>( {banks, address,}, pin, {}) {}
};

Bank<2> deckBank(1);
Bank<2> shiftKeyBank(10);

// 複数個のボタンに適応したので配列にしている
DualBankButtons dbButton[] = {
  {
    {{
        {deckBank, BankType::CHANGE_CHANNEL},
        {shiftKeyBank, BankType::CHANGE_ADDRESS},
      }
    },
    7,
    {66, CHANNEL_1}, //Aボタン
  },
  {
    {{
        {deckBank, BankType::CHANGE_CHANNEL},
        {shiftKeyBank, BankType::CHANGE_ADDRESS},
      }
    },
    6,
    {65, CHANNEL_1}, //Bボタン
  },
};

```
これでA,Bボタンに対してdeckBankが適応されればChannel+1、shiftKeyBankが適応されればAddress+10となるようにできました。

コード自体の解説はちょっと理解度が足りてなくてできないのですが、とりあえずこれで実現できたという感じになります。
参考になれば幸いです。
複数のGithubアカウントを使う

ここに全て書いてありますが。。

https://www.wakuwakubank.com/posts/380-git-multiple-account/

https://qiita.com/yampy/items/24638156abd383e08758




　　
　　　　
### 秘密鍵と公開鍵を作る

```ターミナル
cd ~/.ssh
ssh-keygen -t rsa -C {Githubメールアドレス} -f {作成する鍵の名前}
```

オプション
-t・・・鍵の種類（RSA）
-C・・・コメント
-b・・・鍵の長さ（2048とか）
-f・・・ファイル名

 
※もしSourceTreeにSSHキーを読み込ませるには、SSHキーのファイルを「ユーザー名-GitHub.pub」にしないといけない。
　　　

　　　　
~/.ssh/config を編集します。

```ターミナル
Host github.com.main
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/id_rsa_main
  TCPKeepAlive yes
  IdentitiesOnly yes
Host github.com.sub
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/id_rsa.sub
  TCPKeepAlive yes
  IdentitiesOnly yes
```


### 公開鍵をGitHubに登録

githubに行き、右上のアイコンから
Settings > SSH and GPG keys > New SSH key
に適当にパソコンの名前つけて、公開鍵をコピペ

公開鍵はcatとかで見る

```ターミナル
cat ~/.ssh/id_rsa_main.pub
```


### 接続確認

```ターミナル
ssh -T git@github.com.main
ssh -T git@github.com.sub
```

successできたらOK。



### cloneなど

適当なディレクトリ作って、移動して、

もしmainブランチなら
```ターミナル
gti clone git@github.com.sub:username/repository-name.git
```

もし特定のブランチなら
```ターミナル
gti clone -b ブランチ名  git@github.com.sub:username/repository-name.git
```


後からブランチ追加してチェックアウトして最新にする
```ターミナル
git checkout -b ブランチ名 origin/branch
git pull origin ブランチ名
```

確認など
```ターミナル
git branch
```

その他
```ターミナル
#ステージング
git add ファイル名

#コミット
git commit -m "コミットメッセージ"

#push
git push origin ブランチ名
```


　　　
　　　　
そういえば~/.gitconfigの設定してなかったけどしなくてもいいのかな。


と思ったらやっぱり必要になったので追記。

### gitconfigの設定

もうすでにローカルに存在していたgitの場合、originのurlを変更しないといけなかった。

まず確認
```ターミナル
git config remote.origin.url
```

ローカルのgitのconfigファイルを開き、remote.origin.urlの項目を
```ターミナル
remote.origin.url=git@github.com.main:username/repository-name.git
```
に変更




　　　
ーーーーーーーーーーーーーーーーーーーー
参考

https://qiita.com/0084ken/items/f4a8b0fbff135a987fea
https://qiita.com/shimotaroo/items/ed08d76447144d566637
https://qiita.com/takuyanin/items/c6a097028a837052c90c
https://qiita.com/naoto_isogai/items/39d4c1a6ce592ddd00c8
Laravelで新しいプロジェクトの作成時に起きたエラーの対処 (mkdir() permission denied)

## はじめに
Laravelで開発しようと思い弄っているとエラーが出たのでその対処を書いていく

## 詳細
これが実際のエラー
![キャプチャ.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/6916a8f9-eba2-7b32-536b-82db520b717e.png)

## 原因
原因はstorageディレクトリに書き込もうとしたユーザに書き込み権限がなかっためでした.

## 解決法
1.ディレクトリを変更する
2.グループの所有権を変更する
3.グループ権限を追加する
4.新しいlaravelプロジェクトを作成する


#### 1.ディレクトリ変更
```cmd
$ cd /var/www/html
```
#### 2.ユーザ権限を変更
![キャプチャ2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/576af80d-8ce7-823c-8d7b-c8b61c5c3a86.png)
```cmd
$ sudo chown -Rv root:$USER .
```

#### 3.次にグループ権限を追加する
![キャプチャ3.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/ea548213-af27-3222-e3f6-57b1c875b1b2.png)
```cmd
$ sudo chmod -Rv g+rw .
```

#### 4.そしてもう一度プロジェクトを作成するコマンドを入力すると成功する
![キャプチャ5.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/1de4c818-d6d3-2a3c-1cd8-33e0f0e45c55.png)
```cmd
$ composer create-project laravel/laravelprojectName--prefer-dist
```

だけど謎のエラーが...
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/11bcbfcc-8bed-4bbe-a464-16eef069d0b1.png)

今日は力尽きたのでここまで...
## 終わりに
次はこのエラー(?)を消す方法を探していきます．
![キャプチャ4.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2736795/00f831da-5de6-6685-2d8f-1af04294d823.png)
RockyLinux 9.xとUbuntu22.xにOpenSSL 3.1.xをインストールする（ソースからビルド）

RockyLinux 9系では標準でOpenSSL 3系がインストールされていますが､あえて最新バージョンをソースからインストールしたい時に利用します。

## 環境

| ソフトウェア | バージョン |
|:-----------|------------:|
| OS  | rockyLinux 9.2 or Ubunt 22.04|
| OS  | OpenSSL 3.1.2|

## 事前準備

予め以下のPerlパッケージをインストールしておく

```
sudo dnf install perl-FindBin
sudo dnf install perl-IPC-Cmd
sudo dnf install perl-Pod-Html
```

### インストール

```
cd /usr/local/src
wget https://www.openssl.org/source/openssl-3.1.2.tar.gz
tar xvzf openssl-3.1.2.tar.gz
cd openssl-3.1.2
./config -fPIC --shared --prefix=/usr/local/ssl
make -j 4
make install
```

以上で、/usr/local/sslに、OpenSSL3.1.xがインストールされます。
「--prefix」を付与しないと、/usr/local配下に直接インストールされるため、デフォルトインストールのOpenSSLとパスの設定によっては競合を起こすので部ディレクトリにインストールすることが望ましいと思います。
docker+next.jsで環境構築

## はじめに

今回はreactを触ってみたいと思い、知人に相談してみたら、

じゃあ、今はnext.js × vercelが主流だからreact飛ばそっか！と言われ、

「なるほど、確かにな！」と鵜呑みにしたので、next.jsから取り組んでいく流れとなりました。

軽く自己紹介として、自分は1年半ほどrails、nuxt.jsなどに取り組んでいました。その間プー太郎をしてまして、今年４月にSEとして今の会社に入社しました。現在はCodeIgniterを扱っており、モダンな技術への憧れが日々強くなっております！笑

今回紹介する内容は

「**docker＋next.jsで環境構築を行う。**」という擦りまくった内容となります。


## この記事の主な対象者

- とりあえず、docker+next.jsを立ち上げたい人
- 環境構築周りに時間をかけたくない人

## この記事の目標

- next.jsを触れる環境を簡易的に作る。

## Dockerfile
```
FROM node:16.13.2
WORKDIR /usr/src/app

USER node
```

## docker-compose.yml
```
version: '3'
services:
  app:
    build:
      context: .
      dockerfile: Dockerfile
    volumes:
      - ./:/usr/src/app
    command: sh -c "cd sample-app && npm run dev"
    ports:
      - "3000:3000"
```

## command
```
docker-compose run --rm app npx create-next-app sample-app

(もしアプリがないと言われたら、このコマンドを打つ)
docker-compose run --rm app npm install create-next-app

ハマった時に全てを消し去る呪文
docker-compose down --rmi all --volumes --remove-orphans

起動コマンド
docker-compose up
```

`使用したものや参考にしたサイト`
- https://zenn.dev/temple_c_tech/articles/setup-next-on-docker#docker-compose.yml
- https://zenn.dev/temple_c_tech/articles/setup-next-on-docker


## 最後に

いかがだったでしょうか。

今回は初回というのもあり、軽い内容ではありましたが、

少しずつ皆様に役立つ記事を書いていければと思います。

次回は、vercelデプロイ、画面遷移、api連携周りを記事にしたいと思います。
[Power BI] 各ライセンスごとの違い（Pro、PPU、Premium）

# はじめに

2022年7月の情報です。

# 価格

Power BI Premiumは組織に対して適用される。実際にレポートを編集・公開するユーザーには別途Proライセンスが必要。ざっくり500人以上の組織だとProライセンスよりもコストメリットが出てくる。

:::note
Premiumにはコスト以上の価値もあるので要チェック😄
更新速度・回数、データフローの各種機能、配置パイプラインなどなど。
:::

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/e5b6dabc-0474-bd18-3d7e-0bd74fc7e74b.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/f2686de2-c6b3-bbf4-d1d1-d270cbf69400.png)

https://powerbi.microsoft.com/ja-jp/pricing/

# ライセンスごとの違いまとめ

サポートブログにほぼほぼ一覧できるまとめがありましたので引用します😉

https://jpbap-sqlbi.github.io/blog/powerbi/pbi_license/#more

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/80467/355d4051-e80d-f3d3-b12d-2df6b7c746c9.png)

# 更新時間の制限

### データセットの更新

- Power BI Pro 2時間
- PPU/Premium　5時間

XMLAエンドポイント経由の更新は時間無制限

### データフローの更新

- Power BI Pro 
    - テーブルごとに 2 時間、データフローごとに 3 時間
- PPU/Premium
    - 24 時間 (テーブルとデータフローの区別はなし)

# Premiumの機能まとめ

### 概要

https://docs.microsoft.com/ja-jp/power-bi/enterprise/service-premium-features

:::note
Premium Gen2 では、**分析操作が最大 16 倍の速さで実行されます**。 操作は常に最高速度で実行され、容量に対する負荷が容量の上限に近づいても、速度が低下しません。
:::

### データフロー

https://docs.microsoft.com/ja-jp/power-bi/transform-model/dataflows/dataflows-premium-features?tabs=gen2

### デプロイパイプライン（配置パイプライン）

https://docs.microsoft.com/ja-jp/power-bi/create-reports/deployment-pipelines-overview

### Power BI Premium/Embedded でのクエリのキャッシュ

https://docs.microsoft.com/ja-jp/power-bi/connect-data/power-bi-query-caching

### XMLA エンドポイントを使用したデータセット接続

https://docs.microsoft.com/ja-jp/power-bi/enterprise/service-premium-connect-tools

### Premium Per User について 

https://docs.microsoft.com/ja-jp/power-bi/enterprise/service-premium-per-user-faq
Power Query workout - Function type

`signature`の話があったので

https://docs.microsoft.com/en-us/powerquery-m/type-forfunction

```text:Power&#x20;Query
Type.ForFunction(signature as record, min as number) as type
```
> Creates a `function type` from `signature`, a record of `ReturnType` and `Parameters`, and `min`, the minimum number of arguments required to invoke the function.

`ReturnType`と`Parameters`を含むレコードを引数として`signature`に受け付けるってこと。

`(p1, optional p2)=> List.Repeat({p1}, p2 ?? 5)` という関数を定義した時、パラメタと戻り値はすべて `type any`

https://docs.microsoft.com/en-us/powerquery-m/type-functionparameters
```text:Power&#x20;Query
// true
Type.FunctionParameters(
    Value.Type(
        (p1, optional p2)=> List.Repeat({p1}, p2 ?? 5)
    )
) = [
    p1 = type any,
    p2 = type any
]
```
https://docs.microsoft.com/en-us/powerquery-m/type-functionreturn
```text:Power&#x20;Query
// true
Type.FunctionReturn(
    Value.Type(
        (p1, optional p2)=> List.Repeat({p1}, p2 ?? 5)
    )
) is any
```
https://docs.microsoft.com/en-us/powerquery-m/type-functionrequiredparameters
```text:Power&#x20;Query
// true
Type.FunctionRequiredParameters(
    Value.Type(
        (p1, optional p2)=> List.Repeat({p1}, p2 ?? 5)
    )
) = 1
```
https://docs.microsoft.com/en-us/powerquery-m/value-replacetype

Value.ReplaceType で関数のシグネチャを置換
```text:Power&#x20;Query
Value.ReplaceType(
    (p1, optional p2)=> List.Repeat({p1}, p2 ?? 5),
    Type.ForFunction(
        [
            Parameters = [
                TextValue = type text,
                RepeatCount = type nullable number 
            ],
            ReturnType = type list
        ],
        1
    )
)
```

# 思ったこと🙄
Power Query で関数のシグネチャってなんだろね？パラメタと戻り値の定義でよいかなと。
# その他
https://powerbi.connpass.com/

- [Power BI 勉強会 - connpass](https://powerbi.connpass.com/)
- [Power BI Desktop を使い始めるには](http://qiita.com/PowerBIxyz/items/6c4735cb5b5712e70981)
- [Excel で Power Query を使い始めるには](http://qiita.com/PowerBIxyz/items/52e563037b855a099ca9)
Linuxについて４（自分用メモ

・ファイルのコピー
cp コピー元ファイル　コピー先ファイル名
cp コピー先ファイル名　コピー先ディレクトリ

・ファイルの移動
mv 移動先ファイル名　移動先ディレクトリ名
mv 移動先ファイル名　移動先ファイル名

・ファイル削除
rm ［オプション］　ファイル名

「-i」オプションを使用すると、削除前に確認メッセージが表示され、「y」または「yes」を入力しないと削除されない。

・ディレクトリの作成
mkdir ［オプション］　ディレクトリ名

※複数階層のディレクトリを作成する場合は「-p」オプションを使用し
例）mkdir -p top/sub とする

・ディレクトリのコピー
ファイルのコピーと同じくcpコマンドに「-r」オプションを使用する。
例）cp -r top/tmp

ディレクトリの移動にはmvコマンドをオプションなしで利用でき、ファイルの場合と同様にディレクトリ名の変更に使える。

treeコマンドでディレクトリの階層構造ツリー上に表示される。

・ディレクトリの削除
rm -r ディレクトリ名

※ディレクトリを削除する「rmdir」もあるがディレクトリが空でない場合は削除でなきない。

●Linuxで使える圧縮形式でもっとも使われているのがGNU Zip(gzip）形式。
gzip形式ファイルは通常、ファイル名の末尾が「.gz」となる。
gzip形式ファイルを圧縮するにはgzipコマンドを使う。

gzip ファイル名

●gzipファイルの解凍にはgunzipコマンドを使う。

gunzip 圧縮ファイル名

※圧縮する前にファイルを残したまま圧縮したい場合は「gzip -c 圧縮前ファイル　> ファイル名.gz」
圧縮ファイルを残したまま解凍したい場合は「gunzip -c 圧縮ファイル.gz > ファイル名」

●WindowsやMacOSではファイル圧縮にzip形式が使われることが多い。

zip ［-r］　圧縮ファイル名　ファイル名（またはディレクトリ名）

●圧縮されたファイルやディレクトリを解凍
　
unzip 圧縮ファイル名

●ディレクトリ内のファイルやサブディレクトリをディレクトリごとに圧縮するには「tar」コマンドで１つのファイルにまとめる。複数のファイルをまとめたファイルをアーカイブという。アーカイブの作成にはtarコマンドにcvfオプションを使用する。（vオプションは指定しなくても構わない）

tar cvf アーカイブファイル名　ディレクトリ名

tarコマンドで作成したアーカイブファイル名は末尾が「.tar」になるのが一般的。

●圧縮アーカイブの作成と展開
Linuxのtarコマンドはgzipによる圧縮に対応しているので、tarコマンドだけで圧縮アーカイブの作成展開ができる。

tar czvf アーカイブファイル名　ディレクトリ名
tar xzvf アーカイブファイル名

※作成時は「c」、展開時は「x」オプションを使用する。
※gzip圧縮を利用するときはzオプションを使用する。
TypeScriptでCustomEventを起動して受信したいとき

イベントを起動する際にパラメータを渡したいときは`detail`の中に値を入れて渡す。
```ts
    const obj :MyObject = { id: id + 1 }
    document.dispatchEvent(new CustomEvent('custom-event', { detail: obj }))
```

イベントリスナーのイベントハンドラには、`as EventListenerOrEventListenerObject`もしくは`as EventListener`のように型アサーションを書く。

```ts
    const handleEvent = ((event: CustomEvent<MyObject>) => {
      setId(event.detail.id)
    }) as EventListenerOrEventListenerObject

    document.addEventListener('custom-event', handleEvent)
```

## サンプル

```tsx
import React, { useEffect, useState } from 'react'
import './App.css'

interface MyObject {
  id: number
}

function App () {
  const [id, setId] = useState(0)

  useEffect(() => {
    const handleEvent = ((event: CustomEvent<MyObject>) => {
      setId(event.detail.id)
    }) as EventListenerOrEventListenerObject

    document.addEventListener('custom-event', handleEvent)

    return () => {
      document.removeEventListener('custom-event', handleEvent)
    }
  })

  const onClick = () => {
    console.log('onClick')
    const obj :MyObject = { id: id + 1 }
    document.dispatchEvent(new CustomEvent('custom-event', { detail: obj }))
  }

  return (
      <div className="App">
        <p>{id}</p>
        <button onClick={onClick}>Event Dispatch</button>
      </div>
  )
}

export default App

```

## ユニットテスト

```ts:useCustomEvent.ts
import { useEffect, useState } from 'react'

export interface MyObject {
  id: number
}

export const useCustomEvent = () => {
  const [id, setId] = useState(0)

  useEffect(() => {
    const handleEvent = ((event: CustomEvent<MyObject>) => {
      setId(event.detail.id)
    }) as EventListenerOrEventListenerObject

    document.addEventListener('custom-event', handleEvent)

    return () => {
      document.removeEventListener('custom-event', handleEvent)
    }
  })

  return { id }
}
```

```ts:useCustomEvent.test.ts
import { renderHook } from '@testing-library/react-hooks'
import { useCustomEvent } from './useCustomEvent'
import { act } from '@testing-library/react'

describe('custom-event', () => {
  test('event listener', () => {
    const { result } = renderHook(() => useCustomEvent())

    act(() => {
      document.dispatchEvent(new CustomEvent('custom-event', { detail: { id: 1 } }))
    })

    expect(result.current.id).toBe(1)
  })
})

```




## 参考

https://developer.mozilla.org/ja/docs/Web/API/CustomEvent/CustomEvent

https://developer.mozilla.org/ja/docs/Web/Events/Creating_and_triggering_events