Public speaking course notes Read "Dynamo, Amazon’s Highly Available Key-value Store" Read "Bigtable, A Distributed Storage System for Structured Data" Read "Streaming Systems" 3, Watermarks Read "Streaming Systems" 1&2, Streaming 101 Read "F1, a distributed SQL database that scales" Read "Zanzibar, Google’s Consistent, Global Authorization System" Read "Spanner, Google's Globally-Distributed Database" Read "Designing Data-intensive applications" 12, The Future of Data Systems IOS development with Swift Read "Designing Data-intensive applications" 10&11, Batch and Stream Processing Read "Designing Data-intensive applications" 9, Consistency and Consensus Read "Designing Data-intensive applications" 8, Distributed System Troubles Read "Designing Data-intensive applications" 7, Transactions Read "Designing Data-intensive applications" 6, Partitioning Read "Designing Data-intensive applications" 5, Replication Read "Designing Data-intensive applications" 3&4, Storage, Retrieval, Encoding Read "Designing Data-intensive applications" 1&2, Foundation of Data Systems Three cases of binary search TAMU Operating System 2 Memory Management TAMU Operating System 1 Introduction Overview in cloud computing 2 TAMU Operating System 7 Virtualization TAMU Operating System 6 File System TAMU Operating System 5 I/O and Disk Management TAMU Operating System 4 Synchronization TAMU Operating System 3 Concurrency and Threading TAMU Computer Networks 5 Data Link Layer TAMU Computer Networks 4 Network Layer TAMU Computer Networks 3 Transport Layer TAMU Computer Networks 2 Application Layer TAMU Computer Networks 1 Introduction Overview in distributed systems and cloud computing 1 A well-optimized Union-Find implementation, in Java A heap implementation supporting deletion TAMU Advanced Algorithms 3, Maximum Bandwidth Path (Dijkstra, MST, Linear) TAMU Advanced Algorithms 2, B+ tree and Segment Intersection TAMU Advanced Algorithms 1, BST, 2-3 Tree and Heap TAMU AI, Searching problems Factorization Machine and Field-aware Factorization Machine for CTR prediction TAMU Neural Network 10 Information-Theoretic Models TAMU Neural Network 9 Principal Component Analysis TAMU Neural Network 8 Neurodynamics TAMU Neural Network 7 Self-Organizing Maps TAMU Neural Network 6 Deep Learning Overview TAMU Neural Network 5 Radial-Basis Function Networks TAMU Neural Network 4 Multi-Layer Perceptrons TAMU Neural Network 3 Single-Layer Perceptrons Princeton Algorithms P1W6 Hash Tables & Symbol Table Applications Stanford ML 11 Application Example Photo OCR Stanford ML 10 Large Scale Machine Learning Stanford ML 9 Anomaly Detection and Recommender Systems Stanford ML 8 Clustering & Principal Component Analysis Princeton Algorithms P1W5 Balanced Search Trees TAMU Neural Network 2 Learning Processes TAMU Neural Network 1 Introduction Stanford ML 7 Support Vector Machine Stanford ML 6 Evaluate Algorithms Princeton Algorithms P1W4 Priority Queues and Symbol Tables Stanford ML 5 Neural Networks Learning Princeton Algorithms P1W3 Mergesort and Quicksort Stanford ML 4 Neural Networks Basics Princeton Algorithms P1W2 Stack and Queue, Basic Sorts Stanford ML 3 Classification Problems Stanford ML 2 Multivariate Regression and Normal Equation Princeton Algorithms P1W1 Union and Find Stanford ML 1 Introduction and Parameter Learning

Ruby practice 3

2016-04-30

Q1: attr_accessor_with_history

attr_accessor uses metaprogramming to create getters and setters for object attributes on the fly. Define a method attr_accessor_with_history that provides the same functionality as attr_accessor but also tracks every value the attribute has ever had:

class Foo 
    attr_accessor_with_history :bar
end
f = Foo.new     # => #<Foo:0x127e678>
f.bar = 3       # => 3
f.bar = :wowzo  # => :wowzo
f.bar = 'boo!'  # => 'boo!'
f.bar_history # => [nil, 3, :wowzo, 'boo!']

Here are some hints and things to notice to get you started:

  1. The first thing to notice is that if we define attr_accessor_with_history in class Class, we can use it as in the snippet above. This is because in Ruby a class is simply an object of class Class.
  2. The second thing to notice is that Ruby provides a method class_eval that takes a string and evaluates it in the context of the current class, that is, the class from which you’re calling attr_accessor_with_history. This string will need to contain a method definition that implements a setter-with-history for the desired attribute attr_name.
  3. bar_history should always return an Array of elements, even if no values have been assigned yet.
  4. Don’t forget that the very first time the attribute receives a value, its history array will have to be initialized.
  5. Don’t forget that instance variables are referred to as @bar within getters and setters.
  6. Although the existing attr_accessor can handle multiple arguments (e.g. attr_accessor :foo, :bar), your version just needs to handle a single argument. However, it should be able to track multiple instance variables per class, with any legal class names or variable names, so it should work if used this way:
  7. History of instance variables should be maintained separately for each object instance. that is, if you do:
class SomeOtherClass attr_accessor_with_history :foo
	attr_accessor_with_history :bar
end
f = Foo.new
f.bar = 1
f.bar = 2
f = Foo.new
f. bar = 4
f.bar_history

then the last line should just return [nil,4], rather than [nil,1,2,4]. Here is some skeleton code:

class Class
 def attr_accessor_with_history(attr_name)
   attr_name = attr_name.to_s   # make sure it's a string
   attr_reader attr_name        # create the attribute's getter
   attr_reader attr_name+"_history" # create bar_history getter
   class_eval "your code here, use %Q for multiline strings"
 end
end
class Foo
    attr_accessor_with_history :bar
end
f = Foo.new
f.bar = 1
f.bar = 2
f.bar_history # => if your code works, should be [nil,1,2]

My Example Code

class Class
	def attr_accessor_with_history(attr_name)
		attr_name = attr_name.to_s
		attr_reader attr_name
		attr_reader attr_name + "_history"

		#our setter code here
		class_eval %Q{
			def #{attr_name}=(attr_name)
				@#{attr_name} = attr_name

				unless @#{attr_name + "_history"}
					@#{attr_name + "_history"} = []
					@#{attr_name + "_history"} << nil
				end
				@#{attr_name + "_history"} << attr_name
			end
		}
	end
end

class Test
	attr_accessor_with_history :sample
end

t = Test.new
t.sample = "test"
t.sample = 1
t.sample = :abc
print t.sample_history

Q2: Extend Currency Conversion Example

Extend the currency-conversion example from the text so that you can write: 5.dollars.in(:euros), 10.euros.in(:rupees)

You should support the currencies ‘dollars’, ‘euros’, ‘rupees’, and ‘yen’ where the conversions are: 1 rupee to 0.019 dollars, 1 yen to 0.013 dollars, 1 euro to 1.292 dollars.

Both the singular and plural forms of each currency should be acceptable, e.g. 1.dollar.in(:rupees) and 10.rupees.in(:euro) should work. You can use the code below (http://pastebin.com/agjb5qBF) as a starting point.

class Numeric
    @@currencies = {'yen' => 0.013, 'euro' => 1.292, 'rupee' => 0.019}
    def method_missing(method_id)
        singular_currency = method_id.to_s.gsub( /s$/, '')
        if @@currencies.has_key?(singular_currency)
        self * @@currencies[singular_currency]
        else
            super
        end
     end
end

My Example Code

class Numeric
	@@currencies = {'dollar' => 1.000,'yen' => 0.013, 'euro' => 1.292, 'rupee' => 0.019}
	
	def method_missing(method_id)
		sigular_currency = method_id.to_s.gsub(/s$/,'')
		if @@currencies.has_key?(sigular_currency)
			self * @@currencies[sigular_currency]
		else
			super
		end
	end

	def in(currency)
		sigular_currency = currency.to_s.gsub(/s$/,'')
		self / @@currencies[sigular_currency]		
	end

end

puts 5.dollars.in(:euros)
puts 10.euros.in(:rupees)

Creative Commons License
Melon blog is created by melonskin. This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.
© 2016-2024. All rights reserved by melonskin. Powered by Jekyll.