Forecasting from Times Series model using Python

Playing with large set of data is always fun if you know how to do it. You can fetch interesting information from it. As part of my Master’s course I have had opportunity to work on forecasting using Times Series modeling. And yes, now I can predict future without being a clairvoyant. 😀

Considering popularity of R in Data Science, I started with R. But soon I realized it has learning curve. So, I opt out for Python. I am not going to write R vs Python because it is already written nicely here in DataCamp’s blog.

So, lets get started. Time series models are very useful models when data points collected at constant time intervals. This time series stationarity is main per-requisite for the dataset. Until unless your time series is stationary, you cannot build a time series model. There is a popular example named “Random Walk”. The summary of the example is prediction becomes more inaccurate as input data is randomize.

We will use two completely different dataset to for prediction.

  • Nile Water Level between AD 622 to AD 1284. Get it here
  • Air Quality data of Italy taken in Hourly basis. Get it here

The reason we are taking two different model because we want to show multiple different Time Series models.

ARMA:

ARMA is basically combination of two different time series model AR and MA. AR stands for Auto Regressive and MA stands for Moving Average. In ARMA we work with single dependent variable indexed by time. This method is extremely helpful when we do not have any other data than time and one specific type of data. For example in case of Nile data we only have the water level data which is indexed by time(year). I am giving you warning, if your data is not stationary you will be tearing off all of your hair to fit the model. So, make sure your data is consistent to save your hair.

We have used Pandas for Data management.

We have used StatsModels ARMA method for prediction. It takes an mandatory parameter order which defines two parameters p,q of ARMA model. p is the order for AR model and MA is for MA model. Full API reference for this function can be found here. StatsModels also provides ARIMA modeling. In case of ARIMA model we just have to pass difference order parameter.

The predictors depend on the parameters (p,d,q) of the model. Here is the short description about it.

  1. Number of AR (Auto-Regressive) terms (p): AR terms are just lags of dependent variable. For example if p is 5, the predictors for x(t) will be x(t-1)â€Ļ.x(t-5).
  2. Number of MA (Moving Average) terms (q): MA terms are lagged forecast errors in prediction equation. For example if q is 5, the predictors for x(t) will be e(t-1)â€Ļ.e(t-5) where e(i) is the difference between the moving average at ith instant and actual value.
  3. Number of Differences (d): These are the number of nonseasonal differences, i.e. in this case we took the first order difference. So either we can pass that variable and put d=0 or pass the original variable and put d=1. Both will generate same results.

To calculate p and q I have run Autocorrelation Function (ACF) and Partial Autocorrelation Function (PACF). StatsModels have acf and pacf function to do this for us.

How I have done it:

At first I have installed Anaconda to get everything I need. Yes. we have gathered the whole zoo to do our data science. Python, Pandas and now Anaconda. Don’t forget you can write your code in IDE named Spider. Whatever…

 

After that, I have used Pandas to read csv. At first I was trying to fit ARMA on Air data. But since it was hourly data, fitting those data was difficult. Then I moved to Nile data. I was having hard time fitting Nile data because the time span for the data was out of the range of supported timestamp. So, instead of using DateTime index I switched to period range of Pandas. I have generated custom period range to support the time range. The while fitting ARMA model I passed the dates generated by the period range with annual frequency. For p and q order I have used ACF and PACF. I have calculated the lags and then plot it to a graph with bounds.

ACA and PACA observation

ACA and PACA observation

Observing the graph I have taken (2,2) as (p,q) order. After fitting the model I have predicted using the model. Here is the output of the prediction:

Nile Water level prediction

Nile Water level prediction

 

Linear Regression & Random Forrest Regression:

Besides ARMA and ARIMA model we have tried to use other prediction model. One of them are Linear Regression. SciKitLearn provides handful methods to do Linear Regression and Random Forrest Regression. I have ran these models on Air Quality data and got very good output. It has been observed that Random Forrest Regression generates more accurate predictions than Linear Regression. Random Forrest Regression has error rate of 12.8169340263% where as Linear Regression generates output with error rate 29.8718180357%.

 

How I have done it:

After reading data from CSV using pandas I have dropped NA(not available) or null values. Then I have omitted extreme values. I have run a co-relation calculation with all the columns against Temperature. The output was following:

Corelation with Temperature

Corelation with Temperature

Then I have ran prediction model on on the data. I have considered Temperature “T” as dependent variable and others as independent variable. The output was following:

Random forrest

Random forrest

 

Here is the code for everything I described above.


__author__ = "K.M. Tahsin Hassan Rahit"
__email__ = "tahsin.rahit@gmail.com"
import pandas as pd
import statsmodels.api as sm
import matplotlib.pylab as plt
from matplotlib import *
from spectrum import *
from pylab import *
import spectrum.arma
from pylab import plot, log10, hold, legend
from statsmodels.tsa.stattools import acf, pacf
from statsmodels.tsa.arima_model import ARIMA
from sklearn.cross_validation import train_test_split
#####
# data = pd.read_csv('air_data.csv',
# parse_dates=[['Date', 'Time']], index_col='Date_Time')
# dta = data.ix[:,['T']]
# res = sm.tsa.ARMA(dta, (6, 23), freq='H').fit()
# #print res.predict(7000, 10000)
# fig, ax = plt.subplots()
# ax = dta.ix[6500:].plot(ax=ax)
# res.plot_predict(8000, 10000, dynamic=True, ax=ax,
# plot_insample=False)
# plt.show()
#####
def check_pq_value(data):
data_diff = data – data.shift()
lag_acf = acf([float(i) for i in data['L'].tolist()], nlags=10)
lag_pacf = pacf([float(i) for i in data['L'].tolist()], nlags=10, method='ols')
plt.subplot(121)
plt.plot(lag_acf)
plt.axhline(y=0,linestyle='–',color='gray')
plt.axhline(y=2/np.sqrt(len(data_diff)),linestyle='–',color='gray')
plt.axhline(y=4/np.sqrt(len(data_diff)),linestyle='–',color='gray')
plt.title('Autocorrelation Function')
plt.subplot(122)
plt.plot(lag_pacf)
plt.axhline(y=0,linestyle='–',color='gray')
plt.axhline(y=2/np.sqrt(len(data_diff)),linestyle='–',color='gray')
plt.axhline(y=4/np.sqrt(len(data_diff)),linestyle='–',color='gray')
plt.title('Partial Autocorrelation Function')
plt.tight_layout()
plt.show()
def do_arma(data, target, freq, train_start, pred_start, pred_end):
plt.style.use('ggplot')
y = [float(i) for i in data[target].tolist()]
nobs = len(y)
# dates = sm.tsa.datetools.dates_from_range('1680m1', length=nobs)
dates = pd.period_range(train_start, periods=nobs, freq=freq)
y = pd.Series(y, index=dates.to_timestamp(freq=freq))
arma_mod = sm.tsa.ARMA(y, order=(2, 2))
arma_res = arma_mod.fit()
pred = arma_res.predict(pred_start, pred_end)
# pred_idx = pd.period_range('1755-12-31', end='1888-12-31', freq='A')
fig, ax = plt.subplots()
ax.plot(y[100:300])
ax.plot(pred)
plt.show()
# data = pd.read_csv('air_data.csv')
# do_arma(data, 'T', 'H', '1755-12-31', '1756-01-05', '1756-01-10')
data = pd.read_csv('nile-water-level.csv')
# check_pq_value(data)
do_arma(data, 'L', 'A', '1755-12-31', '2025-12-31', '2150-12-31')


__author__ = "K.M. Tahsin Hassan Rahit"
__email__ = "tahsin.rahit@gmail.com"
import pandas as pd
import numpy as np
import matplotlib.pylab as plt
from matplotlib import *
from matplotlib.pylab import rcParams
from sklearn.ensemble.forest import RandomForestRegressor
from sklearn.cross_validation import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error
plt.style.use('ggplot')
data = pd.read_csv('air_data.csv', parse_dates=[['Date', 'Time']], index_col='Date_Time')
# print data
data = data[data["T"] > 0]
data = data.dropna()
train, test = train_test_split(data, random_state=1, test_size=.1)
print data.corr()["T"]
columns = data.columns.tolist()
target = 'T'
columns = [c for c in columns if c not in ['T', 'Date', 'Time', 'RH', 'AH']]
model = LinearRegression()
# model = RandomForestRegressor(n_estimators=100, min_samples_leaf=5, random_state=1)
#print columns
# Fit the model to the training data.
model.fit(train[columns], train[target])
predictions = model.predict(test[columns])
print mean_squared_error(predictions, test[target])
test_indecies = test['T'].index.tolist()
fig, ax = plt.subplots()
ax.scatter(test_indecies, predictions, c='r', marker="s", label='Predicted')
ax.scatter(test_indecies, test['T'], c='g', marker="o", label='Original')
plt.legend(loc='upper left')
plt.grid(True)
# ax.plot([test[target].index.min(), test[target].index.max()], [predictions.min(), predictions.max()], 'k–', lw=4)
plt.show()

Dynamic form field based on another model’s entries and save them in a m2m way in Django

It’s been a while since I have done this type of brain storming stuff. Today is my country’s victory day and I have got some free time.

Objective:

I have a inventory model named Item. An item can have many attributes such as height, width etc. Think about a system where more attributes can be added in future. I wanted to build such a system where I can dynamically add these attributes so that I don’t need to modify my  model or code for this type of changes.

The idea:

The idea is very simple. I will have 3 models.

  • Item
  • Attribute
  • ItemAttribute

Item model will hold basic information about the item. In Attribute model I can add as many attribute as I wish. This model will have a type field which will determine the type of each attribute such as text, choice, number etc. It is possible to add more fields like length, required etc and add business logic for these. But for keep it simple for now.

ItemAttribute is the many to many relational table between Item and Attribute. It will have an extra field called value to store the value of this attribute.

In short: Item has many Attribute. Each of which has a value. To facilitate this we need many to many (m2m) relation between Item and Attribute.

How it is done:

Here is the gist how I achieved this functionality.


from myapp.models import Attribute, Item, ItemAttribute
from django.forms import ModelForm, HiddenInput, IntegerField, CharField
class ItemForm(ModelForm):
class Meta():
model = Item
exclude = ['attributes']
def __init__(self, *args, **kwargs):
self.request = kwargs.pop('request')
super(ItemForm, self).__init__(*args, **kwargs);
# Getting all attributes
attributes = Attribute.objects.all()
# Dynamically adding form field for each attribute
for attr in attributes:
# hardcodingly using char field type.
# In future it will be dynamicly handled by the type
# specified in attribute_type
self.fields[attr.attribute] = CharField(required=True)

view raw

form.py

hosted with ❤ by GitHub


from __future__ import unicode_literals
from django.db import models
class Attribute(models.Model):
TYPE_CHOICES = (
('text', 'text'),
('number', 'number')
)
attribute = models.CharField(primary_key=True, max_length=50)
attribute_type = models.CharField(max_length=20, choices=TYPE_CHOICES)
def __str__(self): # __unicode__ on Python 2
return self.attribute
class Item(models.Model):
id = models.AutoField(primary_key=True)
name = models.CharField(max_length=50)
attributes = models.ManyToManyField(Attribute, through='ItemAttribute')
def __str__(self): # __unicode__ on Python 2
return self.id
class ItemAttribute(models.Model):
id = models.AutoField(primary_key=True)
item = models.ForeignKey(Item, on_delete=models.CASCADE)
attribute = models.ForeignKey(Attribute, on_delete=models.CASCADE)
value = models.CharField(max_length=250)

view raw

models.py

hosted with ❤ by GitHub


from django.core.urlresolvers import reverse_lazy
from myapp.forms import ItemForm
from myapp.models import Item, ItemAttribute, Attribute
class ItemCreate(FormView):
form_class = ItemForm
template_name = 'myapp/item_form.html'
success_url = reverse_lazy('item_list')
# add the request to the kwargs
def get_form_kwargs(self):
kwargs = super(ItemCreate, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
def form_valid(self, form):
item = form.save(commit = True)
attributes = Attribute.objects.all()
for attr in attributes:
value = self.request.POST.get(attr.attribute)
item_attribute = ItemAttribute.objects.create(item=item, attribute=attr, value=value)
return super(ItemCreate, self).form_valid(form)

view raw

views.py

hosted with ❤ by GitHub

image manipulation with cache facility in nginx

Manipulation like resizing to cropping, rotating an image is very easy through image_filter module of nginx. In addition we can cache this manipulated images.

We will need 2 nginx server.

  1. original server [ i,e, http://mysite.local:80 ]
  2. media server. [ i,e, http://media.local:80 ] This server will be used to deliver the desired resized or cropped images.

Here is the configuration for the servers:


# My project directory is /home/rahit/www/mysite. I am storing cache file in my project folder under cache folder.
# You can use any of your prefered location in system. may be: /tmp/nginx
# I am naming keys_zone name my_cache. You can give it yours. We will need it later on in proxy_cache.
# Just make sure you put same zone name there
proxy_cache_path /home/rahit/www/mysite/cache levels=1:2 keys_zone=my_cache:10m max_size=1G;
# This is our media server, which will be used to resize and crop.
server {
listen 80;
server_name media.loc;
root /home/rahit/www/mysite;
# exaple url: /resize/<WIDTH>/<HEIGHT>/<IMAGE_PATH_FROM_ROOT>
# /resize/100/-/logo.jpg
# /resize/-/100/logo.jpg
location ~* ^/resize/([\d\-]+)/([\d\-]+)/(.+)$ {
alias /home/rahit/www/mysite/$3;
image_filter resize $1 $2;
image_filter_buffer 2M;
error_page 415 = /empty;
}
# exaple url: /crop/<WIDTH>/<HEIGHT>/<IMAGE_PATH_FROM_ROOT>
# /crop/100/-/logo.jpg
# /crop/-/100/logo.jpg
location ~* ^/crop/([\d\-]+)/([\d\-]+)/(.+)$ {
alias /home/rahit/www/mysite/$3;
image_filter crop $1 $2;
image_filter_buffer 2M;
error_page 415 = /empty;
}
location = /empty {
empty_gif;
}
}
# Here is our main server setting.
server {
listen 80;
root /home/rahit/www/mysite;
server_name mysite.loc http://www.mysite.loc;
# If we see an url which satisfy following regex we will pass this request to media server.
# Also we are going to cache the result we get from media server.
location ~* ^/(resize|crop)/ {
proxy_pass http://media.loc:80;
proxy_cache my_cache;
proxy_cache_key "$host$document_uri";
proxy_cache_valid 200 1d;
proxy_cache_valid any 1m;
proxy_cache_use_stale error timeout invalid_header updating;
}
}

view raw

nginx.conf

hosted with ❤ by GitHub

IntelliJ IDEA 14 + Phonegap 5.1 + Android SDK + Genymotion + linux

It is bit tricky to do this all together. Let me give me a overview why I choose these tools .

  • IntelliJ IDEA is an IDE I love working on. Actually for all of my developing purpose I use Jetbrain’s Product. PhpStorm, PyCharm, WebStorm. Since, it is not targeted for native android development choosing Android Studio is not necessary. I use that for native as it.
  • Phonegap is being used as I need to develop hybrid app. Android SDK is needed for deployment in android platform.
  • You may ask why Genymotion in lieu of AVD. The answer is, Genymotion seems faster to me. If you have already use AVD, it is not important how high end machine you use, I am sure you are very annoyed when you try to emulate. Genymotion may reduce your anger to some extent.
  • Linux: seriously?? You are going to ask me why linux??

How to:

Downloads & Installations:

  1. To use phonegap make sure you have node.js and npm installed in you system. Then run following command.

    $ sudo npm install -g phonegap

  2. Download android SDK. Extract it to the folder where you want to install it. Lets say it is the “home” folder. ~/android-sdk-linux Add ~/android-sdk-linux/tools and ~/android-sdk-linux/platform-tools to your path variable.
  3. Run $ andoird and download necessary libraries and API.
  4. Download genymotion and install it and install it buy running the .bin file.
  5.  Download IntelliJ IDEA. Extract it to the folder where you want to install it. Lets say it is the “home” folder
  6. run $ bin/idea.sh (make sure it is executable) and follow the installation process.

Setting Up:

  1. Install “Genymotion” and “Phonegap/Cordova” plugin. To install it, go to Settings → Plugins → Install JetBrains pluginâ€Ļ, then select PhoneGap/Cordova Plugin and click Install plugin. Same goes for genymotion.
  2. Create a new project using Web Static → Phonegap/Cordova category.
  3. after project creating the project open Project Structure (ctrl+shift+alt+s) in SDK add JDK library then Android SDK.
  4. On same window (Project Structure) select Modules. Click on (+) → import module. Select android folder under platform folder. and  click next. Important note that, do not import debug folders. When folder selection screen comes, select all folders (eg: ../android and all ../gen and ../src folder) except debug folders.
  5. Open Run/Debug Configuration.Click (+) → Android Application. Select then module you imported earlier. In Target Device select “Show Chooser Dialog” option.
  6. Run Genymotion and start your device.
  7. Run this newly created android configuration instead of Phonegap run and you will see your app running on your genymotion device.

Known Issue:

  • No module in step 5 ?
    – Make sure you have imported the module properly as described in step 4.
  • Errors on importing module ?
    – Follow the instruction carefully. May be you have added debug folders too.

Solution of infinite digest loop error for ng-repeat with object property filter in AngularJS

Few months ago I wrote a code in AngularJS which was something like this:


<ul ng-repeat="course in courses|filter:{is_taken:true }" >
<li>{{ course.name }}</li>
</ul>

 

It was generating a digesting loop error. Though the data was showing correctly. Soon I realized that it was generating because for each turn in ng-repeat loop, courses are filtered up. So, it was watched and digest by default characteristics of angular Scope. In this situation the easiest solution to me was following:


<div ng-init="filteredCourses=courses|filter:{is_taken:true }">
<ul ng-repeat="course infilteredCourses" >
<li>{{ course.name }}</li>
</ul>
</div>

 

What I did was I initiated a new object using ng-init which contains the filtered objects. Then use that newly created object to loop on. And all those errors are gone… 🙂

āĻ˛āĻžāĻ­ āĻ˛ā§‹āĻ¨

āĻ†āĻœāĻ•ā§‡ AIUB Job Fair āĻ āĻ…āĻ¨ā§‡āĻ•āĻŸāĻž āĻ˜ā§‹āĻ°āĻžāĻ˜ā§āĻ°āĻŋāĻ° āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ā§‡āĻ‡ āĻ—ā§‡āĻ˛āĻžāĻŽāĨ¤ āĻœāĻŦ āĻĒāĻžāĻ“ā§ŸāĻž āĻŦāĻž āĻ¸ā§‡āĻ°āĻ•āĻŽ āĻ•ā§‹āĻ¨ā§‹ āĻ‰āĻĻā§āĻĻā§‡āĻļā§āĻ¯ āĻ›āĻŋāĻ˛ āĻ¨āĻžāĨ¤ āĻ¯āĻžāĻ‡ āĻšā§‹āĻ•, āĻ¸ā§āĻŸāĻ˛āĻ—ā§āĻ˛ā§‹āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻŦā§‡āĻļ āĻ•ā§Ÿā§‡āĻ•āĻŸāĻž āĻŦā§āĻ¯āĻžāĻ‚āĻ•ā§‡āĻ°āĻ“ āĻ¸ā§āĻŸāĻ˛ āĻ›āĻŋāĻ˛āĨ¤

āĻŦā§āĻ¯āĻžāĻ‚āĻ•āĻ—ā§āĻ˛ā§‹āĻ° āĻŦā§āĻ¯āĻžāĻ¨āĻžāĻ°ā§‡ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ āĻ§āĻ°āĻ¨ā§‡āĻ° āĻ˛ā§‹āĻ¨ āĻāĻ° āĻŦāĻŋāĻœā§āĻžāĻžāĻĒāĻ¨ āĻ›āĻŋāĻ˛āĨ¤

  • āĻ•āĻŋāĻĄāĻ¸ āĻ•ā§‡ā§ŸāĻžāĻ° āĻ˛ā§‹āĻ¨
  • āĻāĻĄā§āĻ•ā§‡āĻļāĻ¨ āĻ˛ā§‹āĻ¨
  • āĻŦāĻŋāĻĻā§‡āĻļā§‡ āĻ˛ā§‡āĻ–āĻžāĻĒā§œāĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ¨
  • āĻ—āĻžā§œāĻŋ āĻ•ā§‡āĻ¨āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ¨
  • āĻ›ā§‹āĻŸ, āĻŦā§œ, āĻŽāĻžāĻāĻžāĻ°āĻŋ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ āĻ§āĻ°āĻ¨ā§‡āĻ° āĻŦā§āĻ¯āĻŦāĻžāĻ¸āĻž āĻļā§āĻ°ā§ āĻ•āĻ°āĻžāĻ° āĻ˛ā§‹āĻ¨
  • āĻŦāĻŋā§Ÿā§‡ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ¨
  • āĻœāĻžā§ŸāĻ—āĻž-āĻœāĻŽāĻŋ āĻ•ā§‡āĻ¨āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ¨
  • āĻŦāĻžā§œāĻŋ āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ¨
  • āĻ•ā§‡āĻ¨āĻžāĻ•āĻžāĻŸāĻž āĻ•āĻ°āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ¨
  • āĻšāĻŋāĻ•āĻŋā§ŽāĻ¸āĻž āĻ•āĻ°āĻžāĻ¨ā§‹āĻ° āĻœāĻ¨ā§āĻ¯ āĻ˛ā§‹āĻ¨

āĻŦāĻŋāĻœā§āĻžāĻžāĻĒāĻ¨āĻ—ā§āĻ˛ā§‹ āĻ†āĻ—ā§‡āĻ“ āĻĻā§‡āĻ–ā§‡āĻ›āĻŋāĨ¤ āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻŦāĻžāĻ° āĻĻā§‡āĻ–āĻžāĻ° āĻĒāĻ°ā§‡ āĻāĻ•āĻŸāĻž āĻœāĻŋāĻ¨āĻŋāĻ¸ āĻŽāĻ¨ā§‡ āĻšāĻ˛, āĻŦā§āĻ¯āĻžāĻ‚āĻ•āĻ—ā§āĻ˛ā§‹ āĻŽā§‹āĻŸāĻžāĻŽā§āĻŸāĻŋ āĻļāĻŋāĻļā§āĻ•āĻžāĻ˛ āĻĨā§‡āĻ•ā§‡ āĻŦāĻžāĻ°ā§āĻ§āĻ•ā§āĻ¯ āĻĒāĻ°ā§āĻ¯āĻ¨ā§āĻ¤ āĻ¸āĻŦāĻ•āĻŋāĻ›ā§āĻ‡ cover āĻ•āĻ°ā§‡ āĻĢā§‡āĻ˛ā§‡āĻ›ā§‡, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻāĻ•āĻŸāĻž āĻ—ā§āĻ°ā§āĻ¤ā§āĻŦāĻĒā§‚āĻ°ā§āĻŖ āĻ…āĻ§ā§āĻ¯āĻžā§Ÿ āĻ¤āĻžāĻ°āĻž āĻŽāĻŋāĻ¸ āĻ•āĻ°ā§‡ āĻ—āĻŋā§Ÿā§‡āĻ›ā§‡āĨ¤
āĻāĻ‡āĻŸāĻžāĻ° āĻœāĻ¨ā§āĻ¯ā§‡āĻ“ āĻ¤āĻžāĻ°āĻž āĻ¯āĻĻāĻŋ āĻ˛ā§‹āĻ¨ āĻĻā§‡ā§ŸāĻž āĻļā§āĻ°ā§ āĻ•āĻ°ā§‡ āĻ¤āĻžāĻšāĻ˛ā§‡ āĻ¤āĻžāĻĻā§‡āĻ° āĻ˛āĻžāĻ­ āĻ…āĻ¨ā§‡āĻ• āĻŦāĻžā§œāĻŦā§‡ āĻ¨āĻŋāĻļā§āĻšāĻŋāĻ¤āĨ¤ āĻ•āĻžāĻ°āĻŖ āĻ˛ā§‹āĻ¨ā§‡āĻ° āĻ¨āĻžāĻŽā§‡āĻ° āĻ­āĻŋāĻ¤āĻ°ā§‡āĻ‡ āĻ˛āĻžāĻ­āĨ¤ āĻ¸ā§‡āĻŸāĻŋ āĻšāĻšā§āĻ›ā§‡, “āĻ˛āĻžāĻ­ āĻ˛ā§‹āĻ¨”āĨ¤ I mean “Love Loan”.

āĻŦāĻ°ā§āĻ¤āĻŽāĻžāĻ¨ āĻ¸āĻŽā§Ÿā§‡, āĻ—āĻžāĻ°ā§āĻ˛āĻĢā§āĻ°ā§‡āĻ¨ā§āĻĄ āĻšāĻžāĻ˛āĻžāĻ¨ā§‹ āĻ•āĻ°āĻž, āĻŦāĻ‰ āĻšāĻžāĻ˛āĻžāĻ¨ā§‹āĻ° āĻšā§‡ā§Ÿā§‡āĻ“ āĻ…āĻ¨ā§‡āĻ• āĻ¸āĻŽā§Ÿā§‡ āĻŦā§‡āĻļā§€ āĻ…āĻ°ā§āĻĨāĻ¨ā§ˆāĻ¤āĻŋāĻ•āĻ­āĻžāĻŦā§‡ āĻŦā§‡āĻļā§€ āĻšā§āĻ¯āĻžāĻ˛ā§‡āĻžā§āĻœāĻŋāĻ‚āĨ¤ āĻ†āĻŦāĻžāĻ°, āĻ—āĻžāĻ°ā§āĻ˛āĻĢā§āĻ°ā§‡āĻ¨ā§āĻĄā§‡āĻ° āĻšāĻžāĻšāĻŋāĻĻāĻž āĻŽā§‡āĻŸāĻžāĻ¤ā§‡ āĻ¨āĻž āĻĒāĻžāĻ°āĻ˛ā§‡ āĻ…āĻ¨ā§‡āĻ• āĻ•ā§āĻˇā§‡āĻ¤ā§āĻ°ā§‡ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ• āĻšā§āĻŽāĻ•āĻŋāĻ° āĻŽā§āĻ–ā§‡ āĻĒā§œā§‡ āĻ¯āĻžā§ŸāĨ¤ āĻ¤āĻžāĻ° āĻ‰āĻĒāĻ°ā§‡ āĻ—āĻžāĻ°āĻ˛āĻĢā§āĻ°ā§‡āĻ¨ā§āĻĄāĻ•ā§‡ āĻ¨āĻŋā§Ÿā§‡ KFC, BFC, Bashundhara, Cineplex, Nandoos āĻ‡āĻ¤ā§āĻ¯āĻžāĻĻāĻŋ āĻ‡āĻ¤ā§āĻ¯āĻžāĻĻāĻŋ āĻœāĻžā§ŸāĻ—āĻžā§Ÿ āĻ¨āĻž āĻ—ā§‡āĻ˛ā§‡ āĻ¤ā§‹ āĻŽāĻžāĻ¨āĻ¸āĻŽā§āĻŽāĻžāĻ¨āĻ‡ āĻĨāĻžāĻ•āĻ˛ā§‹ āĻ¨āĻžāĨ¤ āĻ¤āĻžāĻ° āĻ‰āĻĒāĻ°ā§‡ āĻ—āĻžāĻ°ā§āĻ˛āĻĢā§āĻ°ā§‡āĻ¨ā§āĻĄā§āĻ°ā§‡āĻ° āĻĒā§‹āĻˇāĻž āĻ•ā§āĻ•ā§āĻ°ā§‡āĻ° āĻœāĻ¨ā§āĻŽāĻĻāĻŋāĻ¨ā§‡āĻ° āĻ—āĻŋāĻĢāĻŸ āĻĨā§‡āĻ•ā§‡ āĻļā§āĻ°ā§ āĻ•āĻ°ā§‡ āĻŦāĻŋāĻ­āĻŋāĻ¨ā§āĻ¨ āĻ…āĻ•ā§‡āĻļāĻ¨āĻžāĻ˛ āĻ—āĻŋāĻĢāĻŸ āĻ¤ā§‹ āĻ†āĻ›ā§‡āĻ‡āĨ¤

āĻāĻ¤ āĻ–āĻ°āĻš āĻāĻ•āĻœāĻ¨ āĻŦā§‡āĻ•āĻžāĻ° āĻ¯ā§āĻŦāĻ• āĻ•ā§‹āĻĨāĻž āĻšāĻ‡āĻ¤ā§‡ āĻĒāĻžāĻ‡āĻŦā§‡? āĻŦāĻžāĻŦāĻžāĻ° āĻŸāĻžāĻ•āĻž āĻ†āĻ° āĻ•āĻ¤āĻ‡ āĻŦāĻž āĻŽāĻžāĻ°āĻž āĻ¯āĻžā§Ÿ? āĻāĻ‡ āĻ¯ā§āĻŦāĻ•āĻŸāĻŋāĻ“ āĻ¤ā§‹ āĻŽāĻžāĻ¨ā§āĻˇ āĻ¨āĻžāĻ•āĻŋ? āĻāĻ‡ āĻĒā§āĻ°ā§‡āĻŽāĻŋāĻ• āĻ¯ā§āĻŦāĻ•āĻŸāĻŋāĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸āĻŽāĻžāĻœ āĻ•āĻŋ āĻ•āĻŋāĻ›ā§āĻ‡ āĻ•āĻ°āĻŋāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻ¨āĻž?

āĻ¤āĻžāĻ‡ āĻ†āĻŽāĻŋ āĻŦā§āĻ¯āĻžāĻ‚āĻ•āĻ—ā§āĻ˛ā§‹āĻ° āĻĒā§āĻ°āĻ¤āĻŋ āĻ‰āĻĻāĻžāĻ¤ā§āĻ¤ āĻ†āĻšāĻŦāĻžāĻ¨ āĻœāĻžāĻ¨āĻžāĻšā§āĻ›āĻŋ, āĻ†āĻĒāĻ¨āĻžāĻ°āĻž āĻ…āĻ¤āĻŋ āĻļā§€āĻ˜ā§āĻ° āĻ˛āĻžāĻ­ āĻ˛ā§‹āĻ¨ āĻšāĻžāĻ˛ā§ āĻ•āĻ°ā§āĻ¨āĨ¤ āĻŽā§‹āĻŦāĻžāĻ‡āĻ˛ āĻ•ā§‹āĻŽā§āĻĒāĻžāĻ¨āĻŋāĻ—ā§āĻ˛ā§‹ āĻ†āĻĒāĻ¨āĻžāĻĻā§‡āĻ° inspiration āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡āĨ¤ āĻ¤āĻžāĻ°āĻž āĻŦā§āĻāĻ¤ā§‡ āĻĒā§‡āĻ°ā§‡āĻ›āĻŋāĻ˛, āĻ āĻ¯ā§āĻ—ā§‡āĻ° āĻĒā§āĻ°ā§‡āĻŽāĻŋāĻ•-āĻĒā§āĻ°ā§‡āĻŽāĻŋāĻ•āĻžāĻ°āĻž āĻ•āĻ¤āĻŸāĻž āĻāĻ•āĻœāĻ¨ āĻ†āĻ°ā§‡āĻ•āĻœāĻ¨āĻ•ā§‡ āĻ•ā§‡ā§ŸāĻžāĻ° āĻ•āĻ°ā§‡āĨ¤ āĻ¤āĻžāĻ°āĻž āĻāĻ‡āĻ¸āĻŦ āĻ¯ā§āĻ—āĻ˛āĻĻā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻŦāĻŋāĻļā§‡āĻˇ āĻŦāĻŋāĻļā§‡āĻˇ āĻĒā§āĻ¯āĻžāĻ•ā§‡āĻœ āĻĻā§‡ā§ŸāĻž āĻļā§āĻ°ā§ āĻ•āĻ°āĻ˛āĨ¤ āĻ†āĻĒāĻ¨āĻžāĻ°āĻžāĻ“ āĻāĻ‡ āĻ˛ā§‹āĻ¨ āĻšāĻžāĻ˛ā§ āĻ•āĻ°āĻ˛ā§‡ āĻ†āĻŽāĻŋ āĻ—ā§āĻ¯āĻžāĻ°āĻžāĻ¨ā§āĻŸāĻŋ āĻĻāĻŋā§Ÿā§‡ āĻŦāĻ˛āĻ¤ā§‡ āĻĒāĻžāĻ°āĻŋ, āĻ†āĻĒāĻ¨āĻžāĻĻā§‡āĻ° āĻ˛āĻžāĻ­ā§‡āĻ° āĻ—ā§āĻ°āĻžāĻĢ āĻŠāĻ°ā§āĻ§ā§āĻŦāĻŽā§āĻ–ā§€ āĻšāĻŦā§‡āĨ¤ āĻ¸āĻžāĻŽāĻžāĻ¨ā§āĻ¯ āĻ•’āĻŸāĻž āĻŸāĻžāĻ•āĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻāĻ•āĻŸāĻŋ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ• āĻ­ā§‡āĻ™ā§‡ āĻ¯āĻžāĻŦā§‡? āĻ āĻšāĻ¤ā§‡ āĻĒāĻžāĻ°ā§‡ āĻ¨āĻžāĨ¤ āĻāĻ‡ “āĻ˛āĻžāĻ­ āĻ˛ā§‹āĻ¨” āĻĒāĻžāĻ°ā§‡ āĻāĻ°āĻ•āĻŽ āĻļāĻ¤ āĻļāĻ¤ āĻ˛āĻžāĻ­āĻ•ā§‡ āĻ•ā§āĻˇāĻ¤āĻŋāĻ° āĻšāĻžāĻ¤ āĻĨā§‡āĻ•ā§‡ āĻŦāĻžāĻāĻšāĻŋā§Ÿā§‡ āĻĻāĻŋāĻ¤ā§‡…

āĻ¸āĻ‚āĻŦāĻŋāĻ§āĻŋāĻŦāĻĻā§āĻ§ āĻ¸āĻ¤āĻ°ā§āĻ•ā§€āĻ•āĻ°āĻŖāĻƒ āĻŸāĻžāĻ•āĻž-āĻĒā§ŸāĻ¸āĻž āĻ¯ā§‡āĻ•ā§‹āĻ¨ā§‹ āĻ¸āĻŽā§āĻĒāĻ°ā§āĻ•ā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ•ā§āĻˇāĻ¤āĻŋāĻ•āĻ°āĨ¤ āĻ¯ā§‡ āĻ†āĻĒāĻ¨āĻžāĻ° āĻŸāĻžāĻ•āĻž āĻĻā§‡āĻ–ā§‡ āĻ†āĻ¸āĻŦā§‡, āĻ¸ā§‡ āĻ†āĻĒāĻ¨āĻžāĻ° āĻšā§‡ā§Ÿā§‡ āĻŦā§‡āĻļā§€ āĻŸāĻžāĻ•āĻž āĻĻā§‡āĻ–āĻ˛ā§‡ āĻšāĻ˛ā§‡ āĻ¯āĻžāĻŦā§‡…

āĻ¤āĻ–āĻ¨-āĻāĻ–āĻ¨

āĻ¤āĻ–āĻ¨āĻƒ āĻ›ā§‡āĻ˛ā§‡-āĻŽā§‡ā§Ÿā§‡āĻĻā§‡āĻ° āĻŽāĻ§ā§āĻ¯ā§‡ āĻ­ā§‹āĻ°ā§‡ āĻ“āĻ āĻžāĻ° āĻ…āĻ­ā§āĻ¯āĻžāĻ¸ āĻ›āĻŋāĻ˛āĨ¤
āĻāĻ–āĻ¨āĻƒ āĻ¸āĻ•āĻžāĻ˛āĻ‡ āĻ¤ā§‹ āĻšā§Ÿ ā§§ā§§-ā§§ā§¨āĻŸāĻžā§Ÿ

āĻ¤āĻ–āĻ¨āĻƒ āĻ¸āĻ•āĻžāĻ˛ā§‡ āĻ‰āĻ ā§‡ āĻŦā§œ āĻ­āĻžāĻ‡ā§Ÿā§‡āĻ°āĻž āĻ›ā§‹āĻŸ āĻ­āĻžāĻ‡-āĻŦā§‹āĻ¨āĻĻā§‡āĻ° āĻ‰āĻ āĻžāĻ¤, āĻ‰āĻ āĻžāĻ¨ā§‡ āĻšāĻžāĻāĻ¸-āĻŽā§āĻ°āĻ—ā§€ āĻ›ā§‡ā§œā§‡ āĻĻāĻŋāĻ¤, āĻ—āĻ°ā§āĻ—ā§āĻ˛ā§‹āĻ•ā§‡ āĻŽāĻžāĻ ā§‡ āĻ›ā§‡ā§œā§‡ āĻĻāĻŋā§Ÿā§‡ āĻ†āĻ¸āĻ¤…
āĻāĻ–āĻ¨āĻƒ āĻŦā§œ āĻ­āĻžāĻ‡ā§Ÿā§‡āĻĻā§‡āĻ° āĻ¨āĻŋāĻœā§‡āĻĻā§‡āĻ°āĻ‡ āĻ•ā§‹āĻ¨ā§‹ āĻ āĻŋāĻ•-āĻ āĻŋāĻ•āĻžāĻ¨āĻž āĻ¨āĻžāĻ‡āĨ¤ āĻ­āĻžāĻ‡-āĻŦā§‹āĻ¨, āĻšāĻžāĻāĻ¸-āĻŽā§āĻ°āĻ—ā§€, āĻ—āĻ°-āĻ›āĻžāĻ—āĻ˛ā§‡āĻ° āĻ–āĻŦāĻ° āĻ¨ā§‡ā§ŸāĻžāĻ° āĻ¸āĻŽā§Ÿ āĻ•ā§‹āĻĨāĻžā§Ÿ?

āĻ¤āĻ–āĻ¨āĻƒ āĻ›ā§‡āĻ˛ā§‡āĻĻā§‡āĻ° āĻœāĻ¨ā§āĻ¯ āĻ¸āĻŦāĻšā§‡ā§Ÿā§‡ āĻšā§āĻ¯āĻžāĻ˛ā§‡āĻžā§āĻœāĻŋāĻ‚ āĻ•āĻžāĻœ āĻ›āĻŋāĻ˛ āĻŦāĻžāĻ¸āĻžā§Ÿ āĻ¨āĻž āĻœāĻžāĻ¨āĻŋā§Ÿā§‡ āĻ¸āĻŋāĻ¨ā§‡āĻŽāĻž āĻšāĻ˛ā§‡ ā§ĒāĻ†āĻ¨āĻž āĻĻāĻŋā§Ÿā§‡ āĻŦāĻžāĻ‚āĻ˛āĻž āĻ¸āĻŋāĻ¨ā§‡āĻŽāĻž āĻĻā§‡āĻ–āĻžāĨ¤ āĻŽāĻž-āĻŦāĻžāĻŦāĻžāĻ° āĻ•āĻžāĻ›ā§‡ āĻāĻŸāĻž āĻ›āĻŋāĻ˛ āĻāĻ–āĻ¨āĻ•āĻžāĻ° āĻĒāĻ°ā§āĻŖ āĻĻā§‡āĻ–āĻžāĻ° āĻŽāĻ¤āĻ‡ āĻ—āĻ°ā§āĻšāĻŋāĻ¤ āĻ…āĻĒāĻ°āĻžāĻ§āĨ¤
āĻāĻ–āĻ¨āĻƒ āĻ•ā§āĻ˛āĻžāĻ¸ ā§Ģ-ā§Ŧ āĻ āĻĒā§œāĻž āĻāĻ•āĻŸāĻž āĻŦāĻžāĻšā§āĻšāĻžāĻ° āĻ•āĻžāĻ›ā§‡āĻ“ āĻāĻ–āĻ¨ āĻ•ā§Ÿā§‡āĻ•āĻļ āĻœāĻŋāĻŦāĻŋ āĻĒāĻ°ā§āĻŖā§‡āĻ° āĻ•āĻžāĻ˛ā§‡āĻ•āĻļāĻžāĻ¨ āĻ†āĻ›ā§‡ āĻšā§ŸāĻ¤ā§‹āĨ¤ āĻ†āĻ° āĻ¸āĻžāĻ¨āĻŋ āĻ˛āĻŋā§ŸāĻ¨āĻ•ā§‡ āĻĻā§‡āĻ–āĻž āĻ¤ā§‹ āĻ¸ā§āĻŦāĻžāĻ­āĻžāĻŦāĻŋāĻ• āĻŦā§āĻ¯āĻžāĻĒāĻžāĻ°āĨ¤

āĻ¤āĻ–āĻ¨āĻƒ āĻ›ā§‡āĻ˛ā§‡āĻ°āĻž āĻŦāĻŋāĻ•āĻžāĻ˛ā§‡ āĻŽāĻžāĻ ā§‡ āĻ–ā§‡āĻ˛āĻ¤, āĻŽāĻžāĻ  āĻĨā§‡āĻ•ā§‡ āĻ—āĻ°ā§āĻ—ā§āĻ˛ā§‹āĻ•ā§‡ āĻŦāĻžāĻ¸āĻžā§Ÿ āĻ¨āĻŋā§Ÿā§‡ āĻ†āĻ¸āĻ¤āĨ¤
āĻāĻ–āĻ¨āĻƒ Coaching, Facebook āĻ•āĻŋāĻ‚āĻŦāĻž FIFA āĻŦāĻž FarmVille āĻ•āĻ°āĻ¤ā§‡ āĻ•āĻ°āĻ¤ā§‡āĻ‡ āĻĻāĻŋāĻ¨ āĻ•ā§‡āĻŸā§‡ āĻ¯āĻžā§Ÿ

āĻ¤āĻ–āĻ¨āĻƒ āĻ›ā§‡āĻ˛ā§‡āĻ°āĻž āĻĒā§œāĻžāĻ˛ā§‡āĻ–āĻž āĻ†āĻ° āĻ¸ā§āĻŦāĻžāĻŦāĻ˛āĻŽā§āĻŦā§€ āĻšāĻ“ā§ŸāĻžāĻ° āĻĻāĻŋāĻ•ā§‡ āĻŦā§‡āĻļā§€ āĻŽāĻ¨ā§‹āĻ¯ā§‹āĻ—ā§€ āĻ›āĻŋāĻ˛āĨ¤ āĻĢā§āĻ¯āĻžāĻļāĻ¨ āĻŦāĻž āĻ¸ā§ŒāĻ¨ā§āĻĻāĻ°ā§āĻ¯āĻšāĻ°ā§āĻšāĻž āĻ›āĻŋāĻ˛ āĻļā§āĻ§ā§āĻ‡ āĻŽā§‡ā§Ÿā§‡āĻĻā§‡āĻ° āĻ…āĻ§āĻŋāĻ•āĻžāĻ°ā§‡āĨ¤
āĻāĻ–āĻ¨āĻƒ āĻŽā§‡ā§Ÿā§‡āĻ°āĻž āĻĒā§œāĻžāĻ˛ā§‡āĻ–āĻž āĻ†āĻ° āĻ¸ā§āĻŦāĻžāĻŦāĻ˛āĻŽā§āĻŦā§€ āĻšāĻ“ā§ŸāĻžāĻ° āĻœāĻ¨ā§āĻ¯ āĻŦā§‡āĻļā§€ āĻ†āĻ—ā§āĻ°āĻšā§€āĨ¤ āĻ†āĻ° āĻ›ā§‡āĻ˛ā§‡āĻ°āĻž āĻĢā§āĻ¯āĻžāĻļāĻ¨, āĻŦāĻĄāĻŋ āĻ āĻŋāĻ• āĻ•āĻ°āĻž āĻ†āĻ° āĻŽā§‡ā§Ÿā§‡āĻĻā§‡āĻ° āĻĻā§ƒāĻˇā§āĻŸāĻŋ āĻ†āĻ•āĻ°ā§āĻˇāĻŖā§‡āĻ‡ āĻŦā§‡āĻļā§€ āĻ‰ā§ŽāĻ¸āĻžāĻšā§€āĨ¤

āĻ¤āĻ–āĻ¨āĻƒ āĻ•ā§‹āĻ¨ āĻĄāĻžāĻ•ā§āĻ¤āĻžāĻ° āĻ•āĻŋāĻ‚āĻŦāĻž OT āĻ›āĻžā§œāĻžāĻ‡ āĻ¨āĻ°āĻŽāĻžāĻ˛ āĻĄā§‡āĻ˛āĻŋāĻ­āĻžāĻ°āĻŋ āĻšāĻ¤āĨ¤
āĻāĻ–āĻ¨āĻƒ āĻāĻ–āĻ¨ āĻ¤ā§‹ āĻ¸āĻŋāĻœāĻžāĻ°āĻŋā§ŸāĻžāĻ¨ āĻ›āĻžā§œāĻž āĻŦāĻžāĻšā§āĻšāĻž āĻšā§Ÿ āĻ•āĻŋāĻ¨āĻž āĻ¸āĻ¨ā§āĻĻā§‡āĻšāĨ¤

āĻ¤āĻ–āĻ¨āĻƒ āĻŽāĻŋāĻ¨āĻŋāĻŽāĻžāĻŽ āĻ¸āĻ¨ā§āĻ¤āĻžāĻ¨ āĻ¸āĻ‚āĻ–ā§āĻ¯āĻž āĻ›āĻŋāĻ˛ āĻāĻ•āĻŸāĻž āĻĢā§āĻŸāĻŦāĻ˛ āĻŸāĻŋāĻŽāĨ¤
āĻāĻ–āĻ¨āĻƒ “”āĻĻā§’āĻŸāĻŋ āĻ¸āĻ¨ā§āĻ¤āĻžāĻ¨ā§‡āĻ° āĻŦā§‡āĻļā§€ āĻ¨ā§ŸāĨ¤ āĻāĻ•āĻŸāĻŋ āĻšāĻ˛ā§‡ āĻ­āĻžāĻ˛ āĻšā§ŸāĨ¤””

āĻ¤āĻ–āĻ¨āĻƒ āĻ…āĻ¨ā§‡āĻ• āĻ•ā§āĻ°āĻŋā§Ÿā§‡āĻŸāĻŋāĻ­āĻŋāĻŸāĻŋ āĻĻāĻŋā§Ÿā§‡ āĻĒā§āĻ°ā§‡āĻŽāĻĒāĻ¤ā§āĻ° āĻ˛āĻŋāĻ–ā§‡ āĻ…āĻ¨ā§‡āĻ• āĻŦā§āĻĻā§āĻ§āĻŋ āĻ•āĻ°ā§‡ āĻ¸ā§‡āĻŸāĻŋ āĻĒā§āĻ°ā§‡āĻŽāĻŋāĻ•āĻžāĻ° āĻ¨āĻŋāĻ•āĻŸ āĻĒā§ŒāĻ›āĻžāĻ¤ā§‡ āĻšāĻ¤ā§‹āĨ¤
āĻāĻ–āĻ¨āĻƒ Net āĻ search āĻ•āĻ°āĻ˛ā§‡āĻ‡ āĻ˛āĻžāĻ– āĻ˛āĻžāĻ– creativity āĻĒāĻžāĻ“ā§ŸāĻž āĻ¯āĻžā§ŸāĨ¤ āĻāĻ°āĻĒāĻ° āĻŽā§‹āĻŦāĻžāĻ‡āĻ˛ā§‡āĻ° Message āĻ…āĻĒāĻļāĻ¨ā§‡ āĻ—āĻŋā§Ÿā§‡ āĻ•āĻĒāĻŋ-āĻĒā§‡āĻ¸ā§āĻŸ āĻ•āĻ°ā§‡ send…

“āĻ†āĻ§ā§āĻ¨āĻŋāĻ• āĻŦāĻŋāĻœā§āĻžāĻžāĻ¨ āĻŽāĻžāĻ¨ā§āĻˇāĻ•ā§‡ āĻĻāĻŋā§Ÿā§‡āĻ›ā§‡ āĻŦā§‡āĻ—, āĻ•āĻŋāĻ¨ā§āĻ¤ā§ āĻ•ā§‡ā§œā§‡ āĻ¨āĻŋā§Ÿā§‡āĻ›ā§‡ āĻ†āĻŦā§‡āĻ—āĨ¤ āĻ¤āĻžāĻ¤ā§‡ āĻ†āĻ›ā§‡ āĻ—āĻ¤āĻŋāĻ° āĻ†āĻ¨āĻ¨ā§āĻĻ, āĻ¨ā§‡āĻ‡ āĻ¯āĻ¤āĻŋāĻ° āĻ†ā§Ÿā§‡āĻ¸āĨ¤â€ ― āĻ¯āĻžāĻ¯āĻžāĻŦāĻ°, āĻĻā§ƒāĻˇā§āĻŸāĻŋāĻĒāĻžāĻ¤

Make AJAX requests in CakePHP without disabling SecurityComponent

Security is always a big deal for a software specially for web app where you don’t know your users’ intention. To ensure some common security measure, CakePHP provides SecurityComponent with its core.

Let’s come to the point. If you try to POST any request through AJAX, you will get Bad Request exception and your request will be Black Holed.

So, how do you prevent this without disabling the SecurityComponent for the action(many online resources do this. But this is not what we want, right?)? Well, you need to do 2 things to do in your beforeFilter to achieve that.

$this->action == 'add') {
    $this->Security->csrfUseOnce = false; // We will use CSRF token for more than one time
    $this->Security->validatePost = false; // Disabling form POST validation
}

Why these two:

  1. Since we may do the request several time from different parts of a single page, we will use same CSRF token. Though there is a complex way to update CSRF token of the page after the ajax request processed, but lets stick with the easier way.
  2. Also, SecurityComponent require you create your form using FormHelper shipped with CakePHP core. I’m assuming the form is not built with the FormHelper. You can ignore this if you generate your form using FormHelper.

If you do not using FormHelper to ensure CSRF protection you will need to post CSRF token with your post data in specific format. Here is how the CSRF token should be in post data.

array( 
'_Token' => array(
    'key'=> $this->Session->read('_Token.key');
    ),
'ModelName' => array(
    // modeldata
    )
)

PHP Image Manipulation

GD library (http://php.net/manual/en/book.image.php) is a good PHP library for manipulating images. I was familiar with it but never used in production before. I’m working on a personal project now which required some image manipulation for profile image (avatar). So, I used GD library and it’s really easy to use.

If you are using latest version of XAMPP, GD library is already included and activated. You don’t need to set up anything. Just start coding. Though php.net has the manual how to install GD library. If you are interested, you can see that. The manual contains almost everything you need to complete your task. You can resize, create, copy, crop and many more manipulation. I enjoyed using this. I hope it will help you too.

If you want you can use imagick (aka: ImageMagick). This extesnion has some advanced options. But many online server does not support imagick. But this extension is awesome too and will full-fill almsot everything you need to tweak you images.

2012

This year was tremendous for me. It was a successful year for me. I have also broken down some of my barrier. I’m sharing here some of these here. But at first I want to thank God for giving me such a wonderful year.

Varsity life:

I started my university life on 15th January. I’ve passed a wonderful year there maintaining a good CGPA. Got some new friends there. Yesterday I got my 3rd semester result and it is 4 out of four. So, I’m finishing the year with CGPA 3.87.

Professional life:

Officially I started my professional life in this year on March. My first project was a php project for an e-commerce website. I was hired through oDesk. It was a great experience. Followed by I was hired by an US company as an executive assistant and Drupal developer. Besides this I’m working as an Web developer in a local company. I’ve completed a government project with them. Then I started working with an Italian company as a cakephp developer. I’m still working with them. In the meantime I got some good job offer. But unfortunately I decided not to accept those offers to continue my personal learning.

Foundation life:

Many of you may know that I am a member of Quantum Foundation. Personally I’m not happy with my involvement this year. I should have given a bit more time there. But I’m happy to continue my regular meditation. This year I didn’t miss meditation for a day. Also I’m happy to continue my regular prayer. I got certification in Public Speaking this year from Quantum Foundation.

Misc. Facts of this Year:

  • I bought HP pavilion dv7 Notebook which cost 85,000 Tk. 60% of the money paid by myself and rest of the money from my family.
  • Bought Sony Xperia Ray with my own earning.
  • A year without playing computer game !!!! 😮 How I did this. OMG. I’ve just noticed it.
  • Launched my website officially with domain name http://tahsinrahit.com
  • Learned and learning : Android Developing, CakePHP, advanced C++, advanced PHP, advanced JAVA
  • Created a 2D cricket game using C++ all alone. It was a great experience. Enjoyed working on this.
  • And guys guess what… I started blogging this year. 😉

These are the things that come to my mind now about 2012. Wishing a very happy new year to all of you. See you next year. Good bye 2012…