Giter VIP home page Giter VIP logo

willy_fog_planner's Introduction

Design

Some considerations:

  • I consider a trip starts always from base city (SVQ in our example)
  • The arrival hours misses the date, so I assume is the same day as the flight/train started

First Steps

I have dealt with this exercise same way I would deal with a open source project for converting this kind of input data. Instead of converting the input in the output format directly I created an internal state in the midle. I have used Ecto (maybe too much for this but I wanted to take advantage of the cast/changeset power). I also used Timex for date's formatting.

How the library works

The main module and entry point is WillyFog.Planner. Here we define two functions:

  • parse/1 which receives a string and returns a ok tuple with a Plan
  • parse_file/1 which receives a path to a file and then calls internally to parse/1.

For example, lets try with this input:

BASED: SVQ

RESERVATION
SEGMENT: Flight SVQ 2023-03-02 06:40 -> BCN 09:10

RESERVATION
SEGMENT: Hotel BCN 2023-01-05 -> 2023-01-10

RESERVATION
SEGMENT: Flight SVQ 2023-01-05 20:40 -> BCN 22:10
SEGMENT: Flight BCN 2023-01-10 10:30 -> SVQ 11:50

First we need to load the library in our elixir IEX console (this is not an application).

iex -S mix

In the console we can run the library now

iex(2)> WillyFog.Planner.parse input
{:ok,
 %WillyFog.Planner.Plans.Plan{
   base: "SVQ",
   trips: [
     %WillyFog.Planner.Plans.Trip{
       origin: "SVQ",
       destinations: ["BCN"],
       segments: [
         %WillyFog.Planner.Plans.Segment{
           type: "flight",
           flight: %WillyFog.Planner.Plans.Segment.Flight{
             origin: "SVQ",
             destination: "BCN",
             starts_at: ~N[2023-01-05 20:40:00],
             arrives_at: ~T[22:10:00]
           },
           train: nil,
           hotel: nil
         },
         %WillyFog.Planner.Plans.Segment{
           type: "hotel",
           flight: nil,
           train: nil,
           hotel: %WillyFog.Planner.Plans.Segment.Hotel{
             city: "BCN",
             checkin: ~D[2023-01-05],
             checkout: ~D[2023-01-10]
           }
         },
         %WillyFog.Planner.Plans.Segment{
           type: "flight",
           flight: %WillyFog.Planner.Plans.Segment.Flight{
             origin: "BCN",
             destination: "SVQ",
             starts_at: ~N[2023-01-10 10:30:00],
             arrives_at: ~T[11:50:00]
           },
           train: nil,
           hotel: nil
         }
       ]
     },
     %WillyFog.Planner.Plans.Trip{
       origin: "SVQ",
       destinations: ["BCN"],
       segments: [
         %WillyFog.Planner.Plans.Segment{
           type: "flight",
           flight: %WillyFog.Planner.Plans.Segment.Flight{
             origin: "SVQ",
             destination: "BCN",
             starts_at: ~N[2023-03-02 06:40:00],
             arrives_at: ~T[09:10:00]
           },
           train: nil,
           hotel: nil
         }
       ]
     }
   ]
 }}

Note that I am returning a Plan struct instead of the required output String. I have done this having maintainability in mind, this means, today maybe we want to return a simple text but maybe tomorrow we would need to send an email with the itinerary, or a csv, or store it in the db... So the Plan struct is our main model. For this I created the module Formatter which currently only supports the simple_text/1 output.

Lets format the previous response:

iex(4)> WillyFog.Planner.Formatter.simple_text result
"TRIP to BCN\nFlight from SVQ to BCN at 2023-01-05 20:40 to 22:10\nHotel at BCN on 2023-01-05 to 2023-01-10\nFlight from BCN to SVQ at 2023-01-10 10:30 to 11:50\n\nTRIP to BCN\nFlight from SVQ to BCN at 2023-03-02 06:40 to 09:10\n"

Run a file

In the root of the project we have the required input.txt file. I have created an Elixir script for running it (check /scripts folder), you can run it with:

$ mix run scripts/read_input_txt.exs
"TRIP to BCN\nFlight from SVQ to BCN at 2023-01-05 20:40 to 22:10\nHotel at BCN on 2023-01-05 to 2023-01-10\nFlight from BCN to SVQ at 2023-01-10 10:30 to 11:50\n\nTRIP to MAD\nTrain from SVQ to MAD at 2023-02-15 09:30 to 11:00\nHotel at MAD on 2023-02-15 to 2023-02-17\nTrain from MAD to SVQ at 2023-02-17 17:00 to 19:30\n\nTRIP to NYC, BOS\nFlight from SVQ to BCN at 2023-03-02 06:40 to 09:10\nFlight from BCN to NYC at 2023-03-02 15:00 to 22:45\nFlight from NYC to BOS at 2023-03-06 08:00 to 09:25\n"

It is calling internally the functions defined before, you can check this file

Testing

In order to run tests you run

mix test

I also provided a more extended function

mix check

This add aditional checks like code format, credo, coverage and dialyzer. This function takes some time the first time we run it since the Dialyzer's PLTs has to be built.

Further steps

Since this is a prototype I didn't pay too much attention to performance. In a real world scenario we would check the size of the inputs, if they were huge we will try to find a better solution for reading the data with streams in a lazy way instead of loading all in memory.

willy_fog_planner's People

Contributors

ferigis avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.