<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>goodmami.org</title>
	<atom:link href="http://www.goodmami.org/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.goodmami.org</link>
	<description>Homepage of Michael Wayne Goodman, student of computational linguistics at the University of Washington</description>
	<lastBuildDate>Fri, 29 Mar 2013 20:11:49 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Python One-Liner: Getting Only the First Match in a List Comprehension</title>
		<link>http://www.goodmami.org/2013/01/python-one-liner-getting-only-the-first-match-in-a-list-comprehension/</link>
		<comments>http://www.goodmami.org/2013/01/python-one-liner-getting-only-the-first-match-in-a-list-comprehension/#comments</comments>
		<pubDate>Wed, 30 Jan 2013 20:04:02 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[one-liner]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=133</guid>
		<description><![CDATA[Python&#8217;s list comprehensions are great, but I&#8217;ve found a new (to me) use of them: iterating over a list and returning the first match when there might be multiple possible matches. (To be more accurate, my solution uses a generator expression rather than a list comprehension) In other words, I&#8217;m emulating a break statement in [...]]]></description>
			<content:encoded><![CDATA[<p>Python&#8217;s list comprehensions are great, but I&#8217;ve found a new (to me) use of them: iterating over a list and returning the first match when there might be multiple possible matches. (To be more accurate, my solution uses a generator expression rather than a list comprehension)</p>
<p>In other words, I&#8217;m emulating a <tt>break</tt> statement in the loop, but only for the first match. In code, that is:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">val <span style="color: #66cc66;">=</span> <span style="color: #008000;">None</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> some_list:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> match<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; val <span style="color: #66cc66;">=</span> x<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">break</span></div></td></tr></tbody></table></div>
<p>I could do this with a list comprension and getting the element at index 0:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">val <span style="color: #66cc66;">=</span> <span style="color: black;">&#91;</span>x <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> some_list <span style="color: #ff7700;font-weight:bold;">if</span> match<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span></div></td></tr></tbody></table></div>
<p>&#8230;but that means the whole list is created, and what if the list is large and/or the match() function is expensive? I&#8217;d really like to just stop looping when I&#8217;ve got a match. Generator expressions come in handy here:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">val <span style="color: #66cc66;">=</span> <span style="color: black;">&#40;</span>x <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> some_list <span style="color: #ff7700;font-weight:bold;">if</span> match<span style="color: black;">&#40;</span>x<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>.<span style="color: black;">next</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Also note that in Python3, functions like <tt>filter()</tt> return an iterator (which may have a generator under the hood, I&#8217;m not sure), so this is possible:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">val <span style="color: #66cc66;">=</span> next<span style="color: black;">&#40;</span><span style="color: #008000;">filter</span><span style="color: black;">&#40;</span>match<span style="color: #66cc66;">,</span> some_list<span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>Now I&#8217;ve got the first matching value, and I don&#8217;t have to match against every item in the list. Hooray for functional Python</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2013/01/python-one-liner-getting-only-the-first-match-in-a-list-comprehension/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>RTSP Stream Dumping with VLC</title>
		<link>http://www.goodmami.org/2013/01/rtsp-stream-dumping-with-vlc/</link>
		<comments>http://www.goodmami.org/2013/01/rtsp-stream-dumping-with-vlc/#comments</comments>
		<pubDate>Mon, 21 Jan 2013 08:43:21 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[streaming]]></category>
		<category><![CDATA[VLC]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=125</guid>
		<description><![CDATA[I&#8217;m taking a language class at my university, and there are sound files online that we use for our homework. The sound files are streamable through some embedded Quicktime player, without the option for a direct download. So I just need to install some Quicktime plugin for my browse&#8211;screw that, I&#8217;m gonna find a way [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m taking a language class at my university, and there are sound files online that we use for our homework. The sound files are streamable through some embedded Quicktime player, without the option for a direct download. So I just need to install some Quicktime plugin for my browse&#8211;screw that, I&#8217;m gonna find a way to download the files.</p>
<p>So the URL for the page I can stream files from looks like this:</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://.../chinese/CHI_030/index_textbook.php</div></td></tr></tbody></table></div>
<p>So I tried removing the &#8220;index_textbook.php&#8221; part, and luckily they didn&#8217;t block me from getting a directory listing. I see there&#8217;s a &#8220;mov/&#8221; subdirectory, so I go there, and voila! all the files right in front of me. But why are they .mov files? Aren&#8217;t they supposed to be audio files? I download one and try opening it. Each time I open it, it has to buffer for a few seconds. Moreover, the file is only 84 bytes. Ah, so the .mov file is probably just a container with a reference to some network resource. I open it to find out:</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">rtsptext rtsp://.../chinese//CHI_030/mov/CHI_030_018.mov</div></td></tr></tbody></table></div>
<p>Yep, that was it. But what is RTSP? Just some <a href="http://en.wikipedia.org/wiki/Real_Time_Streaming_Protocol">streaming protocol</a>; nothing interesting. Now how do I get the actual audio data? Here&#8217;s where <a href="http://www.videolan.org/index.html">VLC</a> comes to the rescue. I look up some <a href="http://wiki.videolan.org/Documentation:Streaming_HowTo/Receive_and_Save_a_Stream#Save_a_stream_with_VLC">documentation on dumping streams</a>. Let&#8217;s try a simple command (note, the &#8220;vlc://quit&#8221; at the end makes sure it terminates when it&#8217;s done, otherwise it will hang, waiting for more input):</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cvlc rtsp://.../chinese//CHI_030/mov/CHI_030_018.mov --sout=file/mov:test.mov vlc://quit</div></td></tr></tbody></table></div>
<p>(a few minutes later)</p>
<p>And there it is, an audio file! The first time I got a file with lots of skips and gaps, so be sure that you dump the stream as it is stored, and transcode later. In this case, the file was an mp4 audio file wrapped in a mov container. If that wasn&#8217;t the problem, try running the command again and make sure nothing else on your computer is using a lot of bandwidth.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2013/01/rtsp-stream-dumping-with-vlc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Time/date conversion at the command line</title>
		<link>http://www.goodmami.org/2012/08/timedate-conversion-at-the-command-line/</link>
		<comments>http://www.goodmami.org/2012/08/timedate-conversion-at-the-command-line/#comments</comments>
		<pubDate>Mon, 27 Aug 2012 08:50:07 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=118</guid>
		<description><![CDATA[When I didn&#8217;t trust my mental ability to convert dates and times, I relied on online tools like http://worldtimeserver.org/, but this task can easily be done from the command line (and without an internet connection). For instance, I am now in Taipei, and I want to know what time it will be here when it [...]]]></description>
			<content:encoded><![CDATA[<p>When I didn&#8217;t trust my mental ability to convert dates and times, I relied on online tools like <a href="http://worldtimeserver.org/">http://worldtimeserver.org/</a>, but this task can easily be done from the command line (and without an internet connection). For instance, I am now in Taipei, and I want to know what time it will be here when it is 4:30pm in Pacific time. A quick search <a href="http://superuser.com/questions/164339/timezone-conversion-by-command-line">revealed</a> the following use of the `date` command:</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">date --date='TZ=&quot;America/Los_Angeles&quot; 2012-9-17 16:30'<br />
Tue Sep 18 07:30:00 CST 2012</div></td></tr></tbody></table></div>
<p>Using the date, it will also consider daylight saving&#8217;s time. Compare it with:</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">date --date='TZ=&quot;America/Los_Angeles&quot; 2012-12-17 16:30'<br />
Tue Dec 18 08:30:00 CST 2012</div></td></tr></tbody></table></div>
<p>Now I see there is an example if the man-documentation of `date`, along with other options.</p>
<p>[UPDATE]</p>
<p>The above only converts from some other timezone to the one your shell is set to. If you want to go the other way around, you need to <a href="http://unix.stackexchange.com/questions/48101/how-can-i-have-date-output-the-time-from-a-different-timezone">change the timezone</a> (temporarily) when the command is run. For example, if you are in the Pacific timezone and want to convert a time to Singapore time, do the following (all on one line):</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">TZ=&quot;:Singapore&quot; date --date='TZ=&quot;America/Los_Angeles&quot; 2013-04-02 16:30'</div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/08/timedate-conversion-at-the-command-line/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Background section complete-ish.</title>
		<link>http://www.goodmami.org/2012/03/background-section-complete-ish/</link>
		<comments>http://www.goodmami.org/2012/03/background-section-complete-ish/#comments</comments>
		<pubDate>Thu, 01 Mar 2012 20:28:34 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=111</guid>
		<description><![CDATA[I think the draft of the background section of my morphology paper is complete. One thing that is absent is a review of position class morphology, but it may not be necessary. I also have a comment in the .tex file to review the Paradigm Function Morphology section for explanation received in Paris two summers [...]]]></description>
			<content:encoded><![CDATA[<p>I think the draft of the background section of my morphology paper is complete. One thing that is absent is a review of position class morphology, but it may not be necessary. I also have a comment in the .tex file to review the Paradigm Function Morphology section for explanation received in Paris two summers ago, but I don&#8217;t recall what that explanation was.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/03/background-section-complete-ish/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Accumulating dictionaries in Python</title>
		<link>http://www.goodmami.org/2012/02/accumulating-dictionaries-in-python/</link>
		<comments>http://www.goodmami.org/2012/02/accumulating-dictionaries-in-python/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 07:57:46 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[counting]]></category>
		<category><![CDATA[dictionaries]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=106</guid>
		<description><![CDATA[I often have a need to count tokens in a corpus. In Python, there are many ways to do this, but currently I most often use defaultdicts: 123d = defaultdict&#40;int&#41; for x in sequence: &#160; d&#91;x&#93; += 1 I would like to get rid of the for-loop and construct such a dictionary at once. I [...]]]></description>
			<content:encoded><![CDATA[<p>I often have a need to count tokens in a corpus. In Python, there are many ways to do this, but currently I most often use defaultdicts:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">d <span style="color: #66cc66;">=</span> defaultdict<span style="color: black;">&#40;</span><span style="color: #008000;">int</span><span style="color: black;">&#41;</span><br />
<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> sequence:<br />
&nbsp; d<span style="color: black;">&#91;</span>x<span style="color: black;">&#93;</span> +<span style="color: #66cc66;">=</span> <span style="color: #ff4500;">1</span></div></td></tr></tbody></table></div>
<p>I would like to get rid of the for-loop and construct such a dictionary at once. I wrote a dict-derived class to do that, but it can do even more. But first, here is how I would do the above:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">d <span style="color: #66cc66;">=</span> AccumulationDict<span style="color: black;">&#40;</span><span style="color: #ff7700;font-weight:bold;">lambda</span> x<span style="color: #66cc66;">,</span> y: x + y<span style="color: #66cc66;">,</span> <span style="color: black;">&#91;</span><span style="color: black;">&#40;</span>x<span style="color: #66cc66;">,</span> <span style="color: #ff4500;">1</span><span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> sequence<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
<p>That&#8217;s it!</p>
<p>Notice how it takes a function as its first parameter. This is similar to how defaultdict takes a callable, but instead of taking a 0-arity callable, AccumulationDict takes a binary function. Whenever it &#8220;accumulates&#8221; a key-value for a key that already exists, the existing value and new value are sent to this function, and the result is what is set as the new value in the dictionary. This function will most likely be addition (rather than the lambda expression one could use operator.add), but it could be anything. Say you&#8217;re calculating probabilities of multiple events, you could use operator.mul.</p>
<p>I did not want to break KeyErrors, so accumulating is separate from getting and setting. This means you can still use __setitem__() and update() to reset the values of keys. Accumulation happens in the constructor, in dictionary addition, and with a new accumulate() function. accumulate() is identical to update() in interface, but uses the provided accumulator function to &#8220;merge&#8221; values when there are key collisions.</p>
<p>The code is below, but it represents a proof-of-concept and could be improved:</p>
<div class="codecolorer-container python railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br /></div></td><td><div class="python codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #ff7700;font-weight:bold;">class</span> AccumulationDict<span style="color: black;">&#40;</span><span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> accumulator<span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #008000;">hasattr</span><span style="color: black;">&#40;</span>accumulator<span style="color: #66cc66;">,</span> <span style="color: #483d8b;">'__call__'</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Accumulator must be a binary function.'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">accumulator</span> <span style="color: #66cc66;">=</span> accumulator<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">accumulate</span><span style="color: black;">&#40;</span>*args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span><br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> __additem__<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> key <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> <span style="color: #008000;">self</span>.<span style="color: black;">accumulator</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span><span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span><span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span> <span style="color: #66cc66;">=</span> value<br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__add__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> other<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; result <span style="color: #66cc66;">=</span> AccumulationDict<span style="color: black;">&#40;</span><span style="color: #008000;">self</span>.<span style="color: black;">accumulator</span><span style="color: #66cc66;">,</span> <span style="color: #008000;">self</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; result.<span style="color: black;">accumulate</span><span style="color: black;">&#40;</span>other<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">return</span> result<br />
<br />
&nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">def</span> accumulate<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: #66cc66;">,</span> *args<span style="color: #66cc66;">,</span> **kwargs<span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> arg <span style="color: #ff7700;font-weight:bold;">in</span> args:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>arg<span style="color: #66cc66;">,</span> <span style="color: #008000;">list</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> arg:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.__additem__<span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">elif</span> <span style="color: #008000;">isinstance</span><span style="color: black;">&#40;</span>arg<span style="color: #66cc66;">,</span> <span style="color: #008000;">dict</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> <span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span> <span style="color: #ff7700;font-weight:bold;">in</span> arg.<span style="color: black;">items</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.__additem__<span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> value<span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">else</span>:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">TypeError</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">'Argument must be of type list or dict.'</span><span style="color: black;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> key <span style="color: #ff7700;font-weight:bold;">in</span> kwargs:<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.__additem__<span style="color: black;">&#40;</span>key<span style="color: #66cc66;">,</span> kwargs<span style="color: black;">&#91;</span>key<span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div></td></tr></tbody></table></div>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/02/accumulating-dictionaries-in-python/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Hulden and Bischoff, similar implementation</title>
		<link>http://www.goodmami.org/2012/02/hulden-and-bischoff-similar-implementation/</link>
		<comments>http://www.goodmami.org/2012/02/hulden-and-bischoff-similar-implementation/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 23:25:57 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>
		<category><![CDATA[morphology]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=102</guid>
		<description><![CDATA[I just came across a paper for doing non-concatenative morphology with an implementation remarkably similar to my own. This paper by Mans Hulden and Shannon Bischoff uses unification of three different morphotactic constraints (unification, exclusion, coercion) in lexical rules to deal with co-occurrence restrictions and 4 different operators for modelling morpheme ordering (precedes, immediately precedes, [...]]]></description>
			<content:encoded><![CDATA[<p>I just came across a paper for doing non-concatenative morphology with an implementation remarkably similar to my own. <a href="http://dialnet.unirioja.es/servlet/articulo?codigo=2675984">This paper</a> by Mans Hulden and Shannon Bischoff uses unification of three different morphotactic constraints (unification, exclusion, coercion) in lexical rules to deal with co-occurrence restrictions and 4 different operators for modelling morpheme ordering (precedes, immediately precedes, follows, immediately follows).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/02/hulden-and-bischoff-similar-implementation/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Koskenniemi&#8217;s Two-Level Morphology</title>
		<link>http://www.goodmami.org/2012/01/koskenniemis-two-level-morphology/</link>
		<comments>http://www.goodmami.org/2012/01/koskenniemis-two-level-morphology/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 08:51:21 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>
		<category><![CDATA[morphology]]></category>
		<category><![CDATA[review]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=95</guid>
		<description><![CDATA[I just read what appears to be Koskenniemi&#8217;s most cited article on Two-Level Morphology, and now I am reviewing my understanding before writing a summary in my paper. When Kimmo Koskenniemi worked out two-level morphology, generative phonology via context-sensitive rewrite rules were the common way of describing morphological systems. These kinds of rules were fairly [...]]]></description>
			<content:encoded><![CDATA[<p>I just read what appears to be Koskenniemi&#8217;s <a href="http://dl.acm.org/citation.cfm?id=980529">most cited article</a> on <a href="http://www.ling.helsinki.fi/~koskenni/esslli-2001-karttunen/">Two-Level Morphology</a>, and now I am reviewing my understanding before writing a summary in my paper.</p>
<p>When Kimmo Koskenniemi worked out two-level morphology, generative phonology via context-sensitive rewrite rules were the common way of describing morphological systems. These kinds of rules were fairly expressive in generating surface forms from lexical forms, but were nearly useless in lexical analysis, and furthermore were computationally expensive. <a href="http://en.scientificcommons.org/3718887">Johnson 1972</a>, and later Kay and Kaplan in &#8220;Phonological Rules and Finite-State Transducers&#8221;, 1981, showed that these rules were insufficient and proposed finite-state transducers as cascading rules applied to lexical forms, and further that the sequence of FSTs could be collapsed to a single, very-expressive (and large) FST. In this context, Koskenniemi&#8217;s proposed a two-level system where smaller FSTs were applied in parallel instead of in sequence.</p>
<p>Aside from the computationally tractable benefits of two-level morphology, from what I could tell it only addresses the morphophonological changes to a lexical item. For instance, it may define a rule that inserts an e after a consonate-y sequence and before a (morpheme-boundary)-s sequence (as in the English plural &#8220;spy&#8221; -> &#8220;spies&#8221;; a separate rule handles the y->i conversion):</p>
<div class="codecolorer-container text railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">C y 0 + s<br />
| | | | |<br />
_ _ e _ _</div></td></tr></tbody></table></div>
<p>I don&#8217;t see how the &#8220;spy0+s&#8221; lexical form gets created, but the generality of +s being plural for all inflectional patterns is convenient. Also, I don&#8217;t see how long distance restrictions are modeled, as the rules appear to be limited to immediately-adjacent contexts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/01/koskenniemis-two-level-morphology/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Morphology paper: AVM problem fixed, no new text yet</title>
		<link>http://www.goodmami.org/2012/01/morphology-paper-avm-problem-fixed-no-new-text-yet/</link>
		<comments>http://www.goodmami.org/2012/01/morphology-paper-avm-problem-fixed-no-new-text-yet/#comments</comments>
		<pubDate>Fri, 20 Jan 2012 07:01:09 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=87</guid>
		<description><![CDATA[I fixed the problem I was having with avm.sty. It turned out I had some avm environments using an older style of notation which no longer worked with the 1.02 version of avm.sty. The whole document now compiles with xelatex. I also found some articles by Koskenniemi (here and here) and Karttunen, Kaplan, Zaenen (here), [...]]]></description>
			<content:encoded><![CDATA[<p>I fixed the problem I was having with avm.sty. It turned out I had some avm environments using an older style of notation which no longer worked with the 1.02 version of avm.sty. The whole document now compiles with xelatex.</p>
<p>I also found some articles by Koskenniemi (<a href="http://mnd.ly/zRv7Q4">here</a> and <a href="http://mnd.ly/Ax3umx">here</a>) and Karttunen, Kaplan, Zaenen (<a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.27.9455">here</a>), but I haven&#8217;t yet read or written about them.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/01/morphology-paper-avm-problem-fixed-no-new-text-yet/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Morphology paper update</title>
		<link>http://www.goodmami.org/2012/01/morphology-paper-update/</link>
		<comments>http://www.goodmami.org/2012/01/morphology-paper-update/#comments</comments>
		<pubDate>Thu, 19 Jan 2012 02:45:52 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[phd-updates]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=81</guid>
		<description><![CDATA[Getting back into the general&#8217;s paper on morphology, I found that xelatex failed to compile it with the avm environment (using the 2006 version of avm.sty). So my current goals for the paper are: to compile the whole thing (after uncommenting the avms) do some reading, then write the background/previous-work section Koskenniemi&#8217;s 2-level automata Beesly [...]]]></description>
			<content:encoded><![CDATA[<p>Getting back into the general&#8217;s paper on morphology, I found that xelatex failed to compile it with the avm environment (using the 2006 version of avm.sty). So my current goals for the paper are:</p>
<ul>
<li>to compile the whole thing (after uncommenting the avms)</li>
<li>do some reading, then write the background/previous-work section</li>
<ul>
<li>Koskenniemi&#8217;s 2-level automata</li>
<li>Beesly and Karttunen&#8217;s flag diacritics</li>
</ul>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2012/01/morphology-paper-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple logging in Bash scripts</title>
		<link>http://www.goodmami.org/2011/07/simple-logging-in-bash-scripts/</link>
		<comments>http://www.goodmami.org/2011/07/simple-logging-in-bash-scripts/#comments</comments>
		<pubDate>Mon, 04 Jul 2011 21:53:04 +0000</pubDate>
		<dc:creator>goodmami</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[Bash]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[script]]></category>

		<guid isPermaLink="false">http://www.goodmami.org/?p=62</guid>
		<description><![CDATA[I couldn&#8217;t find much mention of logging utilities for Linux shell scripting (namely Bash), so I wrote my own fairly quickly. I wanted several functions for various levels of logging (info, debug, warning, errors, etc), and a way to adjust what levels can be displayed. I followed the fairly standard convention of using numeric values [...]]]></description>
			<content:encoded><![CDATA[<p>I couldn&#8217;t find much mention of logging utilities for Linux shell scripting (namely Bash), so I wrote my own fairly quickly. I wanted several functions for various levels of logging (info, debug, warning, errors, etc), and a way to adjust what levels can be displayed. I followed the fairly standard convention of using numeric values for these levels and setting a &#8220;verbosity&#8221; level. If you know of an existing solution for Bash, let me know in the comments. Anyway, here&#8217;s the main idea:</p>
<div class="codecolorer-container bash railscasts" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br /></div></td><td><div class="bash codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #7a0874; font-weight: bold;">exec</span> <span style="color: #000000;">3</span><span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">2</span> <span style="color: #666666; font-style: italic;"># logging stream (file descriptor 3) defaults to STDERR</span><br />
<span style="color: #007800;">verbosity</span>=<span style="color: #000000;">2</span> <span style="color: #666666; font-style: italic;"># default to show warnings</span><br />
<span style="color: #007800;">silent_lvl</span>=<span style="color: #000000;">0</span><br />
<span style="color: #007800;">err_lvl</span>=<span style="color: #000000;">1</span><br />
<span style="color: #007800;">wrn_lvl</span>=<span style="color: #000000;">2</span><br />
<span style="color: #007800;">inf_lvl</span>=<span style="color: #000000;">3</span><br />
<span style="color: #007800;">dbg_lvl</span>=<span style="color: #000000;">4</span><br />
<br />
notify<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$silent_lvl</span> <span style="color: #ff0000;">&quot;NOTE: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #666666; font-style: italic;"># Always prints</span><br />
error<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$err_lvl</span> <span style="color: #ff0000;">&quot;ERROR: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
warn<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$wrn_lvl</span> <span style="color: #ff0000;">&quot;WARNING: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
inf<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$inf_lvl</span> <span style="color: #ff0000;">&quot;INFO: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span> <span style="color: #666666; font-style: italic;"># &quot;info&quot; is already a command</span><br />
debug<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span> log <span style="color: #007800;">$dbg_lvl</span> <span style="color: #ff0000;">&quot;DEBUG: $1&quot;</span>; <span style="color: #7a0874; font-weight: bold;">&#125;</span><br />
log<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #007800;">$verbosity</span> <span style="color: #660033;">-ge</span> <span style="color: #007800;">$1</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>; <span style="color: #000000; font-weight: bold;">then</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># Expand escaped characters, wrap at 70 chars, indent wrapped lines</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;$2&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> fold <span style="color: #660033;">-w70</span> <span style="color: #660033;">-s</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'2~1s/^/ &nbsp;/'</span> <span style="color: #000000; font-weight: bold;">&gt;&amp;</span><span style="color: #000000;">3</span><br />
&nbsp; &nbsp; <span style="color: #000000; font-weight: bold;">fi</span><br />
<span style="color: #7a0874; font-weight: bold;">&#125;</span></div></td></tr></tbody></table></div>
<p>I added line wrapping and indenting so users don&#8217;t have to manually put in line-breaks to get nicer looking outputs, but there is the drawback that it makes the output harder to grep. Perhaps I should add an option to disable the line wrapping.</p>
<p><a href="http://goodmami.org/files/logging.bash">Here</a> is a longer example with some simple option parsing (apologies for using getopt; I&#8217;m currently looking for a better solution).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.goodmami.org/2011/07/simple-logging-in-bash-scripts/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
