技術をかじる猫

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

組織と経営戦略の勉強

会社について

法的には会社法による「法人」と考えるのが正しく、会社の形態は主に以下

  • 株式会社
    普通一般の会社。所有と経営を分離した組織。
    会社を所有するのが株主で、出資した責任を負う代わりに配当金をもらう。一方で会社の経営には参加せず、株主総会での重要事項を決議していく。
    経営陣は 取締役会、会計参与、監査役監査役会、会計監査人、委員会があって、定款 1 の合意の上で設置していく。
  • 持分会社
    株式会社以外の以下のパターンの会社。

尚昔あった「有限会社」は法律上は既に存在しない。

経営組織

典型的組織構造は以下の物がある

  • 職能部門別組織
    営業部門、仕入部門、製造部門、経理部門、人事部門など、職能によって区分けされた組織。
    ごく一般的組織。
  • 事業部別組織
    エリア、顧客、製品別を単位に組織分割する組織。
    各組織を独立採算にするなど、自己完結が可能な組織構造。
    指揮命令系統が一元化されてるメリットはあるが、専門技術を持った要員が各部門に冗長配置されてるなど、全体最適化ができず、セクショナリズムに陥りやすい。
  • SBU(Strategic Business Unit)
    戦略的事業単位にプロジェクトチームを作る組織形態。
    構成員が複数のチームに所属することになるので、指揮系統のコンフリクトが起るケースがある。
  • カンパニー制組織
    事業部別組織に部門の独立性、市場原理まで持ち込んだ組織体制。
    社内分社制、疑似会社組織とも言う。
    要するに外側は同じ会社だけど、中は複数の小さな企業で競い合ってる的な状況。
  • 持株会社
    複数の企業の株主企業で、そうした企業を統括・管理する企業。
    自らは事業を持たない。
    独占禁止法の兼ね合いで、1997 年まで日本では禁止していた。
    ○○グループ企業とかはこの配下企業。
  • 委員会型組織
    各部門の代表者を集めて定期的に会議形式で話し合う組織形態。
    合議制で、問題の発見などは早いが、全体の素早い方針転換などには向かない。
  • 執行役員
    経営管理と、事業の執行機能を分離した企業。
    役割と責任の所在が明確になっている。
    CTO (チーフテクニカルオフィサー)とか CIO(チーフインフォメーションオフィサー)とかあるのはこの手の企業。

経営戦略

「売上 N% アップ」を経営目標とすると、「目標達成のための手段」策定が経営戦略。
そこに「いつ・だれが・何を」を割り当てて行くのが計画。

有名どころで以下のものがある

  • アンゾフの経営戦略
    市場(既存/新規)と製品(既存/新規)のマトリクスを作成し、現在自社の置かれている状況を分析し、どの方向へ舵を切るか決定していく。
    製品(既存)+市場(既存)=市場浸透戦略
    製品(新規)+市場(既存)=新製品開発
    製品(既存)+市場(新規)=市場開拓
    製品(新規)+市場(新規)=多角化
  • Product Portfolio Management
    切り口が「市場成長率」と「市場占有率」の割合で分布を作って、どこを目指すかという話。
    高 金のなる木 花形 占有率 負け犬 問題児 低           高 成長率

基本的な戦略の建て方プロセスは

  1. 3-5 年の経営目標を立てる
  2. 外部環境、経営資源(内部環境)の抽出
  3. SWOT分析 2
  4. CSF(重要成功要因)の抽出
  5. CSF を達成するための方法≒経営戦略(このときコアコンピタンス 3 も実施することが多い)

事業分析には以下の段階がある。

ちょっと増えすぎて来たので個々の詳細は明日。


  1. 会社設立時に発起人全員の同意のもとで定める企業の根本原則が記載された「会社の憲法」とも呼ばれている書類

  2. Strength (自社の強み) Weakness (自社の弱み) Opportunity (機会:外部環境) Threat (脅威:外部環境) の分析。

  3. 企業独自のノウハウや技術で、これが利益の源泉になるもの

Salesforce 以外の LWC

目次

プロジェクトの作成方法

ざっくりアプリケーションの雛形を作成します。
※ このやり方は 2022/03 としてはやや古いやり方です。最新版は、公式レシピ含め、Windows11 で正常に動作しなかったため、説明を諦めます。

$ npx create-lwc-app account-book

⚡⚡⚡⚡⚡  Lightning Web Components  ⚡⚡⚡⚡⚡
? Do you want to use the simple setup? Yes
? Package name for npm account-book
? Select the type of app you want to create Standard web app
? Do you want a basic Express API server? Yes
   create package.json
   create .eslintrc.json
   create .eslintignore
   create .prettierignore
   create .prettierrc
   create .gitignore
   create .husky\pre-commit
   create src\client\modules\jsconfig.json
   create lwc.config.json
   create lwc-services.config.js
   create jest.config.js
   create README.md
   create src\client\index.html
   create src\client\index.js
   create src\client\modules\my\app\app.css
   create src\client\modules\my\app\app.js
   create src\client\modules\my\app\app.html
   create src\client\modules\my\greeting\greeting.css
   create src\client\modules\my\greeting\greeting.js
   create src\client\modules\my\greeting\greeting.html
   create src\client\modules\my\app\__tests__\app.test.js
   create src\client\modules\my\greeting\__tests__\greeting.test.js
   create src\client\resources\lwc.png
   create src\client\resources\favicon.ico
   create scripts\server.js
   create src\server\api.js

プロジェクトディレクトリが作成されたので

$ cd account-book
$ npm run watch

これで localhost の 3001 ポートでサーバが起動します。
http://localhost:3001/

ディレクトリ構成

ディレクトリ構成は、以下のようになっています。
通常のLWCが Salesforce 前提ですが、OSS 版は Salesforce は無いので、サーバはほぼ自作する必要があります。

  • プロジェクトルート
    • scripts : 開発サーバ設定が記載されています(基本的に触りません)
    • src : ソースディレクトリルート
      • client : LWC のソース本体です
        • modules : LWC モジュール/コンポーネントを配置します
          • module1 : モジュール名を指定します。Salesforce 版 LWC で言う所の「c-」部分です。
            • component1 : LWC コンポ-ネントディレクトリです。
              • component1.html : テンプレート
              • component1.css : スタイル
              • component1.js : コントローラソース
            • component2
            • ...
          • module2
          • ...
        • resources
        • index.html : 一番最初に表示される HTML ファイルです。基本的に <div id="main"></div> 位しか書いていません。
        • index.js : 一番最初の画面が表示された祭に実行される JavaScript です。LWC アプリを起動する役割があります。
      • server : バックエンドサーバソースです。express で作成することになります。

LWC アプリ開発の違い

  • メタデータが存在しない Salesforce 版だと、LWCをどこに使うか等を指定するメタデータがありますが、OSS 版はどこかに埋め込む運用ではないので、そんなものはありません。
    制御は全部 JavaScript/JSON で記述します。
  • バックエンドが存在しない Salesforce ではないので、バックエンドは存在しません。
    代わりに、ExpressJS がセットアップされるので、これをつかって API サーバを作成し、フロントの LWC 側から Ajax 通信で処理します。※ Tips に関連
  • JavaScript への制限がない
    Salesforce 版だと、JavaScript の記述には一部制限が入ります。(おそらく好き勝手されないように)
    しかし、OSS 版はそうした制限はないので、adapter やプロトタイプ汚染等、そこそこ凶悪な操作がやりたい放題です。
  • モジュール名が自由に命名できる
    Salesforce 版だと、カスタムコンポーネントc- プレフィックス固定で、コンポーネント名も小文字のハイフン区切り(例 : <c-example-component />)すが、 OSS 版はその制限がないので <bootstrap-customAlert /> といったそれなりに自由なコンポーネント名で定義できます。
  • 共通スタイルは無い
    Salesforce 版だと、Lightning Design System のスタイルが自動適用されますが、OSS 版はそれはありません。
    自力で適用する必要があります。※ Tips に関連

Tips

共通スタイルシートを適用する

デフォルトでは、何のスタイルも自動適用されません。
そこで、共通のスタイルを適用するため、次のような手段を用います。

  1. src/styles/common.css を作成する。
  2. src/client/modules/common/BaseElement を作成する。(※1)
  3. コンポーネント作成時は、この BaseElement を継承する。(※2)

※1

import { LightningElement } from 'lwc';
export default class CssCommonElement extends LightningElement {
    _commonCss() {
        let _bootstrap = '../styles/common.css';
        const styles = document.createElement('link');
        styles.href = _bootstrap;
        styles.rel = 'stylesheet';
        return styles;
    }

    connectedCallback() {
        this.template.appendChild(this._commonCss());
    }
}

※2

import BaseElement from 'common/basBaseElemente';

export default class AddBrand extends BaseElement { /* ... */ }

バックエンドサーバ(Express)で REST API を作成する

デフォルトでは、Express JS サーバは REST API を作成する形ではセットアップされない。
そこで、REST API モードとするために設定を行う

これは src/server/api.js で次のように記述する。

const express = require('express');

const app = express();
app.use(express.json());

NodeJs で SQLite3 をセットアップ

デフォルトでは、データベースすらセットアップされていない。
そこで、データベースを使えるようにセットアップを行う。

  1. npm install sqlite3 -i で sqlite3 をインストールする
  2. 後述のような共通 DB アクセスライブラリ(DBCommon)を作成する ※1
  3. データベースアクセスクラス(DAO)を作成していく ※2

こんな感じにしておけば色々使いやすいかも知れない。

※1

const sqlite3 = require("sqlite3")

let database

class DBCommon {
  static init() {
    database = new sqlite3.Database("data.sqlite3")
  }
  static get() {
    return database
  }
}

DBCommon.init();
exports.DBCommon = DBCommon;

※2

const common = require("./DBCommon");
const sqlite3 = require("sqlite3")

function createTable() {
  const db = common.DBCommon.get();
  return new Promise((resolve, reject) => {
    try {
      db.serialize(() => {
        db.run(
          `create table if not exists Brand (
            id integer primary key AUTOINCREMENT,
            name varchar(512) not null,
            account varchar(32) not null,
            description text default null
          )`
        )
      });
      return resolve();
    } catch (error) {
      return reject(error);
    }
  });
}
createTable();

class BrandTable {
  static async select(id, db = common.DBCommon.get()) {
    return new Promise((resolve, reject) => {
      db.get(`select id, name, account, description from Brand where id = ?`, id, (err, row) => {
        if (row) {
          resolve(row);
        } else {
          reject(err);
        }
      });
    });
  }

  static async insert(brand, db = common.DBCommon.get()) {
    db.run(
      `insert into Brand (name, account, description) values ($name, $account, $description)`,
      { $name: brand.name, $account: brand.account, $description: brand.description }
    );
  }
}
exports.BrandTable = BrandTable;

通信用アダプタ

こんな通信用クラスを用意しておくと便利です。

function jsonSending(method, url, sendBody) {
  return new Promise((resolve, reject) => {
    let req = new XMLHttpRequest();
    req.open(method, url);
    req.onload = function() {
      if (req.status === 200) {
        resolve(JSON.parse(req.responseText));
      } else {
        window.console.log(req);
        reject(new Error(req.statusText));
      }
    };
    req.onerror = function() {
      window.console.log(req);
      reject(new Error(req.statusText));
    };
    req.setRequestHeader('Content-Type', 'application/json');
    req.send(JSON.stringify(sendBody));
  });
}

export default class Ajax {

  /**
   * HTTP Get request
   * @param {String} url
   * @returns Promise(String)
   */
  static async get(url) {
    return new Promise((resolve, reject) => {
      let req = new XMLHttpRequest();
      req.open('GET', url, true);
      req.onload = function() {
        if (req.status === 200) {
          resolve(JSON.parse(req.responseText));
        } else {
          reject(new Error(req.statusText));
        }
      };
      req.onerror = function() {
        reject(new Error(req.statusText));
      };
      req.send();
    });
  }

  /**
   * HTTP Post request.
   * @param {String} url
   * @param {String} sendBody
   * @returns Promise(String)
   */
  static async post(url, sendBody) {
    return jsonSending('POST', url, sendBody);
  }

  /**
   * HTTP PUT request.
   * @param {String} url
   * @param {String} sendBody
   * @returns Promise(String)
   */
   static async put(url, sendBody) {
    return jsonSending('PUT', url, sendBody);
  }
}

参考情報

-ExpressJs : https://expressjs.com/ja/ 軽量な Javascript Web フレームワーク - LWC : https://lwc.dev/ - テンプレートエンジン : https://developer.salesforce.com/docs/platform/lwr/guide/lwr-templates.html

ノートン等に「壊れたレジストリが見つかりました」と言われたときの無料対処

ノートンMcAfee 等を入れてるとたまに「壊れたレジストリが見つかりました」と言われることがある。
で、そのダイアログを見ると、追加コンポーネントの購入だとか、製品ページに飛ばされるわけである。

見つけてくれるのはありがたいが、騙しがないだけで正直「スケアウェア1」の感がある。

レジストリとは?

OS・ハードウェア・プログラムのオプション、設定、情報、その他の値を保存するデータベース。
Windows 設定とかアプリのライセンス情報とかこの辺に入ってたりする。

これが壊れると、不安定になったり、アプリ起動がおかしかったり、つながってるデバイスがうまく認識しなくなったり等が発生する。

regedit 使って、主導で編集もできなくないし、そうすることで更に細かいWindowsカスタマイズだったり効率化だったりもできなくはない。
本題からは外れるので、これは一旦横に置いとく。

修復方法

ということでその修復方法。
Avast の有料プランとか、ノートンの追加コンポーネントとかは買わなくていい。
Windows の標準で大体治せる。

手段 1 コマンドだけで治す

  1. cmd を管理権限で起動する。
    アプリケーションの検索で「cmd」で探して、右クリックメニューに「管理者として実行」があるのでクリック。
    f:id:white-azalea:20220305131239p:plain
  2. sfc /scannow を実行して、修復。
    Windows には標準でついてるスキャナがあるのでこれを実行。
    お茶でも飲んでお待ち下さい。
    f:id:white-azalea:20220305131509p:plain
  3. DISM /Online /Cleanup-Image /ScanHealth で修正を確認して終了。
    修正が完了下なら上記コマンドで修正結果を確認できる。手段 3 を状況次第で検討する。
    f:id:white-azalea:20220305131649p:plain

手段 2 自動修復機能

  1. 設定から「システム>回復」を呼び出して、「PCの起動をカスタマイズする」で再起動
    f:id:white-azalea:20220305133010p:plain
  2. 起動オプションで「トラブルシューティング」を選択
    f:id:white-azalea:20220305133052p:plain
  3. 「詳細オプション」→「スタートアップ修復」を実行すると、自動修復モードに入る。

手段 3 壊れる前の状態に戻す

※ この手段は以前の状態に戻す操作なので、治りはするけど色々消えてしまうのでバックアップ取ってからを推奨。

  1. コンパネ開いて
    f:id:white-azalea:20220305133416p:plain
  2. 「回復」「システムの復元を開く」
    f:id:white-azalea:20220305133519p:plain
  3. 壊れる前を探して戻す
    f:id:white-azalea:20220305133743p:plain

これでもダメなら最終手段

最終手段 : リセットする

Windows を初期化しちゃえば破損なんて全部戻るよね☆ という最強かつユーザのダメージも大きい文字通りの最終手段。
当然ライセンスキーなど含めバックアップを推奨

設定から「このPCをリセット」する。
個人用ファイルも「すべて削除する」とか、「ファイルを削除してドライブのクリーニングを実行する」までやるとほぼ確実。
PCを買ってきたばかりの頃のサクサク感をお楽しみください。

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


  1. 利用者に恐怖を与えて、お金を請求する悪質なソフト/広告等のこと

CakePHP 4 で特定のラジオボタン出力だけでレイアウトをフルカスタムする

通常であればフォームヘルパー経由でラジオボタンを作成するはず。
しかし、通常のフォームは以下の様な構造で出力されてしまう。

<div class="input radio">
    <label for='xxx1'>
        <input type='radio' id='xxx1' name='xxx1' />
        Hoge
    </label>
</div>

これをどうにか

<div class="input radio">
    <div class='wrapper'>
        <input type='radio' id='xxx1' name='xxx1' value='Hoge' />
        <label for='xxx1'>
            Hoge
        </label>
    </div>
</div>

こうしたい。
そこで、実際にこんな出力が出るように調査してみたログ。

で、目をつけたのが これ です。

book.cakephp.org

で、具体的にどう書くのかをペタリ。
明日コピペできるコードをあなたに

$this->Form->control(
    'xxx', // Id 値
    {
        'type' => 'radio',  // input タイプはラジオボタン
        'options' => ['Hoge', 'Fuga'],    // 選択値
        'nestedInput' => false, // ネストレイアウト(label の中に input タグを置く設定)を false
        'templates' => [ // 出力するテンプレートの上書き
            // input タグの出力テンプレート上書き
            'radio' => '<input type="radio" name="{{name}}" value="{{value}}"{{attrs}} />',

            // ラベルの出力上書き。
            'nestingLabel' => '{{hidden}}{{input}}<label {{attrs}}>{{text}}</label>',

            // 上2つのラッパー
            'radioWrapper' => '<div class='wrapper'>{{label}}</div>'
        ]
    }
);

とりあえずこれで意図通りの出力ができるようになった。
というか公式が「暗黙の了解でわかるんだろう?」的な説明不足で、初見では具体的な設定方法がマジ読み取れん(汗

書籍レビュー:ジェイソン流お金のお増やし方

紹介する書籍

ざっくり書評

投資未経験者~中級者まで楽しく読める投資入門書。
(自分は上級では無いので、おそらく中級)

約15年間投資を続けたことで、FIRE を既に達成している人物による投資の経験本。
感覚的に日本人に非常に合う投資方法(リスクとしては低での投資)を行っていることもあり、コレを真似るだけで十分再現できそうな内容。

見どころ

  • ジェイソン氏が金持ちになった方法≒おすすめの方法
  • 達成するための価値観、考え方
  • 死ぬほどやってることはシンプル(これで駄目ならどんな投資本見ても無駄!)

それ故に日本人の殆どが全てでないにせよ、それなりに貯蓄を作ることができます。

尚、海外投資で「アセットアロケーション」とか「リスク許容度」等銘柄を選ぶ上で必要な判断基準用語には触れません。
なので銘柄を自分で判断する場合の考え方…などを学ぶには少々難しいかもしれません。
とはいえ、初心者向けならそんな事せずにとりあえず「VTIにぶっこんどけ!」で良いのかもしれません。(汗

ざっくり内容

ジェイソン流の投資方法は以下の通り

  1. まずは節約しよう
  2. 節約で浮いた金を 3 ヶ月分の生活費を残して全部投資にぶっこむ
  3. 投資は ティッカーシンボル*1「VTI *2」に全力投資。
  4. 売らずにガチ保持

これだけ!というかコレが全部と言っていいです。
具体的やり方…という目次とその概要。

各章のざっくり

尚、2章+3章で本 7 割を占めるという…

*1:株やETF等を示す略称。

*2:Vanguard Total Stock Market Index Fund ETF。全米株の詰め合わせセットだと思えばよろしい

続きを読む

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

Prepare for your Salesforce JavaScript Developer I Credential Trailmix

コレの続き。

Lightning Web コンポーネントSalesforce データ

Lightning データサービスを使用したデータの操作

trailhead.salesforce.com

まぁ単純に作る系のお話。

  • LWC(Name: ContactCreator) 作って
  • コンポーネントではオブジェクトとフィールド名を用意。保存完了時に toast (画面↑に緑の帯で出るメッセージ)表示

オブジェクトのフィールド定義系

// Object
import CONTACT_OBJECT from '@salesforce/schema/Contact';
// Fields
import FIRST_NAME_FIELD from '@salesforce/schema/Contact.FirstName';
import LAST_NAME_FIELD from '@salesforce/schema/Contact.LastName';
import EMAIL_FIELD from '@salesforce/schema/Contact.Email';

// 中略
    objectApiName = CONTACT_OBJECT;
    fields = [FIRST_NAME_FIELD, LAST_NAME_FIELD, EMAIL_FIELD];
  • 保存成功時は toast で表示する
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

// 中略
    handleSuccess(event) {
        const toastEvent = new ShowToastEvent({
            title: "Account created",
            message: "Record ID: " + event.detail.id,
            variant: "success"
        });
        this.dispatchEvent(toastEvent);
    }
        <lightning-record-form
            object-api-name={objectApiName}
            fields={fields}
            onsuccess={handleSuccess}>
        </lightning-record-form>
  • 最後に Lightning App Builder で登録できるようにして登録
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>52.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target><!-- アプリケーションページで使いますよー宣言 -->
    </targets>
</LightningComponentBundle>

ちなみに、これで一旦レコード作ってしまうと、再編集しても保存後の表示が変わらない…
キャッシュ機構があると思われるので、

refreshValues() {
    const inputFields = this.template.querySelectorAll('lightning-input-field');
    if (inputFields) {
        inputFields.forEach((field) => {
            field.reset();
        });
    }
}

で強制的にリフレッシュしてもいいし、レコード状態が変化したことを Salesforce経由で通知 してもいい

続きを読む

DeepLearning 生成させる学習方法

RNN(LSTM/GRU) 等

時系列のデータを扱うタイプの DeepLearning.

画像であれば、画像のY軸を時系列データと想定して、残りを予測させるといったやり方で画像を作成できるっぽい。
要するにどのように時系列データとして食わせるかで次の値を予測させるというもののようだ。

単純に手書き数字の上半分だけ食わせて、下半分を予測させるとこんな感じで生成された。

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

2,3,8 は上半分の形状が似ているせいでよくわからないことになってしまった。
8, 7 は学習データがそもそも悪いwww
5, 6 は混ざって学習したんじゃないかという予想。
9 は上半分で切ったとき微妙に2に混ざったかなにかしたかなという印象。

時系列情報から次の値を予測させるという意味では、やはり先頭部分の情報ありきだ。
キモは「どのように時系列のデータに見立てるか」だと思われる。

尚、翻訳などにはこれを利用した Seq2Seq (Sequence to Sequence。Sequence という系列情報を認識して別の系列に変換する) というアルゴリズムを使っていて、この根底も RNN を使っていくそうな。
ぱっと見た感じ、形態素解析した上でRNNに食わせて変換しているっぽい。

CNN

認識・判定用

これは画像などの認識を行うニューラルネット
映像判定とか顔判定等をメインに扱うものなので、極論すると生成には向かないと思われる。

単純な入力→出力型DeepLearning

下書きを読み込んで線画にするAIは予測系ではなくて単純に入力→結果対応をしてると思う。
画像を行列にして食わせて、線画の結果を取得する。

色を付けるのも多分似たようなものかもしれない。

ただしサンプルは相当な量が必要だし、画像となれば学習時間もエグい事になりそう…
ちょっと個人で手が出るものでは無いと思われる。

VAE (Variational Autoencoder)

画像などから特徴情報に変換(Encoder。特徴抽出と圧縮)し、中間集中力(この値を「潜在変数」と呼び、)その特徴情報から出力(Decoder)の二段回の変換を行うニューラルネット
潜在変数値は元の情報より圧縮されてる。教師なし学習に分類されるご様子。

主に、入力と出力の差分を取ることで異常値を検出できる。

で、この時潜在変数を任意にイジってやることで、全く新しい画像を自動生成できるということらしい。
派生で Conditional VAE (潜在変数の他に、ラベルパラメータを指定することで、生成するデータのカテゴリを指定できるようにしたVAE)。
β-VAE (複数要素を含む情報を処理できるVAE)Vector Quantised-VAE (潜在変数が特徴を捉えきれなかった場合にボケる等が発生する問題に対処したVAE。潜在変数を離散値で扱う) Vector Quantised-VAE2 (Vector Quantised-VAE を階層構造にすることで、高解像度の生成を行えるようにしたもの)

GAN (Generative Adversarial Networks)

敵対的生成ネットワーク。
Generator (ランダムなノイズから、偽データを生成するNN)と、Descriminator(偽データと本物のデータを見て真贋判定するNN)の2つで競わせるニューラルネットワーク
完全に新しい画像等を生成するのに用いる。