Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

͜Μʹͪ͸ʂ

Slide 3

Slide 3 text

೔ຊޠೖྗࢼݧ

Slide 4

Slide 4 text

Aaron Patterson @tenderlove

Slide 5

Slide 5 text

GitHub

Slide 6

Slide 6 text

ko1: ϓϩάϥϛϯάΛ͍ͯͯ͠ʮ͓͓ɺ ੌ͍ίʔυ͕ॻ͚ͨʯʮ͜Ε͸ੌ͍΋ͷ Λ࡞ͬͯ͠·ͬͨʯͷΑ͏ͳܦݧͳͲ

Slide 7

Slide 7 text

Me: ʮੌ͍ίʔυʯ ͍͍ͬͯͬͨԿͩΖ͏

Slide 8

Slide 8 text

No content

Slide 9

Slide 9 text

;ͨͭͷҙຯ ڪΖ͍͠ / ා͍ ૉ੖Β͍͠ / ྑ͍

Slide 10

Slide 10 text

ೋͭͷτϐοΫ ڪΖ͍͠ / ා͍: PHP ૉ੖Β͍͠ / ྑ͍: Computer Vision ൿີ

Slide 11

Slide 11 text

ੌ͍ίʔυ ૉ੖Β͍͠ / ྑ͍

Slide 12

Slide 12 text

ίϯϐϡʔλ Ϗδϣϯ

Slide 13

Slide 13 text

ΨϥΫλ͕ ͍ͬͺ͍

Slide 14

Slide 14 text

Magic The Gathering (MtG)ͱ͸

Slide 15

Slide 15 text

Collectible Card Game

Slide 16

Slide 16 text

ࢲͷ໰୊ (Χʔυͷத਎) • Too many cards • Don’t know what they do • Are they worth any money? • Plus many more!

Slide 17

Slide 17 text

ίϯϐϡʔλʔʹ߹͏ ໰୊Έ͍ͨ Seems like a job for computers!

Slide 18

Slide 18 text

ࢲͷղܾ

Slide 19

Slide 19 text

ਓ޻஌ೳ Χϝϥ ೣ! Ruby!

Slide 20

Slide 20 text

High Level Process

Slide 21

Slide 21 text

ࣸਅΛࡱΔ ΧʔυΛൈ͚Δ ΧʔυΛ֬ೝ͢Δ σʔλΛอଘ͢Δ

Slide 22

Slide 22 text

Χʔυͷೝࣝ

Slide 23

Slide 23 text

श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύε

Slide 24

Slide 24 text

श ͬͨ ਪଌ ϓϩϯϓτ ڭ͑Δ ίʔύ ε

Slide 25

Slide 25 text

ਓ޻஌ೳ

Slide 26

Slide 26 text

σʔλɹϞσϧ

Slide 27

Slide 27 text

Χʔυͷ৘ใ

Slide 28

Slide 28 text

ࣸਅ ໊લ ਓؾ౓ ηοτ

Slide 29

Slide 29 text

image belongs_to(:card) card has_one(:image)

Slide 30

Slide 30 text

No content

Slide 31

Slide 31 text

image belongs_to(:card) card has_many(:images)

Slide 32

Slide 32 text

No content

Slide 33

Slide 33 text

image habtm(:cards) card habmt(:image)

Slide 34

Slide 34 text

׬શσʔλϞσϧ Cards Images Hashes habtm has_many

Slide 35

Slide 35 text

ίʔύεͷੜ੒

Slide 36

Slide 36 text

Executor Pool class ThreadExecutor def initialize size @queue = Queue.new @size = size @pool = size.times.map { |i| Thread.new { while job = @queue.pop; job.run end } } end def execute job = Proc.new promise = Promise.new job @queue << promise promise end def shutdown @size.times { @queue << nil } @pool.each(&:join) end end

Slide 37

Slide 37 text

Queue up work promise = @executor.execute do @http_pool.with_connection do |conn| uri = URI 'http://gatherer.wizards.com/Pages/Default.aspx' response = conn.request uri # save the response end end # some time later promise.value

Slide 38

Slide 38 text

Me Wizards

Slide 39

Slide 39 text

1.6GB

Slide 40

Slide 40 text

http://mtgjson.com/

Slide 41

Slide 41 text

ॻ͘લʹ άʔάϧͨ͠ํ͕͍͍

Slide 42

Slide 42 text

Χʔυͷೝࣝ

Slide 43

Slide 43 text

஌֮తϋογϡ libphash (gem install phasion)

Slide 44

Slide 44 text

11998341215223291070 12079686925145871551 Reference Scanned

Slide 45

Slide 45 text

ϋϛϯάڑ཭ require 'phashion' left = Phashion.image_hash_for "a.jpg" right = Phashion.image_hash_for "b.jpg" p Phashion.hamming_distance left, right # => 8

Slide 46

Slide 46 text

5622372658725034411 12079686925145871551 Reference Scanned

Slide 47

Slide 47 text

ϋϛϯάڑ཭ require 'phashion' left = Phashion.image_hash_for "c.jpg" right = Phashion.image_hash_for "b.jpg" p Phashion.hamming_distance left, right # => 28

Slide 48

Slide 48 text

ϋογϡΛ௥Ճ͢Δͱ ஌͕ࣝ૿͑Δ

Slide 49

Slide 49 text

ϋʔυ΢ΣΞ

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

No content

Slide 52

Slide 52 text

No content

Slide 53

Slide 53 text

ιϑτ΢ΣΞ

Slide 54

Slide 54 text

OpenCV https://github.com/ruby-opencv/ruby-opencv

Slide 55

Slide 55 text

ࡱͬͨࣸਅ

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

ཉ͍͠Πϝʔδ

Slide 58

Slide 58 text

No content

Slide 59

Slide 59 text

Χʔυͷൈ͖ํ

Slide 60

Slide 60 text

؆୯ͳ8ஈ֊͚ͩ!* * ؆୯͡Όͳ͍ɺଟ෼

Slide 61

Slide 61 text

No content

Slide 62

Slide 62 text

લॲཧ

Slide 63

Slide 63 text

άϨʔεέʔϧ gray = OpenCV.BGR2GRAY img

Slide 64

Slide 64 text

No content

Slide 65

Slide 65 text

Τοδݕग़ canny_img = gray.canny @thresh, @thresh http://en.wikipedia.org/wiki/Canny_edge_detector

Slide 66

Slide 66 text

No content

Slide 67

Slide 67 text

ྠֲΛݟ͚ͭΔ contours = [] contour_node = processed.find_contours( :mode => OpenCV::CV_RETR_TREE, :method => OpenCV::CV_CHAIN_APPROX_SIMPLE) while contour_node unless contour_node.hole? contours << contour_node end contour_node = contour_node.h_next end

Slide 68

Slide 68 text

ྠֲ ݀

Slide 69

Slide 69 text

No content

Slide 70

Slide 70 text

Ұ൪େ͖ͳྠֲ max = contours.max_by { |c| c.contour_area }

Slide 71

Slide 71 text

No content

Slide 72

Slide 72 text

ଟ֯ܗΛݟ͚ͭΔ approx = max.approx_poly(:method => :dp, :recursive => true, :accuracy => 0.02 * peri) x = approx.convex_hull2.to_a clockwise_points = clockwise x.reverse

Slide 73

Slide 73 text

No content

Slide 74

Slide 74 text

ಁࢹม׵ͷߦྻ to = [ OpenCV::CvPoint2D32f.new(0, 0), OpenCV::CvPoint2D32f.new(width, 0), OpenCV::CvPoint2D32f.new(width, height), OpenCV::CvPoint2D32f.new(0, height), ] from = polygon_points transform = OpenCV::CvMat.get_perspective_transform(from, to)

Slide 75

Slide 75 text

ΠϝʔδΛม׵͢Δ new_img = img.warp_perspective transform

Slide 76

Slide 76 text

No content

Slide 77

Slide 77 text

ڥք࠲ඪΛઃఆ͢Δ new_img.set_roi OpenCV::CvRect.new(0, 0, width, height)

Slide 78

Slide 78 text

No content

Slide 79

Slide 79 text

It’s Just That Easy!

Slide 80

Slide 80 text

ϢʔβʔΠϯλʔϑΣΠε ΧϝϥͰ ࡱͬͨ Πϝʔδ ਪଌ #1 ਪଌ #2 ਪଌ #3

Slide 81

Slide 81 text

No content

Slide 82

Slide 82 text

Կ͕͋Δʁ Card.joins(:images) .where('images.type' => 'UserImage') .group('cards.name') .count

Slide 83

Slide 83 text

Ͳͷ͙Β͍ྑ͍ʁ Card.joins(:images) # best .where('images.type' => 'UserImage') .order('rating desc').first Card.joins(:images) # worst .where('images.type' => 'UserImage') .order('rating asc').first

Slide 84

Slide 84 text

࠷ߴ:

Slide 85

Slide 85 text

࠷௿:

Slide 86

Slide 86 text

ϓϩδΣΫτͷ໰୊

Slide 87

Slide 87 text

য఺ͷ࣌ؒ

Slide 88

Slide 88 text

No content

Slide 89

Slide 89 text

ࣦഊͷ࣌

Slide 90

Slide 90 text

No content

Slide 91

Slide 91 text

ֆ͸ࣅͯΔ

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

अຐೣ

Slide 94

Slide 94 text

No content

Slide 95

Slide 95 text

ར఺ ઃఆ͸؆୯ ඞཁϋʔυ΢ΣΞ͸͋·Γͳ͍ ͍҆ ΩϟϦϒϨʔτ͠ͳ͍

Slide 96

Slide 96 text

ܽ఺ ෳࡶͳιϑτ΢ΣΞ ࿑ಇ ֬ೝͷ஗͞

Slide 97

Slide 97 text

ࠓޙͷ׆ಈ

Slide 98

Slide 98 text

ࣗಈԽ

Slide 99

Slide 99 text

ੌ͍ίʔυ ڪΖ͍͠ / ා͍

Slide 100

Slide 100 text

PHP + Ruby

Slide 101

Slide 101 text

Phuby (ϑʔϏΟ) https://github.com/tenderlove/phuby એ఻

Slide 102

Slide 102 text

Examples

Slide 103

Slide 103 text

PHPͷ ΦϒδΣΫτΛ࢖͏

Slide 104

Slide 104 text

਺ࣈ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$v = strlen('PHP INSIDE OF RUBY');" puts runtime['v'] # => 18 end

Slide 105

Slide 105 text

จࣈྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$name = 'Aaron';" puts runtime['name'] # => Aaron end

Slide 106

Slide 106 text

഑ྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$cars = array('Toyota', 'Honda', 'BMW');" p runtime['cars'][0] # => Toyota p runtime['cars'][1] # => Honda p runtime['cars'][2] # => BMW end

Slide 107

Slide 107 text

࿈૝഑ྻ require 'phuby' Phuby::Runtime.php do |runtime| runtime.eval "$e = array('foo' => 'bar', 'bar' => 'baz');" p runtime['e']['foo'] # => 'bar' p runtime['e']['bar'] # => 'baz' end

Slide 108

Slide 108 text

Rubyͷ ΦϒδΣΫτΛ࢖͏

Slide 109

Slide 109 text

Objects require 'phuby' class RubyKaigi def where puts "౦ژ" end end Phuby::Runtime.php do |runtime| runtime['kaigi'] = RubyKaigi.new runtime.eval("$kaigi->where();") # => ౦ژ end

Slide 110

Slide 110 text

ͳͥʁ

Slide 111

Slide 111 text

͍͍͔Β

Slide 112

Slide 112 text

scientists were so preoccupied with whether or not they could that they didn't stop to think if they should.

Slide 113

Slide 113 text

ϓϩάϥϜͷମܕ

Slide 114

Slide 114 text

Runtime Proxy Object Map Ruby Object Proxy PHP Object Proxy

Slide 115

Slide 115 text

Wrapper Access PHP Objects Ruby C PHP Object Map Ruby Proxy PHP Runtime Object

Slide 116

Slide 116 text

Wrapper Access Ruby Objects Ruby C PHP Object Map Ruby Proxy PHP Runtime Object

Slide 117

Slide 117 text

ϓϩδΣΫτͷ ໰୊

Slide 118

Slide 118 text

PHPΛ ίϯύΠϧ͢Δ

Slide 119

Slide 119 text

GC

Slide 120

Slide 120 text

άϩʔόϧͷม਺

Slide 121

Slide 121 text

໰୊ require 'phuby' require 'openssl' p OpenSSL::Cipher.ciphers # => ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", ... ] Phuby::Runtime.php do |runtime| runtime.eval("$hi = 'Hello World';") end p OpenSSL::Cipher.ciphers # => []

Slide 122

Slide 122 text

Solution: fork require 'phuby' require 'openssl' p OpenSSL::Cipher.ciphers # => ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", ... ] Process.waitpid fork { Phuby::Runtime.php do |runtime| runtime.eval("$hi = 'Hello World';") end } p OpenSSL::Cipher.ciphers # => ["AES-128-CBC", "AES-128-CBC-HMAC-SHA1", ... ]

Slide 123

Slide 123 text

Rails Support

Slide 124

Slide 124 text

PHP templates

Slide 125

Slide 125 text

No content

Slide 126

Slide 126 text

Πϯελϯεม਺

Slide 127

Slide 127 text

No content

Slide 128

Slide 128 text

ActiveRecord΋࢖͑·͢

Slide 129

Slide 129 text

No content

Slide 130

Slide 130 text

How much would you pay for this?

Slide 131

Slide 131 text

200ԁ?

Slide 132

Slide 132 text

250ԁ?

Slide 133

Slide 133 text

https://github.com/ tenderlove/phuby FREE!

Slide 134

Slide 134 text

ൿີͷτϐοΫ

Slide 135

Slide 135 text

ko1 said this is a tech conference, so you don’t have to tell any jokes

Slide 136

Slide 136 text

So I won’t tell any jokes.

Slide 137

Slide 137 text

ੌ͍ίʔυ How does it work?

Slide 138

Slide 138 text

Homeopathic Optimizations

Slide 139

Slide 139 text

Homeopathy ͱ͸ʁ

Slide 140

Slide 140 text

رऍɻ

Slide 141

Slide 141 text

௕͗͢Δʂ

Slide 142

Slide 142 text

No content

Slide 143

Slide 143 text

No content

Slide 144

Slide 144 text

Modern advocates of homeopathy have proposed a concept of "water memory", according to which water "remembers" the substances mixed in

Slide 145

Slide 145 text

ਫ͸ هԱग़དྷ·͢

Slide 146

Slide 146 text

ۭന΋ هԱ͢Δࣄ͕Ͱ͖Δʁ

Slide 147

Slide 147 text

YES!

Slide 148

Slide 148 text

σϞͷ࣌ؒ!

Slide 149

Slide 149 text

No content

Slide 150

Slide 150 text

Ͳ͏΍ͬͯ ಈ͍ͯΔʁ

Slide 151

Slide 151 text

VM ͸هԱ͢Δ

Slide 152

Slide 152 text

ͦΕ͸ۭന͡Όͳ ͯ͘ɺهԱͩɻ

Slide 153

Slide 153 text

ଞͷಛ௃

Slide 154

Slide 154 text

No content

Slide 155

Slide 155 text

ར఺

Slide 156

Slide 156 text

ߴ଎Խ

Slide 157

Slide 157 text

"No code is faster than no code"

Slide 158

Slide 158 text

رऍ͞ΕΕ͹͞ΕΔ΄Ͳ ϓϩάϥϜ͸ΑΓ଎͘ͳ Δ

Slide 159

Slide 159 text

ҡ࣋

Slide 160

Slide 160 text

ίʔυ͸ͳ͍͔Β

Slide 161

Slide 161 text

THANK YOU!!!

Slide 162

Slide 162 text

࣭໰ʁ