What is Bootstrap? A Short Bootstrap Tutorial on the What, Why, and How

 

 

If you’re doing anything web related, chances are you’ve heard about Bootstrap. If by now you still don’t know what Bootstrap is, or you just want to find a bootstrap tutorial for beginners to get a better overview of what it is and what it does best, you’ve come to the right place.

Bootstrap is a powerful toolkit – a collection of HTML, CSS, and JavaScript tools for creating and building web pages and web applications. It is a free and open source project, hosted on GitHub, and originally created by (and for) Twitter.

After its open source release in 2011, Bootstrap became popular very quickly, and not without reason. Web designers and web developers like Bootstrap because it is flexible and easy to work with. Its main advantages are that it is responsive by design, it maintains wide browser compatibility, it offers consistent design by using re-usable components, and it is very easy to use and quick to learn. It offers rich extensibility using JavaScript, coming with built-in support for jQuery plugins and a programmatic JavaScript API. Bootstrap can be used with any IDE or editor, and any server side technology and language, from ASP.NET to PHP to Ruby on Rails.

With Bootstrap, web developers can concentrate on the development work, without worrying about design, and get a good looking website up and running quickly. Conversely, it gives web designers a solid foundation for creating interesting Bootstrap themes.

Getting Started with this Bootstrap Tutorial

Bootstrap is available in two forms; as a precompiled version, and as a source code version. The source code version uses the Less CSS preprocessor, but if you are more into Sass, there is an official Sass port of Bootstrap also available. To make it easier to make use of CSS vendor prefixes, Bootstrap uses Autoprefixer.

The source code version comes styles source code written in Less (or Sass), all the JavaScript, and accompanying documentation. This allows more ambitious designers and developers to change and customize, at their will, all the provided styles, and to build their own version of Bootstrap. But if you are not familiar with Less (or Sass), or you are just not interested in changing the source code, don’t worry. You can just use the precompiled vanilla CSS. All the styles can be overridden later by using custom styles.

File Structure

We’ll focus on the precompiled version, which can be downloaded here. When you download the zip archive and uncompress it, the basic file structure looks like this:

bootstrap/
├── css/
│   ├── bootstrap.css
│   ├── bootstrap.css.map
│   ├── bootstrap.min.css
│   ├── bootstrap-theme.css
│   ├── bootstrap-theme.css.map
│   └── bootstrap-theme.min.css
├── js/
│   ├── bootstrap.js
│   └── bootstrap.min.js
└── fonts/
    ├── glyphicons-halflings-regular.eot
    ├── glyphicons-halflings-regular.svg
    ├── glyphicons-halflings-regular.ttf
    ├── glyphicons-halflings-regular.woff
    └── glyphicons-halflings-regular.woff2

The Bootstrap structure is pretty simple and self-explanatory. It includes precompiled files that enable quick usage in any web project. Besides compiled and minified CSS and JS files, it also includes fonts fromGlyphicons, and the optional starting Bootstrap theme.

This structure can be easily incorporated in your own project’s file structure by just including the Bootstrap files exactly as they come out of the zip archive, or if it suits your project better, you can rearrange these files and place them anywhere you like. Just be sure that the Glyphicons fonts folder is on the same level as the CSS folder.

Basic HTML Template

A basic Bootstrap HTML template should look something like this:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <title>Bootstrap Template</title>
    <link href="css/bootstrap.min.css" rel="stylesheet">
  </head>
  <body>
    <h1>Hello, world!</h1>
    https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js
    http://js/bootstrap.min.js
  </body>
</html>

It is important to start any HTML with a HTML 5 Doctype declaration, so that browsers know what kind of a document they can expect. The head contains three important <meta> tags that must be declared first, and any additional head tags must be added after these. If you want to support older browsers like IE8, you can also include HTML 5 shim in the head, which will enable use of HTML5 elements in older browsers, andRespond.js, that will polyfill CSS3 Media Queries, in the old versions of Internet Explorer.

<head>
  ...
  <!--[if lt IE 9]>
    https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js
    https://oss.maxcdn.com/respond/1.4.2/respond.min.js
  <![endif]-->
</head>

Although this is not very important if you are targeting only modern browsers.

JavaScript files are added to the end of the body to allow the web page to load visibly before any JavaScript is executed. jQuery is needed for Bootstrap plugins, and needs to load before bootstrap.js. If you aren’t using any of Bootstrap’s interactive features, you can also omit these files from the source.

This is the bare minimum that is needed to get a basic Bootstrap layout up and running. If you’re a developer, you’ll probably want to take a look at some more advanced examples at Bootstrap’s examples page. If you’re a designer, or just looking for inspiration, Bootstrap Expo showcases sites that are built using Bootstrap. As we’ll see later, every part of Bootstrap can be easily customized in CSS. But if that’s not your thing, and you are looking for a slightly different look and feel from the prepackaged Bootstrap themes, there are a lot of free, open source and premium themes available from sources like Bootswatch and WrapBootstrap.

Components

Bootstrap comes bundled with basic HTML and CSS design templates that include many common UI components. These include Typography, Tables, Forms, Buttons, Glyphicons, Dropdowns, Buttons and Input Groups, Navigation, Pagination, Labels and Badges, Alerts, Progress Bars, Modals, Tabs, Accordions, Carousels, and many others. Many of these use JavaScript extensions and jQuery plugins.

These templates are made available as well-factored CSS classes that you can apply to your HTML to achieve different effects. This makes using Bootstrap very convenient. By using semantic class names like .success, .warning and .info, these components are easily reusable and extensible. But while Bootstrap uses descriptive class names that have meaning, it isn’t specific about implementation details. All classes can be overridden with custom CSS style and color, and still the meaning of the class will stay the same.

Grids

Before we dive more into Bootstrap components and design templates, it is important to mention one of the major features that Bootstrap introduced in version 3: a mobile-first design philosophy, which resulted in a Bootstrap that is responsive by design. The end result is that Bootstrap easily and efficiently scales with a single code base, from phones, through tablets, to desktops.

This responsiveness is achieved using a fluid grid system that can be applied to appropriately scale up to 12 columns according to the size of the device or viewport. Grids provide structure to the layout, defining the horizontal and vertical guidelines for arranging content and enforcing margins. Grids also offer an intuitive structure for viewers, because it’s easy to follow a left to right, or a right to left flow of content moving down the page. Before grids, and before CSS was so powerful, grid based layouts were achieved by using tables, where the content would be arranged inside table cells. As CSS became more mature, a number of CSS frameworks for grid-based layouts started to appear. These include YUI grids, 960 GS and blueprint, to name a few.

To use the Bootstrap grid system, a few rules need to be followed. Grid column elements are placed inside row elements, which create horizontal groups of columns. You can have as many rows as you want on the page, but columns must be immediate children of rows. In a full row, the column widths will be any combination that adds up to 12, but it is not mandatory to use all 12 available columns.

Rows need to be placed either in a fixed-width layout wrapper, which has a .container class and a width of 1170px, or in full-width layout wrapper, which has a .container-fluid class, and which enables the responsive behavior in that row.

The Bootstrap grid system has four tiers of classes: xs for phones (<768px), sm for tablets (≥768px), md for desktops (≥992px), and lg for larger desktops (≥1200px). These basically define the sizes at which the columns will collapse or spread horizontally. The class tiers can be used in any combination to get dynamic and flexible layouts.

Bootstrap on desktop and mobile

It is possible to disable page responsiveness completely. This will basically disable the “mobile site” aspects of Bootstrap. Just keep in mind that if you disable responsiveness, any fixed-width component, such as a fixed navbar, will not be visible when the viewport becomes narrower than the page content. For a non-responsive container, that means a width of 970px. Also in this case, navbars won’t collapse in mobile views as described later.

These are just basic examples. To see the full potential of the grids, check out Bootstrap’s Grids documentation.

Typography

Beginning developers often assume their pure and un-styled HTML will look the same across all browsers. Unfortunately, every browser has its own default “user agent” style sheet that is applied to the HTML, and no two browsers have the same defaults. For example, heading font sizes are not consistent across browsers, some unordered and ordered lists have left margins and others have left padding, browsers apply custom borders and padding to the HTML body, and even buttons are rendered differently across browsers. To solve all these inconsistencies, different CSS “reset” rules were born that define consistent style defaults.

Bootstrap brings some more goodies to table besides pure CSS reset. It comes with normalize.css, an HTML5-ready alternative to CSS resets, and it also has some well-designed defaults of its own. For example, Bootstrap sets the global default font-size to 14px, with a line-height of 1.428. The default font is changed to Helvetica/Arial, with sans serif fallback. All these styles are applied to the <body> and all paragraphs, with the addition that <p> (paragraphs) receive a bottom margin of half their computed line-height (10px by default). Besides these defaults, there are also customizable styles for standard HTML tags that bring more consistency to the text, such as highlighted text (<mark>), deleted text (<del> and <s>), underlined text (<u>), small text (<small>), and bold text (<strong>). Alignment classes help to arrange content on the page more easily by using .text-left, .text-center, .text-right, .text-justify and .text-nowrap classes. There are also predefined styles for block quotes, and unordered and ordered list, with inline options, just to name a few. To get a full list, head to the Bootstrap Typography page.

One interesting thing that Bootstrap also makes possible is that you can use, for example, heading styles by using either the <h1> tag, or the .h1 class. The latter will match the styling of the <h1> heading, but will allow the text to be displayed inline.

Forms

Forms have come a long way over the years, and today using a web form is one of the most common activities performed while browsing the web. While HTML5 introduced a number of new form attributes, input types, and other helper elements, browsers haven’t visually improved forms much. This is one area where Bootstrap really shines, because aligning and styling labels and inputs, validating forms, and showing error messages, can be tricky without some help.

First, Bootstrap sets all textual input elements, like <input>, <textarea>, and <select>, to 100% width of the parent form element. It also gives you the ability to choose between inline forms, which will render multiple labels and input fields in the same line, by using the .form-inline class, or horizontal forms, which use grids to align each input in its own row, by using the .form-horizontal class. And if you need to place plain text next to a form label, instead of the input field, you can give it the .form-control-static class to make it match the visual look of the form.

Maybe the greatest feature that Bootstrap brings to forms is validation styles for error, warning, and success states. These can be applied using the .has-warning, .has-error, and .has-success classes, respectively. Combining this with icons that can be placed inside the input forms, we can get quick and effective form validation effects, even without using any error text message.

 

Again, we have only scratched the surface here. For more examples, take a look at Bootstrap’s Forms documentation.

Images and Icons

Images in Bootstrap can be made responsive by simply giving them the .img-responsive class. This will apply max-width:100%; height:auto; and display:block; to the image in question, so that it scales to the parent element.

Besides making images responsive, we can easily add different effects. For example, rounded corners are applied with the .img-rounded class, and the image can be shaped to be a circle by using .img-circle, or to a thumbnail by using .img-thumbnail class.

Bootstrap comes bundled with over 260 glyphs in font format, from the Glyphicons Halflings set. Jan Kovařík, author and designer of Glyphicons, has made them available for Bootstrap for free and under the same license as Bootstrap, which is awesome. Font icons have many advantages over plain raster images, a big one being that they are scalable. They can also easily be customized using just CSS, so manipulating size or color, or even adding a drop a shadow, is a breeze.

Buttons, Button Groups, and Button Dropdowns

Buttons are one of the things every browser renders totally differently. If you want to have consistent design across all browsers, this is potentially a big problem. Luckily, Bootstrap has an elegant solution for buttonsalso. And besides making them consistent, it brings a lot of variations to play with. You can apply the .btnclass to <a> and <input> elements. You can group a series of buttons together into a single line using the .btn-group class on the parent <div>. With a little help from JavaScript, you can create radio- and checkbox- style behavior on buttons. Or you can turn your buttons into dropdown menus by placing it within a .btn-group, and providing the proper menu markup of unordered list of items.

The navigational bar, or navbar, is a Bootstrap component designed specifically to build the primary navigation menu of the website. On big screens, it is displayed horizontally, and on small and mobile screens (those below 768px), it transformed into a “hamburger” dropdown menu. Under the hood, navbar is an unordered inline list of menu items, with additional HTML elements that are added as desired. Among the possible additions are branding (either text or logo), form items such as a search bar, and menu dropdowns. Two styles are available to choose from out-of-the-box: light and dark, inverted. Items in the navbar can be aligned left or right by applying .navbar-left or .navbar-right classes, respectively.

Navbars can have 4 different position behaviors. The default float position has buffer space around it; the full-width static navbar scrolls away when the user scrolls down the page, and the fixed navbar, which can be either on the top or the bottom of the window, is always visible on the page, no matter where the user has scrolled to.

Bootstrap navbars

Conclusion

This covers only a few of the great Bootstrap components that puts Bootstrap ahead of similar frameworks, libraries, and toolkits. With Bootstrap, just a few simple CSS classes are all it takes to build a fully responsive and beautiful front end, fast and easily. It’s a great starting point for your next big project or startup.

Full Original post @ https://www.toptal.com/front-end/what-is-bootstrap-a-short-tutorial-on-the-what-why-and-how

Advertisements

Clean Code and The Art of Exception Handling

Exceptions are as old as programming itself. Back in the days when programming was done in hardware, or via low-level programming languages, exceptions were used to alter the flow of the program, and to avoid hardware failures. Today, Wikipedia defines exceptions as:

anomalous or exceptional conditions requiring special processing – often changing the normal flow of program execution…

And that handling them requires:

specialized programming language constructs or computer hardware mechanisms.

So, exceptions require special treatment, and an unhandled exception may cause unexpected behavior. The results are often spectacular. In 1996, the famous Ariane 5 rocket launch failure was attributed to an unhandled overflow exception. History’s Worst Software Bugs contains some other bugs that could be attributed to unhandled or miss-handled exceptions.

Over time, these errors, and countless others (that were, perhaps, not as dramatic, but still catastrophic for those involved) contributed to the impression that exceptions are bad.

The results of improperly handling exceptions have led us to believe that exceptions are always bad.

But exceptions are a fundamental element of modern programming; they exist to make our software better. Rather than fearing exceptions, we should embrace them and learn how to benefit from them. In this article, we will discuss how to manage exceptions elegantly, and use them to write clean code that is more maintainable.

Exception Handling: It’s a Good Thing

With the rise of object-oriented programming (OOP), exception support has become a crucial element of modern programming languages. A robust exception handling system is built into most languages, nowadays. For example, Ruby provides for the following typical pattern:

begin
  do_something_that_might_not_work!
rescue SpecificError => e
  do_some_specific_error_clean_up
  retry if some_condition_met?
ensure
  this_will_always_be_executed
end

There is nothing wrong with the previous code. But overusing these patterns will cause code smells, and won’t necessarily be beneficial. Likewise, misusing them can actually do a lot of harm to your code base, making it brittle, or obfuscating the cause of errors.

The stigma surrounding exceptions often makes programmers feel at a loss. It’s a fact of life that exceptions can’t be avoided, but we are often taught they must be dealt with swiftly and decisively. As we will see, this is not necessarily true. Rather, we should learn the art of handling exceptions gracefully, making them harmonious with the rest of our code.

Following are some recommended practices that will help you embrace exceptions and make use of them and their abilities to keep your code maintainable, extensible, and readable:

  • maintainability: Allows us to easily find and fix new bugs, without the fear of breaking current functionality, introducing further bugs, or having to abandon the code altogether due to increased complexity over time.
  • extensibility: Allows us to easily add to our code base, implementing new or changed requirements without breaking existing functionality. Extensibility provides flexibility, and enables a high level of reusability for our code base.
  • readability: Allows us to easily read the code and discover it’s purpose without spending too much time digging. This is critical for efficiently discovering bugs and untested code.

These elements are the main factors of what we might call cleanliness or quality, which is not a direct measure itself, but instead is the combined effect of the previous points, as demonstrated in this comic:

"WTFs/m" by Thom Holwerda, OSNews

With that said, let’s dive into these practices and see how each of them affects those three measures.

Note: We will present examples from Ruby, but all of the constructs demonstrated here have equivalents in the most common OOP languages.

Always create your own ApplicationError hierarchy

Most languages come with a variety of exception classes, organized in an inheritance hierarchy, like any other OOP class. To preserve the readability, maintainability, and extensibility of our code, it’s a good idea to create our own subtree of application-specific exceptions that extend the base exception class. Investing some time in logically structuring this hierarchy can be extremely beneficial. For example:

class ApplicationError < StandardError; end

# Validation Errors
class ValidationError < ApplicationError; end
class RequiredFieldError < ValidationError; end
class UniqueFieldError < ValidationError; end

# HTTP 4XX Response Errors
class ResponseError < ApplicationError; end
class BadRequestError < ResponseError; end
class UnauthorizedError < ResponseError; end
# ...

Example of an application exception hierarchy.

Having an extensible, comprehensive exceptions package for our application makes handling these application-specific situations much easier. For example, we can decide which exceptions to handle in a more natural way. This not only boosts the readability of our code, but also increases the maintainability of our applications and libraries (gems).

From the readability perspective, it’s much easier to read:

rescue ValidationError => e

Than to read:

rescue RequiredFieldError, UniqueFieldError, ... => e

From the maintainability perspective, say, for example, we are implementing a JSON API, and we have defined our own ClientError with several subtypes, to be used when a client sends a bad request. If any one of these is raised, the application should render the JSON representation of the error in its response. It will be easier to fix, or add logic, to a single block that handles ClientErrors rather than looping over each possible client error and implementing the same handler code for each. In terms of extensibility, if we later have to implement another type of client error, we can trust it will already be handled properly here.

Moreover, this does not prevent us from implementing additional special handling for specific client errors earlier in the call stack, or altering the same exception object along the way:

# app/controller/pseudo_controller.rb
def authenticate_user!
  fail AuthenticationError if token_invalid? || token_expired?
  User.find_by(authentication_token: token)
rescue AuthenticationError => e
  report_suspicious_activity if token_invalid?
  raise e
end

def show
  authenticate_user!
  show_private_stuff!(params[:id])
rescue ClientError => e
  render_error(e)
end

As you can see, raising this specific exception didn’t prevent us from being able to handle it on different levels, altering it, re-raising it, and allowing the parent class handler to resolve it.

Two things to note here:

  • Not all languages support raising exceptions from within an exception handler.
  • In most languages, raising a new exception from within a handler will cause the original exception to be lost forever, so it’s better to re-raise the same exception object (as in the above example) to avoid losing track of the original cause of the error. (Unless you are doing this intentionally).

Never rescue Exception

That is, never try to implement a catch-all handler for the base exception type. Rescuing or catching all exceptions wholesale is never a good idea in any language, whether it’s globally on a base application level, or in a small buried method used only once. We don’t want to rescue Exception because it will obfuscate whatever really happened, damaging both maintainability and extensibility. We can waste a huge amount of time debugging what the actual problem is, when it could be as simple as a syntax error:

# main.rb
def bad_example
  i_might_raise_exception!
rescue Exception
  nah_i_will_always_be_here_for_you
end

# elsewhere.rb
def i_might_raise_exception!
  retrun do_a_lot_of_work!
end

You might have noticed the error in the previous example; return is mistyped. Although modern editors provide some protection against this specific type of syntax error, this example illustrates how rescue Exception does harm to our code. At no point is the actual type of the exception (in this case a NoMethodError) addressed, nor is it ever exposed to the developer, which may cause us to waste a lot of time running in circles.

Never rescue more exceptions than you need to

The previous point is a specific case of this rule: We should always be careful not to over-generalize our exception handlers. The reasons are the same; whenever we rescue more exceptions than we should, we end up hiding parts of the application logic from higher levels of the application, not to mention suppressing the developer’s ability to handle the exception his or herself. This severely affects the extensibility and maintainability of the code.

If we do attempt to handle different exception subtypes in the same handler, we introduce fat code blocks that have too many responsibilities. For example, if we are building a library that consumes a remote API, handling a MethodNotAllowedError (HTTP 405), is usually different from handling an UnauthorizedError (HTTP 401), even though they are both ResponseErrors.

As we will see, often there exists a different part of the application that would be better suited to handle specific exceptions in a more DRY way.

So, define the single responsibility of your class or method, and handle the bare minimum of exceptions that satisfy this responsibility requirement. For example, if a method is responsible for getting stock info from a remote a API, then it should handle exceptions that arise from getting that info only, and leave the handling of the other errors to a different method designed specifically for these responsibilities:

def get_info
  begin
    response = HTTP.get(STOCKS_URL + "#{@symbol}/info")

    fail AuthenticationError if response.code == 401
    fail StockNotFoundError, @symbol if response.code == 404
    return JSON.parse response.body
  rescue JSON::ParserError
    retry
  end
end

Here we defined the contract for this method to only get us the info about the stock. It handles endpoint-specific errors, such as an incomplete or malformed JSON response. It doesn’t handle the case when authentication fails or expires, or if the stock doesn’t exist. These are someone else’s responsibility, and are explicitly passed up the call stack where there should be a better place to handle these errors in a DRY way.

Resist the urge to handle exceptions immediately

This is the complement to the last point. An exception can be handled at any point in the call stack, and any point in the class hierarchy, so knowing exactly where to handle it can be mystifying. To solve this conundrum, many developers opt to handle any exception as soon as it arises, but investing time in thinking this through will usually result in finding a more appropriate place to handle specific exceptions.

One common pattern that we see in Rails applications (especially those that expose JSON-only APIs) is the following controller method:

# app/controllers/client_controller.rb

def create
  @client = Client.new(params[:client])
  if @client.save
    render json: @client
  else
    render json: @client.errors
  end
end

(Note that although this is not technically an exception handler, functionally, it serves the same purpose, since @client.save only returns false when it encounters an exception.)

In this case, however, repeating the same error handler in every controller action is the opposite of DRY, and damages maintainability and extensibility. Instead, we can make use of the special nature of exception propagation, and handle them only once, in the parent controller class, ApplicationController:

# app/controllers/client_controller.rb

def create
  @client = Client.create!(params[:client])
  render json: @client
end
# app/controller/application_controller.rb

rescue_from ActiveRecord::RecordInvalid, with: :render_unprocessable_entity

def render_unprocessable_entity(e)
  render \
    json: { errors: e.record.errors },
    status: 422
end

This way, we can ensure that all of the ActiveRecord::RecordInvalid errors are properly and DRY-ly handled in one place, on the base ApplicationController level. This gives us the freedom to fiddle with them if we want to handle specific cases at the lower level, or simply let them propagate gracefully.

Not all exceptions need handling

When developing a gem or a library, many developers will try to encapsulate the functionality and not allow any exception to propagate out of the library. But sometimes, it’s not obvious how to handle an exception until the specific application is implemented.

Let’s take ActiveRecord as an example of the ideal solution. The library provides developers with two approaches for completeness. The save method handles exceptions without propagating them, simply returning false, while save! raises an exception when it fails. This gives developers the option of handling specific error cases differently, or simply handling any failure in a general way.

But what if you don’t have the time or resources to provide such a complete implementation? In that case, if there is any uncertainty, it is best to expose the exception, and release it into the wild.

Sometimes the best way to handle an exception is to let it fly free.

Here’s why: We are working with moving requirements almost all the time, and making the decision that an exception will always be handled in a specific way might actually harm our implementation, damaging extensibility and maintainability, and potentially adding huge technical debt, especially when developing libraries.

Take the earlier example of a stock API consumer fetching stock prices. We chose to handle the incomplete and malformed response on the spot, and we chose to retry the same request again until we got a valid response. But later, the requirements might change, such that we must fall back to saved historical stock data, instead of retrying the request.

At this point, we will be forced to change the library itself, updating how this exception is handled, because the dependent projects won’t handle this exception. (How could they? It was never exposed to them before.) We will also have to inform the owners of projects that rely on our library. This might become a nightmare if there are many such projects, since they are likely to have been built on the assumption that this error will be handled in a specific way.

Now, we can see where we are heading with dependencies management. The outlook is not good. This situation happens quite often, and more often than not, it degrades the library’s usefulness, extensibility, and flexibility.

So here is the bottom line: if it is unclear how an exception should be handled, let it propagate gracefully. There are many cases where a clear place exists to handle the exception internally, but there are many other cases where exposing the exception is better. So before you opt into handling the exception, just give it a second thought. A good rule of thumb is to only insist on handling exceptions when you are interacting directly with the end-user.

Follow the convention

The implementation of Ruby, and, even more so, Rails, follows some naming conventions, such as distinguishing between method_names and method_names! with a “bang.” In Ruby, the bang indicates that the method will alter the object that invoked it, and in Rails, it means that the method will raise an exception if it fails to execute the expected behavior. Try to respect the same convention, especially if you are going to open-source your library.

If we were to write a new method! with a bang in a Rails application, we must take these conventions into account. There is nothing forcing us to raise an exception when this method fails, but by deviating from the convention, this method may mislead programmers into believing they will be given the chance to handle exceptions themselves, when, in fact, they will not.

Another Ruby convention, attributed to Jim Weirich, is to use fail to indicate method failure, and only to use raise if you are re-raising the exception.

“An aside, because I use exceptions to indicate failures, I almost always use the “fail” keyword rather than the “raise” keyword in Ruby. Fail and raise are synonyms so there is no difference except that “fail” more clearly communicates that the method has failed. The only time I use “raise” is when I am catching an exception and re-raising it, because here I’m not failing, but explicitly and purposefully raising an exception. This is a stylistic issue I follow, but I doubt many other people do.”

Many other language communities have adopted conventions like these around how exceptions are treated, and ignoring these conventions will damage the readability and maintainability of our code.

Logger.log(everything)

This practice doesn’t solely apply to exceptions, of course, but if there’s one thing that should always be logged, it’s an exception.

Logging is extremely important (important enough for Ruby to ship a logger with its standard version). It’s the diary of our applications, and even more important than keeping a record of how our applications succeed, is logging how and when they fail.

There is no shortage of logging libraries or log-based services and design patterns. It’s critical to keep track of our exceptions so we can review what happened and investigate if something doesn’t look right. Proper log messages can point developers directly to the cause of a problem, saving them immeasurable time.

That Clean Code Confidence

Proper exception handling allows for clean code and successful software.

Clean exception handling will send your code quality to the moon!
Exceptions are a fundamental part of every programming language. They are special and extremely powerful, and we must leverage their power to elevate the quality of our code instead of exhausting ourselves fighting with them.

In this article, we dived into some good practices for structuring our exception trees and how it can be beneficial for readability and quality to logically structure them. We looked at different approaches for handling exceptions, either in one place or on multiple levels.

We saw that it’s bad to “catch ‘em all”, and that it’s ok to let them float around and bubble up.

We looked at where to handle exceptions in a DRY manner, and learned that we are not obligated to handle them when or where they first arise.

We discussed when exactly it is a good idea to handle them, when it’s a bad idea, and why, when in doubt, it’s a good idea to let them propagate.

Finally, we discussed other points that can help maximize the usefulness of exceptions, such as following conventions and logging everything.

With these basic guidelines, we can feel much more comfortable and confident dealing with error cases in our code, and making our exceptions truly exceptional!

Special thank to Avdi Grimm and his awesome talk Exceptional Ruby, which helped a lot in the making of this article.

Original Post @ https://www.toptal.com/qa/clean-code-and-the-art-of-exception-handling

Hello, Artificial Intelligence

computerworld
Image from Computerworld.com

Artificial Intelligence (AI) is one of the most interesting technology, It is one of my favorite subject since my college days. The idea of giving a little brain power to computer to make learned decisions based on some patterns or natural language is pretty awesome. We had our first team member couple of months back and in our culture we give 10% of the office time to work on the pet project. Ajeet wanted to work on implementing AI in a project. As an experiment he wanted to take a part of our product and demonstrate us how can we implement a particular functionality in much easier and efficient way?

To give a background, our product deals with huge amount of qualitative and quantitative data. It is a good case study to implement AI at various levels. He had spent last couple of months very sincerely helping our product to give a new look (help.reportingframework.com). So we have decided to give him full week off to work on his pet project which will give him a break and opportunity to explore AI. So this blog post is a shout out if anyone wants to guide him or tag along with him. They can reach out to him via his Linkedin account or put it in the comments below.

A short bio about Ajeet, He is very excited about AI. He has primarily worked with C#, JavaScript and SQL Server. His favorite programming language is Python. Over last couple of months he also got his hands dirty with tools like Dapper, Sphinx (based on python), MS Test, Gimp, RTools (based on python) and even 1 function in Lisp (Unbelievable! that my college project’s programming language has a part to play in our product). He is planning to use Python.

Wish him all the luck and fun working week holiday (passion is not equal to work!)

Progress: Currently he is exploring nltk and spacy

Introduction to Kotlin: Android Programming For Humans

In a perfect Android world, the main language of Java is really modern, clear, and elegant. You can write less by doing more, and whenever a new feature appears, developers can use it just by increasing version in Gradle. Then while creating a very nice app, it appears fully testable, extensible, and maintainable. Our activities are not too large and complicated, we can change data sources from database to web without tons of differences, and so on. Sounds great, right? Unfortunately, the Android world isn’t this ideal. Google is still striving for perfection, but we all know that ideal worlds don’t exist. Thus, we have to help ourselves in that great journey in the Android world.

Can Kotlin replace Java?

Kotlin is a popular new player in the Android world. But can it ever replace Java?

What Is Kotlin, and Why Should You Use It?

So, the first language. I think that Java isn’t the master of elegance or clarity, and it is neither modern nor expressive (and I’m guessing you agree). The disadvantage is that below Android N, we are still limited to Java 6 (including some small parts of Java 7). Developers can also attach RetroLambda to use lambda expressions in their code, which is very useful while using RxJava. Above Android N, we can use some of Java 8’s new functionalities, but it’s still that old, heavy Java. Very often I hear Android developers say “I wish Android supported a nicer language, like iOS does with Swift”. And what if I told you that you can use a very nice, simple language, with null safety, lambdas, and many other nice new features? Welcome to Kotlin.

What is Kotlin?

Kotlin is a new language (sometimes referred to as Swift for Android), developed by the JetBrains team, and is now in its 1.0.2 version. What makes it useful in Android development is that it compiles to JVM bytecode, and can be also compiled to JavaScript. It is fully compatible with Java, and Kotlin code can be simply converted to Java code and vice versa (there is a plugin from JetBrains). That means Kotlin can use any framework, library etc. written in Java. On Android, it integrates by Gradle. If you have an existing Android app and you want to implement a new feature in Kotlin without rewriting the whole app, just start writing in Kotlin, and it will work.

But what are the ‘great new features’? Let me list a few:

Optional and Named Function Parameters

fun createDate(day: Int, month: Int, year: Int, hour: Int = 0, minute: Int = 0, second: Int = 0) {
   print("TEST", "$day-$month-$year $hour:$minute:$second")
}

We Can Call Method createDate in Different Ways

createDate(1,2,2016) prints:  ‘1-2-2016 0:0:0’
createDate(1,2,2016, 12) prints: ‘1-2-2016 12:0:0’
createDate(1,2,2016, minute = 30) prints: ‘1-2-2016 0:30:0’

Null Safety

If a variable can be null, code will not compile unless we force them to make it. The following code will have an error – nullableVar may be null:

var nullableVar: String? = “”;
nullableVar.length;

To compile, we have to check if it’s not null:

if(nullableVar){
	nullableVar.length
}

Or, shorter:

nullableVar?.length

This way, if nullableVar is null, nothing happens. Otherwise, we can mark variable as not nullable, without a question mark after type:

var nonNullableVar: String = “”;
nonNullableVar.length;

This code compiles, and if we want to assign null to nonNullableVar, compiler will show an error.

There is also very useful Elvis operator:

var stringLength = nullableVar?.length ?: 0 

Then, when nullableVar is null (so nullableVar?.length returns null), stringLength will have value 0.

Mutable and Immutable Variables

In the example above, I use var when defining a variable. This is mutable, we can reassign it whenever we want. If we want that variable to be immutable (in many cases we should), we use val (as value, not variable):

val immutable: Int = 1

After that, the compiler will not allow us to reassign to immutable.

Lambdas

We all know what a lambda is, so here I will just show how we can use it in Kotlin:

button.setOnClickListener({ view -> Log.d("Kotlin","Click")})

Or if the function is the only or last argument:

button.setOnClickListener { Log.d("Kotlin","Click")}

Extensions

Extensions are a very helpful language feature, thanks to which we can “extend” existing classes, even when they are final or we don’t have access to their source code.

For example, to get a string value from edit text, instead of writing every time editText.text.toString() we can write the function:

fun EditText.textValue(): String{
   return text.toString()
}

Or shorter:

fun EditText.textValue() = text.toString()

And now, with every instance of EditText:

editText.textValue()

Or, we can add a property returning the same:

var EditText.textValue: String
   get() = text.toString()
   set(v) {setText(v)}

Operator Overloading

Sometimes useful if we want to add, multiply, or compare objects. Kotlin allows overloading of binary operators (plus, minus, plusAssign, range, etc.), array operators ( get, set, get range, set range), and equals and unary operations (+a, -a, etc.)

Data Class

How many lines of code do you need to implement a User class in Java with three properties: copy, equals, hashCode, and toString? In Kaotlin you need only one line:

data class User(val name: String, val surname: String, val age: Int)

This data class provides equals(), hashCode() and copy() methods, and also toString(), which prints User as:

User(name=John, surname=Doe, age=23)

Data classes also provide some other useful functions and properties, which you can see in Kotlin documentation.

Anko Extensions

You use Butterknife or Android extensions, don’t you? What if you don’t need to even use this library, and after declaring views in XML just use it from code by its ID (like with XAML in C#):

<Button
        android:id="@+id/loginBtn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
loginBtn.setOnClickListener{}

Kotlin has very useful Anko extensions, and with this you don’t need to tell your activity what is loginBtn, it knows it just by “importing” xml:

import kotlinx.android.synthetic.main.activity_main.*

There are many other useful things in Anko, including starting activities, showing toasts, and so on. This is not the main goal of Anko – it is designed for easily creating layouts from code. So if you need to create a layout programmatically, this is the best way.

This is only a short view of Kotlin. I recommend reading Antonio Leiva’s blog and his book – Kotlin for Android Developers, and of course the official Kotlin site.

What Is MVP and Why?

A nice, powerful, and clear language is not enough. It’s very easy to write messy apps with every language without good architecture. Android developers (mostly ones who are getting started, but also more advanced ones) often give Activity responsibility for everything around them. Activity (or Fragment, or other view) downloads data, sends to save, presents them, responds to user interactions, edits data, manages all child views . . . and often much more. It’s too much for such unstable objects like Activities or Fragments (it’s enough to rotate the screen and Activity says ‘Goodbye….’).

A very good idea is to isolate responsibilities from views and make them as stupid as possible. Views (Activities, Fragments, custom views, or whatever presents data on screen) should be only responsible for managing their subviews. Views should have presenters, who will communicate with model, and tell them what they should do. This, in short, is the Model-View-Presenter pattern (for me, it should be named Model-Presenter-View to show connections between layers).

MVC vs MVP

“Hey, I know something like that, and it’s called MVC!” – didn’t you think? No, MVP is not the same as MVC. In the MVC pattern, your view can communicate with model. While using MVP, you don’t allow any communication between these two layers – the only way View can communicate with Model is through Presenter. The only thing that View knows about Model can be the data structure. View knows how to, for example, display User, but doesn’t know when. Here’s a simple example:

View knows “I’m Activity, I have two EditTexts and one Button. When somebody clicks the button, I should tell it to my presenter, and pass him EditTexts’ values. And that’s all, I can sleep until next click or presenter tells me what to do.”

Presenter knows that somewhere is a View, and he knows what operations this View can perform. He also knows that when he receives two strings, he should create User from these two strings and send data to model to save, and if save is successful, tell the view ‘Show success info’.

Model just knows where data is, where they should be saved, and what operations should be performed on the data.

Applications written in MVP are easy to test, maintain, and reuse. A pure presenter should know nothing about the Android platform. It should be pure Java (or Kotlin, in our case) class. Thanks to this we can reuse our presenter in other projects. We can also easily write unit tests, testing separately Model, View and Presenter.

MVP pattern leads to better, less complex codebase by keeping user interface and business logic truly separate.

A little digression: MVP should be a part of Uncle Bob’s Clean Architecture to make applications even more flexible and nicely architectured. I’ll try to write about that next time.

Sample App with MVP and Kotlin

That’s enough theory, let’s see some code! Okay, let’s try to create a simple app. The main goal for this app is to create user. First screen will have two EditTexts (Name and Surname) and one Button (Save). After entering name and surname and clicking ‘Save’, the app should show ‘User is saved’ and go to the next screen, where saved name and surname is presented. When name or surname is empty, the app should not save user and show an error indicating what’s wrong.

The first thing after creating Android Studio project is to configure Kotlin. You should install Kotlin plugin, and, after restart, in Tools > Kotlin you can click ‘Configure Kotlin in Project’. IDE will add Kotlin dependencies to Gradle. If you have any existing code, you can easily convert it to Kotlin by (Ctrl+Shift+Alt+K or Code > Convert Java file to Kotlin). If something is wrong and the project does not compile, or Gradle does not see Kotlin, you can check code of the app available on GitHub.

Kotlin not only interoperates well with Java frameworks and libraries, it allows you to continue using most of the same tools that you are already familiar with.

Now that we have a project, let’s start by creating our first view – CreateUserView. This view should have the functionalities mentioned earlier, so we can write an interface for that:

interface CreateUserView : View {
   fun showEmptyNameError() /* show error when name is empty */
   fun showEmptySurnameError() /* show error when surname is empty */
   fun showUserSaved() /* show user saved info */
   fun showUserDetails(user: User) /* show user details */
}

As you can see, Kotlin is similar to Java in declaring functions. All of those are functions that return nothing, and the last have one parameter. This is the difference, parameter type comes after name. The View interface is not from Android – it’s our simple, empty interface:

interface View

Basic Presenter’s interface should have a property of View type, and at least on method (onDestroy for example), where this property will be set to null:

interface Presenter<T : View> {
   var view: T?

   fun onDestroy(){
       view = null
   }
}

Here you can see another Kotlin feature – you can declare properties in interfaces, and also implement methods there.

Our CreateUserView needs to communicate with CreateUserPresenter. The only additional function that this Presenter needs is saveUser with two string arguments:

interface CreateUserPresenter<T : View>: Presenter<T> {
   fun saveUser(name: String, surname: String)
}

We also need Model definition – it’s mentioned earlier data class:

data class User(val name: String, val surname: String)

After declaring all interfaces, we can start implementing.

CreateUserPresenter will be implemented in CreateUserPresenterImpl:

class CreateUserPresenterImpl(override var view: CreateUserView?): CreateUserPresenter<CreateUserView> {

   override fun saveUser(name: String, surname: String) {
   }
}

The first line, with class definition:

CreateUserPresenterImpl(override var view: CreateUserView?)

Is a constructor, we use it for assigning view property, defined in interface.

MainActivity, which is our CreateUserView implementation, needs a reference to CreateUserPresenter:

class MainActivity : AppCompatActivity(), CreateUserView {

   private val presenter: CreateUserPresenter<CreateUserView> by lazy {
       CreateUserPresenterImpl(this)
   }

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_main)

       saveUserBtn.setOnClickListener{
           presenter.saveUser(userName.textValue(), userSurname.textValue()) /*use of textValue() extension, mentioned earlier */


       }
   }

   override fun showEmptyNameError() {
       userName.error = getString(R.string.name_empty_error) /* it's equal to userName.setError() - Kotlin allows us to use property */

   }

   override fun showEmptySurnameError() {
       userSurname.error = getString(R.string.surname_empty_error)
   }

   override fun showUserSaved() {
       toast(R.string.user_saved) /* anko extension - equal to Toast.makeText(this, R.string.user_saved, Toast.LENGTH_LONG) */

   }

   override fun showUserDetails(user: User) {
      
   }

override fun onDestroy() {
   presenter.onDestroy()
}
}

At the beginning of the class, we defined our presenter:

private val presenter: CreateUserPresenter<CreateUserView> by lazy {
       CreateUserPresenterImpl(this)
}

It is defined as immutable (val), and is created by lazy delegate, which will be assigned the first time it is needed. Moreover, we are sure that it will not be null (no question mark after definition).

When the User clicks on the Save button, View sends information to Presenter with EditTexts values. When that happens, User should be saved, so we have to implement saveUser method in Presenter (and some of the Model’s functions):

override fun saveUser(name: String, surname: String) {
   val user = User(name, surname)
   when(UserValidator.validateUser(user)){
       UserError.EMPTY_NAME -> view?.showEmptyNameError()
       UserError.EMPTY_SURNAME -> view?.showEmptySurnameError()
       UserError.NO_ERROR -> {
           UserStore.saveUser(user)
view?.showUserSaved()
           view?.showUserDetails(user)
       }
   }
}

When a User is created, it is sent to UserValidator to check for validity. Then, according to the result of validation, proper method is called. The when() {} construct is same as switch/case in Java. But it is more powerful – Kotlin allows use of not only enum or int in ‘case’, but also ranges, strings or object types. It must contain all possibilities or have an else expression. Here, it covers all UserError values.

By using view?.showEmptyNameError() (with a question mark after view), we are protected from NullPointer. View can be nulled in onDestroy method, and with this construction, nothing will happen.

When a User model has no errors, it tells UserStore to save it, and then instruct View to show success and show details.

As mentioned earlier, we have to implement some model things:

enum class UserError {
   EMPTY_NAME,
   EMPTY_SURNAME,
   NO_ERROR
}

object UserStore {
   fun saveUser(user: User){
       //Save user somewhere: Database, SharedPreferences, send to web...
   }
}

object UserValidator {

   fun validateUser(user: User): UserError {
       with(user){
           if(name.isNullOrEmpty()) return UserError.EMPTY_NAME
           if(surname.isNullOrEmpty()) return UserError.EMPTY_SURNAME
       }

       return UserError.NO_ERROR
   }
}

The most interesting thing here is UserValidator. By using the object word, we can create a singleton class, with no worries about threads, private constructors and so on.

Next thing – in validateUser(user) method, there is with(user) {} expression. Code within such block is executed in context of object, passed in with name and surname are User’s properties.

There is also another little thing. All above code, from enum to UserValidator, definition is placed in one file (definition of User class is also here). Kotlin does not force you to have each public class in single file (or name class exactly as file). Thus, if you have some short pieces of related code (data classes, extensions, functions, constants – Kotlin doesn’t require class for function or constant), you can place it in one single file instead of spreading through all files in project.

When a user is saved, our app should display that. We need another View – it can be any Android view, custom View, Fragment or Activity. I chose Activity.

So, let’s define UserDetailsView interface. It can show user, but it should also show an error when user is not present:

interface UserDetailsView {
   fun showUserDetails(user: User)
   fun showNoUserError()
}

Next, UserDetailsPresenter. It should have a user property:

interface UserDetailsPresenter<T: View>: Presenter<T> {
   var user: User?
}

This interface will be implemented in UserDetailsPresenterImpl. It has to override user property. Every time this property is assigned, user should be refreshed on the view. We can use a property setter for this:

class UserDetailsPresenterImpl(override var view: UserDetailsView?): UserDetailsPresenter<UserDetailsView> {
   override var user: User? = null
       set(value) {
           field = value
           if(field != null){
               view?.showUserDetails(field!!)
           } else {
               view?.showNoUserError()
           }
       }

}

UserDetailsView implementation, UserDetailsActivity, is very simple. Just like before, we have a presenter object created by lazy loading. User to display should be passed via intent. There is one little problem with this for now, and we will solve it in a moment. When we have user from intent, View needs to assign it to their presenter. After that, user will be refreshed on the screen, or, if it is null, the error will appear (and activity will finish – but presenter doesn’t know about that):

class UserDetailsActivity: AppCompatActivity(), UserDetailsView {

   private val presenter: UserDetailsPresenter<UserDetailsView> by lazy {
       UserDetailsPresenterImpl(this)
   }

   override fun onCreate(savedInstanceState: Bundle?) {
       super.onCreate(savedInstanceState)
       setContentView(R.layout.activity_user_details)

       val user = intent.getParcelableExtra<User>(USER_KEY)
       presenter.user = user
   }

   override fun showUserDetails(user: User) {
       userFullName.text = "${user.name} ${user.surname}"
   }

   override fun showNoUserError() {
       toast(R.string.no_user_error)
       finish()
   }

override fun onDestroy() {
   presenter.onDestroy()
}

}

Passing objects via intents requires that this object implements Parcelable interface. This is very ‘dirty’ work. Personally, I hate doing this because of all of the CREATORs, properties, saving, restoring, and so on. Fortunately, there is proper plugin, Parcelable for Kotlin. After installing it, we can generate Parcelable just with one click.

The last thing to do is to implement showUserDetails(user: User) in our MainActivity:

override fun showUserDetails(user: User) {
   startActivity<UserDetailsActivity>(USER_KEY to user) /* anko extension - starts UserDetailsActivity and pass user as USER_KEY in intent */
}

And that’s all.

Demo Android app in Kotlin

We have a simple app that saves a User (actually, it is not saved, but we can add this functionality without touching presenter or view) and presents it on the screen. In the future, if we want to change the way user is presented on the screen, such as from two activities to two fragments in one activity, or two custom views, changes will be only in View classes. Of course, if we don’t change functionality or model’s structure. Presenter, who doesn’t know what exactly View is, won’t need any changes.

What’s Next?

In our app, Presenter is created every time an activity is created. This approach, or its opposite, if Presenter should persist across activity instances, is a subject of much discussion across the Internet. For me, it depends on the app, its needs, and the developer. Sometimes it’s better is to destroy presenter, sometimes not. If you decide to persist one, a very interesting technique is to use LoaderManager for that.

As mentioned before, MVP should be a part of Uncle Bob’s Clean architecture. Moreover, good developers should use Dagger to inject presenters dependencies to activities. It also helps maintain, test, and reuse code in future. Currently, Kotlin works very well with Dagger (before the official release it wasn’t so easy), and also with other helpful Android libraries.

Wrap Up

For me, Kotlin is a great language. It’s modern, clear, and expressive while still being developed by great people. And we can use any new release on any Android device and version. Whatever makes me angry at Java, Kotlin improves.

Of course, as I said nothing is ideal. Kotlin also have some disadvantages. The newest gradle plugin versions (mainly from alpha or beta) don’t work well with this language. Many people complain that build time is a bit longer than pure Java, and apks have some additional MB’s. But Android Studio and Gradle are still improving, and phones have more and more space for apps. That’s why I believe Kotlin can be a very nice language for every Android developer. Just give it a try, and share in the comments section below what you think.

Source code of the sample app is available on Github: github.com/tomaszczura/AndroidMVPKotlin

Original Post @ https://www.toptal.com/software/kotlin-android-language

Work Breakdown Tests

We think Test Driven Development is powerful and It can be used as a tool in a different way to get the distributed product development done.

So here is our experiment. This is how it will work. The idea is we will give you a set of Tests and you have to reply us with production source code by making the test pass. The problem statement will be from real world product.

So if you are interested than drop an email to confiablesolutions@gmail.com and we will share the Test file.

What’s in it for you?

That is a legit question, We are a firm believer in Agile methodology and Lean Principles.

We also believe that in today’s world of digital revolution we want to disrupt the most valuable assets of human being is TIME. Thus this initiative is to challenge your software development skills to solve this problem quickly and efficiently. Thus creating an alternative source of income without trading time for money.

Happy Coding!

Open Xml + Unable to create mutex

The error which took us a while to figure out to fix. As any mysterious error around this one also took a while to crack it. However the exception was IsolatedStorageException. We weren’t able to find the cause of the error.

Isolated Storage:  It is a disk location on server which is used when the processing of document size is bigger or a complex document structure, this was our interpretation. The definition says  “Isolated storage is a storage mechanism that provides isolation and safety by defining standardized ways of associating code with saved data.” You can find the details @ here

Then we got this stackoverflow link http://stackoverflow.com/questions/19465653/openxml-and-unable-to-create-mutex

We were not comfortable with accepted solution because It requires running IIS with elevated permissions which is a security weakness. May be we should have done further research on the Isolated storage and where the file location is created, however after going through the same link couple of weeks later we found another solution which mentioned something about to set Load User Profile to True. That solution worked for us.

Details on User Profile can be found here blogs.msdn.microsoft.com/vijaysk/2009/03/08/… and  iis.net/learn/manage/configuring-security/…

What we learned from this mistake is one has to go into the technical detail of an issue and read all available material related to  topic and do appropriate research before concluding the issue.

Technical Catalog

Teams which does IT Services, Application Development & Maintenance or Mobile development has one thing in common. They get stuck, hit a wall, a problem nags them. Often they come across research for a problems on unknown areas. We need to search about the topic, technical spec, domain, patterns and so on.

That’s where there are helps, forums, stack-overflow etc. The solution you get on internet will be generic. However if your software life cycle is more that one year and a you have a team working on it. Two thing will happen

  1. People will move in and out of the team.
  2. Software will keep evolving.

There will be small technical decision that will be every taken each day which will be specific to out software. which will be taken with the help of some reference link or help from internet. So on one kind of problem/issue the team will have to search all over again to get the background. The solution could be inside the code base, document wiki or over the internet. Below mentioned is a thought to take leverage of efforts already put by the team.

Technical Catalog: It is a simple list of reference links from internet, Small description specific to the software and reference in the software.

Problem Statement Solution Category
Sales report does not work in IE 8 http://someweb.url.com Reports

This will be help the team member starting to resolve any problem to check for the local catalog. which is created by the team with common purpose and goal. Thus helping them to get some initial inertia. Some time it help even the author because we don’t remember what we did six months ago when we stuck at the same problem.