OmniAICreator/Qiita-1.07M huggingface dataset:
DictationRecognizerを使ってみる

# この記事について
Unityの標準で用意されている[DictationRecognizer](https://docs.unity3d.com/ja/2018.4/ScriptReference/Windows.Speech.DictationRecognizer.html)を利用してみます。

# 動作環境
Windows10（Windows10でしか動かないそうです）

<b>注意：設定 > プライバシー > 音声認識がオンになっていないと動きません。</b>

Unity 2021.3.24f1

# やりたいこと
今回やりたいことはゲーム内で音声を受け取ってその結果を取得してゲームに反映させるということを使用と思います。
例：メニューと発言するとUIが表示される

# DictationRecognizer
DictationRecognizerはフレーズを受け取った際にその内容を返す音声認識ライブラリです。
認識するキーワードを用意するわけではないので、歪みのある表記は苦手だと思います。（一と書いて「いち」と読ませるか「はじめ」と読ませるかなど）
帰ってくる値は「仮説（Hypotheses）」と「認識（Recognition）」の2種類の文字列があります。

# HypothesesとRecognition
Hypothesesは認識が甘めの文字列で、発言の途中であっても文字列を返します。
Recognitionは発言終了後に精度が高い文字列を返します。

個人的にはKeywordRecognizerとDictationRecognizerの中間的なライブラリが欲しい......

# 使ってみた

とりあえずドラグスレイブを打ちたくなるのは世代の性。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296240/551fb093-fb0e-6db0-e02f-8840b94c4975.png)

上のテキストがHypothesesです。
文章のとぎれとぎれで値が帰ってきているのがわかります。

下のテキストがDictationRecognizerです。
自分が読み終わった後に1秒程度間があって表示されました。
AWS Lightsailに独自ドメインを紐づけした

# 概要
なにかしらのサーバーが必要になったのだが、月額固定料金にしたかったので AWS Lightsailでサーバーをたてた。せっかくなので、サーバーに固定IPと独自ドメインを設定まで行った。

# 前提
## 独自ドメインの取得
数日前に国内サービスを使用して取得した。業務で取得や管理をしたことはあったが、個人用としては初めて取得。個人情報だだもれ防止用に「Whois情報公開代行」に気を付けるくらいで、あとは期間とお金の問題でたいしたことない。

## なぜAWS Route 53？
AWSのサーバーのDNSのことなので、Route 53を使うことにした。他のサービスでもできると思われるが、あえてAWSを避ける意味もないので、Route 53とした。

## Lightsailの固定IP
Networking > PUBLIC IPから設定した。サーバーが起動している限り無料とのことなので設定しておく。サーバーが不要になって停止するときに解放忘れすると知らぬ間に費用がかかってしまうらしいので気にしておく。困ることなく設定できた。

# 本題
取得したドメインとIPアドレスが紐づくように設定していく。
## ホストゾーン作成
AWSにログインして、Route 53のダッシュボードからホストゾーンの作成を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/83450f5d-0248-035a-b30d-45145c916725.png)

取得したドメイン名を入力して、「ホストゾーン」の作成をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/f4f80a4d-1aef-fcfe-d4d5-9ea17ec52276.png)

## ホストゾーン詳細
4つのネームサーバーをメモする。ドメイン登録サービスの管理画面で入力するのに使う。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/58be0a22-fccb-616b-c504-d6a54625d8f1.png)

## ドメイン登録サービスへの設定
AWS Route 53 > ホストゾーン > 「独自ドメイン」で得た4つのネームサーバーを入力した
反映まで時間がかかることもあるらしい。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/b804b404-3ea6-ba65-d5d6-044ac7d71f57.png)

ネームサーバーが反映されているか確認。入力した4つのネームサーバーが出てきたらOK。

```
nslookup -type=NS [独自ドメイン]
```

IPアドレスが返ってくるか確認。が、返ってこない。

```
nslookup - [独自ドメイン]
```

どうやらAレコードの設定が抜けていた。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1865486/1d8f42b3-4577-dbbc-2bfa-c0a8c174690a.png)

# その他
* Lightsailのサーバーからpingが返ってこない。デフォルト設定では返ってこないのかも
Qiitaを始めるにあたって

## はじめに
こんにちは、Aoto(@AoTo0330)と申します。

2022年1月から、重い腰を上げて本格的にアウトプットを始めるために Qiita アカウントを作成しました。

最初の記事は、今後投稿を続けていくために Qiita の使い方について自分なりに決めた指針をまとめました。

## 記事を書く指針
### 自分の気になることを優先する
エンジニアとして、日々様々な情報や技術に触れる機会がありますが、興味の湧かない内容をまとめるのは骨が折れます。
記事のトピックを決める際は自分が興味があるのか、書いていて面白いと思えるのかを大切にしていきたいです。

### 多くのことを盛り込みすぎない
1つの内容を深堀していくと、あれもこれもとたくさんの関連情報が見つかることがあります。
このような場合には、自分の中でも内容を整理できるようにあくまでトピックの中心となる内容に絞って記事を書きたいと思います。

### とりあえず投稿してみる
今までブログを始められなかった理由として、投稿へのハードルが高いと感じていたということが一番にあげられます。
文章がおかしくないか、情報が正しい内容なのか、内容が薄すぎないか…不安となる要素はあげれば切りがありませんが、あまり気にしすぎないようにしていきます。

自分の記事が全て役に立つべきと思わずに、まずは自分のために投稿し少しずつ改善していくことを前提に投稿していきます。

### 簡潔に、具体的に
記事を見返したり、多くの方に見てもらうためにも何についてまとめているものなのか、すぐにわかるようにタイトルと見出しをつけます。

タイトルを決めた後も、他の指針に沿って柔軟に投稿する内容は精査していきます。
この指針は**良い記事を書くガイドライン**にも記載があります。

https://help.qiita.com/ja/articles/qiita-article-guideline

### 役立つツール
文章のみのブログは読み手に多くの負担を強いる上に、書き手にとっても文章にまとめることが難しいです。そのため、Qiita 公式ブログで紹介されている[**Markdown記法チートシート**](https://qiita.com/Qiita/items/c686397e4a0f4f11683d)を参考に、情報をわかりやすく表示できるように工夫することを意識します。

https://qiita.com/Qiita/items/c686397e4a0f4f11683d

## おわりに
本記事も自分で決めた指針に沿って文章を考え、投稿しました。
今後自分の中で指針が変わった際も、きちんと記事を書いてアウトプットする目的を明確にして Qiita を利用していきたいと思います。
PythonでSlack の特定のチャンネルの全メッセージを取得するまで


#  アプリ作成
[ここ](https://api.slack.com/apps?new_app=1&ref=bolt_start_hub)からCreate an app > From scratch を選択し、アプリ名とslackのどのワークスペースを使うか選択する。

## スコープ

App Manifestに

```
oauth_config:
  scopes:
    bot:
      - channels:history
      - groups:history
      - im:history
      - mpim:history
```
を追加して
以下に変える

```
_metadata:
  major_version: 1
  minor_version: 1
display_information:
  name: APP_NAME
features:
  bot_user:
    display_name: APP_NAME
    always_online: false
oauth_config:
  scopes:
    bot:
      - channels:history
      - groups:history
      - im:history
      - mpim:history
settings:
  org_deploy_enabled: false
  socket_mode_enabled: false
  token_rotation_enabled: false
```

※ OAuth & Permissions > Scope > User Token Scopes > Add an OAuth Scopeから追加することもできる

## トークン作成

OAuth & Permissions > OAuth Tokens for Your Workspace　から　Install to Workspace　を押して
トークンを発行する。


# コード

```
import requests


SLACK_CHANNEL_ID = 'SLACK_CHANNEL_ID'
SLACK_URL = "https://slack.com/api/conversations.history"
TOKEN = "TOKEN"



def main():
    payload = {
        "channel": SLACK_CHANNEL_ID
    }
    headersAuth = {
    'Authorization': 'Bearer '+ str(TOKEN),
    }
    response = requests.get(SLACK_URL, headers=headersAuth, params=payload)
json_data = response.json()
    msgs=[]
    for i in range(len(response.json()['messages'])):
        msgs.append(json_data['messages'][i]["text"])

    msgs.reverse()
    return print(msgs)


if __name__ == "__main__":
    main()
```

- slackの該当チャンネルまで行ってURLを確認すると
https: //app.slack.com/client/T0123456789/C0123456789
といった感じになっており、
SLACK_CHANNEL_IDは　一番最後にある、ここで言う　"C0123456789"である。

- TOKENは先ほど発行したものであり、xoxbからスタートしている。


- msgs.reverse()はmsgsでslackでのテキストメッセージを最新のものから取得するため、リスト内を時系列順に戻すためである。

# メッセージの取得

ターミナルで　このファイルを実行すると

```
{'ok': False, 'error': 'not_in_channel'}

```
とでた。
[Slack api conversations.history returns error: not_in_channel](https://stackoverflow.com/questions/60198159/slack-api-conversations-history-returns-error-not-in-channel)
によるとSlackの該当チャンネルにAPPを追加する必要があるようだったので、
slackの該当チャンネルの右上の人のマークを押し、インテグレーション>APPからアプリ追加を選択し、先ほど作ったアプリ名を追加し、再度ファイルを実行すると
メッセージをリストで取得することができた。

# 展望
このコードでは返信をしたときのメッセージを取得することができないので、次は試みたい。


# 参考

- [Slackの特定チャンネルのメッセージをクロールする方法](https://qiita.com/yoshii0110/items/2a7ea29ca8a40a9e42f4)
- [Slack Api公式](https://api.slack.com/reference/manifests)
- [Slack api conversations.history returns error: not_in_channel](https://stackoverflow.com/questions/60198159/slack-api-conversations-history-returns-error-not-in-channel)
Kotlinで地図アプリ（ゴミ拾いアプリ）。（19日目） AdMob広告の実装

#今日やった事

・AdMob広告の実装


#

```gradle:build.gradle
dependencies {
    implementation 'com.google.android.gms:play-services-ads:15.0.1'
```

```xml:AndroidManifest.xml

        <meta-data android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />

        ...

        <activity android:name="com.google.android.gms.ads.AdActivity"
            android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>
```

```xml:activity_maps.xml
xmlns:ads="http://schemas.android.com/apk/res-auto"

    <com.google.android.gms.ads.AdView
        android:id="@+id/adView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_alignParentBottom="true"
        ads:adSize="BANNER"
        ads:adUnitId="ca-app-pub-3940256099942544/6300978111">
    </com.google.android.gms.ads.AdView>
```

```kotlin:MapsActivity.kt
        // 広告
        val adView = AdView(this)

        adView.adSize = AdSize.BANNER

        adView.adUnitId = "ca-app-pub-3940256099942544/6300978111"
```

#成功するも上手くいかず

広告表示自体は出来たものの、GoogleMapを表示しているfragment layoutの上に表示させる事が出来ず、挫折。

地図のサイズを縮めて、下にスペースを作り、表示させることは可能だと思います。


#レイアウトの理解が乏しい

LinearLayoutなどの基本layoutでの配置は自由に出来るものの、fragmentや、DrawerLayout、ConstraintLayoutの理解度が低い事が問題…。

その辺りの根本的な勉強をゼロからした方が良いかもです。


#参考サイト

https://developers.google.com/admob/android/banner?hl=ja

https://blog.codecamp.jp/programming-android-app-development-banar

https://qiita.com/folivora/items/1a3d6a13c6a0bc62b1d1

https://qiita.com/yamadacsa/items/3434c277d23e04ee50cb

https://qiita.com/naoi/items/79416483cce89c058a95

https://qiita.com/devnokiyo/items/59d72bf285ee378ef637

https://stackoverflow.com/questions/54252846/supportmapfragment-is-hiding-admob-banner/54252976
Invalid route action: [〇〇Controller]. が起きた時に確認すること

## 問題
`__invoke` を使ったシングルアクションコントローラーの作成時に以下のエラーが出た。

```
Invalid route action: [〇〇Controller].
```

## 確認すること

### class名がファイル名であるかどうか

```:〇〇Controller.php
class 〇〇Controller extends Controller
{
}
```

### namespaceの記述があるかどうか

```:〇〇Controller.php
namespace App\Http\Controllers\〇〇;
```

### useの記述があるかどうか

```:〇〇Controller.php
use App\Http\Controllers\Controller;
```

### ルーティングのチェック

```
Route::get('/', 〇〇\〇〇Controller::class);
```
ScriptOfSagaⅡを今更立ててみる ~立ち上げ編~ #1

#概要
CGIゲームのScriptOfSagaⅡを通して、いろいろと勉強してみようというだけです。
計画だったことは考えていないので、体系的な記事にはならないかなと思います。

#背景
昔、CGIゲームというWebゲームが流行りました。
そのころ私は中学生ぐらいでしたが、無料でできることからとてものめりこみました。
また、多くのスクリプトが無料頒布されており自分で中身を読んで何が起こっているのか分かることが面白くて、初めてperlの技術本を買ってプログラミングを勉強した記憶があります(ドット絵も描いた思い出)。

なぜか21年末の冬季連休にふと思い出して気になってしまい、一番ハマっていたScriptOfSagaⅡを調べてみたところ以下のような状態でした...。

>① 利用規約やスクリプトはなんとか参照できる状態
>
>- 利用規約
>  - http://web.archive.org/web/20090603074818/http://www.area-s.com/main/rule.html
>- スクリプト
>  - http://web.archive.org/web/*/http://www.area-s.com/main/archive/sos*
>
>② Shoさんという方が運営されていた「MissingLink」という公開ページは消失
>  http://www.area-s.com/


あの頃はお金も技術力もなくWebサーバでの運用を諦めてしまいまたが、
とても貴重な経験をさせて頂いたゲームであり、また今ウェブ関連の勉強をしている人たちにもとても有益なコンテンツだと感じているため、今一度ScriptOfSagaⅡを立ち上げ、またそれを通して得た知見などをまとめていこうと思い立ったという背景です。
※ちなみに投稿者は現在組込みソフトの仕事をしているので、ウェブアプリは初学者のままです笑

本稿はリンクを上記した利用規約から逸脱しない範囲で進めていきます。

# ロードマップ
計画がないと上述しましたが、一応「直近やること」と「いまやりたいと思っていること」は挙げていこうと思います。

1. まずは公開されているスクリプトをWebサーバに上げる
1. 公開されているスクリプトを可能な範囲で設計書にリバース
1. 再構築 ※ここまでやれたらshoさんのメールアドレスに改造連絡をいれてみる？
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')


自分用メモ
JavaScriptでボタンクリックのイベント発火させようとしたところ、consoleに以下のエラーが出た。

```
Uncaught TypeError: Cannot read properties of null (reading 'addEventListener')
```

ちなみにその時のコードがこちら

```html:index.html
<!doctype html>
<html lang=”ja”>
  <head>
    <title>Index </title>
    <meta charse=”utf8″/>
    <script type="text/javascript" src="{{ url_for('static', filename='index.js') }}"></script>
    <link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
  </head>
  <body>
    <div class="input-area">
      <input id="add-text" placeholder="TODOを入力" />
      <button id="add-button">追加</button>
    </div>
  </body>
</html>
```

```javascript:index.js
const onClickAdd = () => {
    alert('OK')
}

document
    .getElementById("add-button")   //
    .addEventListner("click", ()=> onClickAdd() );
```

#原因
原因は、scriptを読み込ませる位置だった模様。
index.htmlが順番に読み込まれていき、id="add-button"のDOMを生成する前に、index.jsが読み込まれid="add-button"に対し、クリックイベントを発火させようとし、DOMが無いのでエラーになるというものだった。

#対策
scriptを読み込ませる位置を一番後ろに持ってくるとでエラー解消した。

```html:index.html
<!doctype html>
<html lang=”ja”>
  <head>
    <title>Index </title>
    <meta charse=”utf8″/>
  </head>
  <body>
    <div class="input-area">
      <input id="add-text" placeholder="TODOを入力" />
      <button id="add-button">追加</button>
    </div>
  </body>
</html>
<script type="text/javascript" src="{{ url_for('static', filename='index.js') }}"></script>
<link rel="stylesheet" href="{{ url_for('static', filename='style.css') }}">
```
【つぶやき】AとB、どちらを学ぶべきでしょうか？はリアルでしない方がいい質問のはず

「PHPとRubyどちらを学ぶべきでしょうか？」
「LaravelとPhalconどちらを学ぶべきでしょうか？」

こういう質問をリアルで後輩や同僚にされたら、
「面白くないエンジニアになるだろうな」
という印象を抱かれること間違いない。
【OOP】01_オブジェクト・クラス・インスタンス

こんにちは、コイキングです。

本記事では OOP(Object Oriented Programming == オブジェクト指向プログラミング)の説明のうち、オブジェクト・クラス・インスタンスについて、説明したいと思います。

******
# 1. オブジェクトとは?
まず一般的なオブジェクトの概念について探してみると**現実世界に存在する'物体'、'対象'になります。

※ 参考
https://ja.wikipedia.org/wiki/%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88

具体的に例えてみると人間・犬のような動物も、スマートフォン・PC・箱のような物も、ポケモン・デジモンのようなゲームのキャラクターもオブジェクトと言えると思います。

ではOOPでのオブジェクトは何でしょう？
私は現実世界のオブジェクトから重要で核心的な所を抽象化してクラス化し、クラスを元にしてメモリー上にロードされたデータだと思います。

オブジェクト指向では上記の説明通りメモリー上にロードされたオブジェクトの相互作用を通してプログラムを実装します。

# 2. クラスとは?
クラスは'OOPのオブジェクトを作るための一種の設計図'です。
クラスを作るためには現実世界のオブジェクトから重要で核心的なもの・共通点・特徴などを洗出し、1) 属性と 2)行為に定義します。

こちらで属性はクラスのメンバー変数、行為はクラスのメソッドになります。

※ クラスの宣言文法
> ```
> [アクセス制御子] class クラス名 {
>     //...メンバー変数・メソッド
> }
> ```

```java:Person.java
public class Person {
	
    // メンバー変数
	String eye;
	String nose;
	String mouth;
	String hand;
	String foot;
	
    // メソッド
	public void eat() {
		System.out.println("eat");
	}
	
	public void sleep() {
		System.out.println("sleep");
	}
	
	public void defecate() {
		System.out.println("defecate");
	}	
}

```
上記のPersonクラスは人間をクラス化したものです。
人間がもつ目・鼻・口・手足などの属性はメンバー変数に
食べる・寝る・トイレに行くなどの行為をメソッド化しました。

# 3. インスタンスとは?
インスタンスとはクラスを元にしてメモリー上にロードされたデータを意味します。
**OOPで言っているオブジェクト**と言えます。
コードを解析する際に'オブジェクト'という単語と'インスタンス'という単語を同じ意味でよく混用して使ったりします。

 ※ インスタンスを作る方法は以下となります。
> ```
> [クラス名] [インスタンス変数名] = new [コンストラクター()];
> ```

※ インスタンスのメソッド及びメンバー変数の値にアクセスする方法は以下となります。
> ```
> [インスタンス変数名].[メソッド() 又は メンバー変数];
> ```

```java
public static void main(String[] args) {
    Person person = new Person();
    person.eat();
    String eye = person.eye;
    System.out.println(eye);
}
```

※ 例示コード
https://github.com/leeyoungseung/algorithmBasic/blob/master/algorithm/src/objective/basic01/Person.java﻿

※ 韓国語のポストは以下のURLで確認できます。
https://koiking.tistory.com/87
Android開発におけるドキュメント作成"Dokka / KDoc"の導入手順

# Dokkaとは

"KDoc"形式で記載したコメントを、Javadocと同様な形でドキュメントを作成できる。
JavaとKotlinが混在したプロジェクトのドキュメントも生成可能

https://github.com/Kotlin/dokka

# 導入

``` project/build.gradle
buildscript { 
  ext {
    dokka_version = "1.6.10"
  }
  dependencies {
    classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}"
  }
```

``` app/build.gradle
apply plugin: "org.jetbrains.dokka"

android {}
dependencies {}

// dokkaHtml 用の設定
dokkaHtml.configure {
    outputDirectory.set(new File("${buildDir}/dokkaHtml"))
    dokkaSourceSets {
        configureEach {
            // Moduleやパッケージに対するドキュメントを作成する際に指定する
            includes.from("ModuleDoc.md", "PackageDoc.md")
        }
    }
}
```

### モジュールコメント
ここで全体的なパッケージ構成を書いておくと理解が進みそう

``` app/ModuleDoc.md
# Module app

## パッケージ構成について

| Package | Contents |
| ---- | ---- |
| view | view |
| viewmodel | ViewModel |
| domain | logic / service |
| model | Data model |
| repository | Repository |
| infra.api | Remote Resource |
| infra.db | Local DB |
| infra.local | Local Resource |
```

### パッケージコメント
パッケージに対するコメント

``` app/PackageDoc.md
#Package jp.co.foxsal.githubreader.view.repolist
リポジトリ一覧

#Package jp.co.foxsal.githubreader.view.repodetail
リポジトリ詳細
```

### クラス/メソッド等のコメント
KDoc形式で各所に記載する

# ドキュメント生成

```
./gradlew dokkaHtml
または
./gradlew dokkaJavadoc
```

# 成果物イメージ

| dokkaHtml | dokkaJavadoc |
| ---- | ---- |
| <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32594/c860735f-da64-07a9-4a05-0b40d3dd6014.png" /> | <img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/32594/30a9de3a-fe2f-f480-4633-130aae514edc.png" /> |


# 参考リンク

### KDoc
https://kotlinlang.org/docs/kotlin-doc.html#module-and-package-documentation

### dokkaHtmlのオプション設定
https://kotlin.github.io/dokka/1.6.10/user_guide/gradle/usage/#configuration-options
Pythonで文字列を日付に変換

## 文字列から日付(datetime)に変換
```python
from datetime import datetime

str = '20210808134937'
date = datetime.strptime(str, '%Y%m%d%H%M%S')

print(date) # 2021-08-08 13:49:37
print(type(date)) # <class 'datetime.datetime'>
```

## 文字列から日付(date)に変換
```python
import datetime

str = '20210808134937'
date = datetime.datetime.strptime(str, '%Y%m%d%H%M%S')
tdate = datetime.date(date.year, date.month, date.day)

print(tdate) # 2021-08-08
print(type(tdate)) # <class 'datetime.date'>
```

## 日付から文字列に変換
```python
import datetime

tdatetime = datetime.now()
tstr = tdatetime.strftime('%Y/%m/%d %H:%M:%S')

print(tstr) # 2021/08/11 17:18:51
print(type(tstr)) # <class 'str'>
```

## 日付フォーマット


| 書式 | 説明 | 
| -------- | -------- | 
| %Y     | 年 西暦4桁（例、2021）     | 
| %y     | 年 西暦2桁（例、21）     | 
|%m    | 月2桁（例、12）  |
| %d |  日2桁（例、31） |
| %H | 時 24時間表記（例、14） |
| %I  | 	時 12時間表記（例、02）  |
| %p | AM、PM |
| %M | 分2桁  |
| %S  | 秒2桁 |
| %f | マイクロ秒6桁  |
GASでDriveAppクラスを使うと`Exception: We're sorry, a server error occurred. Please wait a bit and try again.`エラーが出る

# 事象

スプレッドシートを指定のフォルダにコピーしようと、DriveAppクラスを使っていたのですが、突然こんなエラーが出ました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/46cadc55-0559-d91a-f078-968a03d457db.png)

GASのエディタから該当の関数だけ実行した結果はこうです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/8519de54-b910-4558-48fd-e6dcac7f0b0c.png)

# 理由
なんでもGASをGCPと紐づけた際に起こるようです。
自分の前の記事（[GASでLINE Bot開発時のログ出力方法](https://qiita.com/sa9ra4ma/items/1acb459fcc713728c03e)）でGCPでログが見れるようにしたことが自分の場合の原因のようです。
GCPと紐づけていないGASで実行した場合、エラーは起きませんでした。

# 解決策
GCPから以下のページに遷移します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/3eca3ac3-6db6-e66e-8c9c-3eedc85cfc8d.png)

検索画面に映るので、「Google Drive API」を検索します。

そこから「有効にする」でこのAPIを有効にします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/638864/ebe3b8c2-adbd-3076-1984-7c5a1765303d.png)

これで解消します！
Certified ScrumMaster(CSM)の更新(2022年1月版)

#あと，数日で期限切れる人向け，超速更新手順

1.SEUsの取得
2.資格更新
ちなみに，期限が切れても最長60日間は延長できるとのこと。


#1.SEUsの取得
## Scrum Alliance Resourcesで記事をみれば，SEUsを獲得できる

##STEP1.Scrum Alliance Resourcesへログイン
crum Alliance Resourcesへログイン
https://resources.scrumalliance.org/

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374963/814012e7-f696-fa93-e322-c5e96bae1f55.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374963/dfba74ad-0c68-092a-8ade-46b2c897cd7a.png)

#2.記事や動画を見る。
## Scrum Alliance Resourcesで記事をみれば，SEUsを獲得できる

おすすめは動画を見続けることです。
ページトップの「Resources」をクリック後，コンテンツタイプを「videos」に変更し，興味のあるページを上から開き，動画を再生すればSEUsがカウントされます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374963/dd18579a-0e85-5b39-ea4d-1cb6a4144c22.png)

3.資格更新
SEUsが溜まったら，ページ上部の「Renew Now」をクリックし，更新費用を払えば更新完了
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2374963/833c4518-6d60-d4c2-0da8-50cf3895e137.png)


#まとめ

SEUsのActivity Descriptionを自分で書くのが面倒な人はScrum Alliance Resourcesで記事や動画を見て自動的にSEUsを獲得しよう。


#用語
Scrum Education Units（SEUs）
https://www.scrumalliance.org/get-certified/scrum-education-units
Bluetoothデバイスの検索ができない時の対処法

bluetoothを使った開発のときに何故かエラーで使えなかったのでその対処法。

# 環境
* Windows 10 Pro (64bit)

# エラーの現象
* 「Bluetoothまたはその他デバイスを追加する」をクリックして探索しても何故か落ちる
    * Windowsの「設定」＞「Bluetoothとその他デバイス」

```
障害が発生しているアプリケーション名: ShellExperienceHost.exe、バージョン: 10.0.19041.1320、タイム スタンプ: 0xe78af3dd
障害が発生しているモジュール名: KERNELBASE.dll、バージョン: 10.0.19041.1387、タイム スタンプ: 0x0b9a844a
例外コード: 0xc0000409
障害オフセット: 0x000000000010b302
障害が発生しているプロセス ID: 0xaa0
障害が発生しているアプリケーションの開始時刻: 0x01d80602a28f349a
障害が発生しているアプリケーション パス: C:\WINDOWS\SystemApps\ShellExperienceHost_cw5n1h2txyewy\ShellExperienceHost.exe
障害が発生しているモジュール パス: C:\WINDOWS\System32\KERNELBASE.dll
レポート ID: dbc39c54-bc78-4d59-a10a-3b10dc6e6091
障害が発生しているパッケージの完全な名前: Microsoft.Windows.ShellExperienceHost_10.0.19041.1320_neutral_neutral_cw5n1h2txyewy
障害が発生しているパッケージに関連するアプリケーション ID: App
```

* Bleakつかって制御ができない(Python)
    * Error 0x800106d9

# 原因／解決策

* デバイスマネージャーよりBluetoothのデバイスドライバーが正しくロードされているか確認する
* 設定にて、Bluetooth機能を有効/オンにする
* Windowsサービス「DeviceAssociationService」を有効化(自動)にする
* ネットワーク接続にある「Bluetoothネットワーク接続」を有効化する

特に筆者は「DeviceAssociationService」を無効化していたことが原因でした。
WebView2ランタイム exists

WebView2ランタイムの存在確認
レジストリキーを確認するタイプは端末で動きが読めず。
バージョン見るタイプ（下）はインストール・アンインストールに反応。

```cs:Browser.cs
class Browser:Form {
	double dpr;
	public Browser() {
		dpr			= DeviceDpi/96.0;
		ClientSize	= GetSize(640,360);
		
		//https://github.com/MicrosoftEdge/WebView2Feedback/issues/421
		var error = "";
		var version = "";
		try{
			version = CoreWebView2Environment.GetAvailableBrowserVersionString();
		}catch(WebView2RuntimeNotFoundException e) {
			error = e.Message;
		}

		if(version=="") {
			NotFound(error);
		}else{
			var view	= new WebView2(){Size=ClientSize};
			view.Source	= new Uri("https://qiita.com/");
			SizeChanged	+= (s,e)=>view.Size=ClientSize;
			Controls.Add(view);
		}
	}
	public void NotFound(string error) {
		var label = new Label() {
			Text	 = "",
			Location = GetPoint(20,80),
			Size	 = GetSize(600,80),
		};
		var button = new Button() {
			Text	 = "WebView2ランタイム ダウンロードページ",
			Location = GetPoint(20,20),
			Size	 = GetSize(240,45),
		};
		button.Click+=(s,e) => {
			OpenBrowser("https://developer.microsoft.com/microsoft-edge/webview2/");
		};
		label.Text += "上記ページから「WebView2ランタイム」をインストールしてください。\n";
		label.Text += "WebView2 ランタイムをダウンロード ＞ エバーグリーン ブートストラップ ＞ 「ダウンロード」\n";
		label.Text += error;
		Controls.Add(button);
		Controls.Add(label);
	}
	public Size GetSize(int w,int h) {
		return new Size((int)(w*dpr),(int)(h*dpr));
	}
	public Point GetPoint(int x,int y) {
		return new Point((int)(x*dpr),(int)(y*dpr));
	}
	public void OpenBrowser(string s) {
		Process.Start(new ProcessStartInfo() {FileName = s,UseShellExecute = true});
	}
}

```
ローカルリポジトリからインストールした際、Ruby関連ファイルのみ「モジュールメタデータは利用不可です」と表示された件

オフライン環境のRHEL8.4にパッケージ導入時したときの話。

##環境
OS：RHEL8.4
オンライン環境：Aサーバ
オフライン環境：Bサーバ
※ともにGUIインストールしただけの状態。

##初めに
AサーバにてRPMパッケージを、Ruby含めざっくり90ファイルほどダウンロードしてローカルレポジトリを作成。
作成したリポジトリをzip圧縮してBサーバに展開。

/etc/yum.repos.d/にrepoファイルを作成後、dnf repolistに登録がある事を確認。
ターミナルから下記コマンドを実行

dnf --disablerepo=* --enablerepo=***_repo install [パッケージ名]

下記のようなエラーが出でました。
※見やすいようにエラーMSGは成形してます。
```
モジュラーパッケージ 'ruby-2.5.9-107.module+el8.4.0+10822+fe4fffb1.x86_64' のモジュラーメタデータは利用不可です
モジュラーパッケージ 'ruby-irb-2.5.9-107.module+el8.4.0+10822+fe4fffb1.noarch' のモジュラーメタデータは利用不です
モジュラーパッケージ 'ruby-libs-2.5.9-107.module+el8.4.0+10822+fe4fffb1.x86_64' のモジュラーメタデータは利用不可です
モジュラーパッケージ 'rubygem-bigdecimal-1.3.4-107.module+el8.4.0+10822+fe4fffb1.x86_64' のモジュラーメタデータは利用不可です
モジュラーパッケージ 'rubygem-did_you_mean-1.2.0-107.module+el8.4.0+10822+fe4fffb1.noarch' のモジュラーメタデー
モジュラーパッケージ 'rubygem-io-console-0.4.6-107.module+el8.4.0+10822+fe4fffb1.x86_64' のモジュラーメタデータはデータは利用不可です
モジュラーパッケージ 'rubygem-json-2.1.0-107.module+el8.4.0+10822+fe4fffb1.x86_64' のモジュラーメタデータは利用不可です
モジュラーパッケージ 'rubygem-openssl-2.1.2-107.module+el8.4.0+10822+fe4fffb1.x86_64' のモジュラーメタデータは利用不可です
モジュラーパッケージ 'rubygem-psych-3.0.2-107.module+el8.4.0+10822+fe4fffb1.x86_64' のモジュラーメタデータは利用不可です
モジュラーパッケージ 'rubygem-rdoc-6.0.1.1-107.module+el8.4.0+10822+fe4fffb1.noarch' のモジュラーメタデータはデータは利用不可です
モジュラーパッケージ 'rubygems-2.7.6.3-107.module+el8.4.0+10822+fe4fffb1.noarch' のモジュラーメタデータは利用不可です
```

##原因

RHEL8のmodule管理にメタデータが含まれていて、リポジトリ作成時にはひと手間かかる、メタデータはYAML形式のファイルで作成される。また主にRuby関連ファイルのみメッセージが発生している。

参考サイト

https://rheb.hatenablog.com/entry/201812-modularity

https://www.fixes.pub/linux/181597.html

##調べたところ

ruby-2.5.9-107はRHEL8.4でデフォルトインストールされるバージョンと判明、
そのほかのRuby関連ファイルもインストール時に一緒に導入されるものとわかる。

なぜRubyのみエラーとなるのかまでは調べておりません。
どなたか教えてくださいませ。。。

調査時に利用したコマンド

```
dnf module list ruby
dnf module install ruby:2.5/common
```
##そこで
ruby関連ファイルでエラーとなっているので先にRubyをインストールし、後にパッケージ関連をインストールする作戦に変更

実際にはAサーバで下記手順を実行

##Aサーバ作業

```
dnf install modulemd-tools

mkdir -p ruby_repo/Packages
cd /usr/local/src/ruby_repo/Packages
dnf download --resolve ruby
cd ..
```
```
ls
Packages

#Packagesフォルダがある階層でcreaterepo_cを実行
createrepo_c .

#メタデータ作成
repo2module  -s stable  . modules.yaml

modules.yamlに追記
data:
  arch: x86_64
profiles:
  default:
      description: ruby  package

#modules.yamlの情報をrepodataに追加
modifyrepo_c --mdtype=modules modules.yaml repodata/

ls repodata/ | grep modules
→*****modules.yaml.gzファイルがあることを確認する
```
あとはレポジトリのフォルダをzip圧縮。zipファイルをＢサーバの適切なフォルダに持っていきunzip.

##Bサーバ作業
```
/etc/yum.repos.d/ruby_repo.repoファイルを作成

vim /etc/yum.repos.d/ruby_repo.repo

[ruby_repo]
name=RubyRepo
baseurl=file:///usr/local/src/ruby_repo
enabled=1
gpgcheck=0

dnf repolistを実行してrepolistに表示があることを確認

#レポジトリを指定してインストール
dnf --disablerepo=* --enablerepo=ha_repo install  ruby
```
無事にインストールできました。
パッケージも同じ手順にてインストールできました。

##感想
冷静に考えれば。。。。

パッケージはGUIの画面があって、GUIにRubyを利用しているのね。。。
今後は言語とパッケージは別々にインストールです。
まぜるな危険！です。

これだけの事ですが、3日ほど悩みました。
だれかの参考になれば幸いです。
Railsで複数レコードを更新する書き方メモ

#はじめに
Railsで複数レコードを作成、更新する際にActiveRecord::Base.transactionをどのように用いるかを調べた際のメモです。
主に以下を参考にさせていただきました。
https://qiita.com/aba0312/items/8b29cafe6b505b6a7a4f
https://www.youtube.com/watch?v=jFBvEQhApKQ

#例
例えば、ユーザーのバルクインサートを行う際に全てのインサートが成功しなければロールバックするという想定をします。

```ruby:User.rb
class User < ApplicationRecord
  def self.bulk_create(users)
    all_valid = true
    transaction(join_table: false, requires_new: true) do
      users.each do |user|
        # 何らかの処理
        all_valid &= user.save
      end

      unless all_valid
        raise ActiveRecord::Rollback
      end
    end
    all_valid
  end
end
```

transactionの引数である、join_tableやrequires_newはこちらを参考にしました。
https://qiita.com/jnchito/items/930575c18679a5dbe1a0

この書き方をすることによって、システムエラー(プログラムのバグにより起こるエラー)が起きればその時点でロールバックがされますし、業務エラー(ユーザーの操作によるエラー)が起きればRollbacを明示的にするようにしています。

```ruby:users_controller.rb
class UsersController < ApplicationContoller
  def create
    if User.bulk_create(@users)
      redirect_to :index
    else
      # エラー通知
      render :new
    end
  end
end
```

#おわりに
おかしい部分があるかもしれません。ご指摘あればよろしくお願い致します。
ターミナル操作 

新しく覚えておきたいコマンドがあったら随時更新

### 確認
現在使用しているディレクトリの確認（今どこにいるかわからなくなったらとりあえずpwd）
pwd (print working direction)

現在使用しているディレクトリの中身のディレクトリ、ファイル一覧を表示
ls (list)

### 新規ファイルの作成
touch "ファイル名".txt

### 新規ファイルを作成して編集（○○ファイルを作成して、編集エディタで開く）
vi(vim) "ファイル名".txt

### 文書の中身を確認
cat "ファイル名".txt
less "ファイル名".txt
vi(vim) "ファイル名".txt

### ファイルを開く
open "ファイルパス"
例) open ./Desktop/DeepLearning/flie1.txt

### ファイルのコピー
cp "ファイルパス"
cp ./Desktop/DeepLearning/file1.txt file2.txt

### ディレクトリの作成
mkdir "作成するディレクトリのパス"
mkdir ./Desktop/New_File

### 空ディレクトリの削除
rmdir"削除したいディレクトリのパス"
rmdir ./Desktop/New_file

### root権限付きでのコマンド実行
sudo rmdir ./Desktop/New_file

### root権限
sudo su -

### 複数階層のディレクトリを一気に作成する
$ pwd # 現在のディレクトリを表示
/Users/seiji
$ mkdir -p ./a/b/c # mkdirにオプション-pを指定して、複数階層のディレクトリを作成
$ cd ./a/b/c　# ディレクトリを移動
$ pwd　# 作成したディレクトリに移動して、カレントディレクトリを表示
/Users/seiji/a/b/c # 存在しないディレクトリも含め作成されている

### ディレクトリ（ファイル）を移動する（cd:current directory）
cd "ディレクトリのパス"
例) cd Desktop/DeepLearning/file1

### ディレクトリ（ファイル）の名前編集
mv "変更したいディレクトリ名(ファイル名)" "変更後のディレクトリ名(ファイル名)"
例) mv file1.txt file2.txt

### ファイルの移動
mv "ファイルのパス" "移動先ディレクトリのパス"
例）mv ./Desktop/DeepLearning/flie1.txt ./Documents

### ディレクトリの削除
rm "ファイル名"
rm -R "ディレクトリ名"

### 階層の移動
cd (ホームディレクトリに戻る)
一つ上のディレクトリに戻る (cd ..)
直前にいたディレクトリに戻る (cd -)
特定のディレクトリに移動する (cd ~/Desktop/file/)

### ディレクトリの情報を見る
ls -la

### 指定したディレクトリ内のファイルやディレクトリの情報を閲覧
ls -la ./file1

### test.logの'ML'を検索して表示
cat ./test.log | grep 'ML'

### MLは検索せずにINFOを検索
cat ./test.log | grep -v 'ML' | grep 'INFO'

### 過去に使用したコマンドを閲覧
history

### 特定のコマンドから履歴を閲覧
history | grep ssh

### 特定のコマンド履歴の検索
ctrl + rで出てくるフォームに検索したいキーワードを入れることで"history | grep ssh"と同じ結果が得られる。

### 稼働中のプロセスを表示する
top

### topコマンドの終了
q

### ターミナルウィンドウを綺麗にする
clear

### 特定のコマンドの使い方を表示する
help "コマンド名"
help help

### What is ??
指定したコマンドの概要機能の表示
whatis "コマンド名"
whatis mkdir

### 指定したコマンドのマニュアル表示
man "コマンド名"
man mkdir

### ターミナルセッションの終了
exit
UnityのKeywordRecognizerを使ってみる

# この記事について
Unityの標準で用意されているKeywordRecognizerを利用してみます。

# 環境
Windows10（Windows10でしか動かないそうです）
Unity 2021.3.24f1

# やりたいこと
今回やりたいことはゲーム内で音声を受け取ってその結果を取得してゲームに反映させるということを使用と思います。
例：メニューと発言するとUIが表示される

# KeywordRecognizer
KeywordRecognizerはUnityが標準で用意している[音声認識ライブラリ](https://docs.unity3d.com/ja/2018.4/ScriptReference/Windows.Speech.KeywordRecognizer.html)です。
このKeywordRecognizerは登録されているキーワードの中から発言内容と最も近しい内容のものを出力するというものになっています。

# 簡単実装
まずは簡単に実装してみましょう。

```csharp:SimpleKeywordRecognizer.cs
    public class SimpleKeywordRecognizer:MonoBehaviour
    {
        [SerializeField]private string[] keywords;
        private KeywordRecognizer _recognizer;

        void Awake()
        {
            _recognizer = new KeywordRecognizer(keywords);
        }

        private void OnEnable()
        {
            _recognizer.OnPhraseRecognized += OnPhraseRecognized;
            _recognizer.Start();
        }

        private void OnDisable()
        {
            _recognizer.OnPhraseRecognized -= OnPhraseRecognized;
            _recognizer.Stop();
        }

        private void OnPhraseRecognized(PhraseRecognizedEventArgs args)
        {
            Debug.Log(args.text + $", LEVEL:{args.confidence}");
        }
    }
```

# 出力内容
音声の入力があったと判定されると「OnPhraseRecognized」が発火します。
引数として「[PhraseRecognizedEventArgs](https://docs.unity3d.com/ja/2018.4/ScriptReference/Windows.Speech.PhraseRecognizedEventArgs.html)」が指定されておりますが、こちらには認識された音声内容が入っています。

| 値               | 説明 |
|:-----------------|:------------|
| text             | 認識された音声の文字列データ。（typeSystem.String）|
| confidence       | 認識精度。High/Middle/Lowのいずれかの値が入ります。（typeUnityEngine.Windows.Speech.ConfidenceLevel）|
| phraseDuration   | 音声の長さ。（typeSystem.TimeSpan）|
| phraseStartTime  | 音声開始日時。（typeSystem.DateTime）|
| semanticMeanings | 認識されたフレーズの語義的な意味（よく分からない）|



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/296240/bf23046e-22c1-cc0a-9b91-55e654923458.png)
C++のメンバは宣言順に初期化される

表題のとおりだが、これは親クラスでも問答無用で当てはまるので注意。

```cpp
#include <stdio.h>
#include <memory>

class AImpl{
public:
    AImpl(){x=123;}
    void greet(){printf("hello world [%d]", x);}
private:
    volatile int x;
};
class BImpl: public AImpl{};

class AIface{
public:
    AIface(std::shared_ptr<AImpl> pAImpl): _pAImpl(pAImpl) {}
    void greet(){_pAImpl->greet();}
private:
    std::shared_ptr<AImpl> _pAImpl;
};
class BIface: public AIface{
public:
    BIface(std::shared_ptr<BImpl> pBImpl): _pBImpl(pBImpl), AIface(pBImpl) {}
private:
    std::shared_ptr<BImpl> _pBImpl;
};

int main(){
    std::shared_ptr<BIface> pBIface = std::make_shared<BIface>(std::shared_ptr<BImpl>(new BImpl));
    pBIface->greet();
}
```

ここで、`_pBImpl(pBImpl), AIface(_pBImpl)`としたくなりますが、そうするとsegmentation faultが発生します。
Photoshopで写真が表示されなくなった時の対処法

# Photoshopで写真が表示されなくなった時の対処法

## 状態
Photoshopは起動するのに
写真を開いても、なぜか写真だけが表示ない。
画面は真っ暗のまま。

## 対処法

　Photoshop → 環境設定 → 一般 → パフォーマンスで、
「グラフィックプロセッサーを使用」のチェックを外す
Windows(WSL2)上にDjango開発環境を構築する

#はじめに
Window10 home上にDjangoの開発環境を構築する方法を纏めます。

#構成
ホストOS: Windows10 Home(x64、21H1)
ゲストOS: WSL2上にUbuntu 20.04.3 LTSをインストール
IDE: Visual Source Code 1.63.2
Python: Python 3.8.10
仮想環境: venv
フレームワーク: Django 4.0.1

#WSL2、Ubuntuインストール
1. WSL2、Ubuntuのインストール  
PowerShellで以下コマンドを実行する。これでWSL2とUbuntuがインストールされる。

    ```powershell:powershell
    wsl --install
    ```

1.  Ubuntuのアップデート  
Ubuntuコンソールで以下を実行して、Ubuntuをアップデートする。

    ```bash:bash
    sudo apt update && sudo apt upgrade
   ```

1. pipのインストール

    ```bash:bash
    sudo apt install python3-pip
    ```

--- 以下の設定は任意 ---

* WSL2の最大メモリ設定
エクスプローラで%USERPROFILE%を開き「.wslconfig」ファイルを新規作成する。

    ```ini:.wslconfig
    [wsl2]
        memory=4GB
    ```
.wslconfigの設定を反映するにはWSL2の再起動が必要なため、**PowerShell**で`wsl.exe --shutdown`を実行する。
Ubuntuのコンソールを開き、`free -h`でメモリの割り当て状況を確認する。
以下の例では、Memのtotalが3.8Giになっているので正しく反映されている。

    ```:free結果
                  total        used        free      shared  buff/cache   available
    Mem:          3.8Gi       435Mi       1.7Gi       0.0Ki       1.8Gi       3.2Gi
    Swap:         1.0Gi          0B       1.0Gi
    ```

* WindowsTerminalのインストール
[こちら](https://dev.classmethod.jp/articles/linux-beginner-wsl2-windowsterminal-setup/)のページを参考に設定した。

#仮想環境（venv）のインストール
Django以外の環境と共存させる為に、venvの仮想環境上にDjango環境を構築する。


1. venvインストール

    ```bash:bash
    apt install python3.8-venv
    ```
1. プロジェクトフォルダ作成

    ```bash:bash
    mkdir HelloWorld
    cd HelloWorld

1. 仮想環境作成

    ```bash:bash
    python3 -m venv .venv
    source .venv/bin/activate
    ```

    activate実行後に以下の様にシェルの先頭が`(.venv)`となっていれば仮想環境に入れている。

    ```bash:bash
    (.venv) hoge@hoge:$~/HelloWorld
    ```
   仮想環境から抜けるには以下を実行する。

    ```bash:bash
    deactivate
    ```

#Visual Studio Codeの設定
1. Remote-WSL 拡張機能をインストールする。
1. 上で作ったプロジェクトフォルダ上で以下コマンドを実行し、WSL2上のVSCodeリモートサーバーを起動する。

    ```bash:bash
    code .
    ```
    VSCodeが起動し、左下のインジケーターに`WSL:Ubuntu`と表示されればWSL2上のリモートサーバーに接続できている。
1. ubuntu用のPython拡張機能をインストールする。
Windows側に入っているPython拡張機能とは別にWSL2側にPython拡張機能をインストールする必要がある。
VSCodeの拡張機能ウィンドウで**Python機能拡張**をインストールする。

#Djangoのインストール
1. 仮想環境を有効にする。
VSCodeのコンソールで以下コマンドを事項し、仮想環境に入る。Djangoは仮想環境内にインストールする。

    ```bash:bash
    source .venv/bin/activate
    ```

1. Djangoのインストール

    ```bash:bash
    python3 -m pip install django
    ```

1. Djangoプロジェクトの生成

    ```bash:bash
    django-admin startproject web_project .
    ```
    成功するとプロジェクトフォルダ下に`manage.py`、`web_projectフォルダ`が作成される。

1. Django開発サーバーの起動

    ```bash:bash
    python3 manage.py runserver
    ```

    `Starting development server at http://127.0.0.1:8000/`と表示されたらサーバー起動成功。
    ブラウザで`http://127.0.0.1:8000/`を開いてDjangoの規定のページが表示さえれば正常動作している。

# 参考にしたサイト

* [Windows で Web 開発に Python を使用する](https://docs.microsoft.com/ja-jp/windows/python/web-frameworks)
* [Linux初心者がWSL2とWindows Terminalのセットアップをやってみた](https://dev.classmethod.jp/articles/linux-beginner-wsl2-windowsterminal-setup/)
WindowsでLinux環境を整えてみた

# はじめに
この記事は、Windows10でVisual Studio Codeをインストールし、WindowsSubsystemForLinux環境を構築するまでの備忘録です。

動機としては、Windows環境でPythonを使おうとすると何かと制約が多いのか、Anacondaというアプリをインストールして使うことをすすめられます。もう一つの選択肢としては、Windows上にLinux環境を構築して、そこで使うという手もあります。

Anacondaも大分便利ですが、拡張機能を使ってカスタマイズしやすく、Python以外の言語も便利に使えるVS Codeをエディターとして使いたいので、今回は後者の方法をまとめていきます。


# WindosSubsystemForLinux(WSL)とは
簡単にまとめると、Windows上でLinux環境を使えるようにするためのアプリケーション。WSL1やWSL2がある。
今回はWSL2を使用する。

https://docs.microsoft.com/ja-jp/windows/wsl/about

# VS Codeとは
Visual Studio Code (VS Code) は、Microsoftが開発している、Windows上などで使用できるソースコードエディターのひとつ。デスクトップ版と機能が制限されているオンライン版があります。どちらも無償で使用することができます。

https://code.visualstudio.com/

# セットアップ
## 手順0.
[手順1.](#手順1)で、WSL2をインストールするために、Windowsのバージョンを最新にしておきます。

## 手順1. 
PowerShell(管理者)を開き、下記のコードを実行します。

```PowerShell
wsl --install
```

コード実行中はコマンドの指示に従います(再起動など)

## 手順2. 
WSL2のインストールプロセスが完了した後は、合わせてUbuntuディストリビューションがインストールされているはずなので、[スタート]メニューからUbuntuアプリを開きます。

Ubuntuのユーザー名とパスワードの作成を求められるので、作成します。

作成後、下記コマンドでパッケージの更新とアップデートを行っておきます。

```Bash
sudo apt update && sudo apt upgrade
```


## 手順3.
下記ページからWindows版のVS Codeインストーラを選択し、VS CodeをWindowsにインストールします。

https://code.visualstudio.com/download

>インストール中に[追加タスクの選択] が求められたときは、コード コマンドを使用して WSL でフォルダーを簡単に開くことができるように、[PATH への追加] オプションがオンになっていることを確認してください。
(https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode より引用)


インストール後は、VS Codeを立ち上げて、拡張機能タブから下画像と同じ「Remote Development」拡張機能を追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2453441/51d3a82c-90dd-25e5-c0a1-f7796cb24072.png)


# WSLプロジェクトの開き方
## コマンドラインから
UbuntuなどのWSLディストリビューションのコマンドラインから下記コードを実行すると、カレントディレクトリでVS Codeが開かれます。

```Bash
code .
```

## VS Codeから
VS Codeでショートカットキー`Ctrl`+`Shift`+`P`を押すとコマンドパレットが開くので、そこに`Remote-WSL`と入力するとWSLプロジェクトに関するオプション一覧が出てくる。


# 終わりに
WSL2が登場してすぐは、もう少し複雑なセットアップだった気がするのですが、[手順1](#手順1)のコマンドが使えるようになって大幅にセットアップしやすくなりました。
今後は他のディストリビューションを追加してみたり、Gitを使えるようにしてみたりもしてみようと思います。

# 引用・参考
1. Microsoft. "WSL 開発環境を設定する". https://docs.microsoft.com/ja-jp/windows/wsl/setup/environment, (参照 2021-01-10)

2. Microsoft. "Linux 用 Windows サブシステムで Visual Studio Code の使用を開始する". https://docs.microsoft.com/ja-jp/windows/wsl/tutorials/wsl-vscode, (参照 2021-01-10)
Ruby &=の使い方



```ruby
# +=や*=と同様に考えれば&演算子の意味がわかれば理解できる
foo &= bar
# これは foo = foo & bar を意味する
```

#&演算子
積集合や論理積を意味する

```ruby
# Arrayの積集合
[1, 1, 2, 3] & [3, 1, 4]
=> [1, 3]

# TrueClass, FalseClass
true & true
=> true

true & false
=> false

false & false
=> false

nil & true
=> false

nil & false
=> false

# Integer(ビット2項演算子)
1 & 1
=> 1

2 & 3
=> 2
```
Python WebフレームワークPlotly Dashで資産管理アプリを作成

## Dashとは
Dashは、データ可視化インターフェースを構築するためのオープンソースフレームワークです。
2017年にPythonのライブラリとしてリリースされ、RやJuliaの実装を含むまでに成長しました。
Flask、React.js、Plotly.jsの3つの技術を使って作成されています。
2020年にリリースされたStreamlitの人気がとても高くなっていますが、2018年からとても高い人気を誇ってます。
![graph.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2465378/b688b492-28fb-511c-2e5d-8373f2eddb84.png)

## ライブラリをインストール
```
pip install pandas
pip install dash
```

## タイトルを作成
```
# -*- coding: utf-8 -*-
import dash
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div(children=[
    html.H1(children='資産管理'),
    ])

if __name__ == '__main__':
    app.run_server(debug=False, host = '127.0.0.1',port=8000)
```
![01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2465378/7dcdba1f-763d-dafe-441f-8c542ec9c02d.png)

## 実行動画
<iframe width="560" height="315" src="https://www.youtube.com/embed/EgowonQ8yr8" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

## 動画の実装結果

![02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2465378/0f877653-626f-bba3-b7ca-59ec52ece42a.png)
AngleSharpでスクレイピング【C#】

#C#でスクレイピングしてみる

スクレイピングならPython一択かと思っていたが、
C#が得意なのでC#でできないか調べたらAngleSharpというライブラリを発見

##AngleSharpとは
https://anglesharp.github.io/

DOMをクエリセレクター風に解析できるライブラリっぽい
jQueryを分かっていればほとんど躓くことなく使用できるので取っ付き易いライブラリだと思う。



##リンクを抽出してみる
```C#:sample.cs
            var domain = @"https://aaaaaaaaaaaaa/";
            var parser = new AngleSharp.Html.Parser.HtmlParser();
            var target = parser.ParseDocument(new WebClient().OpenRead(domain));
            
            Console.WriteLine(target.QuerySelector("title").InnerHtml); // タイトル表示
            var links = target.GetElementsByClassName("links"); //classにlinksが含まれるタグをすべて取得

            foreach (var link in links)
            {
                var element = link.QuerySelector("a"); //aタグを取得
                Console.WriteLine(element.GetAttribute("Href")); // aタグのhref の表示
                Console.WriteLine(element.InnerHtml); // aタグの文章表示
            }
```

上記の様なやり方で、タイトルと*class="links"*下のすべてのaタグを取得できる。

他のライブラリを知らないが、めちゃくちゃ使いやすいなと思った。
テキストファイル読み込み |> 加工 |> テキストファイル書き込み

毎回テキストエディタでファイル加工するのが面倒くさいと思ったことはありますよね？
ファイル読み込み
|> 加工
|> ファイル書き込み

の簡単な例を作ってみました。

```elixir
defmodule YmnTest do
  def convert do
    ret =
      File.read!("in.txt")
      |> String.split("\n")
      |> Enum.filter(fn x -> Regex.match?(~r/"key2":.*/, x) end)
      |> Enum.reduce(fn x, acc -> acc <> "\n" <> x end)
      |> String.replace(~r/[,"]/, "")
      |> String.replace(~r/: /, "\t ")

    File.write("out.txt", ret)
  end
end
```

加工元のテキスト

```in.txt
"key1": "val1",
"key2": "val2",
"key2": "val3",
"key1": "val4",
"key2": "val5",
"key2": "val6"
```

実行してみよう

```
$ iex -S mix
Erlang/OTP 24 [erts-12.0] [source] [64-bit] [smp:2:2] [ds:2:2:10] [async-threads:1] [jit]

Compiling 1 file (.ex)
Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> YmnTest.convert
:ok

```


出力結果

```out.txt
key2	 val2
key2	 val3
key2	 val5
key2	 val6
```

１、File.read!で加工元のテキストファイルを読みます
２、String.splitで改行コードで分割し、配列にします
３、Enum.filterで"key2: "を含む行を抽出します
４、Enum.reduceで抽出した配列の結果を改行コードをつけて文字列にします
５、String.replace　「,」と「”」を空に置き換える
６、String.replace　「: 」をタブに置き換える

Enum.filterで欲しい行を抽出し、String.replaceで文字列置き換えをする。
これの組み合わせを作って置けば大量のテキスト処理も楽になると思います。
【Rails】form_withとは？

##form_withとは？

form_withは、htmlのformタグを生成するためのメソッド。

##どうなるの？
「生成する」というのは少し難しい表現ですが、「置き換わる」と考えても問題ありません。
つまり、form_withのところに、<form　action=~というhtmlのタグが置き換わります。

##へー！すごいね！
このようにhtmlを生成するメソッドをビューヘルパーと呼んでいます。

##ちなみに...

・link_toとは：<a href=~というaタグに置き換わる。ビューヘルパーの一つです。

・f.number_fieldとは：inputタグに置き換わる。ビューヘルパーの一つです。
motpyやーる（Python3.6、Windows10）

# はじめに
motpyやっていくー

# 開発環境
- Windows 10 PC
- Python 3.6

# 実装

1．motpyをクローン

https://github.com/wmuron/motpy

2．ライブラリをインストール

~~~
pip install motpy
pip install -r requirements_dev.txt
~~~

3．実行

~~~shell
python examples/detect_and_track_in_video.py --video_path=./assets/video.mp4 --detect_labels=['car','truck'] --tracker_min_iou=0.15 --device=cuda --track_text_verbose=1
~~~

<blockquote class="twitter-tweet"><p lang="en" dir="ltr">motpy<br><br>python examples/detect_and_track_in_video.py --video_path=./assets/video.mp4 --detect_labels=[&#39;car&#39;,&#39;truck&#39;] --tracker_min_iou=0.15 --device=cuda --track_text_verbose=1<a href="https://twitter.com/hashtag/Python?src=hash&amp;ref_src=twsrc%5Etfw">#Python</a> <a href="https://twitter.com/hashtag/DeepLearning?src=hash&amp;ref_src=twsrc%5Etfw">#DeepLearning</a> <a href="https://twitter.com/hashtag/AI?src=hash&amp;ref_src=twsrc%5Etfw">#AI</a> <a href="https://twitter.com/hashtag/%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92?src=hash&amp;ref_src=twsrc%5Etfw">#機械学習</a> <a href="https://t.co/f3QqVCBuwk">pic.twitter.com/f3QqVCBuwk</a></p>&mdash; がちもとさん@メタバース熊本 (@sotongshi) <a href="https://twitter.com/sotongshi/status/1480471927072641025?ref_src=twsrc%5Etfw">January 10, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 追記
YOLOXと組み合わせてみた
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">YOLOX + motpy trajectory <a href="https://t.co/N8dvPpAnnS">pic.twitter.com/N8dvPpAnnS</a></p>&mdash; がちもとさん@メタバース熊本 (@sotongshi) <a href="https://twitter.com/sotongshi/status/1480591564699480064?ref_src=twsrc%5Etfw">January 10, 2022</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# 参考文献
- [YOLOX+motpyで始めるMultiple Object Tracking(MOT)](https://qiita.com/Saigyo_HBK/items/1116b87a1bb202d1d680?fbclid=IwAR3fk-GndZ0wttWFhlLPlyQfp9N2MYlHVtrkIcXbB-olKhc3_Spi9Pi3iRI)
- [YOLOXやーる（Python3.6、Windows10）](https://qiita.com/SatoshiGachiFujimoto/items/f4282fcd8bcd28b2a450)
Windowsのクリップボードをちょっと便利に使えるようになるアプリを作ってみた

# 概要

以下の記事を参考に、クリップボードを使いやすくするアプリを作ってみました。
<https://codezine.jp/article/detail/11229>

見た目は以下の図のような感じです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452291/ce5a6319-3066-ea52-5ca7-841158f25e7b.png)

サンプルとの差分は以下の通りです。

- 選択しているアイテムをダブルクリックでコピーできます。
- [フィルタ文字列]テキストボックスに文字列を入れるとクリップボード内の履歴から、テキストが含まれるものをフィルタできます。

# 利用方法

以下のURLから、Relase.zipリンクをクリックしてダウンロードしてください。
<https://github.com/niimima/ExtendedClipboard/releases>

ExtendedClipboard.exeを実行すると起動します。
もし起動できない場合はRuntimeが不足している可能性があるため、以下のURLから.NET Runtimeのインストールしてみてください。
https://dotnet.microsoft.com/en-us/download/dotnet/3.1

また、このアプリの利用にはクリップボードの履歴がオンになっている必要があります。そちらもご確認ください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/452291/6643b8a3-b432-913d-d54d-5728bcb1a131.png)


# まとめ

上記の記事を参考にしてみると、思いの外簡単にOSの機能を利用することができました（記事のソースコードをベースにすると2時間ほどで実現できました）。
このように視覚化できると想像以上に楽しめるので、他にも色々OSの仕組みを使ってみたくなりました。
Oracle Cloud Infrastructureの資格とってみた ~ OCI Foundation Associate ~

#はじめに
Oracleのクラウド資格試験が期間限定(2021年12月7日～2022年3月31日)で無料になっているとたまたま目にしたので一念発起してみました。無事資格取得できたので、勉強した時に参考にした情報とTipsをまとめます。

<img width="300" alt="image.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1863184/5206051b-d39f-167e-b58c-1e1ccfdd6568.png">

[![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/7c01bc7d-fdf1-d91a-dfae-cf845f6cafbe.png)](https://www.oracle.com/jp/news/announcement/oracle-offers-free-training-and-certification-for-oracle-cloud-infrastructure-jp-20210909/)

> Oracle公式: [期間限定：無償 Oracle Cloud Infrastructure（OCI） 認定試験提供開始](https://blogs.oracle.com/oraclemaster/post/oci-free-cert)

##レベル感
AWS Solutions Architect Associate資格取得に向けてクラウドの勉強中。AWSクラウドプラクティショナーは2021年に取得済みです。

##結果 (ギリギリ合格!)
なんとかギリギリ70%で合格できました。（合格ラインは68%)
制限時間は90分で全55問でした。
Oracle Cloud Infrastructure Foundations 2021 Associate (Japanese) (1Z0-1085-21-JPN)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/864151/66a36327-a8a2-2ca5-c06b-8a978b8ed06e.png)

#Tips
- AWSと異なるOCI独自の概念(フォールト・ドメインや可用性ドメイン)などは最初戸惑ったが、基本的なクラウドインフラストラクチャーの概念"Region - Availability Zone - データセンター "は同じなのでまずは理解しておくべし。(試験に出る！)
- 他のOCIサービスはAmazon S3, AWS IAM, AWS Lambdaとユースケースや利用方法などが似ている(ほぼ同じ？）ので、これはAWSのxxサービスだなと置き換えながら勉強して試験に臨むと良さそう。
- 無償期間に試験は複数回受けられるので、とりあえずお試し受験してみるのもアリかもです。

#参考情報 (試験によく出たものをピックアップ)
##Oracle公式サイト

https://docs.oracle.com/ja-jp/iaas/Content/GSG/Concepts/concepts.htm

https://docs.oracle.com/ja-jp/iaas/Content/General/Concepts/regions.htm

https://docs.oracle.com/ja-jp/iaas/Content/Compute/Tasks/edit-fault-domain.htm

https://docs.oracle.com/ja/solutions/learn-architecture-deploy-peoplesoft/oracle-cloud-infrastructure-terminology.html#GUID-5A47FD2C-E8DE-4552-AECB-8B01E16DA3E0

https://www.oracle.com/jp/cloud/compute/vmware/

##参考にさせていただいたブログ記事

https://qiita.com/Skogkatter112/items/98c6f815b4e0b6556b7e

https://qiita.com/Skogkatter112/items/d3fc6da9407dc905f29f
Juliaのプログラムを遅くしないための注意点

Juliaのプログラムで計算するときに無駄に遅くなりがちなポイントの覚え書き。

コメントもらえるとうれしいです。

# 全て関数にする
メインの処理とかも関数にぶち込んで、関数を呼び出すようにする。

# グローバル変数は使わない
型が決まらないので、グローバル変数は使わないようにする。

# サイズの大きい配列は使い回す
毎度メモリ確保すると時間食うので、使いまわしましょう。
【React x Typescript】リンク切れの画像の代替画像を表示する

# 概要
画像がリンク切れの時に表示されるimgコンポーネントってイケてないですよね。
そんな時、画像リンク切れの時は別の画像を表示したいニーズが存在すると思います。

React x Typescriptの組み合わせで微妙にハマってしまったので、整理します。

※なお、リンク切れ時には、例えば以下のように表示されます。

|<img width="50%" height="50%" alt="sample_img" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1424230/81da998f-7f0c-d3a5-33ab-15443c3bad73.png" >|
|:-:|

# 環境
```shell
$ node -v
v16.13.1

$ npm -v 
8.1.2
```

# 実装

ポイントは、currentTarget使用する or onErrorの返り値をany型で明示的に指定してあげることでした。
※@YutaUraさんのコメントより、対策法を追加しました！ありがとうございます！

```typescript
export const App: React.FC = () => {
  const imgPath = 'https://pbs.twimg.com/profile_banners/1353986308062908417/1620745196/1080x360'
  const dummy_img = 'https://pbs.twimg.com/profile_banners/2968069742/1628067771/1500x500'

  return (
    <div className="App">
      <img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e) => { e.currentTarget.src = dummy_img }} />
      {/* もしくは以下のように記載 */}
      <img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e: any) => { e.target.src = dummy_img }} />
      
    </div>
  )
}
```

# 解説

Reactのimgコンポーネントは、`React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>`であり、その`onError`オプションで返却される値の型は、`React.SyntheticEvent<HTMLImageElement, Event>`です。

[この記事](https://qiita.com/m3816/items/56b9b6b6f340265cbfab)を参考に実装してみましたが、どうやらこの型にはsrcは含まれておらず、下記のようなエラーが表示されました。

```typescript
{/* こうやって書くのはダメだよ */}
<img src={imgPath} alt='sample_img' width='100%' height='auto' onError={(e) => {e.target.src}}/>
```

```terminal:エラー文
Property 'src' does not exist on type 'EventTarget'.
```

色々試行錯誤した結果、上記のサンプルのように、currentTargetを使用するか、返り値eにany型を付けて実装することで、本エラーを回避できます。

# 余談

Typescriptなのにany使うとは何事だ！と怒られてしまうかもしれません。。。
いいアイデアあれば、コメントいただけると幸いです。
gitのデフォルトブランチ名がconfigに記述しても変更されない！

# はじめに
昨日投稿した以下の記事で「そのうち書こうかな」と言っていたやつです。
gitのデフォルトブランチ名を変えたのに、なぜか`git init`してもブランチがmasterで作成されて困ったという話。

https://qiita.com/devtoku/items/9fd4f135488420a10f4f

# 原因
**gitのバージョンが古いことが原因でした。恥ずかしい。**
どうもconfigでdefaultbranchの名前を変えられる昨日は、バージョン2.28から追加されたようです。
自分のgitのバージョンを調べてみたところ、見事に古いバージョンのものでした。
gitのバージョンを調べるコマンドは以下のとおり。

```
git version

#gitのバージョンが表示されます
git version 2.XX.X
```

# 解決方法
### gitの更新
リポジトリをOSに追加する方法でgitをインストールしてた人は多分`apt update` `apt upgrade`で更新できてたと思うけど、自分はなぜかgitのリポジトリが追加されてなかった（多分直接ファイルダウンロードでもしてたのかな）ので、新しくリポジトリを追加してからパッケージを更新する。

```
add-apt-repository ppa:git-core/ppa
apt update
apt upgrade
```

これだけです。
この後gitのバージョンを確認してみると、しっかり`git version 2.34.1`に更新されていました。
これでちゃんと`init`したときのデフォルトブランチ名が変更されるはず。

# init時のデフォルトブランチ名を変える
情報をまとめるついでにconfigを変える方法も書いておきます。
gitのconfigには以下の3つのスコープがあるもよう。

- system: システム全体に適用 `/etc/gitconfig`
- global: ログインユーザに適用 `home/.gitconfig`
- local: gitリポジトリごとに適用 `{workspace}/.git/config`

これらは上から順に読み込まれます。つまり、特定のリポジトリで作業をする際は、localに記述した内容が最優先されます。
今回はとりあえず`git init`で新規作成する際のブランチ名を変えたいので、globalのconfigに記述を加えます。
記述はコマンドラインから以下のように打ち込めばok。

```
git config --global init.defaultBranch {default branch name}

#例えばmainに変更したい場合は
git config --global init.defaultBranch main

#systemレベルで変更したい場合は
git config --system init.defaultBranch {default branch name}
#sudo必要かも
```

コマンドではなく直接エディタで編集したい場合は、ファイルマネージャでそれぞれのconfigを確認すればいい。
**かんたーーーん！！**
とりあえずgithubのデフォルトがmainだし、人権問題とかでmasterが復権することは（特に海外では）望めなさそうなので、デフォルトブランチ名はmainに変えておくのがよろしいかな。

# おわりに
gitの更新忘れというなんとも粗末な原因で余計な手間と時間を消費してしまった。
やっぱりサービス提供者の発表した重要な更新にはしっかり対応しないとまずそう。
というかせっかく登録したサービスなんだからこまめに使っていかないと、事故に蓄積した情報や技術がいつの間にか陳腐化してしまうから、そのあたり意識変えないといけない。
qiitaももっと活用しなきゃ。