OmniAICreator/Qiita-1.07M huggingface dataset:
【Rails】EC2内でgemをインストールした際に発生したエラーの対処法

某スクールの最終課題をEC2でデプロイする時に発生した事象。(RenderからEC2への移行)
EC2にクローンしたアプリを起動する為に必要なgemをインストールする際に、
上手くインストールが出来ず解決にかなり時間を費やしてしまった為、
備忘録として以下にエラーの詳細と解決方法を記述しておきたいと思います。

## 発生したエラー
先ず、ローカル環境「bunder2.1.4」と同じバージョンのbundlerをEC2側でも導入する為に、下記コマンドを実行。
```
[ec2-user@ip-＊＊＊-**-**-*** <リポジトリ名>]$ gem install bundler -v 2.1.4
[ec2-user@ip-＊＊＊-**-**-*** <リポジトリ名>]$ bundle install
```
すると、下記エラーメッセージが出現。
メッセージの内容はターミナル上でpgのバージョン'1.4.5'を導入する必要があるとのこと。
```
An error occurred while installing pg (1.4.5), and Bundler cannot continue.
Make sure that `gem install pg -v '1.4.5' --source 'https://rubygems.org/'`succeeds before bundling.
```
EC2内ターミナルで指定バージョンのpgのインストールを実行したところ、別のエラーメッセージ「Your PostgreSQL is too old. Either install an older version of this gem or upgrade your database to at least PostgreSQL-9.3.（PostgreSQLのバージョンが古すぎるので、せめて9.3にアップグレードしなさい）」が出てきました。
```
[ec2-user@ip-＊＊＊-**-**-*** <リポジトリ名>]$ gem install pg -v '1.4.5'
Building native extensions. This could take a while...
ERROR:  Error installing pg:
	    ERROR: Failed to build gem native extension.

<省略>

Your PostgreSQL is too old. Either install an older version of this gem or upgrade your database to at least PostgreSQL-9.3.
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details.You may　need configuration options.
```
## エラーの原因
そもそも、EC2ではデータベースにPostgreSQLではなく、MariaDBを使用してデプロイしようとしていたはずなので、PostgreSQLは不要になるのでは？と考え、Render使用時用としてGemfileに記載していた「gem 'pg'」を削除したところ、正常にEC2内でgemをインストールすることができました。やはり、「gem 'pg'」がgemfileに残っていたことが原因だと考えます。

## 解決方法
実際に行った手順の詳細は以下の通りです。
```
①Gemfileで、「gem 'pg'」の記述を削除
②VScodeからGemfile.lockを右クリックで削除、ローカル環境の最終課題アプリでbundle installを実行
③GitHubにコミットとプッシュ
④EC2環境でpull (コマンド： git pull origin main or git pull origin master)
⑤EC2環境でbundle install
```
Laravel9 おすすめ機能

## はじめに
Laravel9 で便利な機能が追加されました。
僕自身が実際に使ってみて便利だと感じた機能を紹介します。

## ① コントローラーのグループ化（おすすめ度 ★★）
``` php
/* 以前の書き方
--------------------------------------------*/
Route::get("test/index", [TestController::class,'index']);
Route::get("test/show", [TestController::class,'show']);

/* Laravel9では以下のように書くことができる
--------------------------------------------*/
Route::controller(TestController::class)->group(function(){
    Route::get('test/index', 'index')->('test.index');
    Route::get('test/show', 'show')->('test.show');
});
// 上の内容をGroupでまとめて以下のように書くことも可能
Route::group([
        'prefix'=>'test',
        'as'=>'test.',
        'controller'=>'App\Http\Controllers\TestController'
    ], function() {
        Route::get('index', 'index')->('index');
        Route::get('show', 'show')->('show');
    });
});
```
## ② to_route()を使ったリダイレクト（おすすめ度 ★★★）
``` php
/* 以前の書き方
--------------------------------------------*/
return redirect(route('index'));

/* Laravel9では以下のように書くことができる
--------------------------------------------*/
return to_route('index');
```
## ③ Checked/SelectedのBlade Directives（おすすめ度 ★★★）

### Checked
``` php
/* 以前の書き方
--------------------------------------------*/
<input type="checkbox"
        name="active"
        value="active"
        // @ifなどを使用して判定する必要があった
        @if(old('active', $user->active) == "active") checked @endif/>

/* Laravel9では以下のように書くことができる
--------------------------------------------*/
<input type="checkbox"
        name="active"
        value="active"
        @checked(old('active', $user->active)) />
```
### Selected
``` php
/* 以前の書き方
--------------------------------------------*/
<select name="version">
    @foreach ($product->versions as $version)
        <option value="{{ $version }}"
             // @ifなどを使用して判定する必要があった
             @if(old('version') == $version) selected @endif>
            {{ $version }}
        </option>
    @endforeach
</select>

/* Laravel9では以下のように書くことができる
--------------------------------------------*/
<select name="version">
    @foreach ($product->versions as $version)
        <option value="{{ $version }}" 
            @selected(old('version') == $version)>
            {{ $version }}
        </option>
    @endforeach
</select>
```

## さいごに
他にも色々と機能は追加になりましたが、個人的にはこの３つをよく使います！
本当にLaravelって便利ですね！:relaxed:
BabylonJS on NextJS sanple【TypescriptReact】

※解説は後程。。。

```tsx

import type { NextPage } from 'next'
import { useEffect } from 'react'
import * as THREE from 'three'

const Home: NextPage = () => {
  let canvas: HTMLElement
  useEffect(() => {
    if (canvas) return
    // canvasを取得
    canvas = document.getElementById('canvas')!

    // シーン
    const scene = new THREE.Scene()

    // サイズ
    const sizes = {
      width: innerWidth,
      height: innerHeight
    }

    // カメラ
    const camera = new THREE.PerspectiveCamera(
      75,
      sizes.width / sizes.height,
      0.1,
      1000
    )

    // レンダラー
    const renderer = new THREE.WebGLRenderer({
      canvas: canvas || undefined,
      antialias: true,
      alpha: true
    })
    renderer.setSize(sizes.width, sizes.height)
    renderer.setPixelRatio(window.devicePixelRatio)

    // ボックスジオメトリー
    const boxGeometry = new THREE.BoxGeometry(1, 1, 1)
    const boxMaterial = new THREE.MeshLambertMaterial({
      color: '#2497f0'
    })
    const box = new THREE.Mesh(boxGeometry, boxMaterial)
    box.position.z = -5
    box.rotation.set(10, 10, 10)
    scene.add(box)

    // ライト
    const ambientLight = new THREE.AmbientLight(0xffffff, 0.7)
    scene.add(ambientLight)
    const pointLight = new THREE.PointLight(0xffffff, 0.2)
    pointLight.position.set(1, 2, 3)
    scene.add(pointLight)

    // アニメーション
    const clock = new THREE.Clock()
    const tick = () => {
      const elapsedTime = clock.getElapsedTime()
      box.rotation.x = elapsedTime
      box.rotation.y = elapsedTime
      window.requestAnimationFrame(tick)
      renderer.render(scene, camera)
    }
    tick()

    // ブラウザのリサイズ処理
    window.addEventListener('resize', () => {
      sizes.width = window.innerWidth
      sizes.height = window.innerHeight
      camera.aspect = sizes.width / sizes.height
      camera.updateProjectionMatrix()
      renderer.setSize(sizes.width, sizes.height)
      renderer.setPixelRatio(window.devicePixelRatio)
    })
  }, [])
  return (
    <>
      <canvas id="canvas"></canvas>
    </>
  )
}

export default Home
```
【PHP】function内で使うreturnについて（早期リターンとは）

#### 早期リターンとは
function　中で　return を使うことで　if　などによるネストを減らすことができるテクニックのこと。

#### if文と言えば
    if(条件１){
        trueの場合の処理
    }else{
        falseの偽の場合の処理
    }
---
上記のイメージが強かったが、returnを使うことで 

    if(条件１){
        return true;
    }
    return false;
    }
---
と表記することができる。

#### なぜelse以下が省略されているか
>「関数内で呼び出されると、return文は***即座にその関数の実行を停止し、引数を関数の値として返します。***」(phpリファレンスより)

つまりtrueの場合、上記の例では true が返された時点で関数の実行が止まるので、それ以下の処理は実行されないということ。
そのためelse以下の記述は省略され、本来falseの場合に実行される処理がif文の外に出されている上記のような形式が成立する。

#### 応用する上で下記の記事が参考になったので備忘として
[初心者向け。覚えておきたい 「ガード節」という書き方。](https://qiita.com/kouyan/items/7b8b456b626447a1e24e)
[早期リターンとApple SLLバグ](https://www.ninton.co.jp/archives/7903)
寝坊で信頼を失う前に……400円で買える保険

# はじめに
:::note warn
この記事は寝坊を防ぐ対策について言及するものではありません。
:::


寝坊をする理由は様々で、目覚ましのかけ忘れ・夜更かし・不眠・体調不良・二度寝・飲酒等等……
生活習慣の改善で解消できるものもありますが、どうしても意識がない睡眠状態では
100％しないと言い切れるものでもありません。

そのくせ社会人としての評価に寝坊は大打撃を与えます。
※自分が所属しているSES会社では客先評価と勤怠の比重が50：50程です。

体調不良で遅刻するという連絡さえできればそこまで大きなマイナス評価にはならないのですが、
寝坊のどうしようもなさは、連絡ができないところにあります。

そこで、設定した時刻までにスマートフォンを操作しなかった場合に、勤怠メールを送信する仕組みを考えました。
以下はAndroidアプリとなるため、ご了承ください。

**用意するもの**
・[Tasker](https://play.google.com/store/apps/details?id=net.dinglisch.android.taskerm&hl=ja&gl=US)・・・Android用自動化アプリ　400円買い切り
・[MailTask](https://play.google.com/store/apps/details?id=com.balda.mailtask&hl=ja&gl=US)・・・Taskerアプリのプラグイン　無料

TaskerはAndroidの自動化アプリです。
例を挙げると、Bluetoothイヤホンを接続したら音楽アプリを立ち上げるといった設定ができます。
これだけでも地味に便利です。

このアプリを使って8時に通知を出し、9時までに通知を消す操作がなかった場合、
Mailtaskであらかじめ設定した内容のメールを送信する設定を作成します。

<h2>タスカーの仕組み</h2>



メール送信の設定は以下3つのプロファイルと4つのタスクを作成します。  

プロファイル
1. 9時にタスク3を実行する。// 通知用
2. 10時にタスク2を実行する。 // 遅刻連絡用
3. 0時にタスク4を実行する。 // 遅刻連絡起動用

タスク
1.プロファイル2の機能を無効化する。
2.メール送信する。
3.通知を表示する。タップするとタスク1を実行する。
4.プロファイル2の機能を有効化する。

詳しい設定方法は需要があれば別途記載します。

役割として、プロファイル2とタスク2の設定だけで最低限指定した時間にメールを送信する目的は達成できますが、
他の設定をすることでプロファイルの起動、停止忘れを防止し利便性が上がります。

寝坊に悩む人が救われれば幸いです。
Foundry,Irisのバージョン確認方法

## 目次
1. はじめに
1. Foundry（Fabric）バージョンの確認方法
1. Iris（Visualizer）バージョンの確認方法
1. 最後に

## はじめに
先日、Foundryのバージョンを確認する際、なかなか見つけることができなかったので、
FoundryとIrisのバージョン確認方法を併せてまとめておきたいと思います📝

※FoundryとIrisの画面を使ってご紹介しますが、
FabricとVisualizerをお使いの方は、読み替えながら進めてください。

## Foundry（Fabric）バージョンの確認方法
Foundryのバージョンは、
App Servicesコンソールで確認することができます。

ログインするとApp一覧のコンソールが開きますが、ここではバージョンは確認できません。
![スクリーンショット_0005-02-02_11_00_42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/9cab8fe5-47de-72d4-6dd7-a61002bf5c3e.png)

バージョンを確認するには、左メニューのEnvironmentsをクリックして、
![スクリーンショット_0005-02-02_11_01_33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/91c6cddb-2fa0-77c9-16cc-d146e528b4f4.png)

確認したい環境のApp Servicesをクリックしましょう。
![スクリーンショット_0005-02-02_11_01_44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/5916f8ed-65c3-547a-589b-007475c5d97e.png)

すると、App Servicesのコンソールペインの左下にバージョンが表記されます。
![スクリーンショット_0005-02-02_10_42_16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/cddd94df-7484-9cff-6d70-7b15c20d9b6f.png)

Foundryのバージョン確認方法は以上です！

## Iris（Visualizer）バージョンの確認方法

次に、Irisのバージョン確認方法を紹介します。

Irisのバージョンは、
左上のVolt MX Irisをクリックし、About Volt MX Irisをクリックしましょう。
![スクリーンショット 0005-02-02 10.45.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/c6eaaefa-9744-9f58-1e21-4863af77d22b.png)

すると、ポップアップが表示され使用しているバージョンを確認することができます。
![スクリーンショット 0005-02-02 10.54.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/592264/77b4e7be-e933-0547-73d2-64242868b578.png)

## 最後に
今回は、バージョンの確認方法について紹介しました！
特にFoundryは忘れやすいので、
忘れっぽい方はブックマーク🔖してすぐに確認できるようにしておきましょう！
Cloud Functionsでfirestoreからspreadsheetへデータ書き込み定時実行の手順

# Cloud Functionsでfirestoreからspreadsheetへデータ書き込み定時実行の手順
Cloud Functionsを定時実行し、firestoreからデータを取得 |> spreadsheetへ書き込む方法のメモを自分用に残しておきます。
サービスアカウントとOAuth２つ認証を使う点が少し混乱しました。


## サービスアカウント作成
1. IAMと管理 > サービスアカウント > サービスアカウントの作成
2. 権限（IAMロール）の付与
    1. IAMと管理 > IAM > アクセス権を付与
        - 「新しいプリンシパル」に作成したサービスアカウントアドレスを入力
        - 「ロールを割り当てる」に下記のロールを割り当て
            - Firebase管理者（firestoreへのアクセス）
            - Cloud Datastoreインポート/エクスポート管理者
                - https://cloud.google.com/firestore/docs/solutions/schedule-export?hl=ja#configure_access_permissions

## Spreadsheetへの書き込み
1. ソースコード記述
    - npm install
    - Node.jsでSpreadsheetに書き込み
    https://qiita.com/Lassieena/items/ba16b220d88bfd596b35
    - google-cloud/local-authのSCOPESが書き込み可能になっていることを確認

2. credentials.json（OAuth2.0クライアントID）の発行
        - https://developers.google.com/sheets/api/quickstart/nodejs

3. Node.js上で実行しブラウザで認証手続きを行ってcredentials.jsonからtoken.jsonを取得
    - google apis 権限のあるアカウント？で認証する 
    - ./functions/token.json へ配置
    - これがないとCloud Functions上で認証できずにtime outする

4. APIの有効化
    1. Google Spreadsheet APIを有効化
        - https://developers.google.com/sheets/api/quickstart/nodejs

## firestoreから取得
1. serviceAccountKey.json取得
    - IAMと管理 > サービスアカウント > （1.で作成したサービスアカウト） > 鍵を追加
    - https://firebase.google.com/docs/firestore/quickstart?hl=ja#:~:text=index.js-,%E7%8B%AC%E8%87%AA%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC%E3%81%A7%E5%88%9D%E6%9C%9F%E5%8C%96%E3%81%99%E3%82%8B,-%E7%8B%AC%E8%87%AA%E3%81%AE%E3%82%B5%E3%83%BC%E3%83%90%E3%83%BC

2. ソースコード記述
    - Cloud Functionsでfirestoreの初期化
    https://firebase.google.com/docs/firestore/quickstart?hl=ja#:~:text=Cloud%20Functions%20%E3%81%A7%E5%88%9D%E6%9C%9F%E5%8C%96%E3%81%99%E3%82%8B
    - firestoreのデータ取得
    https://cloud.google.com/firestore/docs/query-data/get-data?hl=ja

## デプロイ
```
$ firebase deploy --only functions
```

## Cloud Schedulerの作成
- デプロイで勝手に作られる
- https://cloud.google.com/firestore/docs/solutions/schedule-export?hl=ja#test_your_job_and_cloud_function


# エラー
## GaxiosError: invalid_grant
https://oeconomicus.jp/2021/06/google-api-error/
OAuthの期限切れ（テスト環境では7日で切れる）
再発行する.
token.jsonは消しておくこと.

# まとめ
OAuthを使う必要がなければサービスアカウントの認証のみでfirestore、spreadsheetどちらもアクセスできそうだしそれでよさそう。
neosでlogix その106

# 概要
neosでlogixやってみる。
Lerpノード使ってみた。



# Lerp

```
Inputs
 	Float	From
 	Float	To
 	Float	Lerp
Outputs
 	Float	*
```

# 俺コード

```
a = T
	|> Cos
DisplayGraph = Leap 0 1 a
```

# 写真

![2023-02-02 01.42.58.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/18104/865cac00-d630-a8c8-4334-118dfd43a6bc.jpeg)



以上。
Ruby include?メソッド

# include?メソッド
指定した値が配列や文字列内に含まれているかを判定するメソッドです。
指定した値が含まれている→true
指定した値が含まれていない→false　　を返り値として返します。

例1
```ruby
string = ["hello", "goodbye"]
puts string.include?("hello")
```

```
true
# ターミナル出力
```
例2
```ruby
string = ["hello", "goodbye"]
puts string.include?("thanks")
```

```
false
# ターミナル出力
```

# include?メソッドとif文を使って文字列を検知するプログラムを作成する

条件1:名前を入力すると「登録が完了しました」という文字列を出力すること
条件2:名前の中にピリオド(.)がある場合は、「 "!エラー!記号は登録できません"」という文字列を出力すること
条件3:名前の中に空白（半角のみ）がある場合は、「 "!エラー!空白は登録できません"」という文字列を出力すること
※今回空白に関しては、半角スペースのみを考えることとします。


```ruby
def check_name(str) 
  if str.include?(".")
    puts "!エラー!記号は登録できません"
  elsif str.include?(" ")
    puts "!エラー!空白は登録できません"
  else
    puts "登録が完了しました"
  end
end
puts "登録したい名前を入力してください(例)YamadaTaro"
str = gets
check_name(str)
```


条件1~3をcheck_nameメソッド内でif文を使って分岐させていきます。
今回、条件２,3以外は登録が完了しましたという返しが来るため、条件2と3から記述していきました。
ちなみに、if文は条件が当てはまった時点で処理が終了します。
最後にcheck_nameメソッドを呼び出しています。
【Hugging Face】Transformers 3.2.0から4.26.0にバージョンアップした際のコード変更

論文のコードを参考にモデルの実装を行っているのですが、Transformersのバージョンが古く(v.3.2.0)、現在のSTABLEバージョンv.4.26.0と所々API仕様が異なるところがありました(メジャーバージョンが変わったので当たり前ですが...)。

https://qiita.com/suzuki0430/items/89dd028996f7dc774796

公式docやライブラリのコードを読む際に不便なので、このたびバージョンをあげてみました。

案の定エラーが何個か出たので、解消した方法をこちらにメモします。

# DataCollatorForLanguageModelingの_tensorize_batchが使用できない
`torch.tensor`で書き換えました。
```py
batch = self._tensorize_batch(examples)
```
↓
```py
batch = torch.tensor([e.tolist() for e in examples],dtype=torch.long)
```

# ACT2FN, BertLayerNorm, BertForMaskedLM, BertConfigのインポート失敗
インポート先を変更しました。
`BertLayerNorm`は、`torch.nn.LayerNorm`で書けるようになりました。
```py
from transformers.modeling_bert import ACT2FN, BertLayerNorm
from transformers.modeling_bert import BertForMaskedLM
from transformers.configuration_bert import BertConfig
```
↓
```py
from transformers.activations import ACT2FN
from transformers import BertForMaskedLM
from transformers import BertConfig
```

# Trainerクラスの諸々
`trainer.train()`の引数に`model_path`が使えなくなり、`resume_from_checkpoint`が追加されました。
pythonでのデータ分析コードメモ

# pythonのデータ分析コードメモ

```python
#下準備
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

#CSVファイルの読み込み
df = pd.read_csv('/content/insurance.csv')

#データセットの読み込み(SKlearnのデータセット)
from sklearn.datasets import load_boston
dataset = load_boston()
x, t = dataset.data, dataset.target
columns = dataset.feature_names

#ヒストグラムの描画
plt.hist(df['bmi'])

#データ分け
from sklearn.model_selection import train_test_split
x_train, x_test, t_train, t_test = train_test_split(x, t, test_size=0.3, random_state=1)

#重回帰分析
from sklearn.linear_model import LinearRegression
model = LinearRegression()
model.fit(x_train, t_train)

#偏回帰係数の確認
model.coef_

#モデルの検証
print('train score : ', model.score(x_train, t_train))
print('test score : ', model.score(x_test, t_test))

#CSVファイルの書き出し
y = 
array([239.6785766 , 250.53141737, 164.84805461, 120.27678545,
       181.73395543, 262.21230671, 112.23276599, 191.94646405,
       151.50037962, 165.03910148, 193.77497659, 112.03733039,
       172.34904863])

df_test = pd.DataFrame({'pred':y})#ここでデータフレームへ入れる
df_test.to_csv("diabetes_test.csv")#（）内にファイル名を指定しする。

#CSVファイルの書き出し(リストのリスト型)
y= 
array([[237.38111445],
       [251.57608582],
       [162.33925285],
       [122.05644692],
       [186.12912752],
       [120.51573176],
       [172.26027197]])

tmp = pd.DataFrame(y,columns =['pred'])#データフレームへ入れる
tmp.to_csv('pls_pred.csv',index=None)#インデックスを指定してます。

```
正直CSVファイル変換の前処理としてデータフレームへ入れる操作が２種類ある
リスト型とリストのリスト型で処理が異なる理由がわかっていないため
わかり次第別記事でまとめたいと思います。
今後も追加していくと思います。
【言葉でキャラクターに自由自在にモーションを行わせる！】Nvidiaが出した論文、PADL：Language-Directed Physics-Based Character Controlの紹介

# 概要
SIGGRAPH Asia 2022でNvidiaが興味深い動画と論文を公開しました。
論文の名前は「[PADL: Language-Directed Physics-Based Character Control](https://dl.acm.org/doi/pdf/10.1145/3550469.3555391)」
自然言語でキャラクターにに自由自在なモーションを行わせる、という内容の論文です。
例えば「"jump and swing sword down"」（ジャンプして剣を振り下ろせ）と命令すると以下のようにキャラクターがジャンプしながら剣を振り下ろすモーションを行ったり、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315420/34b76b92-a1e0-30be-f31d-47d8ab7bf94d.png)
「"shield charge forward"」（盾で前方向に叩け）と命令すると前方向のシールドバッシュを行ったりします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/315420/23b25a1e-f2c8-542c-32b0-b6cb47855aeb.png)

画像だけではわかりにくいので、動画を見てみましょう。
以下の動画はNvidiaの研究グループが公開した本論文の解説動画です。
<iframe width="560" height="315" src="https://www.youtube.com/embed/CJnUlpxOEdg" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

「Turn right 180 degrees」と命令すると右回りで１８０度回転したり（32秒目付近）、「Shield bash right」と命令することで右側からのシールドバッシュ（37秒目付近）を行ったりしています。
すごい滑らかに行っていますね。
これはユーザーの命令をAIが解釈して、その命令に沿った行動をキャラクターが行っています。

また、目標を伴ったもう少し高度な命令も可能です。
例えば「task:face the blue block skill:right slash」みたいに命令すると、青いブロックのほうを向いて剣を右側から振ったり、「task:knock over the red block  skill:shield charge forward」と命令すると赤いブロックを倒すために前方向のシールドチャージを行ったりします。
これらの命令は大規模言語モデルを事前訓練として学習させているため、130程度のモーションとそのモーションを説明するキャプションだけで、その学習元にない語彙でも命令することが可能です。

本記事では、この論文がどうやって自然言語によるモーションの操作を行っているのかについての仕組みについて解説、しようと思ったけどアプリ作るとか動画作るとかで書く時間がなくなり、放置してしまった。
概要の紹介はできているので、供養として公開します。
暇ができたら詳しい仕組みについて解説を追記します。
Gitlab CIでコロンの後ろにスペースが入ると怒られる( script config should be a string or a nested array of strings up to 10 levels deep )


.gitlab-ci.yamlで以下の例は前者は成功しますが後者は`yaml invalid`が出て実行できません。

● 成功するパターン

```
stages:
  - test

test:
  stage: test
  script:
  - apk add jq curl
  - DOCKER_TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
  - curl --head -H "Authorization:Bearer $DOCKER_TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/lates
```

● 失敗するパターン( script config should be a string or a nested array of strings up to 10 levels deep )

```
stages:
  - test

test:
  stage: test
  script:
  - apk add jq curl
  - DOCKER_TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
  - curl --head -H "Authorization: Bearer $DOCKER_TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/lates
```

上記のコードはDockerhubのpull制限を確認するためAPIをたたくためスクリプトで、script:の部分をローカルで実行すればどちらも成功します。

これの違いはcurlコマンドのAuthorizationの後ろが前者がコロンだけ、後者がコロン+スペースであることだけです。yamlの場合、コロン+スペースがyaml構文のディクショナリーとなるのでscript中に同様のものがでるとうまく解析できないようです。

# 別解

コロン+スペースの形式でコマンドを実行させる方法として以下のように複数行に分けるときに使う`|`をつかってあげるとこれも成功します。

```
test3:
  stage: test
  script:
  - apt-get update && apt-get install -y jq curl
  - DOCKER_TOKEN=$(curl "https://auth.docker.io/token?service=registry.docker.io&scope=repository:ratelimitpreview/test:pull" | jq -r .token)
  - |
    curl --head -H "Authorization: Bearer $DOCKER_TOKEN" https://registry-1.docker.io/v2/ratelimitpreview/test/manifests/lates
```
新しいPCでgitの環境構築

GitLabのプロジェクトをクローンするまでの方法を記載します。

## Gitのインストール

以下を参考にしてGitをインストールする。

[【Windows】Gitの環境構築をしよう！](https://prog-8.com/docs/git-env-win)

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

以下を参考にして公開鍵と秘密鍵を作成する。

[GitLabリポジトリをローカルにクローン(clone)する手順](https://yutaro-blog.net/2021/05/08/gitlab-clone/)

## GitLabに公開鍵を追加

以下を参考にしてGitLabに公開鍵を追加する。

[GitLabリポジトリをローカルにクローン
(clone)する手順](https://yutaro-blog.net/2021/05/08/gitlab-clone/)

## gitconfigを修正

以下を実行し、gitconfigファイルを開く。
>git config --system -e

以下をコメントアウトする。

    #[credential]
    #	helper = manager

## クローンする

以下を参考にしてGitLabに公開鍵を追加する。
ここで、GitLabで作成したアクセストークンを使用する。

[【Git】2段階認証で「git clone」できなくなった場合の3ステップ](https://techtechmedia.com/2-factor-authentication-solution/)
【Laravel】コマンドのオプション指定を対話形式で行えるようになる

## 何が実現するのか？

2023 年 1 月 23 日に以下の PR がマージされました。

https://github.com/laravel/framework/pull/45629

そして 2023 年 2 月 1 日の v9.49.0 で上記変更分がリリースされました。

これにより、以下が実現します。

- **`make:*` コマンドのオプション指定を対話形式で行えるようになる**
- **既存コマンドを対話形式のオプション指定に容易に対応できるようになる**

一つずつ見ていきましょう。

## `make:*` コマンドのオプション指定を対話形式で行えるようになる

多くの Laravel ユーザーにとって真っ先に恩恵があるのはこれでしょう。今回の PR により、`make:*` コマンドが対話形式でのオプション指定に対応しました。

例えば `make:model` だと、これまでは引数が足りない場合以下の通りにエラーが発生しました。

![](https://user-images.githubusercontent.com/4977161/212221423-c6b62de6-cf87-47fc-b55f-752c38d801bc.png)

が、今回の PR により、必要な引数を省略した場合は以下の通りに対話形式で項目を埋めていくことが出来るようになりました。

![](https://user-images.githubusercontent.com/4977161/212221750-dd25cceb-2f7d-42f7-90c5-37058edc6396.png)

これまででも `php artisan make:model --help` というふうに `--help` オプションを付ければ引数の形式を確認出来たのですが、より一層分かりやすくなりましたね。

## 既存コマンドを対話形式のオプション指定に容易に対応できるようになる

以下の通り、`PromptsForMissingInput` インターフェースを実装することで対応ができます。

```php
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\PromptsForMissingInput;

class MyCommand extends Command implements PromptsForMissingInput
{
    // ...
}
```

`PromptsForMissingInput` 自体は空っぽなので何かのメソッドの実装を強要されるわけではありませんが、以下のメソッドをオーバーライドすることでプロンプトの表示や挙動をカスタムすることが可能です。

### 1. `promptForMissingArgumentsUsing`

ある特定のオプションについての質問文を指定します。`make:*` コマンドは一律で以下の通りになっています。

```src/Illuminate/Console/GeneratorCommand.php
    ...
    /**
     * Prompt for missing input arguments using the returned questions.
     *
     * @return array
     */
    protected function promptForMissingArgumentsUsing()
    {
        return [
            'name' => 'What should the '.strtolower($this->type).' be named?',
        ];
    }
    ...
```

### 2. `afterPromptingForMissingArguments`

対話形式で必須引数を埋めた後の処理をフックとして追加できます。デフォルトでは空です。

`make:model` の場合は下記の通り実装されてます。ファクトリーやマイグレーションなどを追加で作成するかどうか尋ねてますね。

```src/Illuminate/Foundation/Console/ModelMakeCommand.php
    ...
    /**
     * Interact further with the user if they were prompted for missing arguments.
     *
     * @param  \Symfony\Component\Console\Input\InputInterface  $input
     * @param  \Symfony\Component\Console\Output\OutputInterface  $output
     * @return void
     */
    protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output)
    {
        if ($this->didReceiveOptions($input)) {
            return;
        }

        collect($this->components->choice('Would you like any of the following?', [
            'none',
            'all',
            'factory',
            'form requests',
            'migration',
            'policy',
            'resource controller',
            'seed',
        ], default: 0, multiple: true))
        ->reject('none')
        ->map(fn ($option) => match ($option) {
            'resource controller' => 'resource',
            'form requests' => 'requests',
            default => $option,
        })
        ->each(fn ($option) => $input->setOption($option, true));
    }
    ...
```

## まとめ

Laravel を使っていると artisan コマンドを使うことはよくありますが、引数などの細かい仕様は忘れがちです。これによりスムーズに使えるようになったり、これまで気付かなかったオプションに気付けたりなどあると思うとささやかながらも便利になったなあと思います。

こういう細かいけど質の向上に寄与するコントリビューションはいいですね。
Auraコンポーネントを使って標準画面を上書きする？


+ [カレンダーから新しいイベントを作成するときに、新しいイベントのオーバーライドの [レコード タイプ選択ページをスキップ] 設定が適用されない](https://trailblazer.salesforce.com/issues_view?id=a1p3A0000003cz0QAA)

表から新しいイベントを作成するときに、新しいイベントのオーバーライドの [レコード タイプ選択ページをスキップ] 設定が適用されない

これを読むとAuraで上書きできそう。
X番目系のCSSまとめ

最初とか最後とかXの倍数とかありきたりのは割愛。

## 最後からX番目

```
:nth-last-child(X)
```

### ある要素の最後からX番目

```
:nth-last-of-type(X)
```

## X番目以降（X番目から最後まで）

```
:nth-child(n+X)
```

### ある要素のX番目以降（X番目から最後まで）

```
:nth-of-type(n+X)
```

## X番目以前（最初からX番目まで）

```
:nth-child(-n+X)
```

### ある要素のX番目以前（最初からX番目まで）

```
:nth-of-type(-n+X)
```

## 最後からX個

```
:nth-last-child(-n+X)
```

### ある要素の最後からX個

```
:nth-last-of-type(-n+X)
```

## 最後からX番目以前

```
:nth-last-child(n+X)
```

### ある要素の最後からX番目以前

```
:nth-last-of-type(n+X)
```
Pardot/Account Engagementでのメール送信エラー

なかなか色んな情報を得ることができたので、独立したページにします。

+ [Lightningメール送信時のエラーについて](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000NFOm2)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/ae4898b4-b72d-2c00-d0a2-3e73cd691895.png)

英語モードにしていただき、英語のエラーメッセージも分かりました。

:::note alert
Your email can't be sent as built. Please correct any errors.
You don't have the necessary permissions. Contact your administrator.
:::

+ [Pardot メール環境の権限](https://help.salesforce.com/s/articleView?id=sf.pardot_eilex_permissions_reference.htm&type=5)

権限はあるとのことでした。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7cd16e8e-fedd-271d-eefe-97b768ad0dd0.png)


ユーザーがメールコンテンツオブジェクトと Salesforce CMS にアクセスできるようにするには、権限を割り当てます。Salesforce システム管理者は、必要な権限を割り当てる準備が整っています

+ [Pardot メールのユーザー権限の割り当て](https://help.salesforce.com/s/articleView?id=sf.pardot_eilex_setup_user_perms.htm&type=5)
+ [Pardot でのメールの設定](https://help.salesforce.com/s/articleView?id=sf.pardot_eilex_setup_main.htm&type=5)

そして、最終的には

HML変更終わっていなかったようでした

1.メールのプレビューを選択したところ、以下のエラーが出てきた

You don't have permission to preview emails as a prospect because you don’t have Handlebars Merge Language (HML) enabled. Your Pardot admin can help with that.

2.Pardot Merge Language (PML) からHandlebars Merge Language (HML)に変えたところ正常に動作するようになった

+ [Pardot で Handlebars 差し込み言語を使用する場合のガイドライン](https://help.salesforce.com/s/articleView?id=sf.pardot_guidelines_hml.htm&type=5)

:::note
Handlebars 差し込み言語 (HML) の差し込み項目を使用してコンテンツをパーソナライズする場合は、以下のガイドラインを念頭に置いてください。
:::


最近 Pardot アカウントにログインした場合は、Pardot メールをパーソナライズするために使用するマージ言語を Handlebars Merge Language (HML) にアップグレードできることを知らせるバナー通知が表示されている可能性があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/96179fdb-a803-b178-0d11-237e029b8449.png)


このアクションにより、メールとテンプレートをパーソナライズするために使用するマージ言語が、Pardot Merge Language (PML) から Handlebars Merge Language (HML) に完全に変更されます。

https://parquet.dev/setting-up-handlebars-merge-language-in-pardot/
2023年02月何故かベストアンサーをつけてくれない質問

[2023年2月の質問の中から整理します](https://qiita.com/Keiji_otsubo/items/cc87f3087f3e064ec1bc)

# トレイルヘッド
+ [Field Service: Customize your view](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JeLc3)
+ [Quiero hacer el reto práctico de la unidad de instalación de aplicaciones y paquetes en Playground](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Jg1wO)
+ [I am getting an error when submitting my Trailblazer joutner app](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000NFGkh)
+ [Bom dia! Estou com este erro e não consigo resolver. Alguém poderia dar uma luz? Obrigado!](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000Jg4M2)
+ [Olá, algúem pode me dizer qual o nome da conta na última etapa do projeto?](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JgG00)
+ [I got an error while doing this basic trail Adding a method to class, As I am a beginner I am not able to figure out what was the issue that I have to re-solve.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JgHyH)

# 数式

+ [Want only system admin profile to be able to make changes to the account owner field.](https://trailhead.salesforce.com/ja/trailblazer-community/feed/0D54S00000JgBIB)
住所型のカスタムフィールドを使う



+ [Validation Rule on Custom Address Field](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Jg4fZ)

まずは有効化しないと住所型は使えない。
+ [Enable Custom Address Fields](https://developer.salesforce.com/docs/atlas.en-us.240.0.caf_dev_guide.meta/caf_dev_guide/caf_dev_manage.htm)

To enable Custom Address Fields in Setup:
1. In Setup, in the Quick Find box, enter User Interface, and then select User Interface.
2. In the Setup section, select Use custom address fields and save your changes.
After you enable custom address fields, the Address data type is available when you add a field via Object Manager.

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/48ab47b3-167f-70a6-c14a-4b77ad7e2784.png)

```
Property_Address__City__s
Property_Address__Street__s  
Property_Address__PostalCode__s 
Property_Address__CountryCode__s 
```
【図解で覚える】Python のエラー出力

Python のエラー出力ついて備忘録を残します。

記事内のコードは Python3.8.6 で動作確認しています。
Python の例外についてもっと詳しく知りたい方は以下の公式ドキュメントも併せてご参照ください。

https://docs.python.org/ja/3/tutorial/errors.html

https://docs.python.org/ja/3/library/traceback.html


# 例外オブジェクトのキホン

Pythonではエラーハンドリングを次のように行います。

```python
try:
    # 危険な処理
except Exception as e:
    # 例外処理
```

`try` 句で 発生した **例外オブジェクト** は `except Exception as e:` の `e` に格納されます。格納する変数名は任意のもので構いませんが、一般には `e` が用いられている印象です。以下本稿では 例外オブジェクト を `e` と表現します。

:::note
公式ドキュメントでは 例外オブジェクト を `N` `identifier` `err` `inst` としている箇所もあります。また、`as e` の記述は必須ではありません。
:::

`e` は常に `BaseException` クラスを継承したインスタンスを格納します。


# 例外サンプル

## 例外オブジェクト

例外オブジェクトを用いることでシンプルな情報を取得することが可能です。

```python
>>> 1/0
# Traceback (most recent call last):
#   File "<stdin>", line 1, in <module>
# ZeroDivisionError: division by zero
```

```python
try:
    1/0
except Exception as e:
    print(e.__class__.__name__) # ZeroDivisionError
    print(e.args) # ('division by zero',)
    print(e) # division by zero
    print(f"{e.__class__.__name__}: {e}") # ZeroDivisionError: division by zero
```

![Fig1_ExceptionObject.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739387/455d22f1-68a0-9af5-d136-e4adaf5a4de4.png)


基本的に個人開発で必要なのは **例外名** と **その説明** 程度かと思いますので以上で十分かと思いますが `Traceback ...` の部分の取得についても調べたので説明します。


## `traceback`

`traceback` は システムトレースを取得するための標準ライブラリです。このライブラリを使用することで `Traceback ...` の部分を取得することができます。基本的に戻り値は `str` ですので、トレースの結果に応じて処理を分岐させるためには細かな文字列操作が必要となります。

![Fig2_StandardLibraryTraceback.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739387/27b31dc4-30ad-41e5-cfb2-c118d1aac378.png)

トレースを取得する上で必要なメソッドは図に示した通りです。図中では省略していますがそれぞれのメソッドは以下の通りに引数を要求します。

```python:main.py
import sys
import traceback

try:
    1/0

except Exception as e:
    
    # 発生中の例外に関する情報を取得する
    etype, value, tb = sys.exc_info()
    
    traceback.format_exception(etype, value, tb) # list[str] を返す
    traceback.format_tb(tb) # list[str] を返す
    traceback.format_exception_only(etype, value) # list[str] を返す
    
    traceback.format_exc() # tuple[str] を返す
```

```python:一部抜粋
print(traceback.format_exception(etype, value, tb))

# 出力（見やすいように整形しています）
['Traceback (most recent call last):\n',
 '  File '
 '"c:\\...\\main.py", '
 'line 5, in <module>\n'
 '    1/0\n',
 'ZeroDivisionError: division by zero\n']
```

このように `traceback` のメソッドを実行すると改行文字 `\n` を含めた `list` が返されます。
例では `traceback.format_exception(...)` を取り上げましたが、他二つのメソッドについても同様です。

### `traceback.format_exc()`

`traceback.format_exc()` というメソッドも用意されています。このメソッドは一切の引数を取りません。内部的に `sys.exc_info()` をアンパックして `traceback.format_exception(...)` に渡す省略表現です（[参考](https://docs.python.org/ja/3.8/library/traceback.html#traceback.format_exc)）。より簡潔に記述することが可能です。

![Fig3_BuiltInSyntaxSuger.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/739387/21bc3cfe-bbb4-2859-ea37-4078d94655cc.png)

:::note
単に `Traceback ...` を記録するだけの場合は `traceback.print_exception()` 等のメソッドが存在します。
| リストで取得する | ターミナルやファイルに出力する |
|:-:|:-:|
| `format_exception()` | `print_exception()` |
| `format_tb()` | `print_tb()` |
| `format_exception_only()` | 該当なし |
| `format_exc()` | `print_exc()` |
:::
ちゃんと知ろう！データベースでよく聞くDBMSのあれこれの話

未経験からエンジニアになりたい人は、プログラミングから始める人が多いと思いますが、
エンジニアの仕事は、プログラミングだけではありません。そして、プログラミングだけでは、エンジニアになれません。同時にプログラミングが苦手でも、システム構成や開発の流れを理解するとエンジニアに近づきます！
今回はDBMSについて更に詳しく調べてみましょう！

![インスタスライド_202301172.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/72a4a21e-9478-66ec-bc02-0f9e86d8e7b7.gif)


# DBMSについて
　DBMSとは DatabaseManagementSystem
　データベースマネージメントシステム

# DBMSのイメージ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/015a5127-abed-cc93-8d63-b9d61c276274.png)

# DBMSについて
利用者は、DBMSを介してテーブル定義やデータの変更、追加、削除などの操作を行います

- データベースは、管理単位として、複数生成する事が可能
- データベースの中に複数テーブルを保有する。
- ログファイルは、データベースの障害回復のためのトランザクションログである
- ワークファイルとは、ソート等を行うためのテンポリー領域を指す。

# DBMSの種類
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23130/24550e10-ce0b-5bb1-07a1-be0dea26327e.png)

# まとめ
ーDBMSとはDatabaseManagementSystem

ーDBMSを介してテーブル定義やデータの変更、追加、削除などの操作を行います

ーオープンソースや有料のものがある

ーMySQL,Oracle等色々なDBMSが存在する

# 最後に
未経験の皆さん、若手エンジニアの皆さん、勉強方法について悩みがあればなんでも気軽に質問して下さい！
これからも記事を書いていきますので、モチベーションアップのためフォロー、イイねお願いします。
Chatter に"Poll" Tabが表示されない

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/e33d33f5-ebf4-d51e-de31-d35d279d9bc2.png)

+ [Chatter is not showing "Poll" Tab.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8iyRSAR)
+ [Ability to Chatter about and follow a Report and Dashboard](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8rRrSAJ)
+ [Now for a little fun: Post something to Chatter, and include an inline image in your post. Remember, post to the Chatter feed in your Trailhead Playground, not your company’s Salesforce org.](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000Jg47p)

:::note
Can you check the Global Publisher layout to see if the 'Post' is added?

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/74c9f223-ba3d-d58b-4d6f-38ff6df00baa.png)
:::


# Emails are not showing in chatter feed item

+ [Emails are not showing in chatter feed item](https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000O8Ho2SAF)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/88ba330f-24d8-2a6e-4bb5-68947b21df1b.png)

:::note
refer https://help.salesforce.com/s/articleView?id=000386458&type=1
:::


# Pollのaskボタンがグレイアウト

+ [Problem with creating a Poll. In my playground this options not working. After filling out a form the button does not activated](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX000000nJ9Z)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/9614f3a5-8460-b08c-25d7-747b5a40664f.png)


:::note
Found the issue, because she was copying and pasting the text from the module challenge that is why the ask button was not activivating. So all is good now, but in future maybe you should mention that not to copy and paste or fix the issue so that a copy and paste option would work.

https://trailhead.salesforce.com/trailblazer-community/feed/0D54S00000A8p2BSAR

I discovered i actually had to type the details rather than copy pasting the information over.


https://trailhead.salesforce.com/trailblazer-community/feed/0D54V00007T46dySAB
:::

# question ボタンがない

+ [Playground Chatter Poll problem](https://trailhead.salesforce.com/trailblazer-community/feed/0D5KX00000SXyvp)

:::note alert
Try adding a question to your page layout 

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/328136/7f074763-a9b9-4b57-9223-aca113a0745b.png)
:::
navigator.taintEnabled()ってなんだ？

かつては、JavaScriptの`navigator`オブジェクトのプロパティには`taintEnabled()`という関数がありました。

# TL;DR
JavaScript 1.2において、Data Tainting（データ汚染）をチェックする機能が有効か無効かをチェックするためのものだったようです。
現在のブラウザ(Safari 14、Chrome 108)では、すでに削除されています。

# リファレンスを見てみる
[MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/taintEnabled) によると、
>Tainting was a security method used by JavaScript 1.2. It has long been removed; this method only stays for maintaining compatibility with very old scripts.

（意訳）
> Taintingは、JavaScript 1.2で使われていたセキュリティの方式です。削除されてから長期間が経過しています。このメソッドは、非常に古いスクリプトとの互換性を保つためだけに残されています。

# 参考ページ
[Navigator.taintEnabled() - Web APIs | MDN](https://developer.mozilla.org/en-US/docs/Web/API/Navigator/taintEnabled)
[\[Chapter 20\] 20.4 The Data-Tainting Security Model](https://docstore.mik.ua/orelly/web/jscript/ch20_04.html) - 「そもそもData Taintingってどういう概念？」ということについて、英語で詳細に解説されています。気になった方はぜひご覧ください。
【Unity】知っていればよかった神技術！！ - WebAR編 -

![qiitaWebAR.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3118254/64a9e271-8330-df34-cd28-4639132b5fe2.png)


# はじめに
僕は、都内の某私立<font color="red">文系</font>大学生の１年生です。
UnityとC#でARコンテンツ開発を主として活動しており、サブでWebアプリ開発も行っています。僕についての紹介はこちらから！
https://qiita.com/RyuseiItoh/items/80cc0f3c419b0d5a5e6b


# WebARとは
WebARは、Webブラウザを使って拡張現実（AR）体験を楽しめるものです！
スマートフォンやタブレットなど、モバイルデバイスからも簡単にアクセスできます！

WebARはアプリをダウンロードしてインストールする必要がないというメリットがあります。これはARを多くの人にアクセスさせることを目的としていて、ビジネスや教育などで活用されることが期待されています！

# WebARの作り方をざっくり解説！！
### 簡単なフローを紹介します！
**（１）開発環境を構築する：HTML、CSS、JavaScriptなどのWeb開発スキルとARフレームワーク/ライブラリを使用することが必要です！**

**（２）ARマーカーを作成する：Webカメラで認識することのできるARマーカー画像を作成します！**

**（３）3Dモデルを作成する：3Dグラフィックスソフトウェアを使用してARアプリケーションで表示する3Dモデルを作成します！**

**（４）ARアプリケーションを開発する：ARマーカーと3Dモデルを組み合わせて、HTML、CSS、JavaScriptなどを使用してARアプリケーションを開発します！**

**（５）アプリケーションをデプロイする：ARアプリケーションをWebサイトにデプロイして、ユーザーがアクセスすることができるようにします！**

これらのステップを通して開発していくすることで、WebARアプリを作成することができます！

# 　　　　    YOUTUBEでの関連動画はこちら！
<iframe width="560" height="315" src="https://www.youtube.com/embed/7oYgjMk_Vy4" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
<iframe width="560" height="315" src="https://www.youtube.com/embed/2dERIze1bVo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>

# おわりに
皆さんいつも最後までご覧いただきありがとうございます！！

諸事情により最近投稿できていなく申し訳ございませんでした！
気持ちを入れ替え頑張っていきますので応援お願いします！

本日はWebARについて簡単にまとめさせていただきました！
反響がありましたら僕の開発のフローを画像や動画付きで投稿させて頂きたいです！
**是非コメント欄にお書きください！！**
GCP触ってみた④

# Google Cloud Storage(GCS)

AWSでいうS3。
Google提供のストレージサービス。

## ストレージクラス
AWSでいうS3 Glacierとかに該当する？
以下のクラスがあるらしい

|ストレージ クラス|最小保存期間|検索料金|アクセス頻度|
|---|---|---|---|
|standard ストレージ|なし|なし|頻繁にアクセスする|
|Nearline ストレージ|30日|あり|月1回程度|
|Coldline ストレージ|90日|あり|四半期に1回程度|

## バケットの作成
```shell
gcloud storage buckets create gs://gcpstudy
Creating gs://gcpstudy/...
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/fa12f4bd-0166-436c-7805-dabf8986912e.png)

バケットが作成できたっぽいので、ペイントで作った以下の画像をアップロードしてみる

![gpic.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/e7c7627c-3833-b9a5-c4f0-de346c4c6389.png)

「ファイルをアップロード」でファイルをアップロードする
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/3bc54472-086e-8362-afd2-2377984f4b20.png)

アップロードできたので、認証済みURLをコピーしてダウンロードしてみる
(一般公開されていることを確認するためにほかのgoogleアカウントから確認)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/de9e99f7-37ba-bb26-2775-e666341f89b2.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/99dd6541-c219-b1c6-5b79-b8ef64b472e4.png)

ん？

```shell
# gpic.pngを全体公開する
gcloud storage objects update gs://gcpstudy/gpic.png --add-acl-grant=entity=AllUsers,role=READER
ERROR: (gcloud.storage.objects.update) unrecognized arguments: --add-acl-grant=entity=AllUsers,role=READER

To search the help text of gcloud commands, run:
  gcloud help -- SEARCH_TERMS
```
なぜかgcloudコマンドだと一般公開できないので、gsutilコマンドを使ってみる

```shell
# gpic.pngを全体公開する
gsutil acl ch -u AllUsers:R gs://BUCKET_NAME/OBJECT_NAME
Updated ACL on gs://gcpstudy/gpic.png
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/791140ef-2c4c-1de2-5e2a-01e164f03be5.png)

できたけど、、、なぜgcloudコマンドだとできないのか

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/cae55d81-f8d7-c160-9fe6-dfe16f92702e.png)

ヨシ！
gcloudコマンドで失敗した理由はすぐにはわからなかったので追って調べます

## 後片付け

```shell
# gcsバケットを削除する
gcloud storage rm --recursive gs://gcpstudy
Removing objects:
Removing gs://gcpstudy/gpic.png#1675272192560106...
  Completed 1/1
Removing Buckets:
Removing gs://gcpstudy/...
  Completed 1/1
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/704575/86092a75-53e4-e43b-f8f0-f9391d925023.png)

ヨシ！

今日はここまで、お疲れ様でした。
現役高校生　はじめてのプログラミング2023

### はじめまして

通信制高校に通う2年生です。
プログラミング学習の振り返り用に記録を残そうと思います。

### なぜプログラミング学習をはじめたのか
きっかけは主に以下の２つが挙げられます。

- IT分野に優れている高校に入学した事
- 短期・長期インターンシップに参加した事

まず「IT分野に優れている高校に入学した事」です。
高専より優れている！とまでは思いませんが、普通科高校に進学するよりも「プログラミング」に触れることが多いのではないか？と感じています。
単位の取得にも使用される、独自の通信教材で基本のプログラミングを生徒全員が自由に受講できる環境が整っています。
またワークショップ等で「プログラミング」を使用することもあるようです:computer:
このような環境に身を置くと自然に（？）プログラミングに親近感が湧きますよね！

次に「短期・長期インターンシップに参加した事」です。
実は高校1年生から現在まで、3社のインターン(長期1：短期2)に参加したことがあります。
はじめての「働く」という経験で、お世話になった皆様には大変ご迷惑をおかけしてきたと思うのですが
その中の1社（短期）がプログラミング学習をはじめることに直結しています。
あまりにも衝撃的で思い出すだけで胸が締め付けられるようなと〜っても苦い思い出ですが、
（色んな意味で）貴重な経験ができ、今後生きる上での財産になったのかな！と今は思えています...:relieved:

### 学習の進捗

現状はHTML,JavaScript,CSSの基本が習得できている状態です。
苦手に思う箇所はあるのですが、定期的に復習をすることで徐々に苦手意識がなくなっているので
（やったー！）現状に満足することなく引き続き復習に取り組みます。

### 今後の学習
今後はIOSのアプリ開発のためのSwift、投資判断に活かすためのR、汎用的なPython
を中心に学習を進めていきたいな..！と思っております。
プログラミング言語以外にも数学や英語の知識も深めることに注力していきたいです:star2:
【AWS】SQSのメッセージ送信を一瞬で大量実行でも対応させる

# 何をしていたのか
AWS環境で、ラムダからラムダの呼び出しをする機能を作っていて、
最初は直接ラムダからラムダを呼び出していたが、
SQS経由でラムダの呼び出しをすることになった。

ポリシーやトリガーの設定とかいろいろしてとりあえずSQSメッセージを送信したらトリガーが発動してラムダを呼んでメッセージとしてパラメータも渡すことができた。

ただ、ここで苦戦したことがあった。

## 大量SQS送信で苦戦
一瞬で大量の送信を行ったとき、送信したメッセージの数に対して受け取れたメッセージの数が少ない。。。
SQSは今の実装で初めて知って調べながら実装していたが、SQSというのはメールみたいに一回送信したら必ず1回すぐにそのまま受信できるようなものではない。

①ショートポーリングからロングポーリングへ変更
→ショートポーリングはリクエストに対して、キューにメッセージが存在していなくてもレスポンスをすぐ返すメッセージ取得方法のため、メッセージが取得できないこともあるし、コール数も多いのでこれをやめて費用削減する。
それと比べてロングポーリングは、SQS内のすべてのサーバにクエリを実行するため、必ずメッセージを取得することができる。また、ショートぽリングに比べてAPIコール数を抑制できるため、コストを低減することができる。

②次に、最大受信数の変更
キューの設定画面に「最大受信数」というがあるが、これは「リトライ数」でもあり「文字通り1度の受信でいくつのメッセージを受信するか」でもある。
この設定は1～1000を設定できる。

この公式ドキュメントにもあるように、最大受信数を1にするのはおススメしないと書いている。つまり、メッセージの受信が失敗するのはよくあることで、ある程度のリトライ数を覚悟してねということだった。
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/working-with-messages.html
![image_720.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/11f91616-f3ac-4a66-56d3-593c859a8001.png)

もしラムダ全体をfor文とかで囲って一瞬で100回送信する処理を書いてみたところ、これが3とか10だと全然安定しない。
このように一瞬で大量の送信を行う場合は、ある程度の最大受信数を指定する必要がある。
いったん最大の1000にしてみる。

## 今度は、受信数が多すぎ！！
送信した分だけメッセージは受け取れるようになったが、今度は重複したメッセージ受信がいっぱい！

そもそもなんで重複するものが受信されるんだというお話だが、大量実行とかすると以下の内容に該当してしまうんか・・・？
https://docs.aws.amazon.com/ja_jp/AWSSimpleQueueService/latest/SQSDeveloperGuide/working-with-messages.html
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/179803/921468f4-d502-c5ea-d2ef-6c654e612bfd.png)


# メッセージを削除処理を追加
受信のたびに複数のメッセージを受け取るので、for文などで取り出してdeleteMessageして削除する。
そのために必要な設定は、可視性タイムアウトを0より大きくする。このタイムアウト時間がないと削除できない。


# 最後にやるべきことがある　
実行してみたら、また受信数が多い。なんでなん？って思ったらひらめいた。

削除機能を実装したあとは問題ないが、実装前に実行した分のメッセージはキューに残ったまま。つまり、今実行したとき、30分前に実行したメッセージも時間差で受信がすることになる。
つまり、キューの画面に行ってクリアする。

これでキレイな環境になった。再実行。。。
むしろ送信数よりも受信数が少なくなった！！
これはバグではない。一回の受信で複数のメッセージを受け取れるから、受信の回数は少ない。
※1回で取り出せるメッセージの数は最大受信数の設定で指定可能



# 感想
メッセージ送信ではあるが、メールみたいなものを想像するとうまくいかない。
SQSは思ったより複雑だったがもう安定して送受信できるようになっているはず！
エンジニアが副業で稼ぐならココナラはおすすめ！出品方法、稼ぐコツ、ポイントまとめ！プログラミングで稼ぐ!

あなたのスキルで小遣い稼ぎに挑戦！稼ぎながら更にスキルアップができます

現役エンジニアの筆者が、スキルを活かしてココナラでサービス出品して稼いだ経験、ノウハウをブログにまとめました。
登録は無料、簡単に出品できます。

詳しくは以下ブログをチェックしてみてください↓

https://toarusw.com/coconara/service-provide/


筆者のココナラでの提供サービスはこちら。
MATLABやC言語などのプログラミング相談、作成、などのサービスを提供しています。
※ちょっと忙しくなっているので少し時間をいただく可能性があります
よければご依頼お待ちしております^^

https://coconala.com/users/2061836
GASでXML形式のデータをpostするときの注意点備忘

# 最終的な成功物
いろいろ試したのですが、僕の場合（portersというツールのAPI）はこれでうまくいきました
```js
  var header = {
    'X-porters-hrbc-oauth-token': *ここにToken*,
    'Content-Type':'application/xml; charset=UTF-8'
    }
 
  var option = {
    method: 'post',
    payload: *ここにXML形式のデータ* ,
    headers: header,
    contentType:'application/xml; charset=utf-8'
  }
  var res = UrlFetchApp.fetch(url,option)
```
# ポイント
### 1つめ
`'Content-Type':'application/xml;`の部分は、`'Content-Type':'application/json;`にしたりして試しましたが無理でした。`~xml`とするのが正解ですね
### 2つめ
`payload`の部分は`data`って書くのかなと思っていましたが、これも`payload`が正解
### 3つめ
XML形式のデータについては改行やスペースを入れるの厳禁です。
```js
var data = `
  <Job>
    <Item>
      <Job.P_Id>-1</Job.P_Id>
        <Job.P_Owner>1</Job.P_Owner>
          <Job.P_Client>12345</Job.P_Client> 
        　<Job.P_Memo>これは、テストメモになります　ほげほげ</Job.P_Memo>   
  　</Item>
  </Job>
`
  var header = {
    'X-porters-hrbc-oauth-token': *ここにToken*,
    'Content-Type':'application/xml; charset=UTF-8'
    }
 
  var option = {
    method: 'post',
    payload: data,
    headers: header,
    contentType:'application/xml; charset=utf-8'
  }
  var res = UrlFetchApp.fetch(url,option)
```
こんな感じで`data`を定義すると、エラーになりました。
見ての通り`data`の中に空白やら改行やらがあるためです。

空白や改行は
```js
data.replace(/[\r\s]+/g,'')
```
で一括で消してからpostしました

:::note
※もし複数行テキストエリアデータなどで改行を消したくない場合は
 ```js
.replace(/[\r\n]+/g,'&#10;')
 ```
ってしてXML用の改行コードに置換してね
:::
ツールの価値には、売上向上、コスト削減ともう1つの指標がありそうな話

# 社内ツールを検討するときふと思った
うちの組織では、どんなツールも「費用対効果が認められるなら導入OK」ってなってる。
SlackとかNotionとか、どんどん普及させたいなーと思っている中で
それらの費用対効果ってものを考えていました。
そんなとき、思ったことがあるので書いてみます。

# ツールの価値を金額換算すると？
新しくサービスを購入したり、自分のツールの売るときなど、
頭を悩ませることの1つが、そう**価格**。

このツールには、**いくらの価値がある**のか、
これから導入しようとしているツールの**費用**対効果はどのくらいか
などなど。
サービス価値の評価方法は考え所。

# 金額換算の方法2つ
まず1つ目に挙げられるのが、**パフォーマンスベース**の考え方。
「このツール、サービスを使うことで、○○円余分に稼ぐことができた」
となれば、そのツールの価値は、少なくとも○○円以上はあると思います。

もう1つが**コスト削減ベース**の考え方。
「このツール、サービスを使うことで、○○時間分の作業が削減された」
となれば、その時間を時給換算してツールの価値をはかることができそうです。

# もう1つ考え方があるのではないか
全てのツールは、上記2つだけで単純に価値をはかることができるのでしょうか。
例えば、以下のような場合を考える
```
ある業務に月30時間（時給換算2000円*30h=6万/month）かけています
※使っているシステムが重い、UIがわかりづらいなどで、
　この業務は非常に煩雑でストレスフルなものと仮定

あるツールを導入すると、スムーズでわかりやすいUIを使うことができ、
ストレスもなくなり、この業務が20時間（4万円分）削減できます
このツールの金額は月に5万円です
導入しますか？
```
単純にコスト削減ベースでやったら、費用対効果はマイナス。
30時間かけてやった方がいいことになります。が本当にそうかなと。


煩雑でモチベが下がるような業務の場合、
理論上30時間で終わるように見えて、だらだらと業務をしてしまいそれ以上の時間がかかってしまったり、
モチベが上がらなくて手を付けるまでに時間がかかってしまったり
この業務にストレスを受けすぎて他の業務が間延びしたり、パフォーマンスが落ちたり
結果として見落としやミスが生まれたり
そんな経験はないですかね。
（僕もうまく言語化できないが、ある気がする）

逆に使いやすいツールに代替することで、
いつも以上に仕事を頑張ろうという気概になれたり、
いい意味で余計に業務にマインドを割け、パフォーマンスが上がったり。

こういったモチベーションベースの金額換算も加味すれば
上記の例のツールに5万円払う価値はあるんじゃあないかなと思ったり。

# まとめ
ツールの価値を評価するにあたって、
- そのツールが余計にいくら分のパフォーマンスを生み出せるか
- そのツールがいくら分の時間を削減できるか

の他に
- そのツールで業務へのモチベがどのくらい上がるか

も考えたほうがいいかもなということです。
ここが金額換算できればもっとわかりやすいんだけどなあ
📗未経験エンジニアが学習においてつまずいたポイント

# JavaScriptの学習を始めて2ヶ月弱
Udemyの教材を使って、フロントエンドエンジニアに必要な知識を学習しています。

https://www.udemy.com/course/the-web-developer-bootcamp-2021-japan/

12月頭から学習を始めて、総学習時間は１００時間を超え、セクションも残り１０％くらいになってきました。
これまでの学習でつまずいたポイントを残しておきたいと思います。

### 1\. テンプレートリテラル
JavaScriptのオブジェクトデータへアクセスし、それをテンプレートリテラルを使ってstringで別の変数へ代入するのに手こずった。一つ一つ見れば簡単だが、問題が重なると出来ることも出来なくなってしまう。エラーが出ている原因を一つずつ潰していく重要性を感じた。

### 2\. 関数（関数式、高階関数、アロー関数）
いまだに理解しきれていないが、何度も見返しながら徐々に理解を深めていきたい。アロー関数は学んだはずなのに、関数をみるたびに初めて見た感覚に陥る。構造の理解が難しい。

### 3\.　非同期処理
この辺りから、なんとなくの理解で次に進んでいき、後々のExpressやMongoDBなどでわからないことが重なり、爆発した。
大変ピンチだったが、わかることわからないことを分けて、一つ一つ復習する機会を作った。それを繰り返し、どんどん理解を深めていく感じ。
わからないことからわかること・わからないことを分別して、、、みたいに繰り返して、頭を整理していった。

## まとめ
今の段階ではほとんど読めないが、基本ドキュメントを読めるようになればなんとかなりそう。あとエラーに臆せず、原因を追求し切れるか。また、エラーの原因は大体タイポ。。

今の所、ゼロからコードを書いていくのはとてもじゃないが厳しい。まずは書いたor書いてあるコードの内容を理解・説明できるようになっていきたいです。