はこねのはこ

はこねさんの備忘録

Railsの開発環境をAtomでまとめた

はじめに

やっとローカルでRails開発始められるようになりました。
開発に必要なものをできるだけ1画面に収めたかったのですが、 いい感じにできたので使ったパッケージをメモ。

前回の話はこちら hakonebox.hatenablog.com

見た目

こんな感じになりました。 f:id:hakonebox:20181017221245p:plain

入れたパッケージ

browser-plus

ブラウザの機能を追加してくれます。
macの場合は'ctrl + option + o'で起動。
f:id:hakonebox:20181017221653p:plain
このLiveボタンを押していると、html等を変更した時にすぐに反映してくれます。
HTMLがどう表示されるのか試しながら書いているのですごい助かります。

atom.io

platformio-ide-terminal

Atom上にターミナルを表示できます。
macの場合は'shift + command + t'で起動。
複数開けました。 AtomのAdd Project Folderで指定したフォルダをカレントディレクトリにしてくれるようです。

atom.io

おわりに

環境が整えられるとやる気出てきますね。

Railsの開発環境を用意するメモ(Mac)

はじめに

macbookpro2012から2018に乗り換えたのでRailsの環境構築します。 (いまさら)

Dockerで完結しようと思いましたが、ローカルにも作っておきます。

環境

手順

rbenvのインストール

rbenvでrubyバージョンを切り替えることができます。

$ brew install rbenv

$rbenv --version
rbenv 1.1.1

インストールできました。

rubyのインストール

バージョン一覧を確認

rbenv install -l
2.4.3
2.4.4
2.5.0-dev

Progateで学習したバージョンに合わせて2.4.4にします。

$ rbenv install 2.4.4

パスの設定をします

$ touch ~/.bash_profile
echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile
$ source ~/.bash_profile

全てのシェル内で使用されるRubyのグローバルのバージョンを設定します

$ rbenv global 2.4.4
$ ruby --version
ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-darwin17]

2.4.4に変更することができました。

bundlerのインストール

rubyのライブラリ’gem’を管理できます

$ sudo gem install bundler
$ rbenv rehash
$ bundler --version
Bundler version 1.16.6

MySQLのインストール

$ brew install mysql
MySQL --version
MySQL  Ver 8.0.12 for osx10.13 on x86_64 (Homebrew)

Railsのインストール

$ sudo gem install rails --version "5.0.3"
$ rails -v
Rails is not currently installed on this system. To get the latest version, simply type:

    $ sudo gem install rails

You can then rerun your "rails" command.

うまくできなかったのかな。 ググった結果以下のコマンドの入力

$sudo gem install railties && rbenv rehash
$ rails -v
Rails 5.2.1

5.2.1が入ってしまった。
Gemfile作る時になんとかしようと思います。

プロジェクトフォルダの作成

$ mkdir 08_Ruby_Rails
$ cd 08_Ruby_Rails/

Railsアプリケーションの準備

$ rails new mussle_logger
Errno::EACCES: Permission denied @ dir_s_mkdir -

エラーが出たので権限の確認

~/.rbenv/versions/2.4.4/lib/ruby/gems/2.4.0/extensions:ls -la
total 0
drwxr-xr-x  3 username  staff   96 10 16 21:42 .
drwxr-xr-x  8 username  staff  256 10 16 22:10 ..
drwxr-xr-x  3 root    staff   96 10 16 21:42 x86_64-darwin-17

権限がrootになっているのが問題らしいです。

sudo chown username x86_64-darwin-17/
ls -la
total 0
drwxr-xr-x  3 username  staff   96 10 16 21:42 .
drwxr-xr-x  8 username  staff  256 10 16 22:10 ..
drwxr-xr-x  3 username  staff   96 10 16 21:42 x86_64-darwin-17

しかしこれでも同じようなエラーが発生

$ sudo gem update
Updating installed gems
Updating did_you_mean
ERROR:  Error installing did_you_mean:
    did_you_mean requires Ruby version >= 2.5.0.
Gems updated: did_you_mean
$ rbenv install 2.5.0
& rbenv local 2.5.0
$ gem update
rbenv local 2.4.4
rails new mussle_logger --skip-bundle
bundle install --path vendor/bundle
bundle exec rails s

http://0.0.0.0:3000/

f:id:hakonebox:20181016231349p:plain

さいごに

やーーーっとYayできました。 恐ろしいほど疲れた。

追記20181017

次の日もう一度rails new mussle_loggerを実行したら何事もなかったかのように通りました。 PCはスリープだったし、ターミナルの再起動? なぜかわからないのが逆に怖い。

参考

参考にさせていただきました。

prog-8.com

ruby.studio-kingdom.com

qiita.com

qiita.com

qiita.com

Ruby - sqlite3のエラーでサーバーが建てられません|teratail

バッチファイルを作成して起動するだけでその日の日付のフォルダを作成する

はじめに

小さなことから楽したいと考えていた時に、このbatファイルを作成しました。

batファイルは食わず嫌いで全く興味なくて調べたことなかったけど、 結構気軽に動かせそうです。

環境

Windows10

なぜつくったの

仕事厨二、その日の日付でフォルダを作ることがよくあるのですが、
毎回作成することがものすごく面倒に感じたので、
ダブルクリックでbatファイルを叩けばその日の日付ファイルが作成できるようにしました。

できたもの

: エコー機能無効
@echo OFF

: 日付を取得し'/'を取り除く
set dirname=%DATE:/=%

: 西暦の千の位、百の位を取り除く
set today=%dirname:~2,6%

: ディレクトリの作成
mkdir %today%

cd %today%

mkdir 01_todo
mkdir 02_done

おわりに

日常の作業を楽できる方法をもっと知りたい。

Unity 画像の向きを反転させる

はじめに

2Dゲームを作っていて、右向きの画像を左向きにするなど、反転させたい時があります。 その時の実現方法のメモです。

動いてる様子

f:id:hakonebox:20181014203254g:plain

実現方法

transform.のScaleのXを1と-1で切り替えると良さそうです。

public class ActorManager : MonoBehaviour
{
    public enum DIR
    {
        NONE,
        LEFT,
        LEFT_UP,
        UP,
        RIGHT_UP,
        RIGHT,
        RIGHT_DOWN,
        DOWN,
        LEFT_DOWN
    }
    public static Vector3 SetObjectDir(DIR dir)
    {
        Vector3 vector3 = new Vector3(1, 1, 1);
        switch (dir)
        {
            case DIR.RIGHT: 
                vector3 = new Vector3(-1, 1, 1); //右方向を向く
                break;
            case DIR.LEFT: 
                vector3 = new Vector3(1, 1, 1); //左方向を向く
                break;
            default:
                //do nothing
                break;
        }
        return vector3;
    }
}
        switch (charMoveSi)
        {
            case MOVE_DIR.STOP:
                break;
            case MOVE_DIR.LEFT:
                transform.localScale = ActorManager.SetObjectDir(ActorManager.DIR.LEFT);
                break;
            case MOVE_DIR.RIGHT:
                transform.localScale = ActorManager.SetObjectDir(ActorManager.DIR.RIGHT);
                break;
        }

おわりに

実現できるようにはなりましたが、なんだか納得できていません。
戻り値にVector3つかって、transform.localScaleに入れるのはどうなんでしょう?
もっとスマートにかけるような....

Unity Invokeの使い方メモ

はじめに

普段Unity開発してた時に、なんとなく使ってたInvoke
現在セットされているかや、キャンセルの仕方等がわかっていなかったので、 やり方を確認しました。
その時のメモです。

Invoke使い方

セットする

Invoke("CallFunction",5)

Invoke(関数名,時間)で実行します。
時間の単位は秒です。
5とすると5秒になります。
0.5fとすると0.5秒になります。

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I)) 
        {
            Debug.Log("Invokeセットしました。");
            Invoke("CallFunction",5);
        }
    }

    void CallFunction()
    {
        Debug.Log("時間が経過しました。");
    }

f:id:hakonebox:20181013210918p:plain
5秒後に実行されました。

セットされているか確認する

IsInvoking("CallFunction")

isInvoking(関数名)を使用します。

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I)) 
        {
            Debug.Log("Invokeセットしました。");
            Invoke("CallFunction",10);
        }
        if (Input.GetKeyDown(KeyCode.C))
        {
            Debug.Log(IsInvoking("CallFunction"));
        }

    }

    void CallFunction()
    {
        Debug.Log("時間が経過しました。");
    }

f:id:hakonebox:20181013210546p:plain
セットされている場合には戻り値はTrueになります。
CallFunction関数が実行後は戻り値はFalseになります。

キャンセルする

特定の関数のみキャンセルする

CancelInvoke("CallFunction")

cancelInvoke(関数名)を使用します。

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I)) 
        {
            Debug.Log("Invokeセットしました。");
            Invoke("CallFunction",5);
            Invoke("CallFunctionCheck",5);
        }
        if (Input.GetKeyDown(KeyCode.C))
        {
            Debug.Log("キャンセルしました。");
            CancelInvoke("CallFunction");
        }
    }

    void CallFunction()
    {
        Debug.Log("時間が経過しました。");
    }
    void CallFunctionCheck()
    {
        Debug.Log("(確認用)時間が経過しました。");
    }

f:id:hakonebox:20181013211554p:plain
キャンセルしたCallFunction関数は実行されず、 CallFunctionCheck関数のみが実行されました。

全てキャンセルする

CancelInvoke()

cancelInvoke()引数なしで実行します。

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.I)) 
        {
            Debug.Log("Invokeセットしました。");
            Invoke("CallFunction",5);
            Invoke("CallFunctionCheck",5);
        }
        if (Input.GetKeyDown(KeyCode.C))
        {
            Debug.Log("キャンセルしました。");
            CancelInvoke();
        }
        if (Input.GetKeyDown(KeyCode.T))
        {
            Debug.Log("経過時間確認用");
        }
    }

    void CallFunction()
    {
        Debug.Log("時間が経過しました。");
    }
    void CallFunctionCheck()
    {
        Debug.Log("(確認用)時間が経過しました。");
    }

f:id:hakonebox:20181013212226p:plain

CallFunction関数もCallFunctionCheck関数も実行されませんでした。

おわりに

Invokeは使いやすくて私は好きです。

はてなブログにGoogleアナリティクスを導入する

はじめに

アクセス解析をみていて、どんな検索ワードで、どんなルートでこのページに辿り着いているのかを知りたいと思いました。

どうやらGoogleアナリティクスが良いらしいので導入してみようと思います。

導入したその時のメモです。

f:id:hakonebox:20181012192029j:plain

導入してみる

アナリティクスの申し込み

marketingplatform.google.com

公式のページからGoogle アナリティクスの使用を開始の申し込みをします。

ラッキングIDの取得

必要事項を記入するだけでした。 登録が終わるとトラッキングIDが表示されました。 f:id:hakonebox:20181012190532p:plain

はてなブログに登録する

設定→詳細設定を開き、 f:id:hakonebox:20181012193033p:plain

解析ツール→Google Analytics 埋め込みに 先ほど取得したIDを貼り付け f:id:hakonebox:20181012191142p:plain

ページ最後の"変更する"を押して設定完了です。

おわりに

思ったよりも簡単に導入できました。
本当に導入できたか不安になるくらいです。
しばらく使ってみようと思います。

HTML,Javascriptでブラウザで動く4択問題集アプリを作ってみた。(CSV読み込み)

はじめに

今日、仕事中に5時間弱ぽっかりと時間ができました。
Javascriptは以前にねこアプリを作って以来1年ほど全く触っていなかったのですが、またなにかしら遊んでみようと思い、 5時間である程度動くところまで開発するチャレンジをしてみました。

JSはしっかりと勉強したことはなく、ググりながらゴリ押しで作っているので、そのへんご了承ください。
また、このスクリプトに関しての解説は全くありません。
また、検査等もほぼほぼ行っていません。

なぜ4択問題集アプリ?

タイトルにもあるように、4択問題集アプリを作りました。
社内でちょっとした年2回試験があるのですが、それの対策のために問題集アプリをちょうど欲しいと思っていました。

できました。

GitHub

github.com

こんな感じで動きます

JS Question 4

index.html

<!DOCTYPE HTML>
<html>
<head>
   <meta charset="utf-8">
   <title>JS Question 4</title>
   <link rel="stylesheet" type="text/css" href="styles.css">
</head>
<script type="text/javascript">
   // 読み込んだデータを1行ずつ格納する配列
   var allData = [];
   var sW,sH,s;
   var now_question = 0;
   if (window.File && window.FileReader && window.FileList && window.Blob) {
   //alert('JS対応');
   } else {
   alert('JS未対応のブラウザです。たぶん動作しません');
   }

   loadCSV("./data.csv");
   setTimeout("setQuestion(now_question)", 10);//ms //一瞬間隔がないとダメみたい

   //ウィンドウサイズを取得する
   function getWindowSize() {
       sW = window.innerWidth;
       sH = window.innerHeight;
   }

   function setQuestion(number){
       document.getElementById("id_question").innerHTML=allData[number].question;
       document.getElementById("id_ChoiceA").innerHTML=allData[number].A;
       document.getElementById("id_ChoiceB").innerHTML=allData[number].B;
       document.getElementById("id_ChoiceC").innerHTML=allData[number].C;
       document.getElementById("id_ChoiceD").innerHTML=allData[number].D;
       if(allData[now_question].Q_gazo != 'none'){
           mondairesize();
           document.getElementById("id_mondaigazo").src='./gazo/'+allData[now_question].Q_gazo;
       }else{
           document.getElementById("id_mondaigazo").scr='';
           document.getElementById("id_mondaigazo").width=0;
       }
       document.getElementById("id_pf").innerHTML='';
       document.getElementById("id_kotae").innerHTML='';
       document.getElementById("id_mondaigazo").scr='';
       document.getElementById("id_kaitougazo").src='';
   }

   function next_question(){
       //現状ではループさせている
       if(allData.length-1 > now_question){
           now_question++;
       }else{
           now_question = 0;
       }
       setQuestion(now_question);
   }

   function kaitouresize(){
       getWindowSize();
       document.getElementById("id_kaitougazo").width=sW;
   }
   function mondairesize(){
       getWindowSize();
       document.getElementById("id_mondaigazo").width=sW;
   }

   function myCheck(){
       var seikai = allData[now_question].ANS;
       var kaitou = '';

       if(document.form1.elements[0].checked){
           kaitou = kaitou + 'A';
       }
       if(document.form1.elements[1].checked){
           kaitou = kaitou + 'B';
       }
       if(document.form1.elements[2].checked){
           kaitou = kaitou + 'C';
       }
       if(document.form1.elements[3].checked){
           kaitou = kaitou + 'D';
       }

       if(kaitou == seikai){
           document.getElementById("id_pf").innerHTML='正解です';
       }else{
           // 不正解の時は背景色を変えたい
           document.getElementById("id_pf").innerHTML='不正解です';
       }
       getWindowSize();
       document.getElementById("id_kotae").innerHTML=seikai;
       document.getElementById("id_kaitougazo").width=sW;
       if(allData[now_question].A_gazo != 'none'){
           document.getElementById("id_kaitougazo").src='./gazo/'+allData[now_question].A_gazo;
       }
   }

   function loadCSV(targetFile) {
       var request = new XMLHttpRequest();
       request.open("get", targetFile, false);
       request.send(null);
       var csvData = request.responseText;
       var lines = csvData.split("\n");
       for (var i = 0; i < lines.length; i++) {
           var wordSet = lines[i].split(",");
           var wordData = {
               question: wordSet[0],
               A: wordSet[1],
               B: wordSet[2],
               C: wordSet[3],
               D: wordSet[4],
               ANS: wordSet[5],
               Q_gazo: wordSet[6],
               A_gazo: wordSet[7],
           };
           allData.push(wordData);
       }
}

</script>
<body>
    <section>
        <hgroup>
            <h1>JS Question</h1>
        </hgroup>
        <section class="section-sub">
            <h4>問題</h4>
            <P id='id_question'>起動中</P>
            <img src="" alt="" id="id_mondaigazo" width="100" onclick="mondairesize();" />
            <form name="form1">
                <input type="checkbox" name="questions" value="A"><label id='id_ChoiceA'>A:選択肢A</label><br>
            <input type="checkbox" name="questions" value="B"><label id='id_ChoiceB'>B:選択肢B</label><br>
            <input type="checkbox" name="questions" value="C"><label id='id_ChoiceC'>C:選択肢C</label><br>
            <input type="checkbox" name="questions" value="D"><label id='id_ChoiceD'>D:選択肢D</label><br>
            <input type="button" value="解答" onclick="myCheck();">
            </form>
        </section>
        <section class="section-sub">
            <h4>解答</h4>
            <p id='id_pf'>-</p>
            <p id='id_kotae'>-</p>
            <img src="" alt="" id="id_kaitougazo" width="100" onclick="kaitouresize()" />
            <form name="form2">
            <input type="button" value="次の問題へ" onclick="next_question()" >
            </form>
        </section>
        <p>画像をクリックでサイズウィンドウ横幅に合わせます</p>
</body>

styles.css

.section-sub{
    background-color: #d8bfd8;
}

つかいかた

CSVに問題と選択肢、解答、参考画像の設定をします。
回答はA,B,AB,BCDなど、どれか一つ選ぶ問題でも複数選ぶ問題も対応しています。
問題の参考画像、解説の参考画像を載せたい場合は、 "gazo"というフォルダを作成し、そこに載せたい画像を保存します。 CSVに画像ファイル名を記載すれば表示できます。
記載しない場合はnoneと記載してください。

5時間チャレンジで達成できなかったこと

またぽっかり時間ができたら更新します。

おまけ宣伝ねこアプリ(クリーンキャット)

1年前に作成したアプリ。
それは癒しのwebアプリ。
たぶん仕事以外に初めて公開したアプリ。 github.com

https://yuikanoyu.github.io/cleanCat/