Write Code or Die

RubyやRailsまたはバスケットボールや筋トレについて書きます。

Goはじめました

Software Skillsに影響された

とあるきっかけでGo言語を利用する機会がでてきたので勉強の記録のためにもここに記す。 ブログとか書かない派だったのだが、Software Skillsを読んで書くことを決意した(単純かというツッコミは置いといて) 「そもそも、勉強した内容とか今更ブログに書いたところでもう既に世の中に出回ってるよー」という感じだが、一応書いてみる。

自分はRuby(Rails歴)2年 = プログラミング歴というバックグラウンドなので、他の言語をしっかり勉強するのは初めてであるし、静的言語とか型とかよくわからないのでこれを機にぜひ克服したい。

パフォーマンスはRubyの3倍らしいので、簡単なAPIサーバーとかGoで書けるようになりたいですな。

Go言語の文法を学ぶ

まずは文法のお勉強から

A Tour of Go

とりあえず一通り理解しながら目を通した感じ。理解が△でもどうせまた使うときにちゃんと調べればいいので、ふーんという感じで流していた。合計2-3時間くらいで完了。

Rubyしか触ったことない自分としては、型宣言するのってこういうことなのかーというのがまずは率直な感想。

途中interfaceってなんやこれはって思ったけれども、 http://cuto.unirita.co.jp/gostudy/post/interface/ これが非常に参考になった。Rubyでダックタイプを使っていたので、それと関連しながら考えることができた。型ってこういうことか。

最後の方に並列処理の部分とかあったけど、普通のWebアプリケーションとかではいつ出番が来るのだろうか?集計した結果とかを表示したい時とかにいいのかな?Go言語で目玉の機能なので積極的に使っていきたい。

WEB Applicationを作ってみる

では実際にGo言語でWeb Applicationを作るためにはどうすればいいのだろうと思ったので、A Tour of Goの最後のページにリンクしてあったオフィシャルなチュートリアルをやってみることにした。

Writing Web Applications - The Go Programming Language

カバーしている領域として

  • 読み書きができるデータ構造の作り方
  • Web Applicationを作るためのnet/httpパッケージの使い方
  • HTMLを処理するためのhtml/templateパッケージの使い方
  • ユーザのインプットをバリデーションするためのregexpパッケージの使い方
  • クロージャの使い方

と書いてあるのでまさに今欲しい内容

上から順番に一通りやって見て、1時間ちょいで完成。

チュートリアルとしても出来が良かった。

関数型言語の書き方がなんとなくわかってきた気がする。

net/httpパッケージを利用すれば簡単にwebアプリケーションを作ることができる感覚もできた。

handlerを準備してあげればよしなにやってくれるのかーと思ったが、もうちょい理解したいので公式ドキュメントを読む

ListenAndServe starts an HTTP server with a given address and handler. The handler is usually nil, which means to use DefaultServeMux. Handle and HandleFunc add handlers to DefaultServeMux:

handlerは通常nilだけど、Handle か HandleFuncがDefaultServeMuxにhandlerを加える….

何がわからないかって単純に「ハンドラ」というものがわからなかった…

What is a handler - Stack Overflow

あるケースでの処理の塊みたいな感じ?

handlerを加えるということは「このURLリクエストの時はこの処理です!」という宣言をするということだろうか。

恐らくかなり基本のことなんだけど、こういう基礎をちゃんとこのタイミングで知れてよかった(本当に良かった…)

というわけでハンドラを加えて簡単なアプリケーションが作れた!

次はJSON API サーバーを作るためにはどうすればいいのだろうか?ということでやって見たいと思う。

体育館予約を自動化しようとした話

この記事はFablic Advent Calendar 16日目の記事です。 http://qiita.com/advent-calendar/2016/fablic

こんにちは。Fablicのサーバーサイドエンジニア、Jamesです。 業務とは関係ないところでちょっとしたシステムを作ろうとした話をします。

今回を機にこのブログ開設しました。気が向いたときに色々発信してたいと思います。

概要

  • 手段と目的
  • 某区の体育館予約を自動化したい
  • 某区の体育館予約システムについて
  • Selenium WebDriverを使って体育館予約を自動化
  • ログインしてみる
  • そしていよいよ予約へ・・・

手段と目的

よく「テクノロジーは手段であり、目的ではない」という言葉を聞きますが、果たしてその通りにテクノロジーを使えている人はどれくらいいるでしょうか?実際に業務でバリバリプログラムを書いているエンジニアも、自分の身の回りのことにその技術を生かしきれていないことは多々あるのではないでしょうか。

かくいう私もそうです。「少しでも世の中を便利にしたい」という思いでエンジニアになったにも関わらず、業務以外で技術を活かすことがなかなかできずに「自分の周りのことも何も変えられないのはなんだかなー」と考え、そんな自分に悔しさを感じていました。

某区の体育館予約を自動化したい

話は変わり、私は中学でバスケットボールを始めてから今でも週1程度で続けております。なかなかハードなスポーツですが、体を動かすのは気分転換になります。好きなプレイヤーは昔からKobeですが、Mike Millerみたいなサイズがあるシューターとか、最近ではKenneth Fariedが好きです。日本人だと筑波大学の馬場雄大選手に注目しています。GW大学の渡辺雄太選手も大注目ですね!Bリーグも開幕して、なかなかバスケットボールシーンは熱くなっております。

しかし、そのバスケットボールを日本でする上で避けては通れない問題が一つあります。 それは 体育館がなかなか取れない ということです。

様々なつながりで集まった仲間でチームを作って活動していたのですが、体育館を取ることができない事が原因でなかなか集まって一緒にバスケットボールをすることができませんでした。

しかし、この状況を打開すべく、ついに先日某区でチーム登録を済ませました。 それまで知り合いのチームに遊びに行かせていただいたり練習もせずに試合に出ていたりしたのですが、体育館が取れるようになると話は変わってきます。

私たちは、「これで自分たちの練習ができる!」と意気込んでいました。

しかし 体育館予約が全然できない のです。

原因としては

  • 予約はWeb上で行うことができるのだが、システムにアクセスできる時間が限られており、見れる人が少ない(9:00~22:00)
  • 予約できる日が限られている
  • 登録団体が多すぎて、空きが出ない

ということが挙げられます。

せっかくチーム登録をしたのに体育館が取れない! これはどうにかしなければいけないと思い、私はこう思いました。

「そうだ、ついに自分の技術力を役立てることができる」

Selenium WebDriverを使って体育館予約を自動化

今回はWeb上の動作を自動化するということで、Selenium WebDriverを使ってみることにしました。 Selenium WebDriverの概要に関しては、ここを参考にしてくだい。

Rubyが使える点と、ちょっと調べてみて参考記事が多そうだったので選びました。

ログインしてみる

いきなり予約する前に、まずは自分のチームでログインしなければなりません。 まずはトップ画面からログイン画面に遷移して、自分のチームのトップ画面に行くところまで作りたいと思います。

対象のシステムでは、

  • トップページ
  • 予約するするボタンをクリック
  • ログイン画面
  • ユーザー情報を入力
  • ログイン成功

という流れでログインできるので、この流れを自動化していきたいと思います

*Selenium WebDriverの使い方の基礎に関してはこの辺りの記事を参考にしました。 こうして、以下のようなスクリプトを作り、ログインした後、ログアウトすることに成功しました。

require 'selenium-webdriver'

class GymReserver
  TOP_PAGE = 'https://example.com' #トップページのURL

  # 以下アカウント情報
  ACCOUNT = 'XXXXX'
  PASSWORD = 'XXXXX'
  CODENUM = 'XXXXX'

  attr_accessor :driver

  def initialize
    @driver = Selenium::WebDriver.for :chrome
  end

  def login_execute
    click_reserve # トップページで「予約する」ボタンをクリックする
    login # ユーザー情報を入力し、ログイン

    driver.find_element(:id, 'FOOT1BTN').click #ログアウトボタンをクリック

    sleep 5  #  トップページで待機

    driver.close()
  end

  def click_reserve
    driver.get TOP_PAGE
    switch_to_iframe
    driver.find_element(:id, 'BB0').click
    puts 'succeeded to click button'
  end
    
  def switch_to_iframe
    iframe = driver.find_element(:name, 'iframe')
    driver.switch_to.frame(iframe)
  end

  def login
    fill_account_info
    driver.find_element(:id, 'loginID').click
  end

  def fill_account_info
    [ACCOUNT, PASSWORD, CODENUM].each { |info| click_each_char_button(info) }
  end

  def click_each_char_button(info)
    info.chars.each { |char| driver.find_element(:id, "KEY#{char}").click }
  end
end

GymReserver.new.login_execute

少しハマったポイントとしては、なぜかシステムがすべてiframeで出力されるようになっていた ために、画面遷移して際はiframeを指定して、そのiframeの中から要素を探してボタンを入力しなければならなかった点です。

  def switch_to_iframe
    iframe = driver.find_element(:name, 'iframe')
    driver.switch_to.frame(iframe)
  end

ユーザー情報を入力しているメソッドで一つ一つの文字を要素から探し出してそれぞれクリックしているのも、普通のformではなくiframe内のformを利用して入力しなければならなかったためです。

  def fill_account_info
    [ACCOUNT, PASSWORD, CODENUM].each { |info| click_each_char_button(info) }
  end

  def click_each_char_button(info)
    info.chars.each { |char|  driver.find_element(:id, "KEY#{char}").click }
  end

市町村が運営している予約システムはこのように素敵な仕様になっていることが多いので、皆さんもぜひ気をつけて下さい。

そしていよいよ予約へ・・・

ログインまで出来れば、あとは予約のパターンを調べて同じように操作をするだけです。 ついにこの瞬間が来ました。

自分のの技術が私自身のためだけでなく、ITからかけ離れているチームメイト達の役にも立つことができる

私は高まる緊張を抑えながら空いている施設を探して、予約パターンを探しました。 一つ一つ施設を検索して、空いている日を探しました。 一箇所でも予約できる施設を見つけれれば私の勝ちです。

しかしここに大きな落とし穴があったのです。













いや、どの体育館も空いてないやないかい (ツ)_/¯