Scala, Java, Unix, MacOS tutorials (page 170)

The Android Developer’s Blog has a good article on how to optimize various memory attributes of Android applications, titled, Getting Santa Tracker Into Shape. A nice thing about their project is that they make their source code available on Github.

An Android blog post about optimizing memory-related issues

On Twitter this morning I saw this post by Pablo Fco. Pérez where he compared some Bash commands to Scala. In particular he noted that this awk command:

awk '{print $1}'

is equivalent to:

map(_.split(" ").head)

While doing some crazy things with SARAH, I realized that the best way to solve a particular problem was to use remote Akka actors. I haven’t had the opportunity to work with Akka much since finishing the Scala Cookbook, so I dug around trying to find a simple Akka remote “Hello, world” example. Unable to find a good one, I read some stuff, and created it myself.

[toc hidden:1]

Apparently today is Rare Disease Day, so in honor of that, here’s this image.

To give you an idea of how rare Mast Cell Activation Disease is, there is a support group on Facebook, and it has only 2,200 members. That’s out of one billion people that use Facebook.

Happy Rare Disease Day

Got to spend my afternoon at The University of Colorado Hospital. Glad to see they are well rated.

The University of Colorado Hospital

I may explain this more in the future, but for now, here’s some source code for an example of how to use Quicklens in a Scala functional programming project.

Given some model/ADT definitions like this:

As I was researching who might be using an “IO Monad” in Scala, I found this quote from Martin Odersky in the Google Group titled “scala-debate”:

“The IO monad was a neat trick for combining side effects with lazy evaluation ... there is only one lazily evaluated language in wide usage today and even its creators have said that laziness was probably a mistake. Strict languages don’t need the IO monad, and generally don’t have it, even though they could. Bob Harper’s posts in his ‘existential type’ series are a good explanation on why not.”

Here’s a link to Bob Harper’s The Point of Laziness article.

A quote from the founder of Buddhist Geeks: “I’ve cow-towed to a culture of sensitivity, whose aim has been to avoid offending others over having difficult conversations.”

This made me think of two things. First, many years ago my company worked as a consultant with a large church, and any time there was conflict about something on the project, all productivity came to a screeching halt. People there all felt the need to be nice to each other above all else, and as a result the tough decisions couldn’t be made, and they were our slowest-moving client of ever.

Second, as I learned from Zen, being your true self doesn’t mean “being nice above all else” all the time. That’s just faking it. There will always be disagreements, and the philosophy I try to follow is, “The best idea wins.”

I learned part of that philosophy — and how to handle conflict — from this article by Bill Parcells, The tough work of turning around a team.

Here’s a Unix shell script that I use to search Java Jar files for any type of string pattern. You can use it to search for the name of a class, the name of a package, or any other string/pattern that will show up if you manually ran jar tvf on each jar file. The advantage of this script — if you’re a Unix, Linux, or Cygwin user — is that it will search through all jar files in the current directory:

One philosophy I have about writing technical material is that I want to condense the material as much as possible, to the point where I want people who use yellow highlighters to mark most of what I write. I am one of those people who use yellow highlighters, and I look for that property in books that I read.

This isn’t necessarily true for blog posts that I write, because for these I usually write them pretty fast. But for books, I take the time to review them and look for this quality. This follows the design mantra, “reduce, reduce, reduce.”

Here’s a photo I took of a wind farm back in December. I think it’s related to the Wind Research Program at Purdue University.

Wind farm

The source code below corresponds to an article I wrote titled, Android ActionBar example: How to create an options menu item.

package com.valleyprogramming.justbe;

import android.app.ListFragment;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Color;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.TextView;
import com.valleyprogramming.justbe.QuotesDatabaseHelper.QuoteCursor;
import com.example.android.swipedismiss.SwipeDismissListViewTouchListener;

public class QuotesListFragment extends ListFragment {

    private static final String TAG = "VPQuotesListFragment";
    private QuoteCursor quoteCursor;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setHasOptionsMenu(true);
        getActivity().setTitle(R.string.title_quotes_screen);

        // config the database and adapter
        quoteCursor = DatabaseManager.get(getActivity()).queryQuotes();

        // create an adapter to point at this cursor
        QuoteCursorAdapter adapter = new QuoteCursorAdapter(getActivity(), quoteCursor);
        setListAdapter(adapter);
    }

    @Override
    public void onDestroy() {
        quoteCursor.close();

        //TODO working on possible memory leaks
        quoteCursor = null;
        setListAdapter(null);
        
        super.onDestroy();
    }

    @Override
    public void onActivityCreated(Bundle bundle) {
        super.onActivityCreated(bundle);
        // get a handle to our list view to implement 'swipe to delete'
        ListView listView = getListView();
        // Create a ListView-specific touch listener. ListViews are given special treatment because
        // by default they handle touches for their list items... i.e. they're in charge of drawing
        // the pressed state (the list selector), handling list item clicks, etc.
        SwipeDismissListViewTouchListener touchListener =
            new SwipeDismissListViewTouchListener(
                listView,
                new SwipeDismissListViewTouchListener.DismissCallbacks() {
                    @Override
                    public boolean canDismiss(int position) {
                        return true;
                    }
                    @Override
                    public void onDismiss(ListView listView, int[] reverseSortedPositions) {
                        for (int position : reverseSortedPositions) {
                            String quoteToDelete = ((QuoteCursor)(getListAdapter()).getItem(position)).getQuote().getQuote();
                            DatabaseManager.get(getActivity()).deleteQuote(quoteToDelete);

                            // need the next two lines to update the list after the delete
                            refreshQuoteCursorDataSet();

                            handleCasesWhereThisQuoteWasTheCurrentlyDisplayedQuote(quoteToDelete);
                        }
                    }
                });
        listView.setOnTouchListener(touchListener);
        // setting this scroll listener is required to ensure that during ListView scrolling,
        // we don't look for swipes.
        listView.setOnScrollListener(touchListener.makeScrollListener());

    }
    
    private void handleCasesWhereThisQuoteWasTheCurrentlyDisplayedQuote(String quoteThatWasDeleted) {
        if (GlobalState.currentlyDisplayedQuote.equals(quoteThatWasDeleted)) {
            if (GlobalState.pinnedStateEnabled) {
                // the quote that was deleted was the current quote and it was pinned
                PreferencesUtils.handleUserUnpinsQuoteAction(getActivity().getBaseContext());
                GlobalState.currentlyDisplayedQuote = "";
            } else {
                // the quote that was deleted was the current quote but it was not pinned
                GlobalState.currentlyDisplayedQuote = "";
            }
        }
    }

    /**
     * When a list item is clicked, perform the 'Edit' action.
     */
    @Override
    public void onListItemClick(ListView l, View v, int position, long id) {
        String quote = ((QuoteCursor)(getListAdapter()).getItem(position)).getQuote().getQuote();
        Log.d(TAG, quote + " was clicked");

        // i'm doing this in the long form just for my own knowledge
        Context context = getActivity();
        Class destination = EditQuoteActivity.class;
        Intent intent = new Intent(context, destination);
        intent.putExtra(EditQuoteFragment.KEY_QUOTE_EXTRA, quote);
        startActivityForResult(intent, 0);
    }

    /**
     * update the list of quotes when the user returns, presumably after
     * using the 'edit' screen. p. 197.
     * 
     * the book's code example actually uses onActivityResult instead of
     * onResume. i just tested it, and they both get called, so either one
     * will work.
     */
    @Override
    public void onResume() {
        super.onResume();
        refreshQuoteCursorDataSet();
    }

    /**
     * as the code shows, the cursor needs to be refreshed before
     * notifyDataSetChanged is called
     */
    private void refreshQuoteCursorDataSet() {
        quoteCursor.requery();
        ((QuoteCursorAdapter)getListAdapter()).notifyDataSetChanged();
    }

    /**
     * the menu layout has the 'add/new' menu item
     */
    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater menuInflater) {
        menuInflater.inflate(R.menu.menu_quotes_list, menu);
        super.onCreateOptionsMenu(menu, menuInflater);
    }

    /**
     * react to the user tapping/selecting an options menu item
     */
    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.menu_item_new_quote:
                Intent addQuoteIntent = new Intent(getActivity(), NewQuoteActivity.class);
                startActivityForResult(addQuoteIntent, 0);
                return true;
            default:
                return super.onOptionsItemSelected(item);
        }
    }

    /**
     * The adapter class that will work with the ListView.
     */
    private static class QuoteCursorAdapter extends CursorAdapter {

        private QuoteCursor mRunCursor;

        public QuoteCursorAdapter(Context context, QuoteCursor cursor) {
            super(context, cursor, 0);
            mRunCursor = cursor;
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            LayoutInflater inflater = (LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            return inflater.inflate(R.layout.quote_item_view, parent, false);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // get the quote for the current row
            Quote quote = mRunCursor.getQuote();

            // this works with my custom view (quote_item_view.xml)
            TextView textView = (TextView)view.findViewById(R.id.the_quote);
            textView.setText(quote.getQuote());

            // set the text size
            textView.setTextAppearance(context, R.style.listViewText);

            // confirmed: this works. can also specify alpha as '00-ff' before the rgb
            // component, but that won't do anything in this case
            textView.setBackgroundColor(Color.parseColor("#ffffff"));
        }

    }

}

The reason I show the code here is because it shows how to enable the Android ActionBar, in this case from a Fragment, and more specifically a ListFragment.

Per The Register, “Advertising revenue flowing back to app developers from Android apps has exceeded the amount returned to developers by Apple for the first time.”

I eat mostly organic food because it seems to help dramatically with my mast cell disease, but it sounds like a lot of other people are going organic as well. Here’s a quote from this SeattleTimes.com article: “We cannot get enough organics to stay in business day in and day out,” Jelinek told the gathered investors.

One of my favorite albums of all time is Us, by Peter Gabriel. I discovered it during a period of existential angst when I was working on a $3B NASA project, and I learned that the entire project was created and would soon be destroyed because of politics. I started listening to the album again recently while practicing yoga at night. This song is Blood Of Eden.

I recently “made the switch” from MacOS to Linux Mint, and was lamenting the fact that I didn’t have Alfred on Mint. But then this morning I learned about Cerebro, which, if it’s not Alfred yet, at least it’s Spotlight for Linux. omgubuntu.co.uk has this good intro article on Cerebro.

Cerebro is written as an Electron app, and as a result it’s available not only for Linux, but Windows and MacOS as well.

Cerebro, Spotlight for Linux

“One must do asana not merely as a physical exercise but as a means to understand and then integrate our body with our breath, with our mind, with our intelligence, with our consciousness, and with our core. In this way, one can experience true integration.”

B.K.S. Iyengar, Light on Life: The Yoga Journey