アルコリズム算出方法を✅

「20時間」MVP完成までの可処分時間。結構やばい。今日のポートフォリオ進捗会の感想は「sycall可愛すぎ」ですね。あと、自分のサービス内容を30秒で説明できるようなスクリプトを準備しようと思いました。

さて、今回は、ポートフォリオに実装中のアルコリズムに関して書いていきたいと思います。

アルコリズムは80%程完成致しました。

アルコリズムとは

「アルコール」と「アルゴリズム」を掛け合わせた造語。「ユーザーの状態に応じてお酒の順番を提供する」というアルゴリズムや、「ユーザーの酒の強さを診断する」というアルゴリズムなどを指す。

完全な造語です。

今回実装途中のアルコリズム

期待する挙動は「ユーザーの状態に応じてお酒の順番を提供する」ことです。

現在作成中のポートフォリオのコア機能をざっくり説明すると、

「ユーザーに、13項目の質問を回答、そして次の飲み会に向けた気分、アプリがユーザーに対して次の飲み会で飲むお酒の順番を提供する」

ものになります。

この13項目の診断結果によって、お酒の強さと次の飲み会に向けた気分が決まります。

それぞれAnalyzeモデルに保存され、enumによって属性が分けられる形になっています。

Analyzeモデル

class Analyze < ApplicationRecord
  belongs_to :user
  enum next_nomivation_types: { flesh: 0, tipsy: 1, heavy_drunk: 2 }
  enum sake_strongness_types: { weak: 0, normal: 1, strong: 2 }
end

そして、提供するお酒が保存されているAlcoholテーブルです。

create_table "alcohols", charset: "utf8mb4", options: "ENGINE=InnoDB ROW_FORMAT=DYNAMIC", force: :cascade do |t|
    t.string "name"
    t.integer "alcohol_percentage"
		t.integer "alcohol_order"
    t.integer "alcohol_amount"
    t.integer "pure_alcohol_intake"
    t.text "description"
    t.datetime "created_at", precision: 6, null: false
    t.datetime "updated_at", precision: 6, null: false
  end

「お酒の度数が低いものを4つまとめてviewに表示する」という挙動を実装したい場合、

alcohol_orderが1のお酒を探し、alchol_percentageの低い順番に並べ、低いものから4つ取り出してviewに表示します。

先述した「ユーザーの状態に応じてお酒の順番を提供する」をもっと落とし込むと、

ユーザーが作成した診断結果(Analyzeデータ)の「next_nomivation_types」と「sake_strongness_types」に応じて「Alcoholデータ」を4つ提供する。になります。

このロジックをjavascriptを使って強引に表してみました。

Image from Gyazo

お酒の強さと次の飲み会に向けた気分は先述した通りで、それぞれ下記のように表されます。

class Analyze < ApplicationRecord
  belongs_to :user
  enum next_nomivation_types: { flesh: 0, tipsy: 1, heavy_drunk: 2 } 
#0: 爽快, 1: ほろ酔い, 2: 酩酊
  enum sake_strongness_types: { weak: 0, normal: 1, strong: 2 }
#0: 下戸, 1: 普通, 2: 酒豪
end

「次の飲み会に向けた気分」

next_nomivation_types: { flesh: 0, tipsy: 1, heavy_drunk: 2 } 0: 爽快, 1: ほろ酔い, 2: 酩酊

「お酒の強さ」 sake_strongness_types: { weak: 0, normal: 1, strong: 2 } 0: 下戸, 1: 普通, 2:酒豪

これらを論理積と条件演算子を使いながらそれっぽい式を作成しました。

論理積

論理積 (&&) 演算子 (論理結合) をオペランドの組み合わせに対して使用すると、すべてのオペランドが true である場合に true になります。

 result_1 = (sakeNomivation === 1) && smallSakeBigNomivation

result_1は、

sakeNomivation === 1がtrue、かつ、smallSakeBigNomivationがtrueの場合

と定義しています。

result_1と定義している理由は、今後sakeNomivationが0や2の場合といったように、増えていくためであり、最終的にresult_9まで作る予定です。要リファクタですね。

条件演算子(三項演算子)

条件 (三項) 演算子JavaScript では唯一の、3 つのオペランドをとる演算子です。条件に続いて疑問符 (?)、そして条件が真値であった場合に実行する式、コロン (:) が続き、条件がfalsyであった場合に実行する式が最後に来ます。この演算子は、 if 文のショートカットとしてよく用いられます。

const a = result_1 ? "あってるよ" : "間違ってるよ"

aを定義します。

先に定義したresult_1がtrueの場合、あってるよ が出力、falseの場合、間違ってるよ が出力されます。

 result_1 = (sakeNomivation === 1) && smallSakeBigNomivation
 const a = result_1 ? "あってるよ" : "間違ってるよ"

この二つの式をsctiptタグのmethods部分にかき、イベントが発火されたタイミングで実行されるようにします。

明日行いたいこと

条件演算子の部分を少し改良して、result_1が正しい場合、「アルコール度数が低い順に並び替えられた4つのお酒をreturnする」ような式を作ろうと思います。

明日にはアルコリズムを完成させます。