2015年7月30日木曜日

[android]ストップウォッチアプリをつくりました

まつもと直伝 プログラミングのオキテ 第20回 MVCとRuby on Rails でMVCの説明の題材となっているRubyでかかれたストップウォッチのサンプルをandroidアプリとして書いてみました。

TORIFUKUKaiou/StopWatch

Enjoy!


2015年7月29日水曜日

[android]Add Tabs to the Action Barはdeprecated → com.android.support:design

久しぶりにアプリを更新しようとおもって、ライブラリの更新とかをやっていると、Add Tabs to the Action Barの内容で作った箇所がまるまるdeprecatedになっていました。
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS)
android.support.v7.app.ActionBar.Tab
android.support.v7.app.ActionBar.TabListener
等がdeprecatedです。

どうしようか途方にくれておりましたところ、com.android.support:designの導入で解決しましたのでご紹介しておきます。

おおまかには次の手順で移行できます。
1. com.android.support:designを使えるようにする。app/src/build.gradleに
compile 'com.android.support:design:22.2.1' みたいなのを追加する感じです
2. android.support.design.widget.TabLayoutとandroid.support.v4.view.ViewPagerを上下に並べたレイアウトを用意する
3. TabLayoutとViewPagerを結びつける。tabLayout.setupWithViewPager(mViewPager);な感じです。

私の場合はViewPagerはそのまま使えました。

とても参考にさせていただきました。ありがとうございます。
Android Design Support Libraryを使う
Design Support Library v22.2.0について Part 3

Enjoy!


2015年7月27日月曜日

[Ruby]最長重複文字列問題

こんな感じ?

class Array
  def tail
    ary = dup
    ary.empty? ? [] : ary.drop(1)
  end

  def tails
    ary = dup
    ary.empty? ? [[]] : ([ary] + ary.tail.tails)
  end
end

class String
  def max_dup_string
    ary = dup.split('')
    ary.tails.sort.tail.zip(ary.tails.sort).map do |fst, snd|
      fst.zip(snd).take_while{|l, r| l == r}.map{|l, r| l}.join.strip
    end.sort{|a, b| b.length <=> a.length}[0]
  end
end

p "Ask not what your country can do for you, but what you can do for your country".max_dup_string
# => "can do for you"
p "Hello, World. Hello, Ruby!".max_dup_string
# => "Hello,"
p "mississippi".max_dup_string
# => "issi"

$ ruby -v
ruby 2.0.0p645 (2015-04-13 revision 50299) [x86_64-darwin14.4.0]

Enjoy!


2015年7月14日火曜日

クイックソート

Haskellをかじりはじめました。
この本で勉強しています。

2006年のものなのでちょっと古いのかもしれませんが、初心者にはとてもわかりやすいです。
ありがとうございます。
本でつかっているghcのバージョンは6.2.2でいまの最新は7.8.4のようです。
本文中のimportのところは下記のように読み替えると大丈夫でした。
import System -> import System.Environment
import List -> import Data.List

qsort [] = []
qsort (p:xs) = qsort lt ++ [p] ++ qsort gteq
                where
                  lt   = [x | x <- xs, x < p]
                  gteq = [x | x <- xs, x >= p]
慣れないうちはなんのことやら? だったのですが、上くらいのことがわかるようになるとクイックソートのことがすっきりとわかるようになりました。


Rubyで書いてみました。
def qsort(ary)
 ary.empty? ?
     [] :
     qsort(ary.drop(1).select{|n| n < ary[0]}) + [ary[0]] + qsort(ary.drop(1).select{|n| ary[0] <= n})
end
p qsort([10, 9, 8, 7, 6, 5, 1000, 0]) # ①
p qsort(%w|hello goodby こんにちは 6 5 1000 0 Ruby Python Haskell C C++ Java|) # ②

①はNumericの配列のソートです。
②はStringの配列のソートです。
まったく同じメソッドがそのまま使えます。
これはFixnumクラス、Stringクラスがmodule Comparableをincludeしていて、
<=>演算子(メソッド)を定義しているので各要素の比較が可能であるためです。
ポリモーフィズムというやつです。
Array#drop(n)はnが1だったら[4,5,6] -> [5,6]を返すメソッドです。nは落とす個数を指定するらしいです。
drop(1)はHaskellのtailと同じ意味あいになるかとおもわわれます。

Arrayにモンキーパッチしてみました。
上の例はpivotを必ず先頭から選んでいますが、ランダムに選ぶようにしてみました。
class Array
  def qsort(ary=self)
    ary.empty? ?
      [] :
      (ary = ary.dup
       pivot = ary.delete_at(rand(ary.length))
       qsort(ary.select{|n| n < pivot}) + [pivot] + qsort(ary.select{|n| pivot <= n}))
  end
end

ary = [10, 9, 8, 7, 6, 5, 1000, 0]
p ary.qsort
p ary # 上の例では新しいArrayインスタンスを返しているので、元の並び順は変更されません。


結局こうすればよいのかもしれません。
module TorifukuModule
  extend self

  def qsort(ary=self)
    ary.empty? ?
      [] :
      (ary = ary.dup
       pivot = ary.delete_at(rand(ary.length))
       qsort(ary.select{|n| n < pivot}) + [pivot] + qsort(ary.select{|n| pivot <= n}))
  end
end

class Array
  include TorifukuModule
end

ary = [10, 9, 8, 7, 6, 5, 1000, 0]
p ary.qsort
p TorifukuModule.qsort(ary)

$ ruby -v
ruby 2.0.0p645 (2015-04-13 revision 50299) [x86_64-darwin14.4.0]

enjoy!

2015/07/27追記
ary=selfがなんか変だなあとおもっていました。
こうすればいいのかもしれません。

module TorifukuModule
  def qsort
    empty? ?
      [] :
      (ary = dup
       pivot = ary.delete_at(rand(ary.length))
       ary.select{|n| n < pivot}.qsort + [pivot] + ary.select{|n| pivot <= n}.qsort)
  end
end

class Array
  include TorifukuModule
end

ary = [10, 9, 8, 7, 6, 5, 1000, 0]
p ary.qsort





2015年7月12日日曜日

フィボナッチ数列

フィボナッチ数列を書いてみました。
Hashのnewの時に渡したblockは、Hashにキーがまだ含まれていないときの初期値を定義します。
これを利用してみました。
case - when 式も練習してみました。

h = Hash.new do |hash, key|
  hash[key] = case key
              when 0 then 0
              when 1 then hash[0] = 0 unless hash.has_key?(0); 1
              else hash[key-1] + hash[key-2]
              end
end

puts h[100]
p h.values

$ ruby -v
ruby 2.0.0p645 (2015-04-13 revision 50299) [x86_64-darwin14.4.0]

class Hashによると、「ハッシュに含まれる要素の順序が保持されるようになりました。 ハッシュにキーが追加された順序で列挙します。」とのことなので、h.valuesで順番通りのArrayインスタンスが得られています。


2015年7月11日土曜日

[Raspberry Pi]7セグLEDを表示してみる

7セグLEDの説明は「7セグ LED と集合抵抗を使ってみよう」が詳しいです。
参考にさせていただきました。ありがとうございます。

私はカソードコモンを使いました。また端子は上下にあるものを使いました。
抵抗は1kΩのものを使いました。



* 3番(下側中央)をGNDに接続しています。GNDに接続するのは8番(上側中央)でもいいみたいです。
* 7個のLED(AからG)にそれぞれHigh(点灯)、Low(消灯)を指示することで数字の表示ができます。
* 私の場合は以下のような回路になっています。
7セグLEDのA : GPIO 5
7セグLEDのB : GPIO 13
7セグLEDのC : GPIO 6
7セグLEDのD : GPIO 20
7セグLEDのE : GPIO 21
7セグLEDのF : GPIO 16
7セグLEDのG : GPIO 19
  * GPIOの番号は「GPIO: MODELS A+, B+ AND RASPBERRY PI 2」の上側の図の番号体系と同じです。
  * プログラム中のled_gpio_dicと対応しておりまして、Value(右側の数字)は何番のGPIOにつないだかによって変更する必要があります。
* またGPIO 24がHigh(スイッチを押したとき)になったら停止するようにしています。
* プログラムはPythonで書きました。
 * $ sudo python filename.py
   で実行できます。

import RPi.GPIO as GPIO
from time import sleep

# 7seg led position : GPIO
led_gpio_dic = {
    "A": 5,
    "B": 13,
    "C": 6,
    "D": 20,
    "E": 21,
    "F": 26,
    "G": 19 }

# number : led position
number_led_dic = {
    0: set([chr(c) for c in range(ord('A'), ord('F')+1)]), # A, B, C, D, E, F
    1: set(["B", "C"]), # B,C
    2: set(["A", "B", "G", "E", "D"]), # A, B, G, E, D
    3: set(["A", "B", "C", "D", "G"]), # A, B, C, D, G
    4: set(["F", "G", "B", "C"]), # F, G, B, C
    5: set(["A", "F", "G", "C", "D"]), # A, F, G, C, D
    6: set(["F", "E", "D", "C", "G"]), # F, E, D, C, G
    7: set(["A", "B", "C"]), # A, B, C
    8: set([chr(c) for c in range(ord('A'), ord('G')+1)]), # A, B, C, D, E, F, G
    9: set(["A", "B", "C", "F", "G"]), # A, B, C, F, G
    "-": set(["G"]) }

def my_callback(channel):
    global done
    if channel == 24:
        done = True

def show(number):
    high_pos_set = number_led_dic[number]
    low_pos_set = number_led_dic[8] - high_pos_set
    for pos in high_pos_set:
        GPIO.output(led_gpio_dic[pos], GPIO.HIGH)
    for pos in low_pos_set:
        GPIO.output(led_gpio_dic[pos], GPIO.LOW)

# init
GPIO.setmode(GPIO.BCM)
GPIO.setup(24, GPIO.IN, pull_up_down=GPIO.PUD_DOWN)
GPIO.add_event_detect(24, GPIO.RISING, callback=my_callback, bouncetime=200)
for pos in number_led_dic[8]:
    GPIO.setup(led_gpio_dic[pos], GPIO.OUT, initial = GPIO.LOW)


done = False
num = 0
try:
    while not done:
        show(num % 10)
        num += 1
        sleep(0.3)
except KeyboardInterrupt:
    pass

GPIO.cleanup()


【環境】
Raspberry Pi 2 Model B
$ uname -a
Linux raspberrypi 4.0.7-v7+ #801 SMP PREEMPT Tue Jun 30 18:38:23 BST 2015 armv7l GNU/Linux



Enjoy!



2015年7月4日土曜日

[Raspberry Pi][Python]教材

Raspberry PiのPiはPythonに由来しているそうで、Pythonを勉強しようかなあとおもっていたところいい教材をみつけました。

MagPiです。

MagPiはRaspberry Piの公式雑誌です。PDFは無料で読めます。
2012/Mayの創刊号から読めます。

MagPiのなかに「the python(TM) pit」というコーナーがありまして、じっくりPythonを説明してくれるそうです。
最初の3つくらいを斜め読みしてみると、pygameの話題が多いかもしれません。

2012/Mayの創刊号をやってみました。
pygameを使ったBAT AND BALLというゲームを打ち込んでみました。
落ちてくるボールをバットで打ち返すゲームです。

ちなみにバックナンバーはここから読めます。




まつもとゆきひろ氏が「生涯プログラマー」でやっていきたい若手に贈る3つの言葉【特集:エンジニア育成の本質】で触れられているような100行程度のゲームプログラムを打ち込む体験が平成の今できます。

Enjoy!