Adding a radius search to your Ruby on Rails 5 application and PostgreSQL

Recently one of my project need to create a functionality for location based search. I choose PostgreSQL as database because I want to use some power of PostgreSQL.

So I want to create a functionality where I can send three param in a PostgreSQL and this database will return me location within this radius.  So I want to search what locations are within X meters of these coordinates.

Using PostgreSQL is lot easier.

First you need to enable some plugin for PostgreSQL.

  CREATE EXTENSION cube;
  CREATE EXTENSION earthdistance;

Now you can run query like:

SELECT \"franchises\".* FROM \"franchises\" WHERE (earth_box(ll_to_earth(40.810649, -73.598605), 2000) @> ll_to_earth(latitude, longitude))

You can also create a scope in rails model.

scope :within_radius, lambda {|latitude, longitude, metres| where("earth_box(ll_to_earth(?, ?), ?) @> ll_to_earth(latitude, longitude)", latitude, longitude, metres) }

And that’s it. You can call

  Franchise.within_radius(43.6422125, -79.3744256, 5000) 

and you’ll have a list of franchises within 5 km of NY.

Happy coding 🙂

Custom seed files in Ruby on Rails 5 project

For project purpose sometimes we need to create multiple seed files. We can do this by simple creating rake tasks in ruby on rails.

To create a rake task for multiple seed file you can use below code:

# lib/tasks/custom_seed.rake
namespace :db do
  namespace :seed do
    Dir[File.join(Rails.root, 'db', 'seeds', '*.rb')].each do |filename|
      task_name = File.basename(filename, '.rb').intern    
      task task_name => :environment do
        load(filename) if File.exist?(filename)
      end
    end
  end
end

Please save this code to lib/tasks/custom_seed.rake file

Now create a folder called seeds inside your db folder: db/seeds

Now you can run any seed file from this folder by simple running below command:

# Name of the file without the .rb extension 
rake db:seed:seed_file_name 

Happy Coding 🙂

zsh: command not found: bundle error

I have installed zsh in my ubuntu 16.04, but after install rails when trying to bundle install I found following error in my console:

zsh: command not found: bundle (after gem install bundle)

After searching on google I found following solution from stackoverflow.com:

  • echo ‘export PATH=”$HOME/.rbenv/bin:$PATH”‘ >> ~/.zshenv
  • echo ‘eval “$(rbenv init -)”‘ >> ~/.zshenv
  • echo ‘source $HOME/.zshenv’ >> ~/.zshrc
  • exec $SHELL

Running all those commands one by one will solve this problem.

Rename columns in pandas data-frame

pandas is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language.

We know for selecting a … in a pandas data-frame we need to use bracket notation with full name of a column. Sometimes our column name is very long with space. So we need to rename this with another name. We can do this with following pandas commands.

import pandas as pd
ufo = pd.read_csv('http://bit.ly/uforeports')
ufo.head()
City Colors Reported Shape Reported State Time
0 Ithaca NaN TRIANGLE NY 6/1/1930 22:00
1 Willingboro NaN OTHER NJ 6/30/1930 20:00
2 Holyoke NaN OVAL CO 2/15/1931 14:00
3 Abilene NaN DISK KS 6/1/1931 13:00
4 New York Worlds Fair NaN LIGHT NY 4/18/1933 19:00
ufo.columns
Index(['City', 'Colors Reported', 'Shape Reported', 'State', 'Time',
       'Location'],
      dtype='object')
Index(['City', 'Colors Reported', 'Shape Reported', 'State', 'Time',
       'Location'],
      dtype='object')
ufo.rename(columns={'Colors Reported' : 'colors_reported',
'Shape Reported' : 'shape_reported'}, inplace=True)

This will rename the old column with new column names.

We can also rename column names without specifying old names. To do so we need to create a python list and replace the old column names.

ufo_cols = ['city', 'colors reported', 'shape reported', 'state', 'time']
ufo.columns = ufo_cols

This will replace all old columns with new columns.

If we have too many columns in a data-frame, we can simply use python replace method replace columns.

Following command will lower case the word and replace spaces with underscore:

ufo.columns = ufo.columns.str.lower().str.replace(' ', '_')

Create new column from Pandas data-frame

pandas is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language.

For data analysis purpose sometimes we need to create a virtual column in existing data-frame. We can do that easily with following commands:

import pandas as pd
ufo = pd.read_table('http://bit.ly/uforeports', sep=',')

or we can use read_csv() method which have a comma separator by default.

ufo = pd.read_csv ('http://bit.ly/uforeports')

ufo.head()
City Colors Reported Shape Reported State Time
0 Ithaca NaN TRIANGLE NY 6/1/1930 22:00
1 Willingboro NaN OTHER NJ 6/30/1930 20:00
2 Holyoke NaN OVAL CO 2/15/1931 14:00
3 Abilene NaN DISK KS 6/1/1931 13:00
4 New York Worlds Fair NaN LIGHT NY 4/18/1933 19:00

To create new column with concatenate two other column

ufo['Location'] = ufo['City'] +', '+ ufo['State']
ufo.head()
Out[14]:
City Colors Reported Shape Reported State Time Location
0 Ithaca NaN TRIANGLE NY 6/1/1930 22:00 Ithaca, NY
1 Willingboro NaN OTHER NJ 6/30/1930 20:00 Willingboro, NJ
2 Holyoke NaN OVAL CO 2/15/1931 14:00 Holyoke, CO
3 Abilene NaN DISK KS 6/1/1931 13:00 Abilene, KS
4 New York Worlds Fair NaN LIGHT NY 4/18/1933 19:00 New York Worlds Fair, NY

Selecting series in a datframe

We know pandas have a most common data structure which is data-frame. We can select some values from a data-frame with some basic commands.

import pandas as pd
ufo = pd.read_table('http://bit.ly/uforeports', sep=',')

or we can use read_csv() method which have a comma separator by default.

ufo = pd.read_csv ('http://bit.ly/uforeports')

ufo.head()
City Colors Reported Shape Reported State Time
0 Ithaca NaN TRIANGLE NY 6/1/1930 22:00
1 Willingboro NaN OTHER NJ 6/30/1930 20:00
2 Holyoke NaN OVAL CO 2/15/1931 14:00
3 Abilene NaN DISK KS 6/1/1931 13:00
4 New York Worlds Fair NaN LIGHT NY 4/18/1933 19:00

We can select a series with bracket notation

ufo['City']
0                      Ithaca
1                 Willingboro
2                     Holyoke
3                     Abilene
4        New York Worlds Fair
5                 Valley City

]
We can also concatenate two column with simple python operation.

ufo['City'] +', '+ ufo['State']
0                      Ithaca, NY
1                 Willingboro, NJ
2                     Holyoke, CO
3                     Abilene, KS
4        New York Worlds Fair, NY
5                 Valley City, ND

 

Pandas data structure

pandas is an open source, BSD-licensed library providing high-performance, easy-to-use data structures and data analysis tools for the Python programming language.

The two primary data structures of pandas, Series (1-dimensional) and DataFrame (2-dimensional), handle the vast majority of typical use cases in finance, statistics, social science, and many areas of engineering. Pandas is built on top of NumPy and is intended to integrate well within a scientific computing environment with many other 3rd party libraries.

Series:
A Series is a one-dimensional object similar to an array, list, or column in a table. It will assign a labeled index to each item in the Series. By default, each item will receive an index label from 0 to N, where N is the length of the Series minus one.

# create a Series with an arbitrary list
s = pd.Series([7, 'Dhaka', 1.16, -1526, 'Happy City!'])
s
0                7
1            Dhaka
2             1.16
3            -1525
4      Happy City!
dtype: object

We can use dictionary as well, using the keys of the dictionary as its index.

d = {'Rajshahi': 100, 'Dhaka': 130, 'Dinajpur': 90, 'Rangpur': 110,
     'Natore': 45, 'Panchagarh': None}
cities = pd.Series(d)
cities
Dinajpur          90
Dhaka            130
Natore           45
Rajshahi         100
Rangpur          110
Panchagarh       NaN 
dtype: float64

You can use the index to select specific items from the Series …

Continue reading Pandas data structure