Rubyのモジュールについて
モジュールとは
モジュールとはクラスと同じくメソッドを定義することができるが、大きな違いはモジュールはオブジェクトを作成できない。主な利用方法は他のクラスの中にモジュールをインクルードして利用すること。
Enumerable
Enumerableモジュールについて
Enumerableモジュールは、配列やハッシュなど集合を表すクラスに数え上げや検索などのメソッドを提供します。
インクルードされているクラス
・Array
・Hash
・Range
・Enumerator (列挙)
・Dir(ディレクトリ)
・Struct(構造体)
・IO(入出力)
よく使うメソッド
dropメソッド
dropメソッドは、引数のn個の要素を先頭から取り除き、残りの要素を新しい配列にして返す。
#配列の場合 "RubyRuby".split("").drop(2) => ["b", "y", "R", "u", "b", "y"] #ハッシュの場合 hash = {name: "keioka", password:"aaaa", mail:"keioka0828@gmail.com"} => {:name=>"keioka", :password=>"aaaa", :mail=>"keioka0828@gmail.com"} hash.drop(2) => [[:mail, "keioka0828@gmail.com"]] #rangeの場合 (1..10).drop(2) => [3, 4, 5, 6, 7, 8, 9, 10]
drop_while
#配列の場合 "RubyRuby".split("").drop(2) => ["b", "y", "R", "u", "b", "y"] #ハッシュの場合 hash = {name: "keioka", password:"aaaa", mail:"keioka0828@gmail.com"} => {:name=>"keioka", :password=>"aaaa", :mail=>"keioka0828@gmail.com"} hash.drop(2) => [[:mail, "keioka0828@gmail.com"]] #rangeの場合 (1..10).drop(2) => [3, 4, 5, 6, 7, 8, 9, 10]
all?
all?メソッドは、ブロック引数itemに要素を入れながらブロックを繰り返し実行し、ブロックの戻り値がすべて真であった場合にtrueを返します。ブロックが偽を返したときは、繰り返しを中断してfalseを返します。
words1 = ["dog", "cat", "mouse", "pig"] puts words1.all? {|w| w.kind_of?(String) }
each_cons
#Rangeの場合 p (1..5).enum_cons(3).to_a =>[[1, 2, 3], [2, 3, 4], [3, 4, 5]] #Hashの場合 hash.each_cons(2).to_a => [[[:name, "keioka"], [:password, "aaaa"]], [[:password, "aaaa"], [:mail, "keioka0828@gmail.com"]]] #よくわからないことになったので、たぶん使わない。 #配列の場合 arr.split(" ").each_cons(2) => #<Enumerator: ["Ruby", "Html", "Css", "Python", "Java", "Javascript", "PHP"]:each_cons(2)> arr.split(" ").each_cons(2).to_a => [["Ruby", "Html"], ["Html", "Css"], ["Css", "Python"], ["Python", "Java"], ["Java", "Javascript"], ["Javascript", "PHP"]]
grep
grepメソッドは、各要素に対して「引数obj === 要素」を試し、その結果が真だった要素を集めて配列にして返します。
Regexpクラスの===は正規表現のマッチです。引数を正規表現にすると、パターンにマッチする文字列を集められます。次の例は、配列の中から半角アルファベットだけの文字列を集めます。
#配列の場合 arr = ["cat", 123, "#dog", "mouse"] p arr.grep(String) =>["cat", "#dog", "mouse"] arr = ["cat", 123, "#dog", "mouse"] p arr.grep(/\A[A-Za-z]+\Z/) {|item| item.upcase } =>["CAT", "MOUSE"]
map
要素の数だけ繰り返しブロックを実行し、ブロックの戻り値を集めた配列を作成して返します。ブロック引数itemには各要素が入ります。ブロックを省略したときは、要素をすべて集めた配列を返します。
#Rangeの場合 (1..10).map{|n| n * 3} => [3, 6, 9, 12, 15, 18, 21, 24, 27, 30] #配列の場合 ["pink", "bule", "yellow", "black", "white"].map{|word| word.upcase} => ["PINK", "BULE", "YELLOW", "BLACK", "WHITE"]
group_by
group_byメソッドは、要素をグループ分けします。ブロック引数itemに各要素を入れながら、要素の数だけブロックを繰り返し、ブロックの戻り値が同じ要素をそれぞれ集めます。メソッドの戻り値は{ ブロックの戻り値 => [要素, 要素, ...], ... }というハッシュになります。
animals = ["cat", "bat", "bear", "camel", "alpaca"] p animals.group_by {|item| item[0].chr } =>{"a"=>["alpaca"], "b"=>["bat", "bear"], "c"=>["cat", "camel"]}
Cycle
Enumerable オブジェクトの各要素を n 回 or 無限回(n=nil)繰り返し ブロックを呼びだします。
#2回繰り返し ["a","b","c"].cycle(2) {|x| puts x } a b c a b c => nil #nil ["a","b","c"].cycle(0) {|x| puts x } =>nil #無限ループ ["a", "b", "c"].cycle{|x| puts x} a b c : : :
Rubyよく使うメソッドメモ(随時更新)
Kernel
.#rand
rand #=> 0.1915194503788923 rand #=> 0.6221087710398319 rand(10) #=> 4 rand(5.5) #=> 0 # rand(5) と同じ。 5 が乱数値の範囲に含まれないことに注意。 rand(1..6) #=> 2 (1 から 6 までの整数) rand(0...10) #=> 1 (0 から 9 までの整数。終端を含まない) rand(1.0..1.5) #=> 1.1362963047752432 (1.0 以上 1.5 以下の実数) rand(1.0...1.5) #=> 1.1382321275715483 (1.0 以上 1.5 未満の実数) rand(1..0) #=> nil
選択ソート
選択ソート
選択ソートとは
選択ソートは配列の最小値(最大値)を持つ要素を探して、それを配列の先頭要素と交換することで整列を行うアルゴリズムです。
Pseudocodeは以下のような感じ
- 配列の先頭要素を仮の最小値を持つ要素(A0)としておく
- (A0)と(A0)以外の要素の値を比較して(A0)より小さい値を持つ要素(A1)が見付かれば(A1)と(A0)の値を交換する
- 2.を繰り返すことで(A0)には配列内での最小値がセットされる
- 次は(A0)を除いて(A1)と(A1)以外の要素、(A1)を除いて(A2)と(A2)以外の要素を比較/交換して整列が完了する
(引用元:選択ソート : アルゴリズム)
ロジック的にはできたかなと思いますが、最小を探すところがもっとうまくできるかなという印象です。
def selection_sort(arr) n = 0 (arr.length - 1).times do |i| min_i = arr.find_index(arr[n..arr.length - 1].min) #未ソート部分の最小値のインデックスを探しています。 if arr[min_i] < arr[i] arr[min_i], arr[i] = arr[i], arr[min_i] end n += 1 end return arr end
def selection_sort(arr) sorted = [] while true return sorted if arr.size == 0 sorted << arr.min arr.delete(arr.min) end end
これは一番初めに書いた選択ソートですが、これはルール違反な気もします。
以下参考にしたコードです。
バブルソート
バブルソートは一応理解しているつもりなので、さくっといきたいと思います。
Pseudocode
1.フラグ変数を用意する、値はfalseが未完了という意味に取りやすいので、falseでいきます。
2.ソートするためのループを用意します。(補足:何度もループさせたいので、whileかuntilを使いますが、フラグ変数がfalseなのでuntilを使います。)
3.さらに実際に配列を並び変えるためのループ(繰り返し処理)を用意します。(補足:すでにループの中に入っているので配列の長さ分だけ繰り返して、抜けてくれれば良いです。)
4.配列の[i]と[i+1]を比べる条件を書きます。[i]が[i+1]より大きければ5の処理を行います。
5.ここでは各配列のインデックスを指定して、入れ替えます。具体的には[i] には [i + 1]、[i + 1]には[i]を入れて交換を行います。
6.このままでは一回で抜けてしまうので、一番元のuntilループに完了の印としてフラグ変数にtrueを入れます。5のif分には未完了のfalseを入れます。
7.最後にuntilループを抜けた後配列を返します。
def bubble_sort(arr) sorted = false #ここで until sorted sorted = true (arr.length - 1).times do |i| if arr[i] > arr[i+1] arr[i+1], arr[i] = arr[i], arr[i+1] sorted = false end end end return arr end
コードを上からの流れで見ていくと、 ということです。
探索アルゴリズムについて
- 線形探索(リニアサーチとは)と二分探索(バイナリーサーチ)の違い
1.線形探索(リニアサーチとは)と二分探索(バイナリーサーチ)の違い
線形探索とは先頭から順に配列を検索する方法。データーに規則性がない場合有効だけれど、計算時間がかかる。 二分探索とはデータが昇順で並んでいた場合、最初に真ん中に位置するデータと比較する。そうすることでどちらか一方のデータは計算しなくてよくなる。
例えば以下のような配列があって3を探したいとする。
[1, 3, 5, 7, 9, 11]
真ん中の数字は6なので、左側にあることがわかる。
2.線形探索のコード
def linear_search(arr, value) arr.each_with_index do |num, index| return index if num == value end return nil end
これわざわざ名前つける必要あるのかってかんじです。
3.二分探索のコード
def binary_search(arr, n) arr.sort! min = 0 max = (arr.length) - 1 while true mid = (min + max) / 2 if arr[mid] > n max = mid elsif arr[mid] < n min = mid elsif arr[mid] == n return mid else return nil end end end
ちなみにテストも見よう見まねで書いた。
describe "#binary" do it "could't find value in array" do expect(binary_search([1, 3, 5, 9, 11, 13, 15, 17, 19, 21, 23], 0)).to eq (nil) end it "works with sorted array" do expect(binary_search([1, 3, 5, 9, 11, 13, 15, 17, 19, 21, 23], 9)).to eq (3) end it "works with unsorted array" do expect(binary_search([15, 38, 325, 19, 211, 143, 125, 17, 19, 21, 230, 100], 21)).to eq (9) end end
一番目のテストで引っかかった。。。終了条件書いていなかった。
describe "#binary" do it "could't find value in array" do expect(binary_search([1, 3, 5, 9, 11, 13, 15, 17, 19, 21, 23], 0)).to eq (nil) end end
見つからなかった場合のケースです。
ようは見つからない場合どういう条件でnilを返すかを書くことが必要でした。。 ということで、見つからない時というのはどういうときかで考えると、「二分割し続けた挙句のはてに二分割の基点となるmidの値が0以下になるか,arrayの個数以上になる」とシンプルにここで切れるようにしました。
def binary_search(arr, n) arr.sort! min = 0 max = (arr.length) - 1 while true mid = (min + max) / 2 if arr[mid] > n max = mid elsif arr[mid] < n min = mid elsif arr[mid] == n return mid elsif mid <= 0 || mid > arr.length return nil end end end
ここでまた無限ループにはまる。 上のプログラムでダメなのは、見つからない場合にループを抜けるための条件が一番下にあること。 これではnが小さい場合に二分割するというif分の二番目{ elsif arr[mid] < n }こいつに当てはまるので一生ここにハマり続けます。
def binary_search(arr, n) arr.sort! p arr min = 0 max = (arr.length) - 1 while true mid = (min + max) / 2 if mid <= 0 || mid > arr.length return nil elsif arr[mid] > n max = mid elsif arr[mid] < n min = mid elsif arr[mid] == n return mid end end end
Rspecの書き方-その1(matcher)
RspecとはBDD(Test Driven)のテストフレームワーク
BDD(Behavior Driven Development)とはTDD(test Driven Development)テスト駆動開発から派生したテストフレームワーク。
レッド:動作しないテストを作成する。 グリーン:テスト動作させる。(1番始めはシンプルに期待する値をそのままreturnで返えしてテスト自体が機能しているか確認する) リファクタリング:グリーンが出たらコードの重複などを整理してシンプルにする。
BDD/TDDについて詳しくは以下から いまさら聞けないTDD/BDD超入門(2):TDD/BDDの思想とテスティングフレームワークの関係を整理しよう (1/3) - @IT
Exapmle
以下のようなメソッドを用意する。
def add(a, b) return a + b end
expect(add(1,2)).to_be←matcher ↑ テストしたいメソッドと引数
結果が5である
expect(add(2, 3)).to eq(5)
結果が5ではない
expect(add(2, 3)).not_to eq(5)
結果が真偽値
expect(add(2, 3)).to be true
結果が10以下
expect(add(2, 3)).to be < 10
結果が1から10の間
expect(add(2, 3)).to be_between(1, 10).inclusive
Matcher一覧
アメリカの会社の種類について
アメリカ会社の種類
Sole Proprietor Ship 【個人経営】
一人で運営するような個人事業に適している企業形態です。設立が簡単で、二重課税の対象 にはなりませんが、ビジネス上発生した全ての責任を法律上個人が負わなくてはいけませ ん。賠償責任、負債に対して事業主は無限の支払い責任を負います。個人経営の形態では、 ビザは取得できません。
C Corporation【C 株式会社】
日本人が、アメリカで起業するのにもっとも適した企業形態です。会社設立は、株主から一 人からで、資本金の最低金額に定めがありません。個人の無限責任は避ける事ができ、事業 主は投資した額に限定されて賠償責任を負います。二重課税の対象となり、税務会計業務は 大変に複雑です。 ビザの取得はもっとも容易となります。
S Corporation【S 株式会社】
税制を優遇した企業形態です。S Corporation は、小規模の C Corporation で、二重課税 されない会社です。個人の無限責任を避ける事ができ、事業主は投資した額に限定されて賠償責任を負います。二重課税の対象とはなりません。 S Corporation は税法上、アメリカ 居住者か、Green Card Holder しか株主となる事はできず、法人の株主をもつこともできま せん。
Partnership【パートナーシップ】
2 人以上の個人または企業が、経営、利益分配に参加する権利を共有しあいビジネスを運営 する形態です。設立が簡単で、二十課税の対象にはなりませんが、誰かが無限の個人責任を 負わなくてはなりません。
LLP【LIMITED LIABILITY PARTNERSHIPS】
パートナーシップの各組合員が他の組合員の責任を有限とした事業形態です。
LLC【LIMITED LIABILITY COMPANIES】
1980 年代後半から各州で規定された比較的新しい事業形態です。LLC は会社としての属性 を維持し全ての出資者の有限責任であることを認めながら、税法上は、事業の利益は個人所 得として申告する事によって二重課税を回避する事ができます。
http://www.attorney-office.com/Establishment.pdf
5.株主の権利 : アメリカ会社法の教科書ー日本語でデラウェア州を中心とした米国の会社法制を学ぼう!