Sunday, December 4, 2016

Thrills of entering into the fascinating world of AI.

As you know I started my career(exploration) as Web Developer. When mobile came to market, then I jumped to mobile app development. Started with Android and couldn’t stop me to explore iOS too. I published few educational apps,financial app,health app in android & some image processing/facial recognition app in iOS. Once while reading a blog I encountered this term “Mobile app with Intelligence”. It left me to think. Aren’t all the apps intelligent? Am I creating dumb apps? How to make then intelligent apps? I just researched in internet. This way I met IBM Watson. To know more about Watson and learn from experts I attended the IBM Watson Developer Conference in San Francisco which took place recently in last November.

I came to know lots of things about Watson. But again just to know isn’t sufficient. I want to try hands on and wish to create my own intelligent apps. My exploration was on and while researching how to create by myself, I stumbled on this course by Udacity Nano degree program  udacity.com/ai. The course tag line is “Learn to build impossible”. I guarantee if someone is a developer at heart can’t resist this word. So I couldn’t. I signed up for the course. I signed very late,almost it reached 9000 number at that time. Still I signed, I was waiting for the selection which was scheduled to be declared on Dec 2. I got my acceptance offer on Nov 30. There are only 500 seats in the first batch while applicants were 10,000.It was very competitive. I feel thrills to enter the fascinating world of AI.



The leader in cognitive technology IBM Watson, Amazon Alexa & DIDI chuxing has designed the course. They will train the future Artificial Intelligent Engineer. 

I don’t know driving yet. I wish to train my car and make it AI enabled and use it. Now I can talk with car using IBM Watson conversion as here .Like for example if I say turn on light, wipe the screen, where is nearby restaurant?  it can do this things for me. Need to know more from Sebastian Thrun who is my current instructor too for AI and pioneer of the Self-Driving Car space.

As IBM CEO Ginni Rometty said in keynote she envision the future world to be man & machine. I envision that too. Everything from education,health, finance,telecom will take advantage of AI. Nothing can be escaped from it.It really interesting to be in this field and to create cool intelligent app, talk to robot, train robot.


Tuesday, November 15, 2016

My experience in attending IBM Watson Developer Conference in San Francisco


I attended the Watson developer conference which took place in San Francisco on Nov 9th & 10 to know more about cognitive technology. Yes I enjoyed the event and came to know about artificial intelligence. 

IBM CEO Ginni Rometty’s keynote "The world we envision is man AND machine." was inspiring & empowering one. I noticed one more thing in her speech, she desperately need developers who will give shape to her vision.

They had parallel track of talks. I wish I could attend both. 

These are following I attend.

Turning Visual Recognition Into Video Recognition

IBM Watson AI XPRIZE for Innovators

Why Audience Intelligence Requires a Modular AI Approach

Intelligent User Engagement with Chat Bots

The Future of Discovery – Deep Insights with Cognitive APIs


I met Olli which is the first vehicle to use cloud-based cognitive computing from IBM Watson Internet of Things to analyze and learn from 30 sensors embedded in the vehicle. Four Watson developer APIs were used that allow Olli to interact with passengers: speech to text, natural language classifier, entity extraction and text to speech. Not only it looks interesting. Riding on it & to train olli might be more interesting than this.


Thursday, May 19, 2016

My experience in attending the Apache Big Data & ApacheCon conference 2016 held in Vancouver,BC



I am a contributor and associated with Apache Fineract(incubating) project.
Apache Fineract (\’fīn-,ә-,rakt\) is an open source system for core banking as a platform. Fineract provides a reliable, robust, and affordable solution for entrepreneurs, financial institutions, and service providers to offer financial services to the world’s 2 billion underbanked and unbanked.

Last week I attended two biggest conference of North America. One is ApacheBigdata & another one is ApacheCon. Luckily both the conference were in my home city Vancouver. I got the chance to attend both. Around 3000 attendees from around the world attended the conference and it was held in Hyatt Regency Vancouver. It gathered together the Apache projects, people and technologies working in Big Data, ubiquitous computing and data engineering and science.

Before this event I did not have much knowledge about the Apache’s other cool projects. I came to know about Apache Hadoop, Twill,Spark,Kafka,Zeppelin.Bigtop,Cassandra. As a computer science professional I was always wanted to know(curious) how the big applications like LinkedIn, Netflix ,Intuit and other like so manage so many number of users. Engineers from these companies explained about their infrastructure and how the open source softwares like Hadoop,Spark ,Kafka, Twill and others are the backbones and it does the heavy lifting. They act like plumbing and enables smooth running of biggest applications.

Apache Zeppelin caught my attention. Like Google Document revolutionized the way we create document collaboratively, Apache Zeppelin is the online data visualization tool.One can make beautiful data-driven, interactive and collaborative documents with Spark SQL,Python, Scala, Hive, Flink, Kylin and more. Zeppelin enables rapid development of Spark and Hadoop workflows with simple, easy visualizations. On writing the simple SQL it generates graph on the fly.It includes the interpreter for different language.
One interesting topic was "How to become Well Rested App Developer Rockstar" by Glynn Bird Developer Advocate @ IBM. I can rest & rock too. How ?

He spoke how to secure data layer and one can be in peace of mind while the database is safe and not vulnerable. This can be achieved with a managed database service that:

  • Gives users increased visibility and control of technology environments
  • Enables users to spend less time obsessing over their database
  • Provides simpler integration between technologies
Topics were quite interesting and it left me in a state to know more about this. Not only to know but to use and work on these popular open source cool products.

Tuesday, March 15, 2016

My contribution to Mifos Android Client

Mifos(mifos.org) is  the open source financial software and it's mission is to provide banking solution to poor. It has complete range of financial services needed for an effective financial inclusion solution.
 Core engine which is java based have all the banking functionalities such as 
  • creating loan product,saving product, Multiple Lending Methodologies such as Individual lending
  • Grameen Joint Liability group lending
  • Multi-tranche loans
  • Standing instructions for automated payments
  • co-op lending
Full Range of Deposit Products
  • Passbook savings
  • Fixed (term) deposits
  • Recurring deposits
  • Current accounts
Client facing android & web softwares have developed to interact with the core engine.
I have worked on both android & web application during my internship period.
My task was to add Surveys and Social Performance Management Scorecards in Mifos X Android Client. This Survey will be used to determine the financial condition of a person/family, based on the score in Survey it will determined whether they need financial help.

Backend server exposes the survey API. I have access the API endpoints to get active surveys from Server. Parsed the json to get survey questions & options. Capture the user response and post it back to server as scorecard.

Android recent material design used in the application. As Material design introduced in Android 5.0, to make it compatible with previous version app compat lib used in the app along with android design library.

What problem it solves?

This mobile survey tool will enable businesses to better understand the needs and interests of low-income consumers, while providing additional revenue for some of the world's poorest people.

What are the technical  challenges faced? 

  •  Some of the Survey question have two selection option and some have eight options. So it was challenging for me to generate radiobutton dynamically.
  • To transfer ArrayList of values from android fragment to activity. 
  • To update the Scorecard( user response) while user decide to change the response. 


So I fetched active surveys from Server and displayed in android listview.
When you select a particular survey it will take you to the question & options of that particular survey.
As few question have 2 options & few has 7 options, so it was challenging for me to display radiobutton dynamically based on the no of options. I have used viewpager widget to scroll to go to next question. 
I need to store QuestionId, ResponseId & ResponseValue of each question  and submit the scorecard value to Server.

Android provides a lot of options for storing data but the preference related settings can be easily stored and maintained using SharedPreferences class.
In this case I have used Android SharedPreferences to store and retrieve user selected responses . Create a separate SharedPreference utility class with methods to save, add, remove and get Scorecards from SharedPreferences.
Android SharedPreferences class does not provide a way to store a List or ArrayList or any collection. In order to store a list (even array, set or any collection) under a key, we convert the list (or collection) to JSON format using Gson and store it as string. While retrieving we convert the JSON string back to list and return it.
Layout Files.
fragment_survey_question.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="20dp"
android:background="@color/primary"
android:orientation="vertical" >
<TextView
android:id="@+id/survey_question_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:textSize="25sp"
android:textColor="@android:color/white"
android:text="Question"/>
<TextView
android:id="@+id/survey_question_no"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="right"
android:textSize="15sp"
android:textColor="@android:color/white"
/>
</LinearLayout>
<RadioGroup
android:id="@+id/radio1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dip"
android:layout_marginTop="5dip"
android:background="#fff"
>
</RadioGroup>
<View android:layout_width="wrap_content"
android:layout_height="0dp"
android:layout_weight="1" ></View>
</LinearLayout>
row_survey_list_item.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent" android:layout_height="match_parent"
android:background="@drawable/card_blueborder"
android:padding="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="survey_name"
android:id="@+id/tv_survey_name"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Description"
android:id="@+id/tv_description"
android:layout_below="@+id/tv_survey_name"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>

Scorecard.xml
In src folder, create a new class Scorecard in the package . 

package com.mifos.objects.survey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* Created by Nasim Banu on 28,January,2016.
*/
public class Scorecard {
private Long userId;
private Long clientId;
private Date createdOn;
private List<ScorecardValues> scorecardValues;
// private Integer value;
public Scorecard() {
super();
}
public Scorecard( final Long userId, final Long clientId,
final Date createdOn, final List<ScorecardValues> scorecardValues) {
super();
this.userId = userId;
this.clientId = clientId;
this.createdOn = createdOn;
this.scorecardValues= scorecardValues;
}
public Long getUserId() {
return userId;
}
public void setUserId(Long userId) {
this.userId = userId;
}
public Long getClientId() {
return clientId;
}
public void setClientId(Long clientId) {
this.clientId = clientId;
}
public Date getCreatedOn() {
return createdOn;
}
public void setCreatedOn(Date createdOn) {
this.createdOn = createdOn;
}
public List<ScorecardValues> getScorecardValues() {
return scorecardValues;
}
public void setScorecardValues(List<ScorecardValues> scorecardValues ) {
this.scorecardValues = scorecardValues;
}
}
view raw Scorecard.java hosted with ❤ by GitHub
SharedPreference class
Create a new class SharedPreference in the package . This class defines methods to save, add, remove and get Scorecards from SharedPreferences.Here we use Gson to convert List to JSON string in saveScorecards method and back again to List in getScorecards method.
package com.mifos.utils;
import android.content.Context;
import android.content.SharedPreferences;
import com.google.gson.Gson;
import com.mifos.objects.survey.ScorecardValues;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by Nasim Banu on 28,January,2016.
*/
public class MyPreference {
public static final String PREFS_NAME = "MY_PREFS";
public static final String SCOREVALUES = "Score_Values";
public static final String question_id = "question_id";
public static final String response_id = "response_id";
public static final String response_value = "response_value";
public MyPreference (){
super();
}
// This four methods are used for maintaining favorites.
public void saveScorecards(Context context, List<ScorecardValues> scorecardValues) {
SharedPreferences settings;
SharedPreferences.Editor editor;
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
editor = settings.edit();
//mcontext=context;
Gson gson = new Gson();
String jsonScores = gson.toJson(scorecardValues);
editor.putString(SCOREVALUES, jsonScores);
editor.commit();
}
public void addScorecard(Context context, ScorecardValues product) {
List<ScorecardValues> scorecardValues = getScorecards(context);
//mcontext=context;
if (scorecardValues == null)
scorecardValues = new ArrayList<ScorecardValues>();
scorecardValues.add(product);
saveScorecards(context, scorecardValues);
}
public boolean checkScoreQid(Context context,ScorecardValues checkProduct) {
boolean check = false;
List<ScorecardValues> scorecardValues = getScorecards(context);
if (scorecardValues != null) {
for (ScorecardValues product : scorecardValues) {
if (product.getQuestionId() == checkProduct.getQuestionId()) {
product.setResponseId(checkProduct.getResponseId()) ;
product.setValue(checkProduct.getValue());
// removeFavorite(context,product);
check = true;
break;
}
}
saveScorecards(context, scorecardValues);
}
return check;
}
public void resetScorecard(Context context) {
SharedPreferences settings;
SharedPreferences.Editor editor;
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
editor = settings.edit();
editor.clear();
editor.commit();
}
public ArrayList<ScorecardValues> getScorecards(Context context) {
SharedPreferences settings;
List<ScorecardValues> scorecardValues;
// mcontext=context;
settings = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE);
if (settings.contains(SCOREVALUES)) {
String jsonScores = settings.getString(SCOREVALUES, null);
Gson gson = new Gson();
ScorecardValues[] scoreItems = gson.fromJson(jsonScores,
ScorecardValues[].class);
scorecardValues = Arrays.asList(scoreItems);
scorecardValues = new ArrayList<ScorecardValues>(scorecardValues);
} else
return null;
return (ArrayList<ScorecardValues>) scorecardValues;
}
}
This file defines custom layout for ListView item which is used by SurveyListAdapter.
In src folder, create a new class SurveyListAdapter in the package . This is the custom list adapter class which displays survey name, description.
SurveyListAdapter
package com.mifos.mifosxdroid.adapters;
import android.content.Context;
import android.content.res.Resources;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import com.mifos.mifosxdroid.R;
import com.mifos.objects.survey.Survey;
import java.util.List;
import butterknife.ButterKnife;
import butterknife.InjectView;
import android.widget.BaseAdapter;
/**
* Created by Nasim Banu on 27,January,2016.
*/
public class SurveyListAdapter extends BaseAdapter{
private LayoutInflater layoutInflater;
private List<Survey> listSurvey;
private Resources resources;
public SurveyListAdapter(Context context, List<Survey> listSurvey){
layoutInflater = LayoutInflater.from(context);
this.listSurvey = listSurvey;
resources = context.getResources();
}
@Override
public int getCount() {
return this.listSurvey.size();
}
@Override
public Survey getItem(int i) {
return this.listSurvey.get(i);
}
@Override
public long getItemId(int i) {
return 0;
}
@Override
public View getView(int i, View view, ViewGroup viewGroup) {
ViewHolder viewHolder;
if(view==null){
view = layoutInflater.inflate(R.layout.row_surveys_list_item,viewGroup,false);
viewHolder = new ViewHolder(view);
view.setTag(viewHolder);
}else{
viewHolder = (ViewHolder) view.getTag();
}
final Survey survey = listSurvey.get(i);
viewHolder.tv_survey_name.setText(survey.getName());
viewHolder.tv_description.setText(survey.getDescription());
return view;
}
public static class ViewHolder{
@InjectView(R.id.tv_survey_name)
TextView tv_survey_name;
@InjectView(R.id.tv_description)
TextView tv_description;
public ViewHolder(View view) {
ButterKnife.inject(this, view);
}
}
}

SurveyQuestionFragment
In src folder, create a new class SurveyQuestionFragment in the package 
  • This class displays list of questions and options.
  • On radio button selection changed it adds that response in Scorecards by saving it in SharedPreferences. 
package com.mifos.mifosxdroid.online;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.Fragment;
import com.mifos.objects.survey.Survey;
import com.mifos.objects.survey.ScorecardValues;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.RadioButton;
import android.widget.RadioGroup;
import android.widget.TextView;
import android.widget.Toast;
import java.util.HashSet;
import java.util.List;
import com.mifos.mifosxdroid.R;
import com.mifos.App;
import com.mifos.utils.MyPreference;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
/**
* Created by Nasim Banu on 28,January,2016.
*/
public class SurveyQuestionFragment extends Fragment {
public interface OnAnswerSelectedListener {
public void answer(int id, int qid,int rid,int rvalue,int chk);
}
// static Strings to retrieve the question and its answers and show them.
public static final String QUESTION = "question";
public static final String PREFS_NAME = "MY_PREFS";
public static final String SCOREVALUES = "Score_Values";
public static final String ANSWERS = "answers";
public static final String ID = "id";
public static final String SID = "sid";
public static final String QSIZE = "qsize";
//public static final int chk = 1;
SharedPreferences sharedPreferences;
private OnAnswerSelectedListener mCallback;
List<ScorecardValues> scorecardValues ;
ScorecardValues scorevalue;
private TextView tvQuestion;
private TextView tvQuestionNo;
private RadioGroup radioGroup1;
RadioButton button1;
RadioButton btn;
private Button btnNext;
Context thiscontext;
private Activity activity;
private String text1;
private boolean selected;
private int Id;
private int surveyId;
private String[] answerarray;
private int qId;
private int qSize;
private int qNo;
private int rId;
private int rValue;
MyPreference myPreference;
public static final SurveyQuestionFragment newInstance(int id, String question,int sid, String[] answers,int qsize) {
SurveyQuestionFragment fragment = new SurveyQuestionFragment();
Bundle bundle = new Bundle();
bundle.putInt(ID, id);
bundle.putInt(SID, sid);
bundle.putInt(QSIZE, qsize);
bundle.putString(QUESTION, question);
bundle.putStringArray(ANSWERS, answers);
fragment.setArguments(bundle);
return fragment;
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
activity = getActivity();
myPreference = new MyPreference();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_survey_question, container, false);
tvQuestion = (TextView) view.findViewById(R.id.survey_question_textView);
tvQuestionNo = (TextView) view.findViewById(R.id.survey_question_no);
thiscontext = container.getContext();
radioGroup1 = (RadioGroup) view.findViewById(R.id.radio1);
Id = getArguments().getInt(ID);
qNo = Id+1;
surveyId = getArguments().getInt(SID);
qSize = getArguments().getInt(QSIZE);
answerarray =getArguments().getStringArray(ANSWERS);
setQuestion(getArguments().getString(QUESTION));
// setAnswers(getArguments().getStringArray(ANSWERS));
ViewGroup hourButtonLayout = (ViewGroup) view.findViewById(R.id.radio1);
for (int i = 0; i < answerarray.length; i++) {
button1 = new RadioButton(thiscontext);
button1.setId(i);
button1.setText(answerarray[i]);
hourButtonLayout.addView(button1);
radioGroup1.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
public void onCheckedChanged(RadioGroup mRadioGroup2,
int checkedId2) {
for (int i = 0; i < mRadioGroup2.getChildCount(); i++) {
btn = (RadioButton) mRadioGroup2.getChildAt(i);
int t = mRadioGroup2.getId();
System.out.println(t);
if (btn.getId() == checkedId2) {
text1 = btn.getText().toString();
App.apiManager.getSurvey(surveyId, new Callback<Survey>() {
@Override
public void success(final Survey survey, Response response) {
if (survey != null) {
String qa = tvQuestion.getText().toString();
int ival = 0;
int k = 0;
if (survey.getQuestionDatas() != null && survey.getQuestionDatas().size() > 0) {
for (int i = 0; i < survey.getQuestionDatas().size(); i++) {
if (survey.getQuestionDatas().get(i).getText().equals(qa)) {
qId = survey.getQuestionDatas().get(i).getQuestionId();
ival = i;
qSize = survey.getQuestionDatas().size();
}
}
for (int j = 0; j < survey.getQuestionDatas().get(ival).getResponseDatas().size(); j++) {
if (survey.getQuestionDatas().get(ival).getResponseDatas().get(j).getText().equals(text1)) {
rId = survey.getQuestionDatas().get(ival).getResponseDatas().get(j).getResponseId();
rValue = survey.getQuestionDatas().get(ival).getResponseDatas().get(j).getValue();
}
}
int chk = 1;
mCallback.answer(Id, qId, rId, rValue, chk);
}
}
}
@Override
public void failure(RetrofitError retrofitError) {
Toast.makeText(getActivity(), "survey not found", Toast.LENGTH_SHORT).show();
}
});
return;
}
}
}
});
}
tvQuestionNo.setText("question " + qNo + " of " +qSize);
return view;
}
@Override
public void onAttach(Activity activity) {
super.onAttach(activity);
// Activity = activity;
try {
mCallback = (OnAnswerSelectedListener) activity;
} catch (ClassCastException e) {
throw new ClassCastException(activity.toString()
+ " must implement OnAnswerSelectedListener");
}
}
public void setQuestion(String question){
tvQuestion.setText(question);
}
@Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
}
@Override
public void onPause() {
super.onPause();
}
SurveyQuestion Activity
package com.mifos.mifosxdroid.online;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.support.v7.app.ActionBarActivity;
import com.mifos.mifosxdroid.adapters.SurveyPagerAdapter;
import com.mifos.objects.survey.Scorecard;
import com.mifos.objects.survey.ScorecardValues;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.mifos.App;
import com.mifos.mifosxdroid.R;
import com.mifos.objects.survey.Survey;
import com.mifos.api.model.ScorecardPayload;
import com.mifos.utils.MyPreference;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Vector;
import retrofit.Callback;
import retrofit.RetrofitError;
import retrofit.client.Response;
import com.mifos.mifosxdroid.core.MifosBaseActivity;
import android.support.v7.app.AppCompatActivity;
/**
* Created by Nasim Banu on 28,January,2016.
*/
public class SurveyQuestion extends MifosBaseActivity implements SurveyQuestionFragment.OnAnswerSelectedListener {
private static final int CONTENT_VIEW_ID = 10101010;
public Communicator fragmentCommunicator;
private ViewPager pager = null;
public static final String PREFS_NAME = "MY_PREFS";
private Button btnNext;
private Button btnSubmit;
private Button btnPrevious;
AppCompatActivity activity;
private PagerAdapter mPagerAdapter = null;
public static final String ID = "id";
public static int surveyId;
public static int qid;
public static int pchk;
public static int pfqid;
public static int pfrid;
public static int pfrvalue;
public static boolean pfselect;
private List<Fragment> fragments = null;
SharedPreferences sharedPreferences;
private String qs;
ViewPager.OnPageChangeListener mPageChangeListener;
MyPreference myPreference;
Context context;
List<ScorecardValues> scorecardValues;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
super.setContentView(R.layout.activity_survey_question);
context = SurveyQuestion.this;
myPreference = new MyPreference();
myPreference.resetScorecard(this);
btnNext = (Button) findViewById(R.id.btnNext);
btnSubmit = (Button) findViewById(R.id.btnSubmit);
btnPrevious = (Button) findViewById(R.id.btnPrevious);
fragments = new Vector<Fragment>();
showBackButton();
Intent mIntent = getIntent();
surveyId = mIntent.getIntExtra("SurveyId", 0);
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor edt = sharedPreferences.edit();
edt.putInt("SURVEY_ID", surveyId);
edt.commit();
App.apiManager.getSurvey(surveyId, new Callback<Survey>() {
@Override
public void success(final Survey survey, Response response) {
if (survey != null) {
String answer[] = new String[10];
ArrayList<String> answerList = new ArrayList<String>();
if (survey.getQuestionDatas() != null && survey.getQuestionDatas().size() > 0) {
for (int i = 0; i < survey.getQuestionDatas().size(); i++) {
qs = survey.getQuestionDatas().get(i).getText();
qid = survey.getQuestionDatas().get(i).getQuestionId();
if (survey.getQuestionDatas().get(i).getResponseDatas().size() > 0) {
for (int j = 0; j < survey.getQuestionDatas().get(i).getResponseDatas().size(); j++) {
answer[j] = survey.getQuestionDatas().get(i).getResponseDatas().get(j).getText();
answerList.add(answer[j]);
}
}
int qSize = survey.getQuestionDatas().size();
String[] answerArr = new String[answerList.size()];
answerArr = answerList.toArray(answerArr);
fragments.add(SurveyQuestionFragment.newInstance(i, qs, surveyId, answerArr, qSize));
answerList.clear();
}
fragments.add(SurveyLastFragment.newInstance(1, "You have reached the end of Survey"));
mPagerAdapter.notifyDataSetChanged();
}
}
}
@Override
public void failure(RetrofitError retrofitError) {
Toast.makeText(SurveyQuestion.this, "Survey not found.", Toast.LENGTH_SHORT).show();
}
});
this.mPagerAdapter = new SurveyPagerAdapter(super.getSupportFragmentManager(), fragments);
pager = (ViewPager) super.findViewById(R.id.surveyPager);
pager.setAdapter(this.mPagerAdapter);
pager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() {
@Override
public void onPageSelected(int position) {
ScorecardValues scorevalue = new ScorecardValues();
scorevalue.setQuestionId(pfqid);
scorevalue.setResponseId(pfrid);
scorevalue.setValue(pfrvalue);
if (myPreference.checkScoreQid(context, scorevalue)) {
Log.i("previous removed: ", String.valueOf(pfrid));
} else {
myPreference.addScorecard(context, scorevalue);
}
if (pager.getCurrentItem() == mPagerAdapter.getCount() - 1) {
btnNext.setVisibility(View.GONE);
btnSubmit.setVisibility(View.VISIBLE);
} else {
btnNext.setVisibility(View.VISIBLE);
btnSubmit.setVisibility(View.GONE);
}
if (pager.getCurrentItem() == 0) {
btnPrevious.setVisibility(View.GONE);
} else {
btnPrevious.setVisibility(View.VISIBLE);
}
}
@Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
}
@Override
public void onPageScrollStateChanged(int state) {
}
});
Button btnNext = (Button) findViewById(R.id.btnNext);
btnNext.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
ScorecardValues scorevalue = new ScorecardValues();
scorevalue.setQuestionId(pfqid);
scorevalue.setResponseId(pfrid);
scorevalue.setValue(pfrvalue);
if (myPreference.checkScoreQid(context, scorevalue)) {
Log.i("previous removed: ", String.valueOf(pfrid));
} else {
myPreference.addScorecard(context, scorevalue);
}
int current = pager.getCurrentItem();
final Toast toast = Toast.makeText(context, "You have not selected any option.", Toast.LENGTH_SHORT);
if (pchk == 1 & current < fragments.size()) {
pager.setCurrentItem(current + 1, true);
toast.cancel();
}
{
toast.show();
pchk = 0;
}
}
});
Button btnPrevious = (Button) findViewById(R.id.btnPrevious);
btnPrevious.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
int current = pager.getCurrentItem();
if (current < fragments.size())
pager.setCurrentItem(current - 1, true);
}
});
Button btnSubmit = (Button) findViewById(R.id.btnSubmit);
btnSubmit.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
scorecardValues = myPreference.getScorecards(context);
int listSize = scorecardValues.size();
for (int i = 0; i < listSize; i++) {
Log.i("Response Value: ", scorecardValues.get(i).getValue().toString());
Log.i("Question Id: ", scorecardValues.get(i).getQuestionId().toString());
Log.i("Response Id: ", scorecardValues.get(i).getResponseId().toString());
}
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
int clientId = sharedPreferences.getInt("CLIENT_ID", 0);
int userId = sharedPreferences.getInt("USER_ID", 0);
int surveyId = sharedPreferences.getInt("SURVEY_ID", 0);
Date date = new Date();
ScorecardPayload scorecardPayload = new ScorecardPayload();
scorecardPayload.setUserId(userId);
scorecardPayload.setClientId(clientId);
scorecardPayload.setCreatedOn(date);
scorecardPayload.setScorecardValues(scorecardValues);
App.apiManager.submitScore(surveyId, scorecardPayload, new Callback<Scorecard>() {
@Override
public void success(Scorecard scorecard, Response response) {
Toast.makeText(context, "Scorecard created successfully", Toast.LENGTH_LONG).show();
}
@Override
public void failure(RetrofitError error) {
Toast.makeText(context, "Try again", Toast.LENGTH_LONG).show();
}
});
}
});
}
@Override
public void answer(int id, int fqid, int frid, int frValue, int chk) {
pfqid = fqid;
pfrid = frid;
pfrvalue = frValue;
pchk = chk;
}
}

This is the main activity class.
  • When the app starts, it begins a new FragmentTransaction and starts SurveyQuestionFragment.
  • SurveyQuestionFragment is placed in Viewpager widget. When you scroll the widget it loads the next question in the series dynamically.
  • When you go back and update selection,it updates Scorecard and saves in SharedPreference.
Output Screens

Tuesday, December 8, 2015

Kick Off Outreachy




I have always worked as an independent web developer, mobile app developer. I was developing android educational apps in my own time as I wish. That to say I was one woman army. I discovered when there is no deadline and no pressure, my work is getting delayed endlessly.

Seeing the popularity of open source culture, I got interested to work for open source organization. There are so many organization who are working towards social cause like eradicate poverty, improve poor’s life.
One of such organization is Mifos Initiative. So I applied to work for them through Outreachy program.

Outreachy is the successor of the Outreach Program for Women (OPW), which connects talented and passionate developers with people working in free and open source software
Luckily I got accepted into program. Purpose of Mifos Initiative is to empower poor women and to give them financial freedom. You can get more detail from their website.

I had the knowledge of  Android Cloud Computing, Rest API, Java Spring framework. They are using the same software stack. I love mathematics too. As Mifos(Microfinance) is a Financial software, so I got interested to work for them.

I made few contribution before I applied. My contribution is at

My mentors are very cooperative and friendly.

I will be working to add few features to their Android Client and to improve the AngularJS based Community app. I will update the blog as the work progress.