Showing posts with label dev. Show all posts
Showing posts with label dev. Show all posts

19 April 2013

Fast Flicking Between Images on Android

So I wanted to be able to have a simple control that supported swapping between a list of images as the user swiped/flicked their finger across the image.

My initial solution was to have a HorizontalScrollView which showed all my images in a row. This worked pretty well but I wasn't able to accurately stop to show each image on the screen as the user flicked between them. They always seemed to end up half off-screen.

After spending a few hours attempting to wrestle the scrolling events in the HorizontalScrollViewer under my control I realised that I must be doing something wrong, surely this isn't this difficult.

ViewPager

And yes, it couldn't have been simpler. More information on the android blog. But basically I ended up creating a simple PagerAdapter like so:

public class ImagePagerAdapter extends PagerAdapter 
{
 Bitmap[] _images = null;

 public ImagePagerAdapter( Bitmap[] images ) 
 {
  _images = images;
 }

 @Override
 public int getCount() 
 {
  return _images == null ? 0 : _images.length;
 }

 @Override
 public boolean isViewFromObject(View view, Object object) 
 {
  return view == ((ImageView)object);
 }
 
 @Override
    public Object instantiateItem(ViewGroup container, int position) 
 {
  ImageView img = null;
  
  if( position >= 0 && position < _images.length )
  {
   final Bitmap bmp = _images[position];
   
   img = new ImageView(container.getContext());
   img.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
   img.setImageBitmap(bmp);
   img.setScaleType(ImageView.ScaleType.CENTER_CROP);
   ((ViewPager)container).addView(img, 0);
  }
  
  return img;
    }

    @Override
    public void destroyItem(ViewGroup container, int position, Object object) 
    {
     ((ViewPager)container).removeView((ImageView)object);
    }

}

Then in my Activity/Fragment class it was a simple matter of just assigning the adapter to my pager and that is it!

ImagePagerAdapter adapter = new ImagePagerAdapter(bitmaps);
((ViewPager)v.findViewById(R.id.fragment_bird_banner_viewpager)).setAdapter(adapter);

Lesson: If things that you feel should be basic are becoming too complicated and taking too much time. You're probably doing them wrong. Step back and search/read a little bit. :)

9 May 2012

Internet Rule Number 36?

In the last few years I've realised that having the attitude that

It's easier to ask for forgiveness than it is to get permission.

is in in many cases the easiest way to get things done. This approach can save you oh-so many pointless arguments and typical corporate ass-covering meetings with people less interested with getting things done and more with their job title and feeling important.
Meetings!
I admire people that just get shit done.

I might not agree with their approach. I might even argue with them, but no one can argue with results!


Unoriginality
When searching for the original author of that comment above I discovered that it is attributed to the late Grace Hopper. A remarkable woman and a great speaker. I think the video below shows possibly one of the best ways to explain intangible concepts. Bring a prop.


5 March 2012

Your code sucks, let's fix it

I found this presentation by Rafael Dohms quite interesting. It has some radical blanket statements and highly objectionable points but also quite a few post publishing edits and corrections.

If you keep a cool head and just take this as it is, you might just learn something (or at least get a refresher). I'll be the first to admit that I did.

24 February 2012

Why I Think C# and Java Trump C and C++

Well the title is a bit sensationalist. As a disclaimer I strongly believe that you need to pick the correct tool that best suits the job at hand and that you believe you will be the most productive in.

However when faced with the agonizing task of printing out Trace messages with variable formatting in a bit of C code that I had lying around recently, I realised just how focused C# is on getting things done rather than faffing about with boilerplate code.

As an example, here are two functions that fundamentally do the same thing, print a formatted string to the system Trace listeners using a single format string and then a variable number of arguments:

First the C# function:
void odprintf(string format, params object[] args)
{
    Trace.WriteLine(string.Format(format, args));
}

Compared to the C equivalent:
void __cdecl odprintf(const char *format, ...)
{
    char buf[4096], *p = buf;
    va_list args;
    int n;

    va_start(args, format);
                             // buf-3 is room for CR/LF/NUL
    n = _vsnprintf(p, sizeof buf - 3, format, args);
    va_end(args);

    p += (n < 0) ? sizeof buf - 3 : n;
    while ( p > buf  &&  isspace(p[-1]) )
            *--p = '\0';

    *p++ = '\r';
    *p++ = '\n';
    *p   = '\0';

    OutputDebugStringA(buf);
}
Really, all this magic is necessary to just print to Trace?

I reserve the right to seriously doubt that "lower" level languages have any place but in highly specialised or those extremely few cases where throughput and latency are more important than developer productivity and deadlines are lax and forgiving.

Here is someone that is more eloquent than I am on this issue.
There is no reason to use C++ for new projects. However, there are existing projects in C++ which might be worth working on. Weighting the positive aspects of such a project against the sad fact that C++ is involved is a matter of personal judgement.

If you end up working with C++, don't try to "fix" it (or "boost" it). You'll just add more layers of complexity. The most productive approach is to accept the problems and try to write simple code which people can easily follow.

If you are an expert in the intricacies of C++, please consider this knowledge a kind of martial art - something a real master never uses.

23 February 2012

Calculating Combinations of 1, 2, 3 Step Jumps

So again I was trolling along on Antonio Gulli's website (which has become a bit of a favorite to find fun problems to solve during a quiet evening). I came across this question:
A child can hop either 1, 2, or 3 steps in a stairway of N steps.
How many combinations do you have?
As the first comment mentions then this problem can be solved using recursion. But the question is, how would you translate this into program code?

... want a second to think about this before reading my attempts?

Initial Attempt
After thinking about this problem for a little while I decided that this might be cleanly solved using a recursive tree traversal algorithm. As we have a branching factor of 3 we should not have a branch height of more than N/3 (only taking 3 step jumps) in the best case and N in the worst case (if only taking 1 step jumps).

The initial naive solution I came up with was a simple DFS search using a stack (LIFO):

static Stack<long> nodes = new Stack<long>();
static long Combinations( int n )
{
    long leafs = 0;
    nodes.Push(n);
    while (nodes.Count > 0)
    {
        var x = nodes.Pop();

        // Leaf, just count
        if (x <= 0) leafs++;
        else
        {
            // Only push down options where the child 
            // can actually complete the stair jump
            if (x - 1 >= 0) nodes.Push(x - 1);
            if (x - 2 >= 0) nodes.Push(x - 2);
            if (x - 3 >= 0) nodes.Push(x - 3);
        }
    }
    return leafs;
}

Improved Attempt
It is soon obvious if you run the first code using non-trivial sizes of N that this naive DFS solution is simply too slow. The time that it takes to iterate through the entire tree and generating all the intermediary nodes is just too great and quite quickly the algorithm takes too long to return a solution within a reasonable time.

When you look closer at this ternary tree it might become obvious that since it is a complete tree it has a simple repeating pattern down each of its branches. Basically each branch is a sub-tree of the one preceding it (with node count n-1). Meaning that the (n-1) branch far to the left at height h has an equal amount of nodes in its immediate (n-1) child at h-1 as the second (n-2) branch at h has.

Using this we can simply pre-cache each height in the tree once we have calculated it completely and thus really only need to do one full depth run on a single branch after which we will have all the necessary values calculated for the remaining nodes.

           A
          /|\
         B C D
        /|\
       E F G
      /|\
     H I J
We only need to calculate the A,B,E,H values, after that no extra recursive traversal is necessary into any other subtrees as we can use the cached value for H for F, J for G, E for C, F for D and so forth.

So by adding a simple map that caches the node count for every remaining node number we can significantly speed up this calculation:

static Dictionary<int, BigInteger> map = new Dictionary<int, BigInteger>();
static BigInteger Combinations2(int n)
{
    if (n <= 0) return 1;

    BigInteger leafs = 0;
    if (map.TryGetValue(n, out leafs))
        return leafs;

    // We need to calculate it if not found
    if (n - 1 >= 0)
        leafs += Combinations2(n - 1);
    if (n - 2 >= 0)
        leafs += Combinations2(n - 2);
    if (n - 3 >= 0)
        leafs += Combinations2(n - 3);

    map[n] = leafs;
    return leafs;
}

We can probably do better than this though?

18 February 2012

geeksforgeeks.org

This one is a fun read geeksforgeeks.org, try solving a few of the programming problems before reading the articles/solutions.

It is fun, I guarantee it :)

Also they have a good interviewing section, just don't get too hung up on it mkay

The absolute difference between two double numbers

How would we create a function

      abs( double a, double b )

that returns the absolute value of the difference between a and b?

Edit 21/02/2012:
I embarrassingly have to admit that before posting this entry in the beginning I had spent about an hour attempting some fancy prancy bit masking solution (as one might do in a integer or long abs function) gazing at bit arrangements and getting myself into an utter dead end and 100+ lines of code. I decided that this might simply be the best solution I could come up with:

public static double abs(double a, double b)
{
    double diff = b > a ? b - a : a - b;
    return diff < 0 ? -diff : diff;
}

Too stupid to fail?

17 February 2012

Bit manipulation gasp, gasp

Call me an elitist if you want, but it still surprises me how reluctant programmers are to use basic bit operations.

As an example, let's say that you have a series of calls to functions that might return true or false and you want to call every single one of them but if one of them returns true you want to preserve that value at the expense of the other false values.

For such a problem I am more likely to encounter code written similar to this:
bool anyreturntrue = false;
for( a few calls )
{
    bool result = SomeFunction();
    if( !anyreturntrue && result)
        anyreturntrue = result;
}
return anyreturntrue;

rather than the more elegant:
bool anyreturntrue = false;
for( a few calls )
    anyreturntrue |= SomeFunction();
return anyreturntrue;

Should this really be considered wizardry?
I hope not.

16 February 2012

Calculating x^y

I stumbled onto this blog (Antonio Gulli) the other day and read through a couple of his suggested programming problems.

Kind of interesting to tackle that power function. After coming up with a rather naive solution to begin with, I attempted to improve on it and ended up with the following implementation for X^Y that works when X and Y  are integers. As I wanted to keep it rooted in the .NET framework implementation I needed to use the BigInteger class so the function will not return a value for negative Y values just yet :)

What do you think?

using System;
using System.Numerics;

internal class Program
{
    private static void Main(string[] args)
    {
        int x = 2;
        int y = 2000;

        BigInteger pow = Pow(x, y);

        Console.WriteLine("{0}^{1}={2}", x, y, pow);
    }

    private static BigInteger Pow(int x, int y)
    {
        if (y == 0) return 1; // Zero power
        int ay = Math.Abs(y);
        BigInteger pow = 1;
        BigInteger sum = x;
        if (ay > 0)
        {
            var iterations = (int) Math.Ceiling(Math.Log(ay, 2));
            for (int i = 0; i <= iterations; ++i)
            {
                if (ay == 0) break;
                if (ay%2 != 0) pow *= sum;
                sum *= sum;
                ay = ay/2;
            }
        }

        // Handle negative powers (Well this will work when we have BigDecimal in System.Numerics)
        return y < 0 ? 1/pow : pow;
    }
}

15 February 2012

What are we, five?

If you wear this badge, I have no respect for you :/