SlideShare a Scribd company logo
1 of 66
Download to read offline
Writing Loveable Code
@seemaisms
seemaullal@gmail.com
!"#
@seemaisms
seemaullal@gmail.com
!"
@seemaisms
seemaullal@gmail.com
Seema Ullal
@seemaisms
@seemaisms
seemaullal@gmail.com
I hope to see Ruby help every
programmer in the world to be
productive, and to enjoy
programming, and to be happy.
That is the primary purpose of
Ruby language.
— Yukihiro Matsumoto
@seemaisms
seemaullal@gmail.com
How did we get
there?
@seemaisms
seemaullal@gmail.com
✨
Let's build a new feature!
@seemaisms
seemaullal@gmail.com
!
Spend some time thinking about how it
should work
@seemaisms
seemaullal@gmail.com
!
Write the code
@seemaisms
seemaullal@gmail.com
It works! Everything is great!
@seemaisms
seemaullal@gmail.com
Sometime later...
@seemaisms
seemaullal@gmail.com
!
: "Let's make this even better"
!
: "Sounds great, I'll start implementing
those changes"
@seemaisms
seemaullal@gmail.com
Hmm, let me take a look at what the code is
doing now
@seemaisms
seemaullal@gmail.com
!
How does it work?
@seemaisms
seemaullal@gmail.com
...does it work?
@seemaisms
seemaullal@gmail.com
!
How do I even start to change this?
@seemaisms
seemaullal@gmail.com
Can I make changes without accidentally
breaking things?
@seemaisms
seemaullal@gmail.com
@seemaisms
seemaullal@gmail.com
We have the most context on the code we
write
@seemaisms
seemaullal@gmail.com
But other people will read your code
@seemaisms
seemaullal@gmail.com
They may even need to change it
@seemaisms
seemaullal@gmail.com
How can we write code that is easy
for people to understand and modify?
@seemaisms
seemaullal@gmail.com
Code That Is
Clear, Testable, Changeable
@seemaisms
seemaullal@gmail.com
class Connect4
def initialize
@board = ("......n"*7).chomp
@player = "2"
@done = false
end
def play col
return "Game has finished!" if @done
begin
@board[%r/A((......n){#{col}}d*)(.)/, 3] = "#@player"
rescue
return "Column full!"
end
@player.tr! "12", "21"
if [0,5,6,7].any?{|off| @board =~ /(d)([sS]{#{off}}1){3}/}
@done = true
"Player #@player wins!"
else
"Player #@player has a turn"
end
end
end
@seemaisms
seemaullal@gmail.com
Give context to your code
@seemaisms
seemaullal@gmail.com
class Connect4
def initialize
@board = initialize_board
@turn = 1
@finished = false
end
def play(row_index)
@row_index = row_index
return 'Game has finished!' if @finished
return "Column full!" if column_full?
@board[@row_index] << @turn
if player_won?
@finished = true
return "Player #{@turn} wins!"
else
toggle_turn
return "Player #{@turn == 1 ? 2 : 1} has a turn"
end
end
@seemaisms
seemaullal@gmail.com
def toggle_turn
@turn = @turn == 1 ? 2 : 1
end
def player_won?
four_in_a_row?(vertical) ||
four_in_a_row?(horizontal) ||
four_in_a_row?(diagonal_up)
||
four_in_a_row?(diagonal_down)
end
def four_in_a_row?(array)
!!array.chunk_while { |i,j| i == j }.find { |arr| arr.length >= 4 && arr[0] }
end
def column_full?
@board[@row_index].length == 6
end
def initialize_board
7.times.with_object([]) { |i, board| board << [] }
end
@seemaisms
seemaullal@gmail.com
class InvoiceCreator
def initialize(user_id, invoice_date)
@user_id = user_id
@invoice_date = invoice_date
end
def create_invoice
user_subscriptions = UserSubscription.where(
user_id: @user_id
).select do |subcription|
subscription.invoice_date == invoice_date
end
total_cost = user_subscriptions.sum do |user_subscription|
if user_subscription.monthly_subscription?
user_subscription.cost
else
user_subscription.cost /12
end
end
UserInvoice.create!(user_id: @user_id, amount: total_cost, date: @invoice_date)
end
end
@seemaisms
seemaullal@gmail.com
Functions and classes should do one thing
well
@seemaisms
seemaullal@gmail.com
class UserSubscriptionFetcher
def fetch(user_id, invoice_date)
UserSubscription.where(user_id: @user_id).select do |subcription|
subscription.invoice_date == invoice_date
end
end
end
class UserSubscription
def monthly_cost
monthly_subscription? cost : cost /12
end
end
class InvoiceCreator
def initialize(user_id, invoice_amount, invoice_date)
@user_id = user_id
@invoice_amount = invoice_amount
@invoice_date = invoice_date
end
def create_invoice
UserInvoice.create!(user_id: @user_id, amount: @invoice_amount, date: @invoice_date)
end
end
@seemaisms
seemaullal@gmail.com
class Employee
# ...
def formatted_phone_number
return '' if phone_number.blank?
return "(#{phone[0..2]}) #{phone[3..5]}-#{phone[6..9]}"
end
end
@seemaisms
seemaullal@gmail.com
Use service objects to isolate complexity
@seemaisms
seemaullal@gmail.com
class PhoneNumberFormatter
def self.number_with_parentheses(phone_number)
return '' if phone_number.blank?
return "(#{phone[0..2]}) #{phone[3..5]}-#{phone[6..9]}"
end
end
@seemaisms
seemaullal@gmail.com
class PayEmployee
def self.call(employee)
payment = PaymentCreator.new(employee: employee).create_payment
DebitCompanyForPayment.call(payment, employee.company)
end
end
@seemaisms
seemaullal@gmail.com
Validate assumptions and fail fast
@seemaisms
seemaullal@gmail.com
class PayEmployee
def self.call(employee)
raise "Employee id #{employee.id} does not have a bank account" unless employee.bank_account
raise "Company id #{company.id} does not have a bank account" unless company.bank_account
payment = PaymentCreator.new(employee: employee).create_payment
DebitCompanyForPayment.call(payment, employee.company)
end
end
@seemaisms
seemaullal@gmail.com
Code That Is
Clear, Testable, Changeable
@seemaisms
seemaullal@gmail.com
Write tests
@seemaisms
seemaullal@gmail.com
Let your tests document how the code
should behave
@seemaisms
seemaullal@gmail.com
context 'when the person lives in Tennessee' do
context 'and also works there' do
it 'includes taxes for Tennessee' do
end
end
context 'when they work in a different state' do
it 'includes taxes for that state also' do
end
end
end
@seemaisms
seemaullal@gmail.com
expect(company_tax_total).to eq(472.67)
@seemaisms
seemaullal@gmail.com
expect(company_tax_total).to eq(
116.55 +
62.59 +
267.63 +
25.9
)
@seemaisms
seemaullal@gmail.com
expect(company_tax_total).to eq(
state_unemployment_tax +
medicare_tax +
social_security_tax +
federal_unemployment_tax
)
@seemaisms
seemaullal@gmail.com
Don't hit the database when you don't need
to
@seemaisms
seemaullal@gmail.com
class User
def full_name
[ first_name, middle_initial, last_name].compact.join(' ')
end
end
# in the test
user = instance_double(User, first_name: 'Cookie', middle_initial: nil, last_name: 'Monster')
@seemaisms
seemaullal@gmail.com
Avoid flaky tests
@seemaisms
seemaullal@gmail.com
describe('user invoice callbacks') do
it 'sends an email after the invoice is created' do
expect(UserMailer).to receive :user_invoice_email
UserInvoice.create
end
end
@seemaisms
seemaullal@gmail.com
describe('user invoice callbacks') do
it 'sends an email after the invoice is created' do
expect(UserMailer).to receive :user_invoice_email
UserInvoice.create
end
end
This usually works.
But, what if we only send
emails on business days.
@seemaisms
seemaullal@gmail.com
before do
Timecop.freeze(Date.new(2018, 1, 10))
end
after { Timecop.return }
@seemaisms
seemaullal@gmail.com
context ‘saving a file’ do
let(:document) { create(:file, val: ‘test’) }
subject { document.save_file! }
it ‘writes to the right path’ do
expect(File).to receive(:open).with("/tmp/documents/1/test")
end
@seemaisms
seemaullal@gmail.com
it ‘writes to the correct path’ do
expect(File).to receive(
:open
).with(
“/tmp/documents/#{document.id}/artifact”
)
end
@seemaisms
seemaullal@gmail.com
Prevent unit tests from testing more than
they should
@seemaisms
seemaullal@gmail.com
class PhoneNumberFormatter
def self.number_with_parentheses(phone_number)
return '' if phone_number.blank?
return "(#{phone[0..2]}) #{phone[3..5]}-#{phone[6..9]}"
end
end
class Employee
def formatted_phone_number
PhoneNumberFormatter.number_with_parentheses(phone)
end
end
@seemaisms
seemaullal@gmail.com
class Employee
def formatted_phone_number
PhoneNumberFormatter.number_with_parentheses(phone)
end
end
describe Employee do
describe '#formatted_phone_number' do
let(:phone_number) { '8001234567'}
it 'returns the formatted version of the phone number' do
expect(employee.formatted_phone_number).to eq('(800) 123-4567')
end
end
end
@seemaisms
seemaullal@gmail.com
describe Employee do
describe '#formatted_phone_number' do
it 'calls the formatter class' do
expect(PhoneNumberFormatter).to
receive(:number_with_parentheses).
with(employee.phone)
end
end
end
@seemaisms
seemaullal@gmail.com
Code That Is
Clear, Testable, Changeable
@seemaisms
seemaullal@gmail.com
Eliminate surprises and side effects
@seemaisms
seemaullal@gmail.com
class Discount
attr_reader :amount
def initialize(amount)
@amount = amount
end
end
@seemaisms
seemaullal@gmail.com
class Discount
attr_reader :amount
def initialize(amount)
@amount = amount
end
end
class DiscountCalculator
def self.calculate(user_id)
user_discounts = UserDiscount.where(user_id: user_id)
user_discounts.sum { |ud| ud.discount.amount }
end
end
@seemaisms
seemaullal@gmail.com
class Discount
attr_reader :amount
def initialize(amount)
@amount = amount
end
end
class DiscountCalculator
def self.calculate(user_id)
user_discounts = UserDiscount.where(user_id: user_id)
user_discounts.sum { |ud| ud.discount.amount }
end
end
Amount is sometimes the amount of the
discount in cents but sometimes it is a
percentage...
@seemaisms
seemaullal@gmail.com
@seemaisms
seemaullal@gmail.com
Consciously uncouple the different parts of
your code
@seemaisms
seemaullal@gmail.com
Delete unneeded comments
@seemaisms
seemaullal@gmail.com
class PhoneNumberFormatter
# this is used to format employee phone numbers,
# user phone numbers, and admin phone numbers
def self.number_with_parentheses(phone_number)
return '' if phone_number.blank?
return "(#{phone[0..2]}) #{phone[3..5]}-#{phone[6..9]}"
end
end
@seemaisms
seemaullal@gmail.com
Any fool can write code that a
computer can understand. Good
programmers write code that
humans can understand.
— Refactoring: Improving the Design of
Existing Code
@seemaisms
seemaullal@gmail.com
Slides on www.seemaullal.com under Talks
✉
seemaullal@gmail.com
@seemaisms
Thank You!
@seemaisms
seemaullal@gmail.com

More Related Content

Similar to Writing Loveable Code That Is Clear, Testable and Changeable

Java script Learn Easy
Java script Learn Easy Java script Learn Easy
Java script Learn Easy prince Loffar
 
Rails, Postgres, Angular, and Bootstrap: The Power Stack
Rails, Postgres, Angular, and Bootstrap: The Power StackRails, Postgres, Angular, and Bootstrap: The Power Stack
Rails, Postgres, Angular, and Bootstrap: The Power StackDavid Copeland
 
So basically I worked really hard on this code in my CS150 class and.pdf
So basically I worked really hard on this code in my CS150 class and.pdfSo basically I worked really hard on this code in my CS150 class and.pdf
So basically I worked really hard on this code in my CS150 class and.pdfeyewaregallery
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Storiesrahoulb
 
Reporting on your domino environment v1
Reporting on your domino environment v1Reporting on your domino environment v1
Reporting on your domino environment v1Bill Buchan
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with RspecBunlong Van
 
KLab 2019 Meetup - TypeScript come (forse) non lo hai mai visto
KLab 2019 Meetup - TypeScript come (forse) non lo hai mai vistoKLab 2019 Meetup - TypeScript come (forse) non lo hai mai visto
KLab 2019 Meetup - TypeScript come (forse) non lo hai mai vistoGianluca Carucci
 
Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)Joao Lucas Santana
 
Working Software 2019 - TypeScript come (forse) non lo hai mai visto
Working Software 2019 - TypeScript come (forse) non lo hai mai vistoWorking Software 2019 - TypeScript come (forse) non lo hai mai visto
Working Software 2019 - TypeScript come (forse) non lo hai mai vistoGianluca Carucci
 
Best Practice in Development
Best Practice in DevelopmentBest Practice in Development
Best Practice in Developmentmirrec
 
Google: Drive, Documents and Apps Script - How to work efficiently and happily
Google:  Drive, Documents  and Apps Script - How to work efficiently and happilyGoogle:  Drive, Documents  and Apps Script - How to work efficiently and happily
Google: Drive, Documents and Apps Script - How to work efficiently and happilyAlessandra Santi
 
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...Codemotion
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelpauldix
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test communityKerry Buckley
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015qmmr
 
How to develop frontend application
How to develop frontend applicationHow to develop frontend application
How to develop frontend applicationSeokjun Kim
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Brian Hogan
 

Similar to Writing Loveable Code That Is Clear, Testable and Changeable (20)

Java script Learn Easy
Java script Learn Easy Java script Learn Easy
Java script Learn Easy
 
Rails, Postgres, Angular, and Bootstrap: The Power Stack
Rails, Postgres, Angular, and Bootstrap: The Power StackRails, Postgres, Angular, and Bootstrap: The Power Stack
Rails, Postgres, Angular, and Bootstrap: The Power Stack
 
So basically I worked really hard on this code in my CS150 class and.pdf
So basically I worked really hard on this code in my CS150 class and.pdfSo basically I worked really hard on this code in my CS150 class and.pdf
So basically I worked really hard on this code in my CS150 class and.pdf
 
RSpec User Stories
RSpec User StoriesRSpec User Stories
RSpec User Stories
 
Reporting on your domino environment v1
Reporting on your domino environment v1Reporting on your domino environment v1
Reporting on your domino environment v1
 
Ruby on Rails testing with Rspec
Ruby on Rails testing with RspecRuby on Rails testing with Rspec
Ruby on Rails testing with Rspec
 
KLab 2019 Meetup - TypeScript come (forse) non lo hai mai visto
KLab 2019 Meetup - TypeScript come (forse) non lo hai mai vistoKLab 2019 Meetup - TypeScript come (forse) non lo hai mai visto
KLab 2019 Meetup - TypeScript come (forse) non lo hai mai visto
 
Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)Desenvolvimento web com Ruby on Rails (parte 3)
Desenvolvimento web com Ruby on Rails (parte 3)
 
Working Software 2019 - TypeScript come (forse) non lo hai mai visto
Working Software 2019 - TypeScript come (forse) non lo hai mai vistoWorking Software 2019 - TypeScript come (forse) non lo hai mai visto
Working Software 2019 - TypeScript come (forse) non lo hai mai visto
 
Best Practice in Development
Best Practice in DevelopmentBest Practice in Development
Best Practice in Development
 
Google: Drive, Documents and Apps Script - How to work efficiently and happily
Google:  Drive, Documents  and Apps Script - How to work efficiently and happilyGoogle:  Drive, Documents  and Apps Script - How to work efficiently and happily
Google: Drive, Documents and Apps Script - How to work efficiently and happily
 
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
Joe Bew - Apprendi un nuovo linguaggio sfruttando il TDD e il Clean Code - Co...
 
Mojolicious
MojoliciousMojolicious
Mojolicious
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Building Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModelBuilding Web Service Clients with ActiveModel
Building Web Service Clients with ActiveModel
 
Tdd for BT E2E test community
Tdd for BT E2E test communityTdd for BT E2E test community
Tdd for BT E2E test community
 
ECMAScript2015
ECMAScript2015ECMAScript2015
ECMAScript2015
 
How to develop frontend application
How to develop frontend applicationHow to develop frontend application
How to develop frontend application
 
Good Coding Practices with JavaScript
Good Coding Practices with JavaScriptGood Coding Practices with JavaScript
Good Coding Practices with JavaScript
 
Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7Intro to Ruby - Twin Cities Code Camp 7
Intro to Ruby - Twin Cities Code Camp 7
 

Recently uploaded

Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Cizo Technology Services
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf31events.com
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogueitservices996
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalLionel Briand
 
Lecture # 8 software design and architecture (SDA).ppt
Lecture # 8 software design and architecture (SDA).pptLecture # 8 software design and architecture (SDA).ppt
Lecture # 8 software design and architecture (SDA).pptesrabilgic2
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Natan Silnitsky
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfkalichargn70th171
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZABSYZ Inc
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Angel Borroy López
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)jennyeacort
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsChristian Birchler
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingShane Coughlan
 

Recently uploaded (20)

Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
Global Identity Enrolment and Verification Pro Solution - Cizo Technology Ser...
 
Sending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdfSending Calendar Invites on SES and Calendarsnack.pdf
Sending Calendar Invites on SES and Calendarsnack.pdf
 
Ronisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited CatalogueRonisha Informatics Private Limited Catalogue
Ronisha Informatics Private Limited Catalogue
 
Precise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive GoalPrecise and Complete Requirements? An Elusive Goal
Precise and Complete Requirements? An Elusive Goal
 
Lecture # 8 software design and architecture (SDA).ppt
Lecture # 8 software design and architecture (SDA).pptLecture # 8 software design and architecture (SDA).ppt
Lecture # 8 software design and architecture (SDA).ppt
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
Taming Distributed Systems: Key Insights from Wix's Large-Scale Experience - ...
 
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdfExploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
Exploring Selenium_Appium Frameworks for Seamless Integration with HeadSpin.pdf
 
Salesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZSalesforce Implementation Services PPT By ABSYZ
Salesforce Implementation Services PPT By ABSYZ
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
Alfresco TTL#157 - Troubleshooting Made Easy: Deciphering Alfresco mTLS Confi...
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
Call Us🔝>༒+91-9711147426⇛Call In girls karol bagh (Delhi)
 
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving CarsSensoDat: Simulation-based Sensor Dataset of Self-driving Cars
SensoDat: Simulation-based Sensor Dataset of Self-driving Cars
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full RecordingOpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
OpenChain AI Study Group - Europe and Asia Recap - 2024-04-11 - Full Recording
 

Writing Loveable Code That Is Clear, Testable and Changeable