problem solving techniques for evolutionary design
DESCRIPTION
In this workshop, Naresh Jain explains what are the core techniques one should master to effectively practice evolutionary design while solving real world problems. To summarize: 1. Eliminate Noise - Distill down the crux of the problem 2. Add constraints to future simplify the problem 3. Focus on one scenario at a time & incrementally build your solution 4. Refactor: Pause, look for a much simpler alternative 5. Be ready to throw away your solution & start againTRANSCRIPT
Problem Solving Techniques For Evolutionary Design
Distilling Down Any Problem to Its Crux
Naresh Jain [email protected]
@nashjain http://nareshjain.com
Rounding Up to the Closest 5 Cents
• In my billing application
• Given the price of an item comes up to $20.23 after tax
• I want to round up 23 cents to the closest 5 cents denomination .i.e. 25 cents
• So I can charge $20.25
• https://github.com/nashjain/rounding_logic
• https://help.github.com/categories/54/articles
Rounding Up - Answer
• var price = 20.23;
• var rounded_price = ceil(price / 0.05) * 0.05;
or
• var rounded_price = ceil(price * 20) / 20;
Hotel Room Charge• Calculate the bill amount based on the number of hotel nights
the guest has stayed in the hotel.
• Per hotel night is charged at 4999 INR for single occupancy and 5499 INR for double occupancy.
• Hotels have a standard 12:00 noon checkin and checkout.
• Early Checkin: Guest can request to checkin early (before 12:00 noon.) If they checkin between 9 and 12, they are charged 50% extra. If they checkin before 9 AM, then they are charged full night charge.
• Late Checkout: Guest can request a late checkout. If they checkout after 12 noon and before 3, they are charged 50% extra and if they checkout after 3:00 PM, they have to pay one whole night's extra charge.
function calculate_hotel_charge(occupancy, hotel_checkin, hotel_checkout) {! var per_night_rate = occupancy == ‘Single’ ? 4999 : 5499;! return per_night_rate * total_nights(hotel_checkin, hotel_checkout);!}!!function total_nights(hotel_checkin, hotel_checkout) {! return actual_nights(hotel_checkin, hotel_checkout)! + early_checkin_nights(hotel_checkin)! + late_checkout_nights(hotel_checkout);!}!!function actual_nights(hotel_checkin, hotel_checkout) {! var hotel_start_date = strip_out_time(hotel_checkin);! var hotel_end_date = strip_out_time(hotel_checkout);! return (hotel_end_date - hotel_start_date) / (24 * 60 * 60 * 1000);!}!!functional early_checkin_nights(hotel_checkin) {! if(hotel_checkin.getHours() > 12) return 0;! if(hotel_checkin.getHours() < 9) return 1;! return 0.5;!}!!function strip_out_time(in_date) {! return new Date(in_date.getFullYear(), in_date.getMonth(), in_date.getDate());!}
Hotel Room Charge Solution
functional late_checkout_nights(hotel_checkout) {! if(hotel_checkin.getHours() < 12) return 0;! if(hotel_checkin.getHours() > 3) return 1;! return 0.5;!}
High-level ApproachEliminate Noise Divide & Conquer
Test Data
Constraints Simple Design
Manual Debug
Refactor Throw Away
Create
Add
Come !up with
Simplify the Problem
Prioritise
Problem-Solving Strategies• Sandboxing: solving the problem in a model of the system before
applying it to the real system
• Metaphor: using a solution that solves an analogous problem
• Brainstorming: exploring a large number of solutions or ideas and combining and developing them until an optimum solution is found
• Divide and conquer: breaking down a large, complex problem into smaller, solvable problems
• Hypothesis testing: assuming a possible explanation to the problem and trying to prove (or disprove) the assumption
• Reduction: transforming the problem into another problem for which solutions exist
• Trial-and-error: testing possible solutions until the right one’s found
Adapted from: http://en.wikipedia.org/wiki/Problem_solving#Problem-solving_strategies
Commercial Break!
http://agilefaqs.com | Copyright © 2014, AgileFAQs. All Rights Reserved.
Mumbai
Tech Talks!
IP Address Range
• Each country has blocks of IPv4 address range assigned to it
• Given I have an IP address I want to figure out which country it belong to
Start End Total IPs Country
1.6.0.0 1.7.255.255 131072 India
1.22.0.0 1.23.255.255 131072 India
1.186.0.0 1.186.255.255 65536 India
1.0.32.0 1.0.63.255 8192 China
1.1.16.0 1.1.31.255 4096 China
1.4.16.0 1.4.31.255 4096 Japan
• https://github.com/nashjain/ip2country
• 196 countries with 100s of such blocks
243.131.122.231243*256*256*256 + 131*256*256 + 122*256 + 231
= 4085480167
public long convertToNumericIp() { long numericIp = 0; String[] octets = ip.split("\\."); for (int i = 0; i < 4; ++i) numericIp += parseInt(octets[i]) * Math.pow(256, 3 - i); return numericIp; }
243.131.122.231243*256*256*256 + 131*256*256 + 122*256 + 231
= 4085480167
Snakes and Ladders• One or more players can play the game
• Typical board size is 10 x10, but user can specify different board size
• User can decide the game mode (Easy = 5 snakes and ladders, Medium = 10 snakes and ladders, Hard = 20 snakes and ladders.) Default to easy mode.
• After each move, snakes and ladders could move, but at least after each game, they should move.
• Game takes the names of all the players and reports the name of the winner.
• Random player gets to start
def move(players, player_turn) new_position = players[player_turn] + throw_dice new_position = @snakes_ladders[new_position]
if @snakes_ladders.has_key?(new_position) return player_turn if new_position >= @board_size players[player_turn] = new_position next_player = (player_turn + 1) % players.length move(players, next_player) end
https://github.com/nashjain/snakes_n_ladders
Medical Age PrinterAge Reported in
Greater than 1 Year <Patient Name> is # Years old
> 1 Month & < 1 Year <Patient Name> is # Months old
> 1 Day & < 1 Month <Patient Name> is # Days old
> 1 Hr & < 1 Day <Patient Name> is # Hours old
https://github.com/nashjain/map
Medical Age PrinterAge Reported in
Greater than 1 Year <Patient Name> is # Years old
> 1 Month & < 1 Year <Patient Name> is # Months old
> 1 Day & < 1 Month <Patient Name> is # Days old
> 1 Hr & < 1 Day <Patient Name> is # Hours old
Doctors and Nurses might like to add and remove new Durations. For Ex: If they add Decade, and Patient’s age is greater than 10 years, then age should be reported as <Patient Name> is # Decades old. Similarly: If they add Week, and Patient’s age is greater than 7 Day, but less than a month, then age should be reported as <Patient Name> is # Weeks old.
https://github.com/nashjain/map
private static final long MILLIS_IN_MIN = 60 * 1000L; private static final long MILLIS_IN_HOUR = MILLIS_IN_MIN * 60; private static final long MILLIS_IN_DAY = MILLIS_IN_HOUR * 24; private static final long MILLIS_IN_MONTH = MILLIS_IN_DAY * 30; private static final long MILLIS_IN_YEAR = MILLIS_IN_DAY * 365; !private final TreeMap<Long, String> millisPerUnit = new TreeMap<Long, String>() { { put(MILLIS_IN_HOUR, "Hours"); put(MILLIS_IN_DAY, "Days"); put(MILLIS_IN_MONTH, "Months"); put(MILLIS_IN_YEAR, "Year"); } }; !public String since(Date dob) { long deltaInMillis = differenceInMillisFromNow(dob); Entry<Long, String> duration = millisPerUnit.floorEntry(deltaInMillis); if (duration == null) return "0 Hours"; return deltaInMillis / duration.getKey() + " " + duration.getValue(); } !private long differenceInMillisFromNow(Date date) { return clock.now() - date.getTime(); }
RecapEliminate Noise Divide & Conquer
Test Data
Constraints Simple Design
Manual Debug
Refactor Throw Away
Create
Add
Come !up with
Simplify the Problem
Prioritise
Important Advice
Pick a Solution after Trying at least 3 Approaches
"Perfection (in design) is achieved not when there is nothing more to add, but rather when there is nothing more to take away." – Eric S Raymond
Quit Multitasking
Deliberate Practice
Next Steps?
Practice An Hour Each Day
Participate