『たのしいRuby 第4版』 第14章 文字列(String)クラス
第14章 文字列(String)クラス
模範解答はこちら
(1)
問題
"Ruby is an object oriented programming language" という文字列に含まれる各単語を要素とする配列を作れ、という問題です。
私的解答
str = "Ruby is an object oriented programming language" ary = str.split(/ /) p ary
split メソッドを使って単純に分割で大丈夫そうです。
引数に何も指定しなければ空白文字による分割になるので、それでもよかった。
(2)
問題
(1)の配列をアルファベット順に並べ替えろ、という問題です。
私的解答
str = "Ruby is an object oriented programming language" ary = str.split(/ /) p ary.sort
sort メソッドを使えば一発です。
(3)
問題
(2)の配列を大文字、小文字の区別なしにアルファベット順に並べ替えろ、という問題です。
私的解答
str = "Ruby is an object oriented programming language" ary = str.downcase.split(/ /) p ary.sort
模範解答のように sort_by メソッドでブロックを作ってそっから配列にするのもいけめんだと思います。
(4)
問題
(1)の文字列に含まれる全ての単語の先頭を大文字に変換しろ、という問題です。
私的解答
str = "Ruby is an object oriented programming language" newStr = "" str.gsub(/\s/, "\n").each_line do |line| newStr << line.capitalize end p newStr.gsub(/\n/, "\s")
今見返すと、二度手間な変換をおこなっていてあまり美しくありませんね。。。
模範解答にあるように、collect(もしくは map) メソッドを使って方が可読性の面でもいいですねー。
(5)
問題
(1)の文字列に含まれる文字とその数を次のような形式で表示させろ、という問題です。
' ': ******* 'R': * 'a': **** 'b': ** 'c': * : :
私的解答
最初に作ったのがこれ。
class String def cntString(word) ary = self.split('') cnt = ary.count("#{word}") puts "'#{word}': " + "*" * cnt end end str = "Ruby is an object oriented programming language" str.cntString(' ') str.cntString('R')
引数に指定した文字がいくつ含まれているかを表示する、cntString メソッドを String クラスに作ってみたものの形式がだいぶ違うのでボツ。
次に作ったのがこれ。
class String def cntStringKai alpha = "abcdefghijklmnopqrstuvwxyz " alphaAry = alpha.split('') alphaCapAry = alpha.strip.upcase.split('') ary = self.split('') alphaCapAry.size.times do |i| cnt = ary.count("#{alphaCapAry[i]}") puts "'#{alphaCapAry[i]}': " + "*" * cnt if cnt >= 1 end alphaAry.size.times do |i| cnt = ary.count("#{alphaAry[i]}") puts "'#{alphaAry[i]}': " + '*' * cnt if cnt >= 1 end end end str = "Ruby is an object oriented programming language" str.cntStringKai
絶対もっといいやり方ある(確信)。アルファベットの配列つくるとことか。 模範解答みたいに、ハッシュ使ってキーと値に分けて考えるとかなりすっきりするということはこの本やって初めて気づいた点です。
(6)
難しすぎて断念。。。
似たような問題はプログラミング入門 - Rubyを使って -, by Chris Pine, 日本語ver. by S. Nishiyamaのチャプター8でやったのですが、なにせ漢字で桁を判断したり云々という部分がわけわかめで時間かかりすぎてしまったのでスルーしました(;´Д`)
いつかリベンジしてやりたいと思います。
『たのしいRuby 第4版』 第13章 配列(Array)クラス
第13章 配列(Array)クラス
模範解答はこちら
(1)
問題
1から100までの整数が昇順に並ぶ配列を作れ、という問題です。
私的解答
a = [] 100.times { |i| a << i + 1 } p a
模範解答にあるように to_a メソッドを使うのも簡単でいいですね。
(2)-1
問題
(1)の配列の各要素を100倍にした新しい配列を作れ、という問題です。
私的解答
a = (1..100).to_a a2 = [] a.each do |i| a2 << i * 100 end p a2
模範解答にあるように collect メソッドを使った方がより綺麗です。。。
(2)-2
問題
新しい配列を作らずに、(1)の配列の各要素を100倍にしろ、という問題です。
私的解答
a.each_with_index do |value, i| a[i] = value * 100 end p a
同上。
なぜこのような書き方になったのか(笑)
(3)-1
問題
(1)の配列から3の倍数だけを取り出した新しい配列を作れ、という問題です。
私的解答
a = (1..100).to_a a3 = [] a.each do |i| a3 << i if i % 3 == 0 end p a3
3の倍数とは3で割って余りが0の数のことなので % を使えばいいですね。
(3)-2
問題
新しい配列を作らずに、(1)の配列を3の倍数だけ取り出した配列にしろ、という問題です。
#
a.delete_if {|i| i % 3 != 0 } p a
私的解答で使った delete_if メソッドと、模範解答にある reject! メソッドは同じ動作をするが、その戻り値だけ異なる。
delete_if メソッドは常にレシーバ自身を返す。
reject! メソッドは削除が行われたときだけレシーバ自身を返し、変化がなかったときはnilを返す。
以上のような違いがあるので、使い方に気をつけたいです。
(4)
問題
(1)の配列を逆順に並べ替えろ、という問題です。
私的解答
a = (1..100).to_a a.reverse! p a
この問題はシンプルに reverse! メソッドを使いました。
(5)
問題
(1)の配列の総和を求めろ、という問題です。
私的解答
a = (1..100).to_a sum = 0 a.each do |i| sum += i end p sum
模範解答とずばりでしたが、ブロックの扱いに気をつけたいです。
基本的には、一行で書けるときは可読性を上げる意味でも、 {}
を使いたいですね。
(6)
問題
(1)の配列から、1~10,11~20,21~30といった具合に10個の要素を含む配列を10個取り出し、その配列を順番に別に配列に格納しろ、という問題です。
私的解答
ary = (1..100).to_a result = Array.new 10.times do |i| result << ary[i*10, 10] end p result
ary[n, m]
とすると、n
は先頭のインデックスを指し、m
は必要な要素数を指します。
(7)
問題
数値からなる配列 nums1 と nums2 に対して、それらの個々の要素を足しあわせた要素からなる配列を返すメソッド sum_array を定義しろ、という問題です。
例: p sum_array([1, 2, 3], [4, 6, 8]) #=> [5, 6, 11]
私的解答
def sum_array(nums1, nums2) result = [] nums1.zip(nums2) do |a, b| result << a + b end result end p sum_array([1, 2, 3], [4, 6, 8])
zip メソッドを使うことで容易に作ることが出来ました。
『たのしいRuby 第4版』第12章 数値(Numeric)クラス
第12章 数値(Numeric)クラス
模範解答はこちら
(1)
問題
摂氏温度を華氏温度に変換する cels2fahr メソッドを定義しろ、という問題です。
私的解答
def cels2fahr(cels) fahr = (9.0 / 5.0) * cels + 32.0 fahr.to_f end 1.upto(100) do |i| puts cels2fahr(i) end
模範解答にもある通り、途中の計算結果が浮動小数点数になるように公式の数値を9.0などにするのがポイントかと思います。
(2)
問題
さっきとは逆に、華氏温度を摂氏温度に変換する fahr2cels メソッドを定義しろ、という問題です。
私的解答
def fahr2cels(fahr) cels = (5.0 / 9.0) * (fahr - 32.0) cels.to_f end puts fahr2cels(32)
ポイントは(1)と同じ。
(3)
問題
サイコロを振って出た目を返す dice メソッドを定義しろ、という問題です。
私的解答
def dice rand(6) + 1 end puts dice
0から引数にとった値の手前までの乱数を発生させる rand メソッドを使います。
(4)
問題
サイコロを10回振って出た目の合計を返す dice10 メソッドを定義しろ、という問題です。
私的解答
def dice10 total = 0 10.times do me = rand(6) + 1 total += me end total end puts dice10
模範解答は(3)で作った dice メソッドを流用しているのでもっと短かったです。
しかし、サイコロの目だからといって変数名を me にするこのセンスをどうにかせねば。。。
(5)
問題
与えられた引数が素数であるかどうかを調べる prime? メソッドを定義しろ、という問題。
私的解答
と行きたいところですが、あまりの難しさに禿げ上がりそうになったので断念してしまいました。。。
以下、模範解答コピペ
def prime?(num) return false if num < 2 2.upto(Math.sqrt(num)) do |i| if num % i == 0 return false end end return true end
この問題は、平方根が用いられていることからも高度な数学的知識を要求する問題であろうことが推察されます。
・・・ん?そーでもないのかな?(笑)
『たのしいRuby 第4版』やった
久しぶりのブログ更新であります。
前々から気になっていた『たのしいRuby』を読んでみました。
入門書という位置づけではありますが、深く読み込むと知っていた知識のさらに向こう側(?)みたいな情報もたくさんあって得ることが多かったです。
で、第3部から主要なクラスについての詳しい説明が始まり、各章の終わりに練習問題があったのでやってみましたが、難易度の高いのもあったので一筋縄ではいかず、結構時間かかってしまいまいした。。。
とりあえず、Github に私的回答集を置いてみました。gotagotagoat/interestingRuby
がしかし、コードだけでは味気ないので、何回かに分けて各章の私的解答をここでさらしながらコメント的なことをしようという企画が自分のなかで持ち上がりました。
まとめてやってから書くので、当時の状況を思い出しながらの作業になり、ちょいちょい忘れてる箇所もあって後悔しながら記事をまとめていこうと思いますー。
Haml使い方メモ
Hamlとは
HTML Abstraction Markup Language の略。
基本的な使い方としては、
%のあとにタグ -> 開始タグと終了タグが生成
インデントで入れ子構造になる
rubyっぽい書き方で属性を指定
例
%html{:lang => "ja"}
てなところ。
コメントの書き方
htmlにも反映したい場合 / コメント
/
コメント
コメント
コメントhtmlには反映したくない場合 -# コメント
-#
コメント
コメント
コメント
htmlに一行で出力する
%p hello
スペースを開けて、一行で書く
hamlでだけ改行して、htmlでは改行したくない場合
%ul %li< item
%ul %li<> item
こうすると親要素の改行もとってくれる。
属性の指定(div)
%div{:id => "main", :class => "myClass"}
と
%div#main.myClass
と
#main.myClass
は同じ。
idとclassはよく使うのでショートカットが用意されている。 さらに、divもよく使うので省略が可能。
cssやjavascriptをhaml内に記述する方法
:css .myStyle { color: red; }
このようにフィルターを利用する。
- 便利なフィルター
:escaped
で実体参照をしてくれる。
rubyの式を評価
%p total is #{5 * 3} #=> <p>total is 15</p>
%p= Time.now #=> <p>2014-06-05 20:25:19 +0900</p>
ただ単にrubyの命令を実行したい場合は - (マイナス)をつける。
- x = 5 %p= x #=> <p>5</p>
sqlite3について
ドットインストールでsqlite3について学んだので自分用メモ。
データベース用語
データベース: アプリごとに作るデータがはいったもの
↓
テーブル: ユーザーテーブル、 レッスンテーブル
↓
フィールド/カラム: 列
レコード: 行
データベースの作成
sqlite3 [データベース名].sqlite3
データベースの削除
ファイル自体を削除すればおk
sqliteの基本的な使い方
終了の仕方
.exit
helpの出し方
.help
外部ファイルの読み込み
.read [ファイル名]
テーブルの作成
create table [テーブル名] ([カラム名1], [カラム名2]);
作成済みテーブルの確認
.tables
テーブルの構造を見る
.schema [テーブル名]
テーブルの削除
drop table [テーブル名];
テーブル名の変更
alter table [旧テーブル名] rename to [新テーブル名];
カラムの追加
alter table [テーブル名] add column [カラム名];
データ型の指定について
NULL
INTEGER 整数値
REAL 少数の入った数値(浮動小数点型)
TEXT 文字列
BLOB (Binary Large OBject)
create table users (name text, email text);
- データ型は指定できるが必須ではない。
- データ型を指定するとそれになるように努力するが、確約はしない。
テーブル作成時のオプション
自動連番の整数値をつける
id integer primary key autoincrement
null値を拒否する
not null
重複した値を拒否する
unique
デフォルト値を指定する
default [値]
例
create table users (id integer primary key autoincrement, name text not null, email text unique, age integer default 20);
チェック機能を含める
create table lessons (title, count_lessons check(count_lessons>0));
-> count_lessonsが1以上であることをチェックするインデックスを付ける
create index [インデックス名] on [テーブル名] (カラム名);
テーブルにデータを挿入する
insert into [テーブル名] ([カラム名]) values ([値])
例
insert into users (name, email, age) values ('example', 'example@example. com', 20)
シングルクォーテーションのエスケープ
insert into users (name, email, age) values ('it''s a pen', 'example@example.com', 20)
->''
と連続で打つnull値で指定
insert into users (name, email, age) values ('it''s a pen', 'example@example.com', null)
->null
とそのまま打つ
データを更新する
update [テーブル名] set [カラム名] = [新データ] where [カラム名] = [旧データ];
データを削除する
delete from [テーブル名] where [場所の指定];
ROWIDについて
内部的に行番号を振ってくれているので便利だよ
-例
-- select ROWID, * from users;
組み込み関数
全件取得
select * from [デーブル名];
件数の取得
select count(*) from [テーブル名];
カラムの最大値の取得
select max([カラム名]) from [テーブル名];
カラムの最小値の取得
select min([カラム名]]) from [テーブル名];
乱数の表示
select random();
- 例
--select * form [テーブル名] order by random() limit1;
--> ランダムに1つのデータを選び出すときに使える
文字列の長さを表示する
select length([カラム名]) from [テーブル名];
型を明示的に表示する
select typeof(カラム名) from [テーブル名];
ユニークな値を取得する
select distinct [カラム名] from [テーブル名];
値を集計する
select sum([カラム名1]) from [テーブル名] group by [カラム名2];
現在時刻を取得する
select current_time;
現在日付を取得する
select current_date;
現在日付時刻を取得する
select current_timestamp;
-例
-- insert into users (name, created) values ('example', current_timestamp) ;
--> 作成時刻を追加できる
日付に関する出力フォーマットを変更する
--例) 日本語で年を出力する
select strftime('%Y年', current_timestamp);
詳しくはリファレンスをば。
rbenv と bundler で rails 環境構築メモ
rbenv と bundler を使って既存のruby環境汚さず rails環境を構築する際の私的メモ。
ローカルインストールしたい rails のバージョンを Gemfile に記載する
作業ディレクトリに移動した後、以下のコマンドを実行し、Gemfile を作成する。
$ cat << EOS > Gemfile source "https://rubygems.org" gem "rails", "~> 3.2.0" # ←ローカルインストールしたいRailsのバージョンを指定。指定しなければ最新版が入る。 EOS
rails を vendor/bundle
以下にインストールする
$ bundle install --path vendor/bundle
すると
Retrying dependency api due to error (2/3): Bundler::HTTPError Network error while fetching https://bundler.rubygems.org/api/v1/dependencies?gems=bcrypt,abstract,mime-types,tlsmail,treetop,hoe,ZenTest,RubyInline,test-spec,camping,fcgi,mongrel,ruby-openid,thin,multimap,tilt,hike,text-hyphen,atomic
なんかこんなかんじのエラーメッセージを吐き腐るのだが、ググれどもググれども解決策らしきものがでてこないが、特に問題なさそうなのでいったん放置。
どなた様か原因がわかる方いらっしゃいましたらぜひご一報をば・・・。
--path [dir]
オプションを指定してbundle install
を実行すると、次回以降のbundle install
時にはディレクトリ指定をしなくてもそのディレクトリが使用されるオプション指定をせず、単に
bundle install
とすると、system または、 rbenv で指定された標準の位置にインストールされてしまうので注意
rails プロジェクトを作成する
今回は example という名前で作成。
$ bundle exec rails new example --skip-bundle
--skip-bundle
を指定しないと、system環境にgemがインストールされてしまうので注意
test-unitを組み込みたくない場合は以下のオプションを指定する。
$ bundle exec rails new example --skip-bundle -T
rails をローカルインストールするために使った bundler の環境を削除する
$ rm -f Gemfile $ rm -f Gemfile.lock $ rm -rf .bundle $ rm -rf vendor/bundle
rails プロジェクトの環境セットアップ
先ほど作成した rails プロジェクトディレクトリに移動した後、Gemfileを編集する。
rspec を使う場合は Gemfile に以下を記載する。
gem 'rspec' gem 'rspec-rails'
Gemfile を編集後、gem群をインストールする。
$ bundle install --path vendor/bundle
その後
$ bundle exec rails g rspec:install
で rspec 設定ファイルを生成する。
こうすることで、新しいコンロトーラーやモデルを生成した場合に、自動的にひな形となる spec を生成してくれるので便利。
ついでに Git の管理対象から vendor/bundle
ディレクトリを外す。
$ echo '/vendor/bundle' >> .gitignore
rails が本当に起動できるかを以下のコマンドで確認すると良い
$ bundle exec rails server
参考URL
http://memo.yomukaku.net/entries/IpCSQmo
http://qiita.com/emadurandal/items/a60886152a4c99ce1017#2-7
http://blog.44uk.net/2012/07/31/rails3-rspec-try-unit-test/