技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

Salesforce 開発者の JavaScript スキル(5)

trailhead.salesforce.com

Salesforce DX 環境の設定

  • クラッチ環境: SalesforceDX で操作するメインターゲット環境。短期間生存する環境を即興で作成、削除できる。
  • 開発者ハブ (Dev Hub) 組織 : スクラッチ環境を作成・管理する親組織

このハンズオンは スクラッチ組織作成機能を On にしてコンソールから接続するテスト。
尚、CLI 空の認証をするには、パスワード再発行手続きでブラウザからログインできるようにする必要あり。

DevHub 起動して f:id:white-azalea:20211020214512p:plain

パスワードリセットしときます f:id:white-azalea:20211020215612p:plain

接続時のコマンドは sfdx auth:web:login -d -a DevHub 名称は好きにして

ID/Pass を入力すると f:id:white-azalea:20211020220131p:plain

続きを読む

Salesforce 開発者の JavaScript スキル(4)

コマンド-ラインインターフェース | Salesforce Trailhead

やってみたら内容薄かった件…裏で LSTM の勉強を進行中…

うーん Prepare for your Salesforce JavaScript Developer I Credential Trailmix このTrailやってるはずなのだけどJavaScript関係なくね?(汗

コマンドラインインターフェースの概要

trailhead.salesforce.com

基本的に Salesforce 開発の操作はコマンドラインが根底にあって、VSCodeSalesforce 組織とやり取りする部分は原則これを通してる。
Windows の CMD とか、Linux 計のターミナル起動は知ってるよね?
因みに、ターミナルはコマンドラインウィンドウであって、その中でデータを処理するのがシェル。BashとかZshとか色々あります。

感想:内容うっすいなぁ

コマンド構造とナビゲーションについて

trailhead.salesforce.com

$ sfdx force:org:delete -u test_XXXXX@xxxx.test.com

説明では

  • sfdx force:org:delete をコマンド
  • -u がフラグ
  • test_XXXXX@xxxx.test.com を引数

と説明してます。
SFDX についての説明だからそうなってるんですよね…こういう標準環境との言葉の使い方の違いが割と嫌い…
シェル的には sfdx がコマンド、force:org:delete 以降は全部引数なんだよねぇ…

Bash 等の使い方、基本コマンドは こういうの 見ると良いと思う。

コマンドラインツールの概要

trailhead.salesforce.com

開発環境を整えるTrailかな

とのこと。
Trailではコマンドラインツールをパッケージインストールしてるみたいですね。

補足として、

  1. nodejs をインストールしたら npm install -g npm コマンド打っておくといい。(npm コマンドのアップデート)
  2. Salesforce CLI インストールは npm install sfdx-cli --global でインストールした方がいい(nodejs と運命を共にさせることができる)
  3. VSCode のターミナル起動は、Win「Ctrl+@」Mac「Command+@」で起動できる

Salesforce 開発者の JavaScript スキル(3)

trailhead.salesforce.com

あー来ちゃったよ日本語じゃないやつら(翻訳追いついてない奴ら)

Get Started with Modern JavaScript Development

モダンな JavaScript を始めよう。
ざっくり JavaScript の歴史を説明している。

重要なのは ES6 (ES2015 以降は年号)以降で一気に真価が加速した点だ。
モジュール化とかなんとかもこの辺から。

昨日が分からなくなったら ここ でどのブラウザが何に対応してるか分かる。
Trail では分からなくなったら Codepen で試そうとか言ってるけど、個人的に JSFiddle の方がシンプルで好きだ。

Explore New Syntax in JavaScript ES6

ES6 の新しい書き方を見ていこう。っても

var の様な関数スコープは昔からあるが、ブロック({ ... } で囲まれた区間のこと)をスコープに持つ const, let の紹介。
展開書式の紹介とかその程度

let numbers = [1, 2, 3, 4]; 
let [one, two, three, four] = numbers;
console.log(one);

とか

const APPLE = {
  type: 'red delicious',
  color: 'red',
  size: 'large'
}
const { type, color } = APPLE;
console.log(color);

とかアンパック構文(destructuring syntax)として使える。

ブロックスコープは管理が楽でええわー

Understand JavaScript Functions

JavaScript の関数を理解しよう

let result = (i,j) => i+j; 
console.log(result(2,3));  

こうじゃ!(関数はオブジェクトなので変数に突っ込めるで)というのと

let message = {
  hello : 'Hello',
  names : ['Sue', 'Joe'],
  showMessage: function() {
    this.names.forEach(function(name) {
      console.log(this.hello + ' ' + name);
    });
  }
}
message.showMessage();  

this 分かりづらいでしょ…( this.hello が undefined になってる)。

f:id:white-azalea:20211011222217p:plain

JavaScriptthis はその処理の呼び出し元を意味するので、

    this.names.forEach(function(name) {
      // この中の this は 「this.names」変数の意味になる
    });

なので

let message = {
  hello : 'Hello',
  names : ['Sue', 'Joe'],
  showMessage: function() {
    let self = this;
    this.names.forEach(function(name) {
      console.log(self.hello + ' ' + name);
    });
  }
}
message.showMessage();  

が正しい書式になる。しかし、クロージャ構文( => )を使うと、宣言したスコープの this を内部でもバインド(束縛)するので

let message = {
  hello : 'Hello',
  names : ['Sue', 'Joe'],
  showMessage: function() {
    this.names.forEach(name => {
      console.log(this.hello + ' ' + name);
    });
  }
}
message.showMessage() 

これは意図通りに動く。

f:id:white-azalea:20211011222237p:plain

因みに可変長引数はこんな感じで定義・アクセスできる。

function testFunc(arg1, ...multiple) {
    console.log(arg1);
    console.log(multiple[0]);
    console.log(multiple[1]);
}
続きを読む

Salesforce 開発者の JavaScript スキル(2)

trailhead.salesforce.com

オブジェクトの作成

  • オブジェクト作成は {} で行けるけど、実際にゃ Object.create() を使っとる。
  • プロトタイプ表記…懐かしい class が出るまではこうしてオブジェクト定義してました。
function Bike(gears, startGear) {
  this.gears = gears;
  this.currentGear = startGear;
}
Bike.prototype.changeGear = function(direction,changeBy){
  if(direction === 'up') {
    this.currentGear += changeBy;
  } else {
    this.currentGear -= changeBy;
  }
}
const bike = new Bike(10, 3);
console.log(bike.gears); // 10
console.log(bike.currentGear); //3
bike.changeGear('up', 1);
console.log(bike.currentGear); //4
  • オブジェクトへのプロパティと関数の代入
    • サンプルコード見れば分かる
const bike = {
  frontGearIndex: 0,
  rearGearIndex: 0,
  transmission: {
    frontGearTeeth: [30,45],
    rearGearTeeth: [11,13,15,17,19,21,24,28,32,36]
  },
  calculateGearRatio: function() {
    let front = this.transmission.frontGearTeeth[this.frontGearIndex],
        rear = this.transmission.rearGearTeeth[this.rearGearIndex];
    return (front / rear);
  },
  changeGear: function(frontOrRear, newValue) {
    if (frontOrRear === 'front') {
      this.frontGearIndex = newValue;
    } else {
      this.rearGearIndex = newValue;
    }
  }
};

....この章ざっくりいうと、JavaScript においてオブジェクトとは、関数(function)もしくはハッシュ({...})でしかなく、関数はプロトタイプを持つ。
で、どっちも実態はハッシュなので、後からプロパティだろうがメソッドだろうが名前を付けて追加・更新・削除ができてしまう。

クラスと JavaScript

class キーワードで大分他の言語と似たような書き方ができるようになってる。
Lightning Web コンポーネントLightningElement 継承して作る…この章ではこのくらいの認識。

続きを読む

Salesforce 開発者の JavaScript スキル(1)

JavaScript の基本概念について

trailhead.salesforce.com

  • JavaScript の概要、使用する理由、使用法
    • 概要だけざっくり
      • もともとJSはHTMLを軽く動かすオプション的扱いだった
      • そのうち動的ページができてきた。サーバ(Salesforce)で処理する VF がそれ。
      • そのうち JS が ECMA 準拠で高機能になって、画面側で色々処理したり画面作れるようになった
      • これが LWC
  • JavaScript ランタイム テストに出る
    • イベントやAPIの応答などがあると、そいつはキューに一旦確保される
    • JS 実行ランタイムは、キューから一つづつそれを拾って、スタックメモリで実行を行う
  • JavaScript という言語 個人的には Apex より馴染みがあって好きな言語です。
    • 絶えず変化してる。ウン、毎年のように更新されてて、最新は ES2021/ES2022を知ろう | フューチャー技術ブログ かな。
      ブラウザはガンガン追従してるよ!
    • API は普遍的に採用されているわけではない
      ブラウザの実装状態によって動かなかったりするね!個人的に一番ひどいのは iOSSafari がバグ多くでう〇こですね!
  • 絶対に知っておくべきこと
    • 大文字と小文字を区別する
      当たり前だ!というのは他言語ガンガンやってる人。「え?」と思うのは Apex 開発者。
      Apex は大文字小文字は関係ない
    • var, let, const キーワードは必須。
      let, const はレキシカルスコープ(他言語と大体同じスコープ+変数寿命)だけど、var は Functionスコープ って言って関数の実行単位のスコープを持つっていう分かりにくいヤツ。
      JavaScriptのスコープ総まとめ | 第1回 スコープの種類とその基本 | CodeGrid この辺がおすすめ。
    • 暗黙的な型の強制変換 テストに出る
      普通に parseInt とか使いましょう。
      let num1 = 9 * "3"; // 27 とかいう PHP 臭い挙動
      let num2 = 9 + "3"; // 93 でなぜか文字列結合wwww
    • Boolean 判定がかなりファジー
      false == ""; // true とか普通に行ける。
      型まで完全に比較するなら false === ""; // false とか使うべき。
      因みに !== とかもある
    • false とみなされる値集
      • false
      • 0
      • ""'' (空文字)
      • null
      • undefined (初期化してない変数や、存在しない変数名を指定したときの値)
      • NaN (算術エラー: 0 で割ったとか)
    • this の意味が違う
    • 関数は値
      関数型言語やってる人御用達。「関数が第一級オブジェクト」という小難しい言い方できる。
      要するに、return に関数を返すことも、引数にすることもできる(高階関数という)。
続きを読む

LSTM の概要

時系列データを利用するDeepLearningの一種。

LSTM = Long short-term memory
以前やってた RNN の一種だけど、記憶のやり方が異なる。

RNN はこれね…

white-azalea.hatenablog.jp

LSTM は以下のようなセルとゲートがあり、それぞれのゲートに学習パラメータを持ってる。

f:id:white-azalea:20210927224336p:plain

  • 記憶セル : 過去の記憶を保持する
  • 忘却ゲート : 過去の記憶を消す割合を調整する
  • 入力ゲート : 新しい記憶を追加する割合を調整する
  • 出力ゲート : 記憶セルの内容を出力に反する割合を調整する

加えて記憶セル → 積の間の Tanh も学習パラメータがあるので、学習パラメータが計4か所もあるという…

忘却ゲート

忘却ゲートはこんな感じ


A^{(t)}_0 = \sigma ( X^{(t)} W_0 + Y^{(t-1)} V_0 + B_0 )
  •  A^{(t)}_0 は活性関数後の値。
  •  \sigma シグモイド関数
  •  X^{(t)} は現時点の入力。
  •  Y^{(t-1)} は前回の結果出力。

W,Bは重みとバイアス。これは前回までもそうだったので今更である。
入力ゲートと新しい記憶データの $Tanh$ はこんな感じになる

入力ゲート


A^{(t)}_1 = \sigma ( X^{(t)} W_1 + Y^{(t-1)} V_1 + B_1 )

まぁ内容は見たままやね。

新しい記憶データは


A^{(t)}_2 = tanh ( X^{(t)} W_2 + Y^{(t-1)} V_2 + B_2 )

こいつらって結構見たままなのよね

出力ゲート


A^{(t)}_3 = \sigma ( X^{(t)} W_3 + Y^{(t-1)} V_3 + B_3 )

というか活性関数通す連中だから基本楽ですよね。

しかしこれを微分するのか…気が滅入るな…

確率周りの勉強続き

大数の法則

完全に一様分布を持つデータは回数を重ねるほど平均値は期待値に近づく

import numpy as np
import matplotlib.pyplot as plt

times = 1000
sample_array = np.array([1, 2, 3, 4, 5, 6])
number_cnt = np.arange(1, times + 1)  # 1, 2, 3, ... 1000

for i in range(5):
    # ランダムで 1000 回サイコロを振った累積値 3, 1, 5... とサイコロの目が出るなら 3, 4, 9... というリストになる
    p = np.random.choice(sample_array, times).cumsum()
    # 試行回数で各値を割って表示する
    plt.plot(p / number_cnt)
    plt.grid(True)

f:id:white-azalea:20210915224558p:plain

中心極限定理

サイコロ等を投げる回数 N が増えれば増えるほどに標本平均が正規分布となっていく法則

def func_central(N):
    mean_array = np.array([])
    for i in range(1000):
        # ランダムで N 回サイコロを振った累積値リスト
        cum_var = np.random.choice(sample_array, N).cumsum() * 1.0
        # 累積値の最終値 / サイコロを振った回数 を平均に突っ込む
        mean_array = np.append(mean_array, cum_var[N-1] / N)
    # 平均値の出現回数をヒストグラムで表示
    plt.hist(mean_array)
    plt.grid(True)

func_central(4)

f:id:white-azalea:20210915224712p:plain f:id:white-azalea:20210915224732p:plain f:id:white-azalea:20210915224757p:plain f:id:white-azalea:20210915224816p:plain