ZawaWorks’s diary

プログラミング技術メモ

p5js:スマホのブラウザ上でmouseX,mouseYが使えない問題と解決法

はじめに

p5jsを使って簡単なお絵描きツールを作ろうとしたのですが、PC上ではマウスで線を描画できたのに、スマホ上ではタッチで線を描画することができませんでした。今回はその問題の解決法を紹介します。

環境設定

PC上でのコード

PCのブラウザ上でマウスを使い線を描画するため、index.htmlを用意しました。

index.html

<!DOCTYPE html>
<html lang="ja">

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width">
    <script language="javascript" type="text/javascript" src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.2.9/p5.min.js"></script>
<body>
    <script>
    / /p5js

       function setup() {
            createCanvas(displayWidth, displayHeight);
            background(255);

            strokeWeight(10)
            stroke(0);
        }

        function draw() {}

        function mouseDragged() {
            line(mouseX, mouseY, pmouseX, pmouseY);
            return false;
        }
  </script>
</body>

</html>

これを実行したすると次の動画のようになります。

youtu.be

スマホ上のコード

解決までの経緯

これをNode.jsでサーバを立ててスマホ上で開いてみます。server.jsindex.htmlと同じフォルダーに入れてください。

server.js

var http = require('http'),
    fs = require('fs');
var server = http.createServer();
var ipadress = "";//pcのipアドレスを書く
var port = 3000;//ポート番号

server.on('request', function (req, res) {
    fs.readFile(__dirname + '/indext.html', 'utf-8', function (err, data) {
        if (err) {
            res.writeHead(404, { 'Content-Type': 'text/plain' });
            res.write("not found!");
            return res.end();
        }
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write(data);
        res.end();
    });
});
server.listen(port, ipadress);
console.log("server listening ...");

これをnode serverで実行してスマホのブラウザで読み込みました。しかし、なぜか描画できない……。 調べてみるとどうやらp5jsにはtouchMoved()という関数が定義されており、スマホ上ではそちらを使うようです。そして、touchMoved()を使って線を描画するサンプルがあったのでindex.htmlの中身を変えてみました。

index.htmlのp5jsコードの部分

 function setup() {
    createCanvas(displayWidth, displayHeight);
    strokeWeight(10)
    stroke(0);
}

function touchMoved() {
    line(mouseX, mouseY, pmouseX, pmouseY);
    return false;
}

p5.js | examplesより引用

しかし、どれだけタッチしてもmouseXmouseYも値が0のままで、PC上のような描画ができませんでした。

解決方法

さらに調べてみるとtoutchesという配列がp5jsで定義されているようです( (p5:touches)https://p5js.org/reference/#/p5/touches

)。これはスマホのタッチデバイスで検出した指の本数分の座標を格納する配列です。これ使い、コードを書き直しました。

index.htmlのp5jsコードの部分

        var ptouchX;
        var ptouchY;

        function setup() {
            createCanvas(displayWidth, displayHeight);
            background(255);

            strokeWeight(10)
            stroke(0);

        }

        function draw() {
            ptouchX = touches[0].x;
            ptouchY = touches[0].y;
        }

        function touchMoved() {
            line(touches[0].x, touches[0].y, ptouchX, ptouchY);
            return false;
        }

youtu.be

すると見事に動きました!

最終的なコード

sketch.html · GitHub

おわりに

p5jsがマウスイベントとタッチイベントを全く別に定義していることを知らなかったため、PC上で動いたコードがスマホ上で動かなかったときは大変驚きました。p5jsは簡単にスマホ向けWebアプリを作れて便利ですので、皆さんもぜひ使ってみてください。

Node.jsでサーバーを立ててngrokで外部公開

はじめに

Node.jsでサーバーを立てて、htmlファイルを読み込むとき、ローカルホストではなく外部からURLを開くと自分のPCのIPアドレスがバレバレになってしまいます。今回は、それを防ぐために、ngrokというサービスを使った話をします。

Node.jsでサーバを立てる

同じフォルダー内にserver.jsindex.htmlを作ります。

sever.js

var http = require('http'),
    port = 3000,//ポート番号
    ipadress = 'localhost',//IPアドレス
    fs = require('fs');


var server = http.createServer();

server.on('request', function (req, res) {
    fs.readFile(__dirname + '/index.html', 'utf-8', function (err, data) {
        if (err) {
            res.writeHead(404, { 'Content-Type': 'text/plain' });
            res.write("not found!");
            return res.end();
        }
        res.writeHead(200, { 'Content-Type': 'text/html' });
        res.write(data);
        res.end();
    });
});

server.listen(port, ipadress);
console.log("server listening ...");

index.html

<!DOCTYPE html>
<html>

<head>
</head>

<body>
    Hello,world!
</body>

</html>

そうしたらコマンドラインを開いて、そのフォルダー内でnode serverとコマンドを打ちます。 そして、ブラウザでhttp://localhost:3000/を開いてください。下の画像のようになったら成功です。 f:id:ZawaWorks:20171225225338p:plain

ngrokで外部に公開

ngrokをインストールするとngrokコマンドが使えるようになります(ngrokのインストール方法)。 Node.jsでサーバを立てたら、以下のコマンドを打ってください。

ngrok http 3000

ここでの3000server.jsで指定したポート番号です。 そうすると以下のような結果が返ってきます。 f:id:ZawaWorks:20171225230017p:plain 上の画像の赤線を引いたURLをブラウザで開いてください。 f:id:ZawaWorks:20171225230156p:plain そうするとローカル環境のサイトであるindex.htmlが外部で公開できていることが分かります。

Processingがどの現場で使われているのか?

はじめに

 私が通う大学では、一年生のときにProcessingという言語を学びます。それゆえに、周り友人はこぞってProcessingでたくさん作っています。あるときその友人の一人が、現役エンジニアの方とお話しする機会があり、そのときに「Processingはあまり企業で使われない」と言われたそうです。この話を聞くと、「就職に関係ないから勉強しても意味がない」と思う方がいますが、そう考えるのはまだ早いです。なぜならProcessingに需要がある分野がきちんとあるからです 。今回は、そんなProcessingがどのような場所で使われているか紹介したいと思います。

Processingが使われている場所

教育

Processingはプログラミングの基礎を教えるのに役立つように作られています。 実際、公式サイトにも It is created to teach fundamentals of computer programming within a visual context and to serve as a software sketchbook and professional production tool. と書いてあります。 Processingは簡単なコードでしかもライブラリなしで描画ができるため、プログラミングやったことない人でもお絵描きやゲーム作成ができます。だからプログラミング初心者は楽しみながら学ぶことができます。その中で「実はfor文というのが便利で……」、「関数っていうのがあってね……」、「クラスって便利だよ……」と教えていくと、すんなりとプログラミングの文法やオブジェクト指向の基礎が身につくのです。

研究

さきほどの話を聞いて「じゃあ、自分はもうプログラミングできるから必要ない」と思った方はちょっと待ってください。Processingはインタラクションデザインやインターフェースデザインといった分野でプロトタイプ(試作品)作成に使われています。たとえばProcessingをプロトタイプに活用した研究に以下のようなものがあります。

この3つのうち上の2つはエンタテインメントコンピューティングシンポジウムという学会で発表されたものです。

ProcessingはOpenCVを使った画像処理やMinimというライブラリを使った音声処理ができます。

r-dimension.xsrv.jp

r-dimension.xsrv.jp

さらにArduinoKinectといったツールとの連帯も可能です。

yoppa.org

www.d-improvement.jp

他にもProcessing..jsというJavaScriptのライブラリを使えばWeb上でProcessingで作った作品を公開することができますし、Processing for AndroidというツールでAndroidアプリを作成することもできます。

qiita.com

youtu.be

このように、Processingは簡単なコードで様々なことができるので、プロトタイプを作るのに適しているのです。

最後に

Processingには様々な活用法があり、すぐに作りたいものができるという利点があります。クオリティや精度を求めるアプリを作成するには向いていないかもしれませんが、それが必要ないならProcessingでさくっと作ってしまうのがお得です。

Yahoo!のエンジニアに聞いてみた五つの質問

はじめに

先月、友人と「【学生エンジニア限定】Yahoo! JAPAN MeetUp #14 ~マーケティングを支える~ - connpass」というイベントに参加してきました。そのイベントでは若手のエンジニアの方が現場でどういう活動をしているのかということをプレゼンしていて、後半に行われた懇親会では、Yahoo!のエンジニアの方と会話する機会がありました。そこで友人と私は色々と気になったことを質問していたら興味深い答えが返ってきたのでそれらをまとめてみました。多少、返答の言葉の表現が違いますのでご了承ください。

目次

質問に答えてくれた方々

  • 新卒一年目のお姉さん
  • 新卒二年目のお姉さん
  • 中途一年目のお兄さん
  • 自称新卒のおじさん(偉い人らしい)

Q.インターンは行った方がいいですか?

来年度、学部三年生になることもあってインターンについて質問してみました。

A.参加するとよい by 新卒一年目のお姉さん

就職面接において、インターンに行ったということは「行動力がある」、「企業での実戦経験がある」と評価されるから。

A.参加するとよい by 新卒二年目のお姉さん

その会社の雰囲気だったり、「働く」ということがどういうものなのか実感できるから。

Q.どんなインターンに行った方がいいですか?

では、どんなインターンがよいのでしょうか? 質問してみたら様々な答えが返ってきました。

A.長期のインターンがよい by 新卒二年目のお姉さん

就職面接のことを考えると長期がよい。というのも、長期インターンにいたということは実際の働く環境を体験し、かつ、長く労働する気力があるということだから。

A.一つに絞るのではなくいろんなところに行こう by 自称新卒のおじさん(お偉いさんらしい)

インターン先は、「大手企業」、「下請け企業」、「ベンチャー企業」の大きく三つに分かれる。これらはそれぞれ雰囲気が違うから各々体験した方がよい。長期か短期かということなら、長期はやりたいことができる場所の方がモチベーションが保ちやすいからよく、短期はあっという間に終わることから自分が勉強してみたい分野で選んだらよいと思う。

Q.転職するときに気をつけることはありますか?

プログラミングの勉強会に参加すると何人か転職の経験があるエンジニアに出会うことがあります。また、ネット記事でもエンジニアの転職について述べているものが何度か目に入ってくることもあって、転職に興味を抱いていました。(まだ就職すらしていない学生なのに……)中途一年目のお兄さんにこの質問を投げてみました。すると二つ答えが帰ってきました。

A.作品を作っておくことが大事 by 中途一年目のお兄さん

たまに「プログラミングができる」と自称しているのに自分の作品を持っていない人がいるけれどこれはダメ。作品を持っているということはそれを作り上げる技術があるという証明になる。逆に作品を持っていないということは「プログラミングができない」のと同じ。

A.中途採用ページを確認しておこう by 中途一年目のお兄さん

中途採用ページには「これがあるとよい」みたいな条件が書かれている。そのスキルを持っている人こそ、その企業が求めている人材。だから、そのスキルを持っているともちろん受かりやすくなる。中途採用ページを見て、自分がその企業の求めてるスキルを持っているか確認しよう。

Q.ハッカソンの参加は面接で評価されるのか?

友人がハッカソンに挑戦するらしくこんな質問をしていました。

A.チームで作ったという経験は評価される by 新卒二年目のお姉さん

入社したら個人での作業よりチームでの作業の方が多い。だから、チームで何かを作ったという経験は評価される。実際に私も面接で聞かれた。

A.賞を取っていれば強みになる by 自称新卒のおじさん

評価されるか否かはハッカソンの内容によって変わってしまう。しかし、賞を取ったという実績はもちろん評価される。

Q.Webサービスを作るときに気をつけることは?

友人がWebサービスを作ってみたいと思っていて、自称新卒のおじさんに質問したら、以下のような答えが返ってきました。

A.公開することが大事 by 自称新卒のおじさん

最初は誰も使ってもらえないけれど、公開してサービスを続けていくことが大事。ユーザに使ってもらうことで改善点が分かり、それを改善していくうちに得るものがあるはず。とは言っても永遠に続ける必要はないからどこかで区切りをつけよう。

おわりに

今回はエンジニアの方々に就職という側面でいろいろな質問をしていきました。学生の私は、あまりエンジニアの働く姿が想像できなかったのですが、このイベントに参加したおかげで、これからどういった行動をすべきかの指針を知ることができました。あくまで個人的に知りたかったことしか質問していなかったのですが、もしこの記事が役立てたなら光栄です。

Google ドキュメントでLaTeXを使う方法

はじめに

Google ドキュメントには計算式を書くツールがあるのですが、それが私には使いづらいものでした。そのとき「LaTeX記法使えたらな~」と探していたら、なんとLaTeX記法が使えるアドオンがあったので紹介します。

Auto-LaTeX

chrome.google.com 今回紹介するのは「Auto-LaTeX」というアドオンです。 上のリンクからインストールすることができるようになっています。

使い方

LaTeX記法の文を書く

今回は$$3^{4^5} + \frac{1}{2}$$と書きました。

Auto-LaTeXを有効にする

f:id:ZawaWorks:20171207172859p:plain

アドオンタグの中にある「Auto-LaTeX」にカーソルを合わせると、右に「start」が出てくるのでそれをクリックします。

LaTeX記法の文を計算式に変換

f:id:ZawaWorks:20171207173242p:plain

すると右側にAuto-LaTeXの操作画面が出てきます。 赤い丸で囲んでいる「Render Equations」というボタンを押してみましょう。

結果

f:id:ZawaWorks:20171207173052p:plain

「Render Equations」を押したらLaTeX記法で書かれた文が計算式に変わります。 ちなみに「De-render Equations」を押すとLateX記法に戻ります。

参考資料

docs.google.com

SQLite:上から何番目の行を削除したい

はじめに

最近、大学でSQLiteを習ったのですが、データベースを作成中「上から〇番目のものを消したいな」と思ったのですが、それが上手くいかなかったのでいろいろと調べてみました。

使うテーブル

テーブル名:user

id name
2 tanaka
5 kato
7 maeda

LIMITとOFFSET

SELECT文ではLIMITとOFFSETという変数を指定するだけで、上から何番目の行を指定することができます。

LIMIT

limitというのは抜き出した行(またはパラメータ)の数を制限する命令です。 たとえば

SELECT * FROM user LIMIT 2;

としたときの結果は以下の表になります。

id name
2 tanaka
5 kato

OFFSET

OFFSETというのは行を取得するときの開始位置を決める命令です。 LIMITを使用しているときのみ使用可能です。

たとえば

SELECT * FROM user OFFSET 1;

と書くとエラーを吐きます。

実際に使用するときは

SELECT * FROM user LIMIT 2 OFFSET 1;

と書きます。その結果は以下の表になります。

id name
5 kato
7 maeda

上からk番目を取得したいとき

以上のことを踏まえると上からk番目を取得する書き方は以下のようになります。

SELECT * FROM user LIMIT 1 OFFSET k-1;

上からk番目を削除したい

これをDELETE文でもできないかと思い以下のようなコマンドを書きました。

DELETE FROM user LIMIT 1 OFFSET k-1;

しかし、このコードはエラーを吐いてしまいました……。 どうしてかと思い調べてみるとこんな図がありました。

f:id:ZawaWorks:20171207233626p:plain

SQLite Syntax: delete-stmt-limitedより引用

つまりはDELETE文ではLIMITOFFSETも使えないらしいです。

SELECT文と組み合わせる

じゃあ、上からk番目を消すことができないのかというと別にそういうわけではなく、SELECT文と組み合わせると可能になるようです。

delete from user where id = (select id from user limit 1 offset k-1);

(select id from user limit 1 offset k-1)は上からk番目の行のidを取得しています。そのidと同じ行を削除すれば結果的に上からk番目の行を削除できるというわけです。

おわりに

今回はDELETE文でスマートに上からk番目を削除したかったのですが、どうやら仕組み的に間接的な方法しかないことが分かりました。 ただ正直、遠回りな分コマンドが長くなってしまうのはあまり好きではないですね……。

参考資料

SQLite Query Language: DELETE

標高からきんモザのアリスちゃんを探してみた

はじめに

今回は大学のプログラミング授業で「APIを使ってWebサービスを作ろう」という課題で自分が提出した作品について語ろります。

Webサービスの説明

左にある地図をタップするとそこの標高が取得され、その標高に合わせてアニメ「きんいろモザイク」のアリスちゃんのgif画像を表示します。

f:id:ZawaWorks:20171206032036p:plain

完成図

youtu.be

試したブラウザ

使用したAPI

プログラムの仕組み

1.緯度・経度を取得

Yahoo!JavascriptマップAPIを使い地図の表示と、そこをタップした座標(緯度・経度)の取得に使いました。

html

 <script type="text/javascript" charset="utf-8" src="https://map.yahooapis.jp/js/V1/jsapi?appid=[ここにapikeyを入れる]"></script>
 <div id="map"></div>

Javascript

 var ymap = new Y.Map("map");

//地図の表示
    ymap.drawMap(new Y.LatLng(35.36055, 138.72777), 15, Y.LayerSetId.NORMAL);//緯度・経度は富士山を基準の座標に指定

//緯度・経度を取得するメゾット
 ymap.bind('click', function (latlng) {
console.log("緯度:" + latlng.lat() + ",経度:" + latlng.lng());
});

2,標高の取得

国土地理院が提供している標高APIは緯度・経度を入力すればそこの標高を返してくれます。

var URL = "http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=" +[経度]+ "&lat=" + [緯度] + "&outtype=JSON"
        
$.getJSON(URL, function (response) {
console.log(response.elevation.);//標高を表示
})

3.きんモザAPIを叩く

きんモザAPIきんいろモザイクのアリスちゃんのgif画像を返してくれるAPIです。一話から十二話までの話数を指定する「ep」とその中で何番目のgif画像を指定するかという「no」を指定するとgif画像を返してくれます。

<iframe id="gif"></iframe>
    var gif_url = 'http://mogashi.com/alice/?ep=' + ep + '&no=' + no;
        document.getElementById('gif').src = gif_url;

4.APIを組み合わせる

大雑把な流れは緯度・経度の取得->標高の取得->標高から「ep」、「no」を指定してgif画像を呼び出すです。 「ep」は標高を300で割った値にして、「no」は十の位と一の位を4で割った値にしている。

最終的なコード

index.html

<!DOCTYPE html>
<html>

<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
</head>

<body>
    <div style="width:1020px; display:table;">
        <div id="map" style="width:600px; height:300px;display: table-cell;"></div>

        <div style="width:600px; display:table-cell;">
            gif画像
            <br><br>
            <iframe id="gif" src="http://mogashi.com/alice/?ep=2&no=50" name="gif" width="500" height="300"></iframe>
        </div>
    </div>
    好きなところにクリックしてね
    <script type="text/javascript" charset="utf-8" src="https://map.yahooapis.jp/js/V1/jsapi?appid=[ここにapikeyを入れる]"></script>
    <script type="text/javascript" src="./main.js"></script>
</body>

</html>

main.js

window.onload = function () {
    var ymap = new Y.Map("map");
    ymap.drawMap(new Y.LatLng(35.36055, 138.72777), 15, Y.LayerSetId.NORMAL);

    ymap.bind('click', function (latlng) {
        var URL = "http://cyberjapandata2.gsi.go.jp/general/dem/scripts/getelevation.php?lon=" + latlng.lng() + "&lat=" + latlng.lat() + "&outtype=JSON"
       
 $.getJSON(URL, function (response) {
            console.log(response.elevation);
            var ep = Math.floor(response.elevation / 300);
            var no = Math.floor((response.elevation - Math.floor(response.elevation / 100) * 100) / 4);
            AliceGif(ep, no);
        })
    });

    //アリスちゃんのgif画像を返してくれる関数
    function AliceGif(ep, no) {
        if (ep < 1) ep = 1;
        if (ep > 12) ep = 12;
        var gif_url = 'http://mogashi.com/alice/?ep=' + ep + '&no=' + no;
        document.getElementById('gif').src = gif_url;
    }

}

おわりに

我ながら意味不明なWebサービスを作ってしまったと思っています……。ただこれによりどんなgif画像が見つかるか予測することが難しいため、未知との遭遇を演出できるのではないでしょうか?今回紹介したAPIやそのソースコードが何かの役に立てたなら光栄です。