Thursday, May 24, 2012

LINQPad

string[] names = {"Michael", "Long"};

IEnumerable<string> query = names
.Where(n=>n.Contains("o"))
.OrderBy(n=>n.Length)
.Select(n=>n.ToUpper());

query.Dump();

// same query as above
IEnumerable<string>filtered = names.Where(n=>n.Contains("o"));
IEnumerable<string>sorted = filtered.OrderBy(n=>n.Length);
IEnumerable<string>finalQuery = sorted.Select(n=>n.ToUpper());

filtered.Dump("Filtered");
sorted.Dump("Sorted");
finalQuery.Dump("FinalQuery");

LINQ Dynamic Query

using System.Linq.Dynamic

var repository = new EmployeeRepository();

var query = repository.GetAll()
.AsQueryable()
.OrderBy("Name")
.Where("DepartmentID = 1");

LINQ Joins


var employeeRepository = new EmployeeRepository();
var departmentRepository = new DepartmentRepository();

Inner Join (Normal)

var employees =
from employee in employeeRepository.GetAll()
join department in departmentRepository.GetAll()
on employee.DepartmentID equals department.ID
select new {employee.Name, Department = department.Name};

Left Join (Grouping on Departments)

var query =
from d in departmentRepository.GetAll()
join e in employeesRepository.GetAll()
on d.ID equals e.DepartmentID
into ed
select new
{
Department = d.Name,
Employees = ed};

foreach(var group in query)
{
Console.WriteLine(group.Department);
foreach(var employee in group.Employees)
{
Console.WriteLine("\t" + employee.Name);
}
}

Cross Join (for completeness)


var employees =
from employee in employeeRepository.GetAll()
join department in departmentRepository.GetAll()
on employee.DepartmentID equals department.ID
select new {employee.Name, Department = department.Name};

LINQ Grouping and Projecting

var repository = new EmployeeRepository();

Comprehensive Query Syntax

var queryByDepartment =
from e in repository.GetAll()
group e by e.DepartmentID
into eGroup
orderby eGroup.Key descending
where eGroup.Key < 3
select new
{
DepartmentID = eGroup.Key,
Count = eGroup.Count(),
Employees = eGroup
};

Extension Methods with Lambda Expressions

var queryByDepartment2 =
repository.GetAll()
.GroupBy(e=>e.DepartmentID)
.OrderByDescending(g=>g.Key)
.Where(g=>g.Key < 3)
.Select(g=>
new
{
DepartmentID = g.Key,
Count = g.Count(),
Employees = g
});

foreach(var group in queryByDepartment2)
{
Console.WriteLine("DID: {0}, Count: {1}",
group.DepartmentID,
group.Count);

foreach(var employee in group.Employees)
{
Console.WriteLine("\t{0}:{1}", employee.DepartmentID, employee.Name);
}
}

Restrictions for Implicit Typing

The following var statements result in compiler errors:

var i;

var j, k = 0;

var n = null;

var number = "2";
int x = number + 1;

Extension Methods with Lambda Expressions vs. Comprehensive Query Syntax

Employee[] employees = new Employee[]
{
new Employee{ID=1, Name="The"},
new Employee{ID=2, Name="Foo"}
};

//Employee the = Array.Find(employees, FindThePredicate);
Employee the = Array.Find(employees, e=>e.Name == "The");

Comprehensive Query Syntax

Collection

IEnumerable<Employee> query1 =
from e in employees
where e.Name == "The"
orderby e.ID ascending
select e;

Single Item

Employee query1 =
(from e in employees
where e.Name == "The"
orderby e.ID ascending
select e).First();

Extension Methods with Lambda Expressions

Collection

IEnumerable<Employee> query2 =
employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e);

Single Item

Employee query2 =
employees.Where(e=>e.Name=="The")
.OrderBy(e=>e.ID)
.Select(e=>e)
.First();

Action and Func Delegates and Lambda Expressions

private static void ActionAndFunc()
{
Action printEmptyLine = () => Console.WriteLine();
Action<int> printNumber = x => Console.WriteLine(x);
Action<int, int> printTwoNumbers = (x,y) =>
{
Console.WriteLine(x);
Console.WriteLine(y);
};

Func<DateTime> getTime = () => DateTime.Now;
Func<int, int> square = x => x*x;
Func<int, int, int> multiply = (x,y) => x*y;

printEmptyLine();
printNumber(6);
printTwoNumbers(2,3);

DateTime now = getTime();
int z = multiply(4,7);
}

Wednesday, May 23, 2012

Named vs. Anonymous Method vs. Lambda Expressions

Named Method Predicate - passing method pointers

static void Main(string[] args)
{
Employee the = Array.Find(employees, FindThePredicate);
}

static bool FindThePredicate(Employee e)
{
return e.Name == "The";
}

Anonymous Method

static void Main(string[] args)
{
Employee the = Array.Find(employees,
delegate(Employee e)
{
return e.Name == "The";
}
);
}

Lambda Expression - anonymous method but with less code

static void Main(string[] args)
{
Employee the = Array.Find(employees, (e) => e.Name =="The");
}

Tuesday, March 13, 2012

Windows Developer Camp

Signed up for the free all-day Windows Developer Camp in Reston, VA on Tuesday March 27. Link: https://msevents.microsoft.com/CUI/EventDetail.aspx?EventID=1032507574&Culture=en-US


Monday, March 5, 2012

Android GPS and Routing

Wrote a little Android program to find a route between the current GPS location and another pre-determined location (GMU) and display it on Android phone's built-in Google Maps.


Friday, March 2, 2012

Android Map View

main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/mainlayout"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent" >

    <com.google.android.maps.MapView
        android:id="@+id/mapview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:clickable="true"
        android:apiKey="useyourown"
    />

</RelativeLayout>

HelloMapViewActivity.java

package com.thekhuc.hellomapview;

import java.util.List;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.widget.LinearLayout;

public class HelloMapViewActivity extends MapActivity {
    LinearLayout linearLayout;
    MapView mapView;
    List<Overlay>mapOverlays;
    Drawable drawable;
    HelloItemizedOverlay itemizedOverlay;

/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
     
        mapView = (MapView) findViewById(R.id.mapview);
        mapView.setBuiltInZoomControls(true);
     
        mapOverlays = mapView.getOverlays();
        drawable = this.getResources().getDrawable(R.drawable.androidmarker);
        itemizedOverlay = new HelloItemizedOverlay(drawable);
     
        GeoPoint point = new GeoPoint(19240000, -99120000);
        OverlayItem overlayitem = new OverlayItem(point, "","");
     
        itemizedOverlay.addOverlay(overlayitem);
        mapOverlays.add(itemizedOverlay);
    }

@Override
protected boolean isRouteDisplayed() {
// TODO Auto-generated method stub
return false;
}
 
}

HelloItemizedOverlay.java

package com.thekhuc.hellomapview;

import java.util.ArrayList;

import android.graphics.drawable.Drawable;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

public class HelloItemizedOverlay extends ItemizedOverlay<OverlayItem> {

private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();

public HelloItemizedOverlay(Drawable defaultMarker) {
super(boundCenterBottom(defaultMarker));
}

@Override
protected OverlayItem createItem(int i) {
return mOverlays.get(i);
}

@Override
public int size() {
return mOverlays.size();
}

public void addOverlay(OverlayItem overlay){
mOverlays.add(overlay);
populate();
}

}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.thekhuc.hellomapview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="com.google.android.maps"/>
        <activity
            android:name=".HelloMapViewActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>




Android Issue: java.lang.RuntimeException: Unable to instantiate activity ComponentInfo


Resolved.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.thekhuc.hellomapview"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="10" />
    <uses-permission android:name="android.permission.INTERNET"/>

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <uses-library android:name="com.google.android.maps"/>
        <activity
            android:name=".HelloMapViewActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Wednesday, February 29, 2012

Free Pluralsight Training TODAY Only

Check out their blog post for more information. I love Pluralsight!

Tuesday, February 21, 2012

Thank You, Microsoft!

Microsoft was nice enough to give me App Hub 12-month membership for free. Now I can finally test and deploy the Windows Phone app. Thank you MS!


Sunday, February 19, 2012

Android Hackbook and Facebook SDK

Hackbook is great for learning Facebook SDK and Android development.


Hackbook Place Check-in


final Intent myIntent = new Intent(getApplicationContext(), Places.class);

new AlertDialog.Builder(this)
.setTitle(R.string.get_location)
.setMessage(R.string.get_default_or_new_location)
.setPositiveButton(R.string.current_location_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
myIntent.putExtra("LOCATION", "current");
startActivity(myIntent);
}
})
.setNegativeButton(R.string.times_square_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
myIntent.putExtra("LOCATION", "times_square");
startActivity(myIntent);
}

}).show();


Hackbook Upload Photo

import android.provider.MediaStore;

final static int PICK_EXISTING_PHOTO_RESULT_CODE = 1;

dialog = ProgressDialog.show(Hackbook.this, "",
getString(R.string.please_wait), true, true);
new AlertDialog.Builder(this)
.setTitle(R.string.gallery_remote_title)
.setMessage(R.string.gallery_remote_msg)
.setPositiveButton(R.string.gallery_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Intent.ACTION_PICK,
(MediaStore.Images.Media.EXTERNAL_CONTENT_URI));
startActivityForResult(intent,
PICK_EXISTING_PHOTO_RESULT_CODE);
}

})
.setNegativeButton(R.string.remote_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
/*
* Source tag: upload_photo_tag
*/  
Bundle params = new Bundle();
params.putString("url",
"http://www.facebook.com/images/devsite/iphone_connect_btn.jpg");
params.putString("caption",
"FbAPIs Sample App photo upload");
Utility.mAsyncRunner.request("me/photos", params,
"POST", new PhotoUploadListener(), null);
}

}).setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface d) {
dialog.dismiss();
}
}).show();
}


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
/*
* if this is the activity result from authorization flow, do a call
* back to authorizeCallback Source Tag: login_tag
*/

case AUTHORIZE_ACTIVITY_RESULT_CODE: {
Utility.mFacebook.authorizeCallback(requestCode, resultCode, data);
break;
}

/*
* if this is the result for a photo picker from the gallery, upload
* the image after scaling it. You can use the Utility.scaleImage()
* function for scaling
*/

case PICK_EXISTING_PHOTO_RESULT_CODE: {
if (resultCode == Activity.RESULT_OK) {
Uri photoUri = data.getData();
if (photoUri != null) {
Bundle params = new Bundle();
try {
params.putByteArray("photo",
Utility.scaleImage(getApplicationContext(), photoUri));
} catch (IOException e) {
e.printStackTrace();
}
params.putString("caption", "FbAPIs Sample App photo upload");
Utility.mAsyncRunner.request("me/photos", params, "POST",
new PhotoUploadListener(), null);
} else {
Toast.makeText(getApplicationContext(),
"Error selecting image from the gallery.", Toast.LENGTH_SHORT)
.show();
}
} else {
Toast.makeText(getApplicationContext(), "No image selected for upload.",
Toast.LENGTH_SHORT).show();
}
break;
}

//}
}



public class PhotoUploadListener extends BaseRequestListener {

        @Override
        public void onComplete(final String response, final Object state) {
            dialog.dismiss();
            mHandler.post(new Runnable() {
                @Override
                public void run() {
                    new UploadPhotoResultDialog(Hackbook.this, "Upload Photo executed", response)
                            .show();
                }
            });
        }

        public void onFacebookError(FacebookError error) {
            dialog.dismiss();
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_LONG).show();
        }
    }

Hackbook Get Friends Graph API


dialog = ProgressDialog.show(Hackbook.this, "",
getString(R.string.please_wait), true, true);
new AlertDialog.Builder(this)
.setTitle(R.string.Graph_FQL_title)
.setMessage(R.string.Graph_FQL_msg)
.setPositiveButton(R.string.graph_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
graph_or_fql = "graph";
Bundle params = new Bundle();
params.putString("fields", "name, picture, location");
Utility.mAsyncRunner.request("me/friends", params,
new FriendsRequestListener());
}

})
.setNegativeButton(R.string.fql_button,
new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
graph_or_fql = "fql";
String query = "select name, current_location, uid, pic_square from user where uid in (select uid2 from friend where uid1=me()) order by name";
Bundle params = new Bundle();
params.putString("method", "fql.query");
params.putString("query", query);
Utility.mAsyncRunner.request(null, params,
new FriendsRequestListener());
}

}).setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface d) {
dialog.dismiss();
}
}).show();


public class FriendsRequestListener extends BaseRequestListener {

        @Override
        public void onComplete(final String response, final Object state) {
            dialog.dismiss();
            Intent myIntent = new Intent(getApplicationContext(), FriendsList.class);
            myIntent.putExtra("API_RESPONSE", response);
            myIntent.putExtra("METHOD", graph_or_fql);
            startActivity(myIntent);
        }

        public void onFacebookError(FacebookError error) {
            dialog.dismiss();
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }
    }

Hackbook Update Status


Bundle params = new Bundle();
params.putString("caption", getString(R.string.app_name));
params.putString("description", getString(R.string.app_desc));
params.putString("picture", Utility.HACK_ICON_URL);
params.putString("name", getString(R.string.app_action));

Utility.mFacebook.dialog(Hackbook.this, "feed", params, new UpdateStatusListener());
String access_token = Utility.mFacebook.getAccessToken();
System.out.println(access_token);


public class UpdateStatusListener extends BaseDialogListener {
        @Override
        public void onComplete(Bundle values) {
            final String postId = values.getString("post_id");
            if (postId != null) {
                new UpdateStatusResultDialog(Hackbook.this, "Update Status executed", values)
                        .show();
            } else {
                Toast toast = Toast.makeText(getApplicationContext(), "No wall post made",
                        Toast.LENGTH_SHORT);
                toast.show();
            }
        }

        @Override
        public void onFacebookError(FacebookError error) {
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel() {
            Toast toast = Toast.makeText(getApplicationContext(), "Update status cancelled",
                    Toast.LENGTH_SHORT);
            toast.show();
        }
    }

Hackbook App Requests


import android.os.Bundle;
import android.widget.Toast;

Bundle params = new Bundle();
params.putString("message", getString(R.string.request_message));
Utility.mFacebook.dialog(Hackbook.this, "apprequests", params, new AppRequestsListener());

public class AppRequestsListener extends BaseDialogListener {
        @Override
        public void onComplete(Bundle values) {
            Toast toast = Toast.makeText(getApplicationContext(), "App request sent",
                    Toast.LENGTH_SHORT);
            toast.show();
        }

        @Override
        public void onFacebookError(FacebookError error) {
            Toast.makeText(getApplicationContext(), "Facebook Error: " + error.getMessage(),
                    Toast.LENGTH_SHORT).show();
        }

        @Override
        public void onCancel() {
            Toast toast = Toast.makeText(getApplicationContext(), "App request cancelled",
                    Toast.LENGTH_SHORT);
            toast.show();
        }
    }