buto > /dev/null

だいたい急に挑戦してゴールにたどり着かずに飽きる日々です

Haskell VSCodeで実行できない

前回の記事HaskellIDEでコーディングするのに必要なツールが分かったので、早速試してみる!!

  • OS:Windows10

StackからGHCをインストール

  1. Stackをインストール
  2. StackからGHCをインストール
    • stack setup
  3. GHCがインストールできたことを確認
    • stack ghc -- --version
      • コンパイラがインストールできた!
      • The Glorious Glasgow Haskell Compilation System, version 8.8.3

haskell-ide-engineをインストール

  1. コマンドプロンプト文字コードUTF-8にしておく
    • chcp 65001
  2. haskell-ide-engine(HIE)をインストール
    • あらかじめGitをインストールしておく
    • cd クローンするフォルダ
    • git clone https://github.com/haskell/haskell-ide-engine
    • cd haskell-ide-engine
    • stack ./install.hs hie
      • Version 1.4, Git revision e4972ff44c7649e3f53ffac37ae899410075aa0f (3903 commits) x86_64 ghc-8.8.3
    • stack ./install.hs data

stack installではなくstack ./install.hsを使うのがポイントらしい (StackのinstallコマンドではなくHIEのinstall.hsを使う)

VisutalStudioCodeをインストール

intelliJだとstack.exeを認識してくれなかったのでVSCodeでやってみる

  1. VSCodeインストーラをダウンロードしてインストール
  2. インストール後にVSCodeを起動して[Extensions]からプラグインを導入
  3. setting.jsonにHIEのパスを設定
    • "haskell.serverExecutablePath": "~/hie/haskell-ide-engine"

これでVSCodeを再起動するとHaskellのビルド・実行ができるはずだった…

f:id:butorisa:20201020174913j:plain

あれ?Haskell実行できない??? (2時間経過) 一旦、コマンドら実行でいいや

Haskell 開発環境に必要なツール

HaskellIDEでコーディングしたい

最近またHaskellに興味がわいてきて、再び入門することにしました これまではAtomなどのテキストエディタでコードを書いて、コマンドでコンパイル・実行していました 他の言語ではIDEを使っているのでHaskellIDEで開発できるようにしたい!

この記事ではHaskell開発環境に必要なツールのまとめです

※正確にはライブラリ、プラグイン…などの言い方があると思いますが、まとめてツールと言っています

Haskellの実行に必要なツール

Haskellコードを書いてコンパイル・実行するためには以下が必要です - GHC(Glasgow Haskell Compiler) - Haskellコンパイラ - グラスゴー大学の先生?が開発したコンパイラで最もメジャーなHaskellコンパイラ - コンパイラのブランドって意識したことなかった。。。

コマンドでコンパイル・実行する時はGHCだけあればOK!

プロジェクト作成・ビルドに必要なツール

Cabalというビルド・パッケージ管理ツールもありますが、初心者にはStackがおすすめと紹介されていたので私はStackを使います CabalとStackの違いは何ですか?

StackはCabalライブラリを使っているようです Cabalを使っているとcabal hell(カバル地獄)という恐ろしい事象があるみたい

IDEを使った開発に必要なツール

【AWS】HTTPS化のアレコレ

うわぁ!やっちゃった!

今朝、社内でテストなどに使っているAWS CloudWatchからコスト超過のSlackが来ました。 まだ8月に入ったばかりです。やばい、と会社の先輩と原因を調べてみると、

CertificateManager $386.85

なんかめっちゃ高い項目ある!なんだろ… あ、これ先月に私が作ったプライベートCAだ

私がプライベートCAを立てた経緯

工数管理・トレーサビリティ向上のために社内AWS環境にRedmineを構築(bitnami AMI) → https化自己署名証明書)を依頼される → 「AWS https化」で検索、ネット記事の手順をそのまま実施 → プライベートCAを作成

Redmineは社内でしか使わない、セキュリティグループもそのように設定しているので プライベートCAを立てずに自己署名証明書のみで良かった!(ていうか、そう依頼されていた)

よく分からないままエイヤでやってしまった

根本的な原因はこれです。https化自己署名証明書の仕組みを理解せず作業してしまいました。 なので、今勉強しておきます!

HTTPS化とは

HTTPSとは 安定のピヨ太くん分かりやすいですね

HTTPだと通信の内容が見られてしまう危険性があるため、 暗号化通信のSSLがセットになったHTTPSを使おう!ということ

HTTPSには「サーバ証明書」が必要(暗号化する鍵)

  • お客様が見るサイトはパブリック認証局が発行するサーバ証明書を使う
  • 社内向けサイトはプライベート認証局(プライベートCA)が発行するサーバ証明書を使う
    • プライベートCAの証明書のみを信頼できるルートとすると、発行した証明書が信頼性のあるものになる
  • 自分しか見られない、暗号化するだけが目的だったらサーバ自身が発行する自己署名証明書

AWSでのHTTPS通信

【初心者向け】AWSのサービスを使ってWebサーバーをHTTPS化する

AWSでのHTTPS通信を実現するには以下2通りの方法がある

  1. EC2に証明書をインストール
  2. ELBに証明書をインストール

何か違いはあるのかな?? → EC2上のWebサーバなどがHTTPS非対応だったらELBに証明書をインストールして   ELB-EC2間はHTTP通信にする

結論:脳死状態でAWS触らない

自分が何をしているのかハッキリ分かっていない状態での環境構築は控えましょう 糖分をとって分からないことは調べて聞いて目的と手順をきちんと理解して作業しましょう そして会社のみなさんごめんなさい!!

pyxel アイテムゲットを実装

前回は画面を右から左に流れるアイテムを実装しました pyxel ゲーム画面にアイテムを流す

今回のソースコードはこちら https://github.com/butorisa/pretty-hopper/tree/debug

アイテムゲット時の動きを実装

キャラが流れてくるアイテムと衝突したら「衝突したアイテムが消える」ようにする

class Skill(Enum):
    """ 画面に流れるオブジェクト """
    Java = auto()
    Python = auto()
    Ruby = auto()

    def __init__(self, num):
        self.active = True
        self.position = [(i * 60, randint(0, 104)) for i in range(4)]

アイテムオブジェクトのクラス 衝突時に self.active をFalseにすれば消える

def switch_active(self, obj_x, obj_y, target_x, target_y, is_activate):
    """ オブジェクトが重なったら一方を非表示にする """
    if not is_activate:
        return False

    if abs(obj_x - target_x) < 10 and abs(obj_y - target_y) < 10:
        if self.game_mode == GameMode.Town:
            self.player.position = [8, 104]
        elif self.game_mode == GameMode.Office:
            self.score += 10
        return False
    else:
        return True

衝突判定(ここのゲームモードはOffice)戻り値のbooleanをself.activeに代入する

デュークくんをゲットすると一斉に消えるバグ

f:id:butorisa:20201020174333g:plain

(デュークくんだけではないですが)ある1つのアイテムをゲットすると画面上にあるすべてのアイテムが消えてしまいました

画面に流れるアイテムが何なのかを分かっていないとこんなバグが生まれます

1つのアイテム = リストの1要素

アイテムは self.skill に格納している この中身が複雑だった…(自分が作ったが)

self.skill:[Java, Python, Ruby] Enumクラスのリスト
┃
┗ Java:Enumクラス
    ┃
    ┗ self.state:デュークくんリスト リストの長さ=デュークくんオブジェクト数
        ┃
        ┗ self.stateの1要素:( x座標, y座標, 表示フラグ )

画面上の1つのデュークくんは上記のself.stateの1要素

バグの原因は「Enumクラス自体に表示フラグを付けていた」こと キャラがアイテムと衝突した時に表示フラグをFalseにすると、Enumクラス以下が非表示になるので self.state にいる「アイテムオブジェクトすべて」が消えてしまっていた

1デュークくんごとに表示フラグを設定

バグを解消するには self.state の要素ごとに表示フラグを設定する

class Skill(Enum):
    """ 画面に流れるオブジェクト """
    Java = auto()
    Python = auto()
    Ruby = auto()

    def __init__(self, num):
        # [x, y, is_active]
        self.state = [(i * 60, randint(0, 104), True) for i in range(4)]

__init__()( x座標, y座標, 表示フラグ ) を持つ長さ4のリストを設定する

f:id:butorisa:20201020174440g:plain

これでゲットしたアイテムだけが消えるようになりました^^

カイジで条件付き確率を学ぶ

カイジにハマっている間にどんどん統計を学んじゃおう! 前回は地下チンチロから3つのサイコロで出目になる確率を求めた(反復試行) カイジで確率(ラプラスの定義)を学ぶ

eカードで条件付き確率っ…!

eカードのルール 怖すぎてちゃんと見られてないから間違ってるかも - カードを互いに出してその強さで勝敗がつく(同じカードの時は引き分け) - 手持ちのカードは5枚 - 皇帝:1枚(勝ち→市民 負け→奴隷) - 市民:3枚(勝ち→奴隷 負け→皇帝) - 奴隷:1枚(勝ち→皇帝 負け→市民) - 引き分けのカードは手元には戻さない

1回目に市民、2回目に皇帝を出す確率

2枚目に皇帝は通せないはずだっ…などの心理戦は考慮しちゃダメ

f:id:butorisa:20201020174143j:plain

2つの事象がどちらも起こること 積事象 を求める おしゃれベン図はCanvaで作ったよ! - 1回目に市民を出す確率 = 3/5 - 2回目に皇帝を出す確率 = 1/4 1回目のカードは戻さないから手持ちのカードは4枚

ベン図からも「積事象」って呼び方からも 2つの事象を掛け合わせればOK!

1回目に市民、2回目に皇帝を出す確率は… 3/5 × 1/4 = 3/20 となる

乗法定理!乗法定理!!乗法定理!!!

P(A∩B) = P(A) × P(B) 事象AとBどちらも起こる確率は「Aが起きる確率×Bが起きる確率」で求められる

式変形で2回目に皇帝を出す確率を求める

今度は「1回目に市民を出した時(事象A)、2回目に皇帝を出す(事象B)確率」を求める

乗法定理の式を変形すると… P(B) = P(A∩B) / P(A) となる

(3/20) / (3/5) = 5/20 = 1/4 当たり前だけど、上記と同じ値になってる!

ちなみに私は分数の分数ができません 分母と分子を入れ替えて掛け算にしています

これは運否天賦などではないっ…、圧倒的ベイズの定理!

ベイズの定理です 圧倒的ベイズなんて言葉はありません

さっき乗法定理を変形した P(B) = P(A∩B) / P(A)ベイズの定理と言うそうです

@kumiizoo さんがベイズの定理を丁寧に解説してくれています 【統計学勉強ノート】その2〜ベイズの定理〜

カイジで確率(ラプラスの定義)を学ぶ

最近Huluを入れてカイジを見ております(シーズン1は悪魔的すぎて途中でやめた) シーズン2で地下の強制労働場でのチンチロリンのシーンで確率の話があったので計算してみる!

チンチロリン(チンチロ)とは

ニコニコ大百科 - チンチロリン

チンチロリンとは、サイコロを使って行うギャンブルゲームである。

子はその回に賭けるチップを張る。 親がサイコロをどんぶりに振り、「出目2~5」以外の出来役は即勝ちもしくは即負けなので清算する。 「出目2~5」ならば子が順にサイコロを振り、出来役に応じて清算する。

f:id:butorisa:20201020173952j:plain

居酒屋でハイボールのサービスとかにも使われてるみたい

3つのサイコロを振って出目になる確率

チンチロのルールはこれ(アニメを思い出して書いています) - 3つのサイコロのうち「2つ以上が同じ数字」になっていれば出目→勝負ができる! - 出目にならなくても「3回まで」はサイコロを振れる - 3回振っても出目にならなかったら負け

まず出目を出さないと始まらない!!

出目になるのは何通り?

サイコロの目は1〜6の6通り ※通常のサイコロ サイコロは3つだから出る目は全部で…6の3乗=「216通り」

出目の確率は「2つのサイコロが同じ数字の確率」+「3つのサイコロが同じ数字の確率」 - 2つのサイコロが同じ数字になる確率 - 「1」が2つ→もう1つのサイコロは2〜6のどれかだから「5通り」 - [1, 1, 2~6]、[1, 2~6, 1]、[2~6, 1, 1] のパターンがあるので、5通り×3パターン=「15通り」 - 「2」〜「6」も同様だから、15×6=「90通り」 - 3つのサイコロが同じ数字になる確率 - 6通り!これは簡単

出目になるのは、90+6=「96通り」 出目の確率は「96/216」約分して「4/9」 1回だけサイコロを振る時は9分の4か…

3回振ったうちに出目になる確率

サイコロは3回まで振れるので、出目の確率はもっと上がる! 1回だったら、4/9(約44.4%) 2回だったら、4/9+(4/9×4/9)=36/81+16/81=52/81(約64.2%) 3回だったら、4/9+(4/9×4/9×4/9)=324/729+64/729=388/729(約53.2%)あれ?下がった

※ ここは自力でできずアニメの解説シーンを頼った

ラプラスの定義だっ…!

何気なく確率 = 出目の事象数 / 全事象数 をしていたが、19世紀にラプラスが定義したもの

統計学の時間で確認 9-2. 確率の計算(数え上げ)

アニメ見返しました

アニメでも解説があったので見返してみた カイジ版チンチロの出目は「108通り」もあったらしく、1回のチャレンジですでに50%で出目! 2回目は0.5+(0.5×0.5)=0.5+0.25=0.75(75%) 3回目は0.75+(0.5×0.5×0.5)=0.75+0.125=0.875(87.5%)

出目を出すだけなら結構な高確率だった

pyxel ゲーム画面にアイテムを流す

前回はキャラが家に入ったらローディング画面を表示するところまで pyxel ゲーム画面遷移+動きをつける

今回はゲーム画面にアイテム(オブジェクト?)を流してみる すべてのコード+画像はこちら

f:id:butorisa:20201020173612g:plain

お手本の記事はこちら 【Pythonでゲームを作ろう!】レトロな2Dゲームを作ってみた!

Pyxel Editorでアイテムを描く

プログラミング言語のアイコンたち

f:id:butorisa:20201020173656p:plain f:id:butorisa:20201020173719p:plain f:id:butorisa:20201020173730p:plain

このアイテムをたくさんゲットしてキャラのスキル(スコア)がアップしていくゲームにする予定

アイテムのクラスを定義

class Skill(Enum):
    """ 画面に流れるオブジェクト """
    Java = auto()
    Python = auto()
    Ruby = auto()

    def __init__(self, num):
        self.position = [(i * 60, randint(0, 104)) for i in range(4)]

    def get_image(self, enum):
        """ イメージバンクから切り出す座標を返す """
        if enum == 'Java':
            return 32, 80
        elif enum == 'Python':
            return 48, 80
        elif enum == 'Ruby':
            return 0, 96

アイテムを追加したらEnumを追加する __init__()でアイテムのランダムに初期位置を設定

# ゲームのメインクラス
def __init__(self):
    self.skill = self.create_skill()

def create_skill(self):
    """ skillオブジェクト生成 """
    num = len([obj.name for obj in Skill])
    skills = [Skill(i) for i in range(1, num + 1)]
    return skills

ゲーム本体の初期化処理で全部のEnumクラスを生成してリストで保持している self.skill = [Javaクラスオブジェクト, Pythonクラスオブジェクト...]

アイテムを画面に描画

def draw_object(self):
    """ 流れてくるオブジェクトを描画 """
    for enum in self.skill:
        u, v = enum.get_image(enum.name)
        for x, y in enum.position:
            pyxel.blt(x, y, 0, u, v, 16, 16, 5)

初期化処理で生成したself.skillから要素を1つずつ取り出してpyxel.blt()で描画する 上記のSkillクラスget_image()の引数にEnumクラス名を渡すと対応したアイテム画像の座標が 返ってくる

アイテムが流れるアニメーションをつける

# ゲームのメインクラス
def update(self):
    """ 画面のコントロール """
    # キー操作でキャラ移動する処理なども書かれている

    if self.game_mode == GameMode.Office:
        for enum in self.skill:
            for i, v in enumerate(enum.position):
                enum.position[i] = self.update_object(*v)

ここでもself.skillから取り出したEnumクラスのposition属性に位置座標を追加する

def update_object(self, x, y):
    """ オブジェクトのアニメーション """
    x -= 2
    if x < -40:
        x += 240
        y = randint(0, 104)
    return x, y

位置座標を引数のx座標 - 2して右→左に流れる座標リストが作れる(ここはお手本を写経)

キャラが会社に出勤してゲームスタート!

f:id:butorisa:20201020173748g:plain