Design Patterns in Swift: Strategy

cover5

The problem:

We order our parts from three different vendors. Each vendor has its own system for fulfilling parts orders.

  1. ACME Parts Co which provides parts for domestic cars requires authorization from our parts supervisor before it can finalize any orders.
  2. PartsNStuff which provides parts for asians cars provides us with reseller discounts and requires each mechanic to provide their designated ID before finalizing orders.
  3. AutoPart Co which provides parts for European cars, as part of their state of the art secure ordering,  sends us a number that we have to return true if even and false if odd before they can fulfill our orders.

We need a system that can fulfil mechanic’s order from all our vendors.

The solution:

We need three different strategies for placing an order. We will solve this problem by implementing an OrderManager that will receives an order and decides which strategy to use to fulfil it. We will then implement three different strategies, each for fulfilling an order with a specific vendor.

Continue reading “Design Patterns in Swift: Strategy”

Design Patterns in Swift

Implementing design patterns is a great way to learn a new language. In my attempt to get a better understanding of Swift (and design patterns for that matter) I’ve decided to solve some of the real world challenges we face at YourMechanic using some of the more common design patterns. Of course some of these problems are worded rather conveniently to fit the specific design pattern :]

Who would find these articles useful:

These tutorials assume some working knowledge of Swift and general understanding of programming and object oriented fundamentals. However you do not need to be an expert in either Swift or design patterns to follow along. Since these articles combine two different subjects, individuals who are more versed in one and wish to learn more about the other would probably find these most useful. If you have an extensive background design patterns and come from a strong C#/Java background and want to get a feel for Swift, these articles would probably serve you well.

All solutions will come with an a link to the completed project on github.

If you spot any error or have and feedback I would love to hear it. This is my twitter

Design Patterns in Swift: Adapter

The problem:

YourMechanic is expanding to Canada. Now our friends to the north can have their cars fixed at their home or office by one of our professional mechanics. To finalize our expansion, we need to make major changes to our system. Providing support for the Canadian currency and the metric system would be a lot of work and we are short on time. Therefore we want an easy way to interface with our current Quote API. The Quote API can add and remove parts, set labor times for a quote, calculate a total price and track a car’s mileage. There also two properties, tax rates and labor rates which cannot be set but are derived from some external data source that we do not have access. All these values are assumed in USD/Imperial by our current system. We need a way to both display and input values in CAD and the metric system and have it remain consistent throughout our system. Also tax rates and labor rates are different in Canada so we need to adapt for those changes as well.

The solution

Repo on Github

Design Patterns in Swift: Prototype

The problem:

Beside having qualified mechanics working for the general public, YourMechanic has several contracts with various businesses. The appointments for these jobs for the most part follow the same configuration (same mechanics, same set of services, same parts, same number of cars and prices). What’s different is the name of the client, the address and the start time. Building a corporate appointment over and over again with the same configuration is time consuming and heavy on our servers. We would like a solution where the same appointment type can be re-created without having to look up our mechanic directory, parts directory or service directory.

The solution

Repo on Github

Design Patterns in Swift: Interpreter

The problem:

Our customers at YourMechanic  request quotes through our website or through their YourMechanic App. The final price for a quote is a combination of two variables, the cost of parts and the cost of labor. We want the ability to apply specific adjustments to either parts or labor prices. These adjustments could come from coupons, gift certificates or discounts. We need a simple language that can express these custom adjustments. For example, we should be able to define an expression that can add a 20% discount for parts. Or a another code that reduces $10 on labor. Or one that does both.

The solution

Repo on Github

Design Patterns in Swift: Chain Of Responsibility

The problem:

Not all mechanics are created equally. Some mechanics are more experienced and can do more than others. We need a system where every job is propagated from the least experienced mechanic to the most. This way  experienced mechanics that can perform more jobs are not busy with jobs that more junior mechanics can take care of.

The solution

Repo on Github

Design Patterns in Swift: Mediator

The problem:

Assume we track the location of all our mobile mechanics. We have noticed that there are times when a mobile mechanic might need assistance from another mechanic or a last minute need for a part that someone else might carry. We want to build a system where mechanics can send requests with the option of defining specific parts needed to all mechanics that are close to their location.

The solution

Repo on Github

Design Patterns in Swift: Observer

The problem:

We have a set of mobile mechanics who are assigned specific zip codes. Each zip code has its own hourly rate. We want to increase and decrease these rates when the number of idle mechanics within a zip code falls or goes above specific thresholds. This way we can proactively set the going rate for each mechanic when demand is high and bring it down when demand is low within a specific zip code.

The solution

Repo on Github

Design Patterns in Swift: Strategy

The problem:

We order our parts from three different vendors. Each vendor has its own system for fulfilling parts orders.

  1. ACME Parts Co which provides parts for domestic cars requires authorization from our parts supervisor before it can finalize any orders.
  2. PartsNStuff which provides parts for Asians cars requires each mechanic to provide their designated ID before finalizing orders.
  3. AutoPart Co which provides parts for European cars, as part of their state of the art secure ordering,  sends us a number that we have to return true if even and false if odd before they can fulfill our orders.

We need a system that can fulfil mechanic’s order from all our vendors.

The solution

Repo on Github

Design Patterns in Swift: State

The problem:

A quote goes through many phases before it is completed by a mechanic. Initially a customer request a quote, once received, our system attempts to automatically provide a quote for the customer. If our system doesn’t have enough information, the quote becomes pending. At this state a member of our customer support team finds out what’s needed to provide a ready quote. Once a quote is ready, the customer can use it to book an appointment. Once an appointment is booked a mechanic is assigned to the quote. We need to be able to retrieve this mechanic’s information. When the appointment is completed we generate a receipt and send it to the customer.

We need a system that can provide us with an interface to get the price, get a customized message that’s dependant on the quotes’s state, and provide the receipt when the appointment is complete.

The solution

Repo on Github

Design Patterns in Swift: Visitor

The problem:

We send out an email and create an internal report when a quote is requested by the customer. We also do the same when an appointment is booked. The content of the email and the report are dynamically generated from the information contained in the quote and the appointment.  We need a system that can provide us with an easy and straightforward way of composing these documents.

Ideally we hope to achieve this without adding repeated report/email functionality to our already cluttered Quote and Appointment class.

The solution

Repo on Github

Design Patterns in Swift: Builder

The problem:

Our customers at YourMechanic request quotes through our website or through their YourMechanic App. A quote is a complicated object. It must have a car, at least one service, the customer’s contact information, a mechanic capable of doing the services, picked automatically by the system or selected by the user and a coupon code that a quote may or may not have. We need a system that can build our quote and guarantee its validity. The system should be extendable and capable of dealing with changes to our quote creation process, ideally without having to change anything in the quote object itself.

The solution

Repo on Github

More to come…

Design Patterns in Swift: Observer

The problem:

We have a set of mobile mechanics who are assigned specific zip codes. Each zip code has its own hourly rate. We want to increase and decrease these rates when the number of idle mechanics within a zip code falls or goes above specific thresholds. This way we can proactively set the going rate for each mechanic when demand is high and bring it down when demand is low within a specific zip code.

The solution:

We will set up an observer that will monitor the status of each mechanic. This observer will send out notifications to its subscribers when there is a change. Then we will set up a price manager object that will subscribe to our observer and consume its status change notifications. The price manager subscriber  will keep tally of our mechanic supply and when their status is changed it will re-calculate and assign new rates for zip codes if their idle supply falls or goes above specific thresholds.

Continue reading “Design Patterns in Swift: Observer”

Design Patterns in Swift: Mediator

The problem:

Assume we track the location of all our mobile mechanics. We have noticed that there are times when a mobile mechanic might need assistance from another mechanic or a last minute need for a part that someone else might carry. We want to build a system where mechanics can send requests with the option of defining specific parts needed to all mechanics that are close to their location.

The solution:

We will define a mediator and have have every mechanics register with it. When a mechanic sends a request, the mediator will detect all close by mechanics and forwards the request to them.

Continue reading “Design Patterns in Swift: Mediator”

Design Patterns in Swift: Chain Of Responsibility

The problem:

Not all mechanics are created equally. Some mechanics are more experienced and can do more than others. We need a system where every job is propagated from the least experienced mechanic to the most. This way  experienced mechanics that can perform more jobs are not busy with jobs that more junior mechanics can take care of.

The solution:

We will break down our mechanics into four different skill levels: oil change only, junior, apprentice and master mechanic. Every mechanic will have their skill level assigned to one of these four values. Each mechanic skill level will also have a reference to a set of mechanics that are at the next skill level. We will then define a virtual shop and pass it our first line of mechanics (our most junior fleet).  Next we will define a set of jobs we wish to perform along with the minimum skill level required. We will pass these jobs to our virtual shop which in turn goes through each skill level, trying to find the mechanic with the minimum skills set required to do the job.

Continue reading “Design Patterns in Swift: Chain Of Responsibility”

Sharing on Facebook, AngularJS and the problem with Facebook Scraper

Facebook sends a crawler to every website that is shared on its platform. If the site contains Open Graph (OG) tags then it will construct the shared item according to what is provided. This is why when your share a link it might contain rich data like featured images, descriptions and all sorts of fancy stuff instead of a lonely URL.

This is being an adult

However when your site is a “Single Page Application” and uses a framework like AngularJS then a lot of that data might be created on the clients side. If your site has content specific URLs that are non-genetic then your OG data would ideally need to be updated for each individual URL. It wouldn’t make sense for someone who is sharing a specific image or video from your site to get a generic logo or description as opposed to the shared item.  The problem is that currently setting up your OG meta data through Angular does not work.

Facebook crawlers do not run Javascript when they visits your site. I learned this after I had implemented what I thought was a rather elegant solution of building OG meta tags dynamically through angular. Facebook ignores all of it and returns AngularJS placeholders. (You will get your general {{variable_with_og_data}})

After some research I realized the best solution for PixPit was to recreate the routes on Rails, check to see if the request is from Facebook and redirect accordingly. This would be achieved by checking if the user-agent was coming from Facebook, if so the request would be routed to a specific Rails generated view with the correct OG meta data. otherwise it would send the request to the default view with Angular.

Create a new route that matches the shared URL

  get "/pic/:id" => "application#pic"

The corresponding controller routes the request when a specific picture from PixPit is shared. It would check to see if it’s coming from Facebook, if so it would set up the image/video’s OG meta tag accordingly and redirect to a specific view “fb_pic”, if not then our default index view with Angular is rendered.

  def pic
    agent = request.headers["HTTP_USER_AGENT"].downcase
    
    image = Image.find_by_id(params[:id])
    if agent.include?("facebook")
      @currentUrl = "http://www.pixpit.com/pic/#{params[:id]}/#{params[:stuff]}"
      @currentImage = image.image_url
      @currentTitle = "<meta property=\"og:title\"content= \"#{image.title}\"  />"
      @currentDescription = "<meta property=\"og:description\" content=\"Endless fun!\"/>"
      if image.img_content_type.include?('video/mp4')
        @currentItem = "<meta property=\"og:video\" content=\"#{image.image_url}\"  />"
        @currentItem += "<meta property=\"og:video:width\" content=\"480\" />"
        @currentItem += "<meta property=\"og:video:height\" content=\"270\" />"
        @currentItem += "<meta property=\"og:video:secure_url\" content=\"#{image.image_url.sub("http:/", "https:/")}\"  />"
        @currentItem += "<meta property=\"og:image\" content=\"http://www.pixpit.com/assets/logo-play.png\"  />"
        @currentItem += "<meta property=\"og:video:type\" content=\"video/mp4\"/>"
      else
        @currentItem = "<meta property=\"og:image\" content=\"#{image.image_url}\"  />"
      end
      render "fb_pic"
      return
    end
    render "index"
  end

The “fb_pic” view doesn’t actually have the image or anything else for that matter. The sole purpose of this page is to render the OG meta data for Facebook.

<head>
<%=@currentTitle.html_safe%>
<meta property="og:type" content="movie"/>
<meta property="og:site_name" content="PixPit - Endless fun!"/>
<meta property="og:url"
content= <%=@currentUrl %> />
<%=@currentDescription.html_safe%>
<%=@currentItem.html_safe%>
</head>

As a quick side note, If you want people to be able to play your video directly on Facebook, make sure you set your type to movie. Anything else (video, article, etc..) will not give you an inline player. This is true even if you set up og:video:type.

<meta property="og:type" content="movie"/>

 

Indexing reddit’s /r/funny images based on user comments

[Edit: This feature on PixPit is currently down]
What would you get if /r/funny images from reddit were indexed based on user comments? something interesting.

corgi

I took on the task this weekend and spent sometime spinning up Elasticsearch and indexing last three months of /r/funny.  I included the image title and url along with all the comments.  I flatten all the comment and add them as an array of text ignoring depth and context. The initial ideas is to treat all comments equally.  This actually ended up working nice for some searches, like ‘cat‘, ‘bear‘,  ‘game of thrones‘, and ‘Metallica‘, but some results are obviously showing up because of random discussions in the comments section.

I’m already planning on decreasing the value of comments further down the tree. These deep comments are usually not relevant to the image and make for bad indexing data.

I also indexed usernames along with the comments. Although this makes finding images that certain users have commented on much easier, it does skew the results based on values that are hardly relevant to the images. However people have such odd and mostly meaningless usernames that not a lot of queries match them.

If you want to play around with it, I have it up here: give it a try here