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

Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based projectAnoyGreter
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...stazi3110
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfAlina Yurenko
 
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
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Hr365.us smith
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Velvetech LLC
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....kzayra69
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityNeo4j
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 

Recently uploaded (20)

Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
MYjobs Presentation Django-based project
MYjobs Presentation Django-based projectMYjobs Presentation Django-based project
MYjobs Presentation Django-based project
 
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
Building a General PDE Solving Framework with Symbolic-Numeric Scientific Mac...
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdfGOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
GOING AOT WITH GRAALVM – DEVOXX GREECE.pdf
 
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)
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)Recruitment Management Software Benefits (Infographic)
Recruitment Management Software Benefits (Infographic)
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...Software Project Health Check: Best Practices and Techniques for Your Product...
Software Project Health Check: Best Practices and Techniques for Your Product...
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....What are the key points to focus on before starting to learn ETL Development....
What are the key points to focus on before starting to learn ETL Development....
 
Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
EY_Graph Database Powered Sustainability
EY_Graph Database Powered SustainabilityEY_Graph Database Powered Sustainability
EY_Graph Database Powered Sustainability
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 

Writing Loveable Code That Is Clear, Testable and Changeable