Sunday, January 30, 2011

Have you ever formed the intention...

Last week's sermon, "You're not the Boss of Me," talks a lot about freedom, but what I've been thinking about is something our pastor asks about 05:30 into the message. At this point, he's recounted the part in Exodus 19 where Moses meets the Lord on the mountain, and God tells Moses he wants to establish a covenant with the people of Israel.
You yourselves have seen what I did to Egypt, and how I carried you on eagles’ wings and brought you to myself. Now if you obey me fully and keep my covenant, then out of all nations you will be my treasured possession. Although the whole earth is mine, you will be for me a kingdom of priests and a holy nation.
Exodus 19:4-6
The Israelites replied, "We will do everything the Lord has said" (Exodus 19:8) -- they formed an intention to obey God. They didn't do very well at it, but they did form the intention. Now the rubber meets the road at this point, where the pastor asks all of us, seriously,
Have you ever said, "I will form the intention of doing whatever God tells me to do"?
He goes on to ask if not, why not, and so on, but I wanted to hit the pause button right there.

My problem was that, rather than just continuing to listen and take notes, I actually thought about the question. Have I ever formed the intention? Well, of course I have. But how's it going? What do I think about in the morning when I first wake up? When I'm waiting for the train?

Well, honestly I'm often thinking about me -- my problems, my desires, etc. But this past week, because of that sermon, I've been thinking about what it means to do whatever God tells me to do. "Lord, what does it mean for me to walk with you today?" has been on my mind as I walked from the train to the office. I had a dream this past week, where Galatians 6:10 came up: "Let us do good to all men..."

That's besides all the stuff about being patient and kind, treating others the way I want to be treated, telling the truth and so on.

But really, when I first wake up in the morning, that's not what I usually think about. Often there's an urgent matter that needs my immediate attention, but when there isn't I'm often thinking about how pleasant it is to have my arms around Carol and to have her head resting on my chest. Or situations at work or church and how do deal with them.

So what's my plan? Well, I mentioned Galatians 6:10 earlier? That's a verse I memorized some 30 years ago but haven't reviewed lately. So one part of that is to step up the verse review. At least it'll get me thinking consciously about God, and bring his word closer to my consciousness. Besides that, I'll keep on with my strategies to overcome envy as well as resentment, anxiety and so on. You can ask the lovely Carol how it's working.

Monday, January 24, 2011

Merton in process

On the book jacket of No Man Is an Island is this fabulous paragraph:
We are warmed by fire, not by the smoke of the fire. We are carried over the sea by a ship, not by the wake of a ship. So too, what we are is to be sought in the invisible depths of our own being, not in our outward reflection in our own acts. We must find our real selves not in the froth stirred up by the impact of our being upon the beings around us, but in our own soul which is the principle of all our acts.
A few paragraphs later -- inside the book -- is this comment:
The reason why men are so anxious to see themselves, instead of being content to be themselves, is that they do not really believe in their own existence…
No Man Is an Island, pp.117-118
What wisdom! What depth of insight into the human condition! And then last night I discovered something in another book -- Echoing Silence -- a quote from his The Seven Storey Mountain:
The more I failed, the more I was convinced that it was important for me to have my work printed in magazines like the Southern Review or Partisan Review or the New Yorker. My chief concern was now to see myself in print. It was as if I could not be quite satisfied that I was real until I could feed my ambition with these trivial glories, and my ancient selfishness was now matured and concentrated in this desire to see myself externalized in a public and printed and official self which I could admire at my ease.
The Seven Storey Mountain was dated 1948, and No Man Is an Island seven years later.

This was a tremendous thing for me to find, because I tend to imagine my spiritual and literary(?) heroes to have always been great -- plucked as they were from Zeus's forehead or something. But here we see Merton struggling himself in his reflections written in 1948, and some years later having this profound insight into human nature. Though I don't want to compare myself with Merton, I like to think that since even he had growth areas, there's hope for me. too.

Sunday, January 23, 2011

Pick Your Favourite Chapter of Isaiah Night

The other night, three of us (the lovely Carol, the ex-teen, and I) chose a chapter of Isaiah to read. Here are the three chapters we chose, in ascending order, with some highlights; see if you can guess who chose which chapter.

Isaiah 40

... is justly famous; the beginning verses appear near the beginning of Handel's The Messiah:
Comfort, comfort ye my people 
    saith your God. 
… 
A voice of him that crieth in the wilderness: 
    Prepare ye the way of the Lord. 
Make straight in the desert a highway 
    for our God.
from Isaiah 40:1-3
John the Baptist quotes this in John 1:23; Mark quotes it in Mark 1:3. Who needs comforting? The Israelites did then, and we do today.

This chapter also has the image of the Lord as one who measured the waters of the seas in the hollow of his hand, marked off the heavens with the span, held the dust of the earth in a basket, etc. "To whom will you compare me? And who is my equal?" -- indeed. Considering the Lord's greatness gives me a whole new perspective on problems. No problem I have is worth comparing with the One who brings out the stars one by one (and calls them each by name).

And there's that promise at the end of the chapter:

Those who hope in the Lord 
    will renew their strength. 
They will soar on wings like eagles; 
    they will run and not grow weary, 
    they will walk and not be faint.
Isaiah 40:31

Isaiah 55

...begins with that great invitation:
“Come, all you who are thirsty, 
    come to the waters; 
and you who have no money, 
    come, buy and eat! 
Come, buy wine and milk 
    without money and without cost…
Isaiah 55:1
The Lord invites them, and us, to a feast he's hosting -- for free! He's inviting us -- urging us to stop defeating ourselves. Good idea.

There's also the verses that talk about seeking the Lord while he may be found, and the promise of being freely forgiven. Repent, he says, and “turn to the Lord, and he will have mercy on him, and to our God, for he will freely pardon” (Isaiah 55:7). That's good news. And this:

“For my thoughts are not your thoughts, 
   neither are your ways my ways,” 
declares the Lord. 
“As the heavens are higher than the earth, 
    so are my ways higher than your ways 
    and my thoughts than your thoughts. 
As the rain and the snow 
    come down from heaven, 
and do not return to it 
    without watering the earth 
    and making it bud and flourish, 
so that it yields seed for the sower  
    and bread for the eater,  
so is my word that goes out from my mouth: 
    It will not return to me empty, 
but will accomplish what I desire 
    and achieve the purpose for which I sent it.
Isaiah 55:8-11
Notice the way his thoughts are higher than ours includes his generosity (55:1-3) and his mercy (Isaiah 55:7) and also that his word shall succeed. And right after that is this cool promise:
You will go out in joy
    and be led forth in peace;
the mountains and hills
    will burst into song before you,
and all the trees of the field
    will clap their hands.
Isaiah 55:12

Isaiah 58

In this chapter the Lord rebukes those who do religious rituals but without doing justice: you fast, he says, yet you “exploit all your workers…You cannot fast as you do today and expected your voice to be heard on high.” (Isaiah 58:3-4). He says similar things about keeping the Sabbath yet continuing to sin. On the positive side, he's got some great promises for us: if you repent of oppressing people, he says,
… and if you spend yourselves in behalf of the hungry 
    and satisfy the needs of the oppressed, 
then your light will rise in the darkness, 
    and your night will become like the noonday.  
The Lord will guide you always; 
    he will satisfy your needs in a sun-scorched land 
    and will strengthen your frame. 
You will be like a well-watered garden, 
    like a spring whose waters never fail.  
Your people will rebuild the ancient ruins 
    and will raise up the age-old foundations; 
you will be called Repairer of Broken Walls, 
    Restorer of Streets with Dwellings.
Isaiah 58:10-12
There's also a promise for those who keep the Sabbath, which I used to think meant that God didn't want us to just relax and enjoy ourselves. But when he talks about honoring the Sabbath "by not going your own way" (Isaiah 58:13) I think he's contrasting our own way (cf Isaiah 53:6) with his way -- his ways are higher than our ways, as we saw in chapter 55. Our ways aren't like his in that we aren't generous, we don't forgive, and we say things without necessarily carrying them out. This is what he means when he says "not going your own way."

So who chose which?

These are all great chapters. All of them deal with eternal questions and with heavenly priorities. All display the Lord's supremacy. Chapter 40 reminds us that the Lord wants to comfort and strengthen us; chapter 55 reminds us of the Lord's reasonableness, his generosity and mercy. When we work hard for things that don't satisfy, this chapter seeks to correct us. Chapter 58 promises rewards for us when we repent, when we serve the poor and hungry; it warns us not to practice religious rituals without changing our hearts.

So what do you think? Which did I choose on "Pick Your Favourite Chapter of Isaiah" night? Which one looks to you like a young person's chapter? Which did the lovely Carol choose? Any ideas? Maybe I'll update this post later with the answer.

and the answer is...

Do you really want to know? Put your mouse → here

Sunday, January 16, 2011

Much activity, little fruit

NOTE: If you're naturally a slacker (I sometimes resemble this remark), this posting may not be for you.

Why do we try to give more than we can afford -- in time and effort, or in emotional involvement? Merton suggests that sometimes it's because we aren't at peace with ourselves, and we want to think we're greater than we actually are:

A man who is not at peace with himself… projects his interior fighting into the society of those he lives with, and spreads a contagion of conflict all around him. Even when he tries to do good to others his efforts are hopeless, since he does not know how to do good to himself…

It is only when we are detached from ourselves that we can be at peace with ourselves. We cannot find happiness in our work if we are always extending ourselves beyond ourselves and beyond the sphere of our work in order to find ourselves greater than we are.

from No Man Is an Island, pp. 120-121
(chapter 7, section 3)
This sort of activity, driven (as all things are) by mixed motives, often fails to yield the desired fruit. I may try to bless others, but if I'm agitated and on edge inside, then all that activity may leave my friends distressed and distracted, and myself disaffected and discouraged. Merton continues:
Our Christian destiny is, in fact, a great one: but we cannot achieve greatness unless we lose all interest in being great. For our own idea of greatness is illusory… It is, therefore, a very great thing to be little, which is to say: to be ourselves. And when we are truly ourselves we lose most of the futile self-consciousness that keeps us constantly comparing ourselves with others in order to see how big we are.

Merton, op. cit., p.122

I really like the comment that being little is being ourselves. Sometimes, the best thing I can give to others is myself -- my own true, little, self, not the spiritual giant I wish I were. Sometimes, "less" is more.

But reading Merton's words also reminded me of this passage from Haggai, who wrote about fruitless activity in another context:

Now this is what the Lord Almighty says: "Give careful thought to your ways. You have planted much, but have harvested little. You eat, but never have enough. You drink, but never have your fill. You put on clothes, but are not warm. You earn wages, only to put them in a purse with holes in it."
Haggai 1:5-6
Does that sound like a life filled with activity tainted by some unnamed disease?

Haggai was, of course, referring to material blessing (or the lack thereof) and his prescription was to stop neglecting the temple. Malachi also exhorts the Israelites to invest their treasure appropriately in the temple. I believe we can apply the insights from Haggai's and Malachi's prescription to our modern-day malaise: both then and now the issue is priorities.

In the time of these prophets, people went about their business without tending to the first priority, and their activities didn't yield the blessing they expected. In our day, many of us run around seeking blessing (yes, some of us put too much into ministry) without first tending to our own spiritual transformation.

In other words, sometimes the best thing I can do for others is to spend time pursuing and enjoying the Lord on my own sacred pathway (what's your favorite way to seek and find God? click here for a quiz) so that my cup can be filled and I'll have good things to share, rather than just a contagion of conflict.

Saturday, January 15, 2011

mail.app can't send mail using that server

Last October I migrated the lovely Carol's computing environment to a mac mini running snow leopard. Incoming mail was handled with an ssh tunnel to our ISP (localhost 60110 forwards to our ISP port 110), but I figured outbound mail didn't need anything that fancy, as our IP address should be on our ISP's list of "good" email addresses.

But lately we've been getting unhappy returns... mail.app would pop up with a "Can't send mail..." and would not tell me why. When the symptom appeared, I tried "telnet mail.ourISP.net 25" and manually-entered mail worked just fine. Wha...??

So this morning, when the symptom hit again, I sat down to do battle. I didn't see wireshark under Applications→Utilities; I didn't see ethereal. So it was time to go Neanderthal; I brought up a Terminal window and said

$ type tcpdump
tcpdump is /usr/sbin/tcpdump        ← Oh yeah, we're in business!
$ sudo tcpdump -w /tmp/tcpdump-mail-try1 -p 
tcpdump: listening on en0, link-type EN10MB (Ethernet), capture size 65535 bytes
Now I didn't actually hit <ENTER> on that tcpdump command until I had a mail message ready to send in mail.app. I hit <ENTER> to start off tcpdump, clicked "Send" in mail.app, got the nasty "Can't send using that server" window from mail.app, and then hit control-C in the Terminal window, thus interrupting tcpdump.

Next step was to copy the tcpdump output file to my OpenSUSE box and look at it with wireshark. A minute later I understood how this attempt failed, even though my "telnet" method worked fine.

Frame number 1 in the main window had the necessary information: we were connecting to our ISP's mail server, not using port 25 as I had thought, but using port 587. I clicked on Analyze&rarrFollow TCP stream and saw that my ISP was asking for authentication, which I didn't really want to send. But what is port 587?

collin@p3:~> grep 587 /etc/services
submission 587/tcp    # Submission
submission 587/udp    # Submission
… remainder elided
Submission, huh? Well, I shouldn't have to submit in this context; I want to use port 25. But how to change it? Google to the rescue! It led me this page, which shows how to tell mail.app to use a different port. Basically, it's Preferences, Accounts, Account Information, Server settings (outbound), Advanced, and in our version of mail.app, set "custom port" -- which I set to 25.

Saturday, January 08, 2011

Now there is no condemnation

Someone asked about a favorite Scripture, and Romans 8:1 (whence the title) immediately came to mind. Here is how I remember it (and the next few verses):
There is therefore now no condemnation for those who are in Christ Jesus. For the law of the Spirit of life in Christ Jesus has set us free from the law of sin and of death. For what the law could not do, weak as it was through the flesh, God did: sending his own son in the likeness of human flesh and (as an offering for) sin, he condemned sin in the flesh so that the righteous requirements of the law might be met in us, who do not walk according to the flesh but according to the Spirit.
Did I get it right? That should be Romans 8:1-4, NASB (biblegateway.com).

I wasn't always so excited about this passage. I mean, it's elementary, right? God sent Jesus his son so that our sins would be forgiven -- so we need not worry about meeting the requirements of the written code.

Elementary, yes, but that doesn't mean that it's boring. A couple of things happened in the decades since I read and memorized the passage (I see it's gotten rusty): one is I've become aware of more things in my soul that aren't right; the other -- well, maybe it's a subset of the first -- is that I see more clearly how much I need to be reminded of this very important truth. This morning I picked up The Message, where I read Peterson's paraphrase of this passage:

1-2With the arrival of Jesus, the Messiah, that fateful dilemma is resolved. Those who enter into Christ's being-here-for-us no longer have to live under a continuous, low-lying black cloud. A new power is in operation. The Spirit of life in Christ, like a strong wind, has magnificently cleared the air, freeing you from a fated lifetime of brutal tyranny at the hands of sin and death. more...
from Romans 8:1-4 MSG
Something I like about the Message is that it points even more emphatically at the end of chapter 7. The NIV and NASB both say "therefore", and there's a rule of Bible study that says when you see a "therefore", find out what it's there for. That alone should have told me to look at what came just before.

Yet seeing Peterson's words "With the arrival of Jesus, the Messiah, that fateful dilemma is resolved" really drove me to look back at Romans 7:25, which says Jesus "acted to set things right in this life of contradictions where I want to serve God with all my heart and mind, but am pulled by the influence of sin to do something totally different." (The Message)

Back to Romans 8:1-4, I also really like Peterson's reminder that spiritual transformation isn't a matter of "you suck, try harder." Here's the last paragraph, from Romans 8:3-4 (MSG):

The law always ended up being used as a Band-Aid on sin instead of a deep healing of it. And now what the law code asked for but we couldn't deliver is accomplished as we, instead of redoubling our own efforts, simply embrace what the Spirit is doing in us.
Romans 8:3-4, The Message (NIV here)
Indeed, it's not a matter of redoubling our efforts; did not the Lord himself say, "apart from me you can do nothing"? (John 15:5) Paul seems to think this is really important, too: "Don't be conformed to this world, but be transformed" (Romans 12:2); we're being transformed from glory to glory (2 Corinthians 3:18); the one who began a good work will complete it (Philippians 1:6); God himself will set us apart, sanctify us (1 Thessalonians 5:23-24).

And that sure sounds like good news to me.

Friday, January 07, 2011

Human being, or a human doing?

"... which is why we're called human beings, not human doings." That little sentence fragment came to mind when I read this from Thomas Merton the other night:
We are warmed by the fire, not by the smoke of the fire. We are carried over the sea by a ship, not by the wake of a ship. So too, what we are is to be sought in the invisible depths of our own being, not in our outward reflection in our own acts. We must find our real selves not in the froth stirred up by the impact of our being upon the beings around us, but in our own soul which is the principle of all our acts.
Merton, No Man Is an Island, p. 117
(chapter 7, Barnes & Noble 2003 edition)
Our pastor said the other day that the sickness of our time is that we are unaware of our souls and hence are unable to take proper care of them.

I think he's right about that. If my soul is what integrates everything in my life and makes it a life rather than a chaos of disparate drives, then having a healthy soul means that my mind, will, and emotions -- my professed beliefs and my actual desires -- will be aligned. I won't say one thing but actually wish another; what I "should want" would become what I actually want, and my "best self" would be what everyone around me sees every day.

Today's reality, of course, doesn't match that description -- in you or in me. David wrote, "Search me, O God, and know my heart; test me and know my anxious thoughts" (Psalm 139:23); his soul wasn't perfect, either, as shown by the adultery and murder he committed in 2 Samuel 11. Less dramatically, we can see David's internal conflict within Psalm 139 itself: after acknowledging that the Lord knows him (Ps. 139:1-6), he thinks about fleeing (139:7-11).

But it seems that our modern, high-tech world is so filled with distractions that most of us don't even know how conflicted we are -- toward God, toward our jobs, toward each other -- even toward ourselves. Fortunately, David shows us a step we can take: confess our needs and our anxious thoughts to God -- indeed, ask God to help us know what they are -- and determine to follow where He leads.

Monday, January 03, 2011

small-c cosmopolitan Low/No Fat Butternut Squash with Onion

This is pretty good; the ex-teenager made it tonight. When we started eating it, she said, "Oh, I forgot the olive oil."

"What?" I cried. "You mean this is low fat??"

It's almost a no-fat dish, actually. Here's how it's made.

  1. Preheat oven to 450°F.
  2. You're only going to use half of it, but you may as well microwave
    • one whole butternut squash
    about two minutes. (Now the other half will be easier to cut up.)
  3. Peel about half of said squash and cut it into 1" cubes; put the rest into the 'fridge.
  4. Cut up
    • a medium onion
    into not-too-small chunks. Maybe eighths as viewed from the poles, and cut at each tropic (24 chunks in all).
  5. Spread the onion and squash in a 9"x13" baking dish.
  6. Drizzle
    • about 2T molasses,
    • about 2T balsamic vinegar
    • about 3T soy sauce
    over the vegetables. These amounts aren't exact (no measuring utensil was used -- just mark-1 eyeball). The soy sauce came out a lot faster so maybe it was 4T?
  7. If you don't want low-fat, add some olive oil over all, but it's not needed. Really.
  8. Bake uncovered at 450°F about 20? minutes or until vegetables are tender and onion doesn't offend.
    • Stir it every 5 minutes or so while baking.
  9. Also optional: mix in
    • about 3T crushed pecans (walnuts would probably also work)
Should have taken a photo. I'm not sure about the timing, and I also don't know how it would affect the dish if you were to cover the baking dish.

Sunday, January 02, 2011

Jumble® and Python

So I was on the train the other day, looking at the daily jumble® in the paper (if you don't know how it works, have a look at their website). I had hit a mental block, trying to decode MUGPIN and only getting as far as "umping" (is it a verb, to "ump"?). I could have typed
$ grep '^......$' /usr/share/dict/words | grep m | grep u | grep g | 
    grep p | grep i | grep n
(which would give me a list of six-letter words in the system-supplied dictionary containing all the letters m,u,g,p,i,n) but I thought, "Hey, I have a little time; I should write a script." That way, rather than typing all those "grep"s, I could type the name of the script ("anagram", say) and the letters of interest (in this case mugpin).
For the impatient: →put your mouse here← to see the answer.
What did all those greps mean?

The first one, "grep '^......$' /usr/share/dict/words", selects lines containing six characters: ^ means beginning-of-line, . matches anything other than end-of-line, and $ matches end-of-line.

The | ("pipe" or vertical bar) means: take the output of the prior command, and feed it to the following command as its input.

The next six greps select lines containing one or more 'm's, one or more 'u's, etc. And it gives the right result, but it's icky having to type "grep" so many times.

How best to write a script for this? There is probably some nice way to get bash(1) to give me a list of letters in a word, but I didn't know what it was. Besides that, I'm trying to write more Python and less bash. It turns out that Python treats a string like a list -- even more so if you say "list('whatever')"
$ python
Python 2.6.5 (r265:79063, Jul  5 2010, 11:47:21) 
[GCC 4.5.0 20100604 [gcc-4_5-branch revision 160292]] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> list('whatever')
['w', 'h', 'a', 't', 'e', 'v', 'e', 'r']
>>> 
My thought was, grab the list of words from /usr/share/dict/words, select the ones of the right length; from those, select the ones that contain all the letters in the supplied word. An initial whack might look something like this:
#!/usr/bin/python -utt
import sys              # for argv

def main(aword):
    dictwords = [X.strip() for X in open('/usr/share/dict/words', 'r')]

    aword = aword.strip().lower()
    awordlen = len(aword)
    somewords = [X for X in dictwords if len(X) == awordlen]
    for aletter in list(aword):
        somewords = [X for X in somewords if aletter in X]
    print aword, somewords

if __name__ == '__main__':
    main(sys.argv[1])

OK, let me explain a little. First, the #! line -- that tells the computer (if you're on a Linux® or Unix™-like system) to run the Python interpreter; the "-utt" says to unbuffer output (I'm so impatient) and to treat tabs as illegal for indentation -- safety first.

Then comes "main", which does the work of this script, takes a single input parameter, the scrambled word in question ('mugpin' in this case). The first thing the script does is get the word-list from the system-supplied dictionary, /usr/share/dict/words (if that file doesn't exist on your system, then I don't know where to get a nice word list from). I've become a fan of list comprehensions (the line beginning dictwords = for example) because I can say a lot in just one line without having it look like too much magic: what this line does is open the dictionary and put the blank-stripped version of each line into the array dictwords.

The script unblanks and downshifts the supplied word (that's what aword.strip().lower() does); it then calculates the resulting length. Then comes another list comprehension: somewords = [X for X in dictwords if len(X) == awordlen] -- this basically takes all words in dictwords of a certain length (the length of aword) and stores this subset into somewords

The loop ("for aletter in list(aword)") further narrows somewords down to only those words in the dictionary that have the letters in the supplied parameter. Finally, main() prints the supplied parameter and the list of matching words.

About the last two lines -- I never (well, hardly ever) write a Python script that just starts running, because when you try to run them under pdb they just run; generally the main part of the script goes into a routine main(), which is called only if this script is the main one being run. The last line passes sys.argv[1] as main()'s one parameter. Now to run in a debugger, I can type this:

% python
Python 2.3.5 (#1, Jan 12 2009, 14:43:55) 
[GCC 3.3 20030304 (Apple Computer, Inc. build 1819)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import pdb
>>> import ana2
>>> ana2.main('umping')
umping ['impugn']
>>> 
The script was saved in a file "ana2.py", so "import ana2" brought it "into" the Python interpreter. Here I just ran it, and it worked (casting caution to the wind and all that). If I wanted to do something a little more careful, I could type:
>>> pdb.run('ana2.main("umping")')
> (1)?()
(Pdb) s
--Call--
> /Users/collin/ana2.py(4)main()
-> def main(aword):
(Pdb) n
> /Users/collin/ana2.py(5)main()
-> dictwords = [X.strip() for X in open('/usr/share/dict/words', 'r')]
(Pdb) n
> /Users/collin/ana2.py(7)main()
-> aword = aword.strip().lower()
(Pdb) c
umping ['impugn']
>>> 
Here I told the debugger to step into the routine I gave it, which it did -- gelling me I was at line 4 of ana2.py; I then said to go to the next statement, line 5 -- which puts the whitespace-stripped list of lines from the dictionary into dictwords, and then to just continue -- then it printed the word I couldn't figure out.

But this naive script doesn't work so well when multiple letters are involved. Consider this embarrassment:

% ./ana2.py account
account ['account', 'auction', 'caution', 'conatus', 'courant', 'outcant']
Oops! A word like "auction" includes some letters besides the original, but "outcant" contains all and only the letters from the original word. We have to do a little more.

The basic idea I came up with was to find the duplicate letters (there may be more than one, as in "balloon" or "lightning"), and look for multiple occurrences of those multiply-occurring letters. As far as finding multiple letters, there are lots of ways to do it; I just sorted the letters and then looked for multiples in adjacent letters. Since there are only 26 letters it might be more efficient to zero an array of letters and look for collisions, but this way seems to work.

While I was at it, I decided to make the input case-insensitive by forcing the input to lowercase. Also I allowed multiple words to be given on the command line. And I added a few comments. Here's the next version:

#!/usr/bin/python -utt
# vim:et:sw=4
'''Usage:
\t%PROG% {word...}

For each _word_ given, print a list of its anagrams found
in the words file, /usr/share/dict/words .
'''

import re
import sys

DEBUG = False
LETTERSONLY = re.compile('[a-z]*$')

__doc__ = __doc__.replace('%PROG%', sys.argv[0])

def usage():
    print "Usage:", sys.argv[0], "{word...}"
    sys.exit(1)

def main(wordlist):
    if len(wordlist) == 0:              # Nothing to do, so don't do it.
        usage()

    # Fetch the words from the system-supplied dictionary
    dictwords = [X.strip() for X in open('/usr/share/dict/words','r')]

    # Screen each _word_, then look for anagrams
    for aword in wordlist:
        aword = aword.strip().lower()
        if LETTERSONLY.match(aword) is None:
            print "%%% Words must consist only of letters:", aword
            continue

        # The overall plan is: find words from dictwords[] that have 
        # the same length as _word_, and have all its letters.
letters = list(aword) mylen = len(letters) letters.sort() # letters[] is the letters in _word_, in ascending alphabetical order. # Now look for duplicates. Without handling duplicates, one might # end up with "abalone" or "albinos" or "ballons" when the user # typed "balloon" prevlet = '' dups = dict() for alet in list(letters): if alet == prevlet: # It's a dup. letters.remove(alet) # remove the dup if alet in dups: dups[alet] += 1 # increase the count else: dups[alet] = 2 prevlet = alet if DEBUG: print "DEBUG: letters", letters print "DEBUG: dups", dups
# Find the words from the dictionary that have the same length somewords = [X for X in dictwords if len(X) == mylen] # ... and have all the letters in the supplied _word_ for alet in letters: somewords = [ X for X in somewords if alet in X ] if DEBUG: print "DEBUG:", len(somewords), "candidates:", somewords # ... and have enough copies of each duplicate letter for duplet,dupcount in dups.items(): patstr = '' for junk in range(dupcount): patstr += ('.*' + duplet) pat = re.compile(patstr) somewords = [X for X in somewords if pat.match(X)] if DEBUG: print "DEBUG: after matching", patstr, ':', somewords print aword + ':', somewords sys.exit(0) if __name__ == '__main__': main(sys.argv[1:])
What's with the text that looks like this? Well, as I was writing about "sort" above, I began to feel a little embarrassed about how un-pythonic the above version was, so I hacked it. This background color indicates text that I changed in the version you see below.

Final(?) version

This one is about 14 lines shorter and doesn't bother with sorting. Changed text is indicated with this background color.
#!/usr/bin/python -utt
# vim:et:sw=4
'''Usage:
\t%PROG% {word...}

For each _word_ given, print a list of its anagrams found
in the words file, /usr/share/dict/words .
'''

import re
import sys

DEBUG = False
LETTERSONLY = re.compile('[a-z]*$')

__doc__ = __doc__.replace('%PROG%', sys.argv[0])

def usage():
    print "Usage:", sys.argv[0], "{word...}"
    sys.exit(1)

def main(wordlist):
    if len(wordlist) == 0:              # Nothing to do, so don't do it.
        usage()

    # Fetch the words from the system-supplied dictionary
    dictwords = [X.strip() for X in open('/usr/share/dict/words','r')]

    # Screen each _word_, then look for anagrams
    for aword in wordlist:
        aword = aword.strip().lower()
        if LETTERSONLY.match(aword) is None:
            print "%%% Words must consist only of letters:", aword
            continue

        # The overall plan is: find words from dictwords[] that have 
        # the same length as _word_, and have all its letters.
mylen = len(aword) # Handle duplicates: _letters_ will map each letter to its count # e.g., for 'off', letters will have 'f':2, 'o':1 letters = dict() for alet in list(aword): letters[alet] = letters.get(alet,0) + 1
# Find the words from the dictionary that have the same length somewords = [X for X in dictwords if len(X) == mylen] # ... and have all the letters in the supplied _word_ for alet in letters: somewords = [ X for X in somewords if alet in X ] if DEBUG: print "DEBUG:", len(somewords), "candidates:", somewords # ... and have enough copies of each duplicate letter for duplet,dupcount in [X for X in letters.items() if X[1] > 1]: patstr = '' for junk in range(dupcount): patstr += ('.*' + duplet) pat = re.compile(patstr) somewords = [X for X in somewords if pat.match(X)] if DEBUG: print "DEBUG: after matching", patstr, ':', somewords print aword + ':', somewords sys.exit(0) if __name__ == '__main__': main(sys.argv[1:])
Call me (off)-white and nerdy, but that was fun!

Saturday, January 01, 2011

20% of peak internet traffic is Netflix streaming? And what about net neutrality?

This article on gizmodo.com says yes: "A recent study says that 20 percent of all downstream internet traffic during peak times in the US is Netflix streaming." The study quoted is here, and a 2009 report says that video-on-demand is about 27% of global internet traffic (never mind peak downstream bandwidth).

I'm no expert on network traffic, but this makes me wonder about net neutrality. I know the analogy isn't quite apt, but I think back to the old days, when one big expensive central processing unit served lots of users "simultaneously." In those days, one might imagine a very long process (a simulation of tomorrow's weather, for example) competing for CPU bandwidth with a very short process (an undergraduate programming assignment that typically would include an aborted compilation).

In those days, operating systems would tend to give short, interactive tasks a higher execution priority than long-running batch-oriented tasks. So if your weather simulation took many hours to run, you'd typically schedule a cheaper (yes, they used to charge users for computer time!) class of service -- you wanted to pay a low per-CPU-second rate -- that would nevertheless let your task use a lot of memory and CPU time, but would let other users (like the undergraduate who hasn't yet mastered the programming language's syntax, or the 72-character line length limit) slip in for a few seconds with quick turnaround.

Likewise, the undergraduates were given a class of service that would give them quick turnaround but with strict limits on how much they could use in the way of computing resources -- CPU-seconds, pages printed, memory, access to files stored on disk, etc.

But what do we do in this new world where during peak times, 20% of all downstream traffic is consumed by Netflix streaming? Is it reasonable that these bytes get the same treatment as the bytes of the short email I'm trying to send, or the blog post I'm trying to read?

Typically, interactive traffic used to involve small amounts of CPU time; lots of CPU time meant something that one knew was going to take a long time and hence didn't involve high "urgency." If we bring the analogy to today, where a big download (of, say, the OpenSUSE 11.3 DVD image) involves a lot of kbytes (not CPU-seconds), vs interactive traffic (when you click "recalculate total" on a merchant's website for example) which involves fewer kbytes but with more stringent latency requirements.

But when we're talking about interactive video (lots of kbytes with stringent latency requirements) or streaming movies (REALLY lots of kbytes, albeit with slightly less stringent latency issues -- that "buffering..." business), I have to say that if a network provider wanted to charge a higher rate for high-volume high-urgency service, that wouldn't seem all that unreasonable to me.

If it costs Netflix less than a dime to stream a two-hour HD movie (3 Gbytes), and it suddenly cost them more like a quarter to stream it -- vs what, 88 cents to ship a DVD to your house and for you to ship it back to them -- well, that wouldn't seem all that unreasonable either.

NOTE: I'm not in the employ of any network infrastructure outfits, nor have I received any bribes or fees for writing this. Nor am I a netflix hater.

Herod and Jesus -- Matthew 2

Matthew doesn't tell us a whole lot about the birth of Jesus -- "no room at the inn," the shepherds and angels -- all that comes from Luke. Matthew does, however, locate the birth of Jesus in space and time -- Jesus was born in Bethlehem, the city of David, during the reign of King Herod.

The next thing Matthew tells us is that Magi came from the east to Jerusalem. Why Jerusalem? They were looking for "the one who has been born king of the Jews" (Matthew 2:2), so naturally they went to the capital.

How many magi were there? Tradition says there were three, but I suppose there were several more. For one thing, consider a journey from present-day Iran to Jerusalem; these men would have had a long ways far from civilization. How large a party would you want to have, knowing that you might encounter bands of robbers? Not just three!

Then there's the matter of their political impact: King Herod meets with them and, Matthew tells us "he was disturbed, and all Jerusalem with him."

Question: How could three strangers from a foreign country shake up a whole city? To me it's more reasonable to suppose that a sizable contingent appeared; we're likely not talking about three wackos stirring up the entire city.

I find it really interesting to consider what Herod does. To find out where the king is to be born, Herod consults priests and legal scholars to ask them where the Christ (note that the magi refer to "born king of the Jews" and Herod equates this with "the Christ").

“In Bethlehem in Judea,” they replied, “for this is what the prophet has written:

“‘But you, Bethlehem, in the land of Judah, are by no means least among the rulers of Judah; for out of you will come a ruler who will be the shepherd of my people Israel.’”

Matthew 2:5-6, quoting Micah 5:2
Herod heard the name of the city but didn't pay enough attention to the rest of the quote. He apparently thought the prophet said about Bethlehem, "out of you will come forth somebody who will get killed before he can become a ruler to shepherd my people Israel."

How silly! How could he think God would get the city right but not the arc of Messiah's life? This guy had some real listening comprehension problems. He reminds me of a lot of other silly people we read about in the Bible, people who apparently never read any Greek tragedies. They think they can outsmart God.

As our pastor said, if we're going to say "Jesus is Lord" we also have to say "Jesus is smart" and that he really does know what he's saying. (By the way, quite a bit of this essay I owe to Pastor John.) Which means that it's best for me to do absolutely everything he says. Which I don't (as 'fessed up here among other places). Which is a way to say Herod also reminds me of me. Not a happy thought.

A recent sermon points out that the phrase "King Herod" is used only in verses 1 and 3; afterwards (seven more times in Matthew 2) he's referred to as simply "Herod"; "Then Herod called" (v.7), "not to go back to Herod" (v.12), "for Herod is going to search for the child" (v.13), etc. It's as if, once he decided to try to kill Messiah, Matthew no longer recognizes Herod as king; he's simply "Herod." Historians call him "Herod the Great" but really he's just Herod the silly.

Back to the Magi for a moment. That the star could lead them to a particular house in Bethlehem (Matthew 2:9-11) suggests to me that the "star" was something in the atmosphere, as even a planetary conjunction would be way too far away to indicate a village, let alone a particular house. They bring Jesus gifts: gold, incense and myrrh. As I understand it, the gifts correspond to the fact that Jesus is king (gold) and God (incense) and sacrifice (myrrh).

The Magi return home by another way and Herod goes bonkers, ordering his troops to kill all boys 2 years old and under in Bethlehem and the surrounding area. Why two years old and under? The Magi told Herod the exact time the star appeared (Matthew 2:7) and Herod could do arithmetic. Exactly how old was Jesus at this time? Well, the Magi saw "the child" rather than "the newborn" -- so probably they didn't come the same night as the shepherds. Luke tells us (Luke 2:39) that Joseph and Mary did everything required by the Law, which means they hung around Bethlehem/Jerusalem forty days at least. Luke doesn't mention the flight to Egypt (Matthew 2:13-14), and I don't know how precise Luke is being when he tells us that they returned (via Egypt maybe?) "when" they had done everything required by the Law. Anyway, Herod's order probably caused (where did I read this?) about two dozen boys to be killed -- Bethlehem was a small village, and even the surrounding area wouldn't include a whole lot of people.

A final note on the phrase "during the time of King Herod" -- this doesn't just refer to the time; it's like "during the McCarthy era" or "the Stalin years" -- it means a particularly dark time. Which it was.

I really recommend the sermon referred to above, particularly if your Christmas wasn't particularly merry.