<?xml version="1.0"?>
<News hasArchived="true" page="8883" pageCount="10801" pageSize="10" timestamp="Wed, 09 Sep 2026 16:15:49 -0400" url="https://my3.my.umbc.edu/posts.xml?mode=activity&amp;page=8883&amp;range=30">
<NewsItem contentIssues="false" id="30037" important="false" status="posted" url="https://my3.my.umbc.edu/posts/30037">
<Title>A New Computer Screen Reaches Out to Touch You</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p>An experimental new touch screen, the Obake, has a stretchable surface that to reacts user interaction in new ways.</p>
    <p>An inexpensive new prototype device called the <a href="http://dhairyadand.com/sec/?page=projects&amp;id=obake" rel="nofollow external" class="bo">Obake</a> adds a new dimension to touch screen technology. The surface of the device, developed by <a href="http://dhairyadand.com/" rel="nofollow external" class="bo">Dhairya Dand</a> and <a href="http://robhemsley.co.uk" rel="nofollow external" class="bo">Rob Hemsley</a><span> </span>of the MIT Media Lab, can react to how it’s being used by reaching out toward the user. It was relatively simple to make: the researchers used an <a href="http://www.openframeworks.cc/" rel="nofollow external" class="bo">open source software framework</a> to enable the screen to react; the hardware costs between $50 and $60, Dand says.</p>
    </div>
]]>
</Body>
<Summary>An experimental new touch screen, the Obake, has a stretchable surface that to reacts user interaction in new ways.  An inexpensive new prototype device called the Obake adds a new dimension to...</Summary>
<Website>http://www.technologyreview.com/view/514261/a-new-computer-screen-reaches-out-to-touch-you/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/30037/guest@my.umbc.edu/e4a192e2d8ee7f698d42e83641f4f6c3/api/pixel</TrackingUrl>
<Tag>development</Tag>
<Tag>internet</Tag>
<Tag>mit</Tag>
<Tag>technology</Tag>
<Tag>web</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 17:29:34 -0400</PostedAt>
</NewsItem>

<NewsItem contentIssues="false" id="110184" important="false" status="posted" url="https://my3.my.umbc.edu/posts/110184">
<Title>Hilltop&#8217;s Michael T. Abrams Presents Health Care and Health Policy Reseach</Title>
<Body>
<![CDATA[
    <div class="html-content">Hilltop Institute Senior Research Analyst Michael T. Abrams, MPH, presented his work on substance use disorder (SUD) treatment to the Maryland Addictions Directors Council on on March 11, 2013. The work focuses on coordination of care and cost saving opportunities evident in the federal Affordable Care Act, and traceable within Maryland’s Medicaid program. On April 10, 2013, Abrams presented a description of three UMBC-centered research projects examining supported employment for persons with serious mental illness at the Behavioral Health Research Conference. The University of Maryland Department of Psychiatry and Maryland Mental Hygiene Administration sponsored the conference. The audience included statewide …</div>
]]>
</Body>
<Summary>Hilltop Institute Senior Research Analyst Michael T. Abrams, MPH, presented his work on substance use disorder (SUD) treatment to the Maryland Addictions Directors Council on on March 11, 2013....</Summary>
<Website>https://news.umbc.edu/hilltops-michael-t-abrams-presents-health-care-and-health-policy-reseach/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/110184/guest@my.umbc.edu/cba06af584ee2f9d36f49eb6b164d8bd/api/pixel</TrackingUrl>
<Tag>hilltopinstitute</Tag>
<Tag>policy-and-society</Tag>
<Group token="umbc-news">UMBC News</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/umbc-news</GroupUrl>
<AvatarUrl>https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xsmall.png?1632921809</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/original.png?1632921809</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xxlarge.png?1632921809</AvatarUrl>
<AvatarUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xlarge.png?1632921809</AvatarUrl>
<AvatarUrl size="large">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/large.png?1632921809</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/medium.png?1632921809</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/small.png?1632921809</AvatarUrl>
<AvatarUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xsmall.png?1632921809</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/001/944/2c79aeea85b1abb37f8cf9fbcdc382b0/xxsmall.png?1632921809</AvatarUrl>
<Sponsor>UMBC News</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 16:09:39 -0400</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="123340" important="false" status="posted" url="https://my3.my.umbc.edu/posts/123340">
<Title>First Works (5/3)</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <p><img alt="" src="http://www.umbc.edu/newsevents/arts/hi-res/dance/fds2005/pic23.jpg" width="286" height="190" style="max-width: 100%; height: auto;">Join the Department of Dance, Friday, May 3 at 8:00 p.m. in Studio 317 of the Fine Arts Building, as Dance students debut their first ever choreographic pieces for this First Works concert.</p>
    <p>Admission to First Works is free.</p>
    </div>
]]>
</Body>
<Summary>Join the Department of Dance, Friday, May 3 at 8:00 p.m. in Studio 317 of the Fine Arts Building, as Dance students debut their first ever choreographic pieces for this First Works concert....</Summary>
<Website>https://umbc.edu/stories/first-works-53/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/123340/guest@my.umbc.edu/ee84da297bebc63d1e6779263d83face/api/pixel</TrackingUrl>
<Tag>cahss</Tag>
<Tag>dance</Tag>
<Tag>policy-and-society</Tag>
<Tag>visualarts</Tag>
<Group token="umbc-news-magazine">UMBC News &amp;amp; Magazine</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/umbc-news-magazine</GroupUrl>
<AvatarUrl>https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="original">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/original.png?1748556657</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xlarge.png?1748556657</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/large.png?1748556657</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/medium.png?1748556657</AvatarUrl>
<AvatarUrl size="small">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/small.png?1748556657</AvatarUrl>
<AvatarUrl size="xsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xsmall.png?1748556657</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/001/943/24435aa6207c452e7bc15cc74b42c7bb/xxsmall.png?1748556657</AvatarUrl>
<Sponsor>UMBC News &amp; Magazine</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 16:00:30 -0400</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="28334" important="false" status="posted" url="https://my3.my.umbc.edu/posts/28334">
<Title>MIT Delivers 1000 Tablets to Ethiopian Children</Title>
<Tagline>With no instructions. In 5 months, taught themselves English</Tagline>
<Body>
<![CDATA[
    <div class="html-content">MIT's One Laptop per Child Program (OLPC) decided to deliver boxes of tablets to two illiterate villages in Ethiopia, taped shut, with no instructions whatsoever. <br><br><img src="http://www.dvice.com/sites/dvice/files/styles/blog_post_media/public/images/ethiopia-tablet-kids.jpg" alt="" height="365" width="550" style="max-width: 100%; height: auto;"><br><em><br>(<em><strong>from dvice.com</strong></em></em>)<em><br><br>"<em><em><em>We left the boxes in the village. Closed. Taped shut. No 
    instruction, no human being. I thought, the kids will play with the 
    boxes! Within four minutes, one kid not only opened the box, but found 
    the on/off switch. He'd never seen</em></em> an on/off switch. He powered
     it up. Within five days, they were using 47 apps per child per day. 
    Within two weeks, they were singing ABC songs [in English] in the 
    village. And within five months, they had hacked Android. Some idiot in 
    our organization or in the Media Lab had disabled the camera! And they 
    figured out it had a camera, and they hacked Android</em>."</em> -<strong> OLPC founder Nicholas Negroponte at MIT Technology Review's EmTech conference <br><br></strong>Check out the rest of the story and let us know what you think! Are kids in developed areas of the world today getting less and less inquisitive? <br>
    </div>
]]>
</Body>
<Summary>MIT's One Laptop per Child Program (OLPC) decided to deliver boxes of tablets to two illiterate villages in Ethiopia, taped shut, with no instructions whatsoever.     (from dvice.com)  "We left...</Summary>
<Website>http://www.dvice.com/archives/2012/10/ethiopian-kids.php</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/28334/guest@my.umbc.edu/b961ca76e0623d85f3b20972ecb9c299/api/pixel</TrackingUrl>
<Group token="themosaic">The Mosaic: Center for Cultural Diversity </Group>
<GroupUrl>https://my3.my.umbc.edu/groups/themosaic</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/xsmall.png?1755890395</AvatarUrl>
<AvatarUrl size="original">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/original.png?1755890395</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/xxlarge.png?1755890395</AvatarUrl>
<AvatarUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/xlarge.png?1755890395</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/large.png?1755890395</AvatarUrl>
<AvatarUrl size="medium">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/medium.png?1755890395</AvatarUrl>
<AvatarUrl size="small">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/small.png?1755890395</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/xsmall.png?1755890395</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/079/8da8369525d899e6fa49decd5a80b73f/xxsmall.png?1755890395</AvatarUrl>
<Sponsor>The Office of Student Life's Mosaic Center</Sponsor>
<ThumbnailUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/028/334/804d1c035371d0119be83a57d690b58f/xxlarge.jpg?1367423148</ThumbnailUrl>
<ThumbnailUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/334/804d1c035371d0119be83a57d690b58f/xlarge.jpg?1367423148</ThumbnailUrl>
<ThumbnailUrl size="large">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/334/804d1c035371d0119be83a57d690b58f/large.jpg?1367423148</ThumbnailUrl>
<ThumbnailUrl size="medium">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/028/334/804d1c035371d0119be83a57d690b58f/medium.jpg?1367423148</ThumbnailUrl>
<ThumbnailUrl size="small">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/028/334/804d1c035371d0119be83a57d690b58f/small.jpg?1367423148</ThumbnailUrl>
<ThumbnailUrl size="xsmall">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/028/334/804d1c035371d0119be83a57d690b58f/xsmall.jpg?1367423148</ThumbnailUrl>
<ThumbnailUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/028/334/804d1c035371d0119be83a57d690b58f/xxsmall.jpg?1367423148</ThumbnailUrl>
<PawCount>0</PawCount>
<CommentCount>1</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 14:56:49 -0400</PostedAt>
<EditAt>Wed, 01 May 2013 11:46:06 -0400</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="28333" important="false" status="posted" url="https://my3.my.umbc.edu/posts/28333">
<Title>Weekend events</Title>
<Body>
<![CDATA[
    <div class="html-content">Hi everyone! Just wanted to let you know that we’ll be playing volleyball at 3:30 tomorrow (Saturday) on the court behind Susquehanna. Also, stop by the Relay for Life tables on the quad tonight, starting at 6 pm, to support … <a href="http://umbciv.wordpress.com/2013/04/26/weekend-events/" rel="nofollow external" class="bo">Continue reading <span>→</span></a>
    </div>
]]>
</Body>
<Summary>Hi everyone! Just wanted to let you know that we’ll be playing volleyball at 3:30 tomorrow (Saturday) on the court behind Susquehanna. Also, stop by the Relay for Life tables on the quad tonight,...</Summary>
<Website>http://umbciv.wordpress.com/2013/04/26/weekend-events/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/28333/guest@my.umbc.edu/eb17cb896e9bac56a4f68a3c4f3bc172/api/pixel</TrackingUrl>
<Tag>posts</Tag>
<Group token="iv">Intervarsity Christian Fellowship</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/iv</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/xsmall.png?1567536344</AvatarUrl>
<AvatarUrl size="original">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/original.png?1567536344</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/xxlarge.png?1567536344</AvatarUrl>
<AvatarUrl size="xlarge">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/xlarge.png?1567536344</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/large.png?1567536344</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/medium.png?1567536344</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/small.png?1567536344</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/xsmall.png?1567536344</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/094/dd82d58268453ca1c56996aa87e97fca/xxsmall.png?1567536344</AvatarUrl>
<Sponsor>InterVarsity Christian Fellowship</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>false</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 14:40:28 -0400</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="28327" important="false" status="posted" url="https://my3.my.umbc.edu/posts/28327">
<Title>Post-URCAD Workshop</Title>
<Tagline>How to get started in Research!</Tagline>
<Body>
<![CDATA[
    <div class="html-content">
    <p>Did you see something at URCAD and wondered how to get started in research? <br><br><strong>Wed, May 1, 2013<br>Acad IV-A Rm. 114B <br>Noon to 1:00 pm</strong></p>
    <p>Join us and we will try to get you started with your undergraduate research/projects.</p>
    </div>
]]>
</Body>
<Summary>Did you see something at URCAD and wondered how to get started in research?   Wed, May 1, 2013 Acad IV-A Rm. 114B  Noon to 1:00 pm  Join us and we will try to get you started with your...</Summary>
<Website>http://umbc.edu/undergrad_ed/research/myMajorResearchOUE.html</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/28327/guest@my.umbc.edu/3cbcfccda07a05e561129b5e0ee49fec/api/pixel</TrackingUrl>
<Tag>urcad</Tag>
<Group token="undergradresearch">Undergraduate Research</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/undergradresearch</GroupUrl>
<AvatarUrl>https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/xsmall.png?1600355057</AvatarUrl>
<AvatarUrl size="original">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/original.jpg?1600355057</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/xxlarge.png?1600355057</AvatarUrl>
<AvatarUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/xlarge.png?1600355057</AvatarUrl>
<AvatarUrl size="large">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/large.png?1600355057</AvatarUrl>
<AvatarUrl size="medium">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/medium.png?1600355057</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/small.png?1600355057</AvatarUrl>
<AvatarUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/xsmall.png?1600355057</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/006/875606ced2b629148af4caa1a4e8dd3c/xxsmall.png?1600355057</AvatarUrl>
<Sponsor>Undergraduate Research</Sponsor>
<ThumbnailUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/028/327/564a379d1109f9f1e9c863560c45d4e2/xxlarge.jpg?1366998831</ThumbnailUrl>
<ThumbnailUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/327/564a379d1109f9f1e9c863560c45d4e2/xlarge.jpg?1366998831</ThumbnailUrl>
<ThumbnailUrl size="large">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/028/327/564a379d1109f9f1e9c863560c45d4e2/large.jpg?1366998831</ThumbnailUrl>
<ThumbnailUrl size="medium">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/327/564a379d1109f9f1e9c863560c45d4e2/medium.jpg?1366998831</ThumbnailUrl>
<ThumbnailUrl size="small">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/028/327/564a379d1109f9f1e9c863560c45d4e2/small.jpg?1366998831</ThumbnailUrl>
<ThumbnailUrl size="xsmall">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/028/327/564a379d1109f9f1e9c863560c45d4e2/xsmall.jpg?1366998831</ThumbnailUrl>
<ThumbnailUrl size="xxsmall">https://assets1-my.umbc.edu/system/shared/thumbnails/news/000/028/327/564a379d1109f9f1e9c863560c45d4e2/xxsmall.jpg?1366998831</ThumbnailUrl>
<PawCount>5</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 14:36:52 -0400</PostedAt>
<EditAt>Fri, 26 Apr 2013 14:42:01 -0400</EditAt>
</NewsItem>

<NewsItem contentIssues="true" id="28328" important="false" status="posted" url="https://my3.my.umbc.edu/posts/28328">
<Title>Biologist/Activist Steingraber Out of Jail, To Speak @ UMBC</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <h5>by Dawn Biehler</h5>
    <div><br></div>
    <div>
    <span>As a biology graduate student and cancer survivor, </span><a href="http://steingraber.com/" rel="nofollow external" class="bo">Sandra Steingraber</a><span>, who will deliver the Gender and Women’s Studies Program’s sixth annual Korenman lecture next Monday (April 29th, 4:00 p.m., AOK Library 7th floor), set out to understand the links between the landscape where she grew up and a suspected cluster of illness among family members and neighbors. </span><span>In March she and other activists were arrested during an act of civil disobedience ... <a href="http://umbcbreakingground.wordpress.com/2013/04/26/biologistactivist-steingraber-released-from-jail-will-speak-at-umbc/" rel="nofollow external" class="bo">(continue reading)</a></span>
    </div>
    </div>
]]>
</Body>
<Summary>by Dawn Biehler     As a biology graduate student and cancer survivor, Sandra Steingraber, who will deliver the Gender and Women’s Studies Program’s sixth annual Korenman lecture next Monday...</Summary>
<Website>http://umbcbreakingground.wordpress.com/2013/04/26/biologistactivist-steingraber-released-from-jail-will-speak-at-umbc/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/28328/guest@my.umbc.edu/e85596688895bff568690bc13096007f/api/pixel</TrackingUrl>
<Group token="bg">UMBC BreakingGround</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/bg</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/xsmall.png?1360169927</AvatarUrl>
<AvatarUrl size="original">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/original.png?1360169927</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/xxlarge.png?1360169927</AvatarUrl>
<AvatarUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/xlarge.png?1360169927</AvatarUrl>
<AvatarUrl size="large">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/large.png?1360169927</AvatarUrl>
<AvatarUrl size="medium">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/medium.png?1360169927</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/small.png?1360169927</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/xsmall.png?1360169927</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/493/e0dc61eceffa1a7dff9d396b4b7c5011/xxsmall.png?1360169927</AvatarUrl>
<Sponsor>UMBC BreakingGround</Sponsor>
<ThumbnailUrl size="xxlarge">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/028/328/555d4939b10bf95704808379fb9d29d0/xxlarge.jpg?1366999739</ThumbnailUrl>
<ThumbnailUrl size="xlarge">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/328/555d4939b10bf95704808379fb9d29d0/xlarge.jpg?1366999739</ThumbnailUrl>
<ThumbnailUrl size="large">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/328/555d4939b10bf95704808379fb9d29d0/large.jpg?1366999739</ThumbnailUrl>
<ThumbnailUrl size="medium">https://assets3-my.umbc.edu/system/shared/thumbnails/news/000/028/328/555d4939b10bf95704808379fb9d29d0/medium.jpg?1366999739</ThumbnailUrl>
<ThumbnailUrl size="small">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/328/555d4939b10bf95704808379fb9d29d0/small.jpg?1366999739</ThumbnailUrl>
<ThumbnailUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/thumbnails/news/000/028/328/555d4939b10bf95704808379fb9d29d0/xsmall.jpg?1366999739</ThumbnailUrl>
<ThumbnailUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/thumbnails/news/000/028/328/555d4939b10bf95704808379fb9d29d0/xxsmall.jpg?1366999739</ThumbnailUrl>
<PawCount>29</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 14:11:02 -0400</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="28332" important="false" status="posted" url="https://my3.my.umbc.edu/posts/28332">
<Title>Cornell University Gets Big Donation to Help Fund NYC Tech Campus</Title>
<Body>
<![CDATA[
    <div class="html-content">The new institute will be part of Cornell Tech, a graduate school expected to attract top
    students and create new local companies.</div>
]]>
</Body>
<Summary>The new institute will be part of Cornell Tech, a graduate school expected to attract top
students and create new local companies.</Summary>
<Website>http://feedproxy.google.com/~r/YoungentrepreneurcomBlog/~3/uQxzXzqd7tE/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/28332/guest@my.umbc.edu/2e42bcde3dfda602bea324602e2024f9/api/pixel</TrackingUrl>
<Tag>cornell-university</Tag>
<Tag>innovation</Tag>
<Tag>new-york-city</Tag>
<Tag>technology</Tag>
<Tag>technology-news</Tag>
<Tag>technology-startups</Tag>
<Group token="entrepreneurship">Alex. Brown Center for Entrepreneurship</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/entrepreneurship</GroupUrl>
<AvatarUrl>https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/xsmall.png?1771000363</AvatarUrl>
<AvatarUrl size="original">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/original.jpg?1771000363</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/xxlarge.png?1771000363</AvatarUrl>
<AvatarUrl size="xlarge">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/xlarge.png?1771000363</AvatarUrl>
<AvatarUrl size="large">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/large.png?1771000363</AvatarUrl>
<AvatarUrl size="medium">https://assets1-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/medium.png?1771000363</AvatarUrl>
<AvatarUrl size="small">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/small.png?1771000363</AvatarUrl>
<AvatarUrl size="xsmall">https://assets2-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/xsmall.png?1771000363</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/092/53c03b106bdc6e19e4bf0a41b5a37add/xxsmall.png?1771000363</AvatarUrl>
<Sponsor>The Alex. Brown Center for Entrepreneurship</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 14:00:10 -0400</PostedAt>
</NewsItem>

<NewsItem contentIssues="true" id="28330" important="false" status="posted" url="https://my3.my.umbc.edu/posts/28330">
<Title>Test-Driving Shell Scripts</Title>
<Body>
<![CDATA[
    <div class="html-content">
    <a href="http://rss.buysellads.com/click.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31487&amp;c=1786931660" rel="nofollow external" class="bo"><img src="http://rss.buysellads.com/img.php?z=1260013&amp;k=d754f1e9ba63a736ba8ff5ece958f7dd&amp;a=31487&amp;c=1786931660" alt="" style="max-width: 100%; height: auto;"></a><p>Writing shell scripts is very much like programming. Some scripts require little time investment; whereas, other complex scripts may require thought, planning and a larger commitment. From this perspective, it makes sense to take a test-driven approach and unit test our shell scripts.</p>
    <p></p>
    <p>To get the most out of this tutorial, you need to be familiar with the command line interface (CLI); you may want to check out the <a href="http://net.tutsplus.com/tutorials/tools-and-tips/the-command-line-is-your-best-friend/?search_index=3" rel="nofollow external" class="bo">The Command Line is Your Best Friend</a> tutorial if you need a refresher. You also need a basic understanding of Bash-like shell scripting. Finally, you may want to familiarize yourself with the test-driven development (TDD) concepts and unit testing in general; be sure to check out these <a href="http://net.tutsplus.com/sessions/test-driven-php/" rel="nofollow external" class="bo">Test-Driven PHP</a> tutorials to get the basic idea.</p>
    <hr>
    <h2>Prepare the Programming Environment</h2>
    <p>First, you need a text editor to write your shell scripts and unit tests. Use your favorite!</p>
    <p>We will use the <a href="http://code.google.com/p/shunit2/downloads/list" rel="nofollow external" class="bo">shUnit2</a> shell unit testing framework to run our unit tests. It was designed for, and works with, Bash-like shells. shUnit2 is an open source framework released under the GPL license, and a copy of the framework is also included with this tutorial’s sample source code.</p>
    <p>Installing shUnit2 is very easy; simply download and extract the archive to any location on your hard drive. It is written in Bash, and as such, the framework consists of only script files. If you plan to frequently use shUnit2, I highly recommend that you put it in a location in your PATH.</p>
    <hr>
    <h2>Writing our First Test</h2>
    <p>For this tutorial, extract shUnit into a directory with the same name in your <code>Sources</code> folder (see the code attached to this tutorial). Create a <code>Tests</code> folder inside <code>Sources</code> and added a new file call <code>firstTest.sh</code>.</p>
    <pre>#! /usr/bin/env sh&#x000A;    &#x000A;    ### firstTest.sh ###&#x000A;    &#x000A;    function testWeCanWriteTests () {&#x000A;    	assertEquals "it works" "it works"&#x000A;    }&#x000A;    &#x000A;    ## Call and Run all Tests&#x000A;    . "../shunit2-2.1.6/src/shunit2"&#x000A;    </pre>
    <p>Than make your test file executable.</p>
    <pre>$ cd __your_code_folder__/Tests&#x000A;    $ chmod +x firstTest.sh&#x000A;    </pre>
    <p>Now you can simply run it and observe the output:</p>
    <pre>$ ./firstTest.sh&#x000A;    testWeCanWriteTests&#x000A;    &#x000A;    Ran 1 test.&#x000A;    &#x000A;    OK&#x000A;    </pre>
    <p>It says we ran one successful test. Now, let’s cause the test to fail; change the <code>assertEquals</code> statement so that the two strings are not the same and run the test again:</p>
    <pre>$ ./firstTest.sh&#x000A;    testWeCanWriteTests&#x000A;    ASSERT:expected:&lt;it works&gt; but was:&lt;it does not work&gt;&#x000A;    &#x000A;    Ran 1 test.&#x000A;    &#x000A;    FAILED (failures=1)&#x000A;    </pre>
    <hr>
    <h2>A Tennis Game</h2>
    <blockquote><p>You write acceptance tests at the beginning of a project/feature/story when you can clearly define a specific requirement.</p></blockquote>
    <p>Now that we have a working testing environment, let’s write a script that reads a file, makes decisions based on the file’s contents and outputs information to the screen.</p>
    <p>The main goal of the script is to show the score of a tennis game between two players. We will concentrate only on keeping the score of a single game; everything else is up to you. The scoring rules are:</p>
    <ul>
    <li>At the beginning, each player has a score of zero, called “love”</li>
    <li>First, second and third balls won are marked as “fifteen”, “thirty”, and “forty”.</li>
    <li>If at “forty” the score is equal, it is called “deuce”.</li>
    <li>After this, the score is kept as “Advantage” for the player who scores one more point than the other player.</li>
    <li>A player is the winner if he manages to have an advantage of at least two points and wins at least three points (that is, if he reached at least “forty”).</li>
    </ul>
    <hr>
    <h2>Definition of Input and Output</h2>
    <p>Our application will read the score from a file. Another system will push the information into this file. The first line of this data file will contain the names of the players. When a player scores a point, their name is written at the end of the file. A typical score file looks like this:</p>
    <pre>John - Michael&#x000A;    John&#x000A;    John&#x000A;    Michael&#x000A;    John&#x000A;    Michael&#x000A;    Michael&#x000A;    John&#x000A;    John&#x000A;    </pre>
    <p>You can find this content in the <code>input.txt</code> file in the <code>Source</code> folder.</p>
    <p>The output of our program writes the score to the screen one line at a time. The output should be:</p>
    <pre>John - Michael&#x000A;    John: 15 - Michael: 0&#x000A;    John: 30 - Michael: 0&#x000A;    John: 30 - Michael: 15&#x000A;    John: 40 - Michael: 15&#x000A;    John: 40 - Michael: 30&#x000A;    Deuce&#x000A;    John: Advantage&#x000A;    John: Winner&#x000A;    </pre>
    <p>This output can be also found in the <code>output.txt</code> file. We will use this information to check if our program is correct.</p>
    <hr>
    <h2>The Acceptance Test</h2>
    <p>You write acceptance tests at the beginning of a project/feature/story when you can clearly define a specific requirement. In our case, this test simply calls our soon-to-be-created script with the name of the input file as the parameter, and it expects the output to be identical with the hand-written file from the previous section:</p>
    <pre>#! /usr/bin/env sh&#x000A;    &#x000A;    ### acceptanceTest.sh ###&#x000A;    &#x000A;    function testItCanProvideAllTheScores () {&#x000A;    	cd ..&#x000A;    	./tennisGame.sh ./input.txt &gt; ./results.txt&#x000A;    	diff ./output.txt ./results.txt&#x000A;    	assertTrue 'Expected output differs.' $?&#x000A;    }&#x000A;    &#x000A;    ## Call and Run all Tests&#x000A;    . "../shunit2-2.1.6/src/shunit2"&#x000A;    </pre>
    <p>We will run our tests in the <code>Source/Tests</code> folder; therefore, <code>cd ..</code> takes us into the <code>Source</code> directory. Then it tries to run <code>tennisGamse.sh</code>, which does not yet exist. Then the <code>diff</code> command will compare the two files: <code>./output.txt</code> is our hand-written output and <code>./results.txt</code> will contain the result of our script. Finally, <code>assertTrue</code> checks the exit value of <code>diff</code>.</p>
    <p>But for now, our test returns the following error:</p>
    <pre>$ ./acceptanceTest.sh&#x000A;    testItCanProvideAllTheScores&#x000A;    ./acceptanceTest.sh: line 7: tennisGame.sh: command not found&#x000A;    diff: ./results.txt: No such file or directory&#x000A;    ASSERT:Expected output differs.&#x000A;    &#x000A;    Ran 1 test.&#x000A;    &#x000A;    FAILED (failures=1)&#x000A;    </pre>
    <p>Let’s turn those errors into a nice failure by creating an empty file called <code>tennisGame.sh</code> and make it executable. Now when we run our test, we don’t get an error:</p>
    <pre>./acceptanceTest.sh&#x000A;    testItCanProvideAllTheScores&#x000A;    1,9d0&#x000A;    &lt; John - Michael&#x000A;    &lt; John: 15 - Michael: 0&#x000A;    &lt; John: 30 - Michael: 0&#x000A;    &lt; John: 30 - Michael: 15&#x000A;    &lt; John: 40 - Michael: 15&#x000A;    &lt; John: 40 - Michael: 30&#x000A;    &lt; Deuce&#x000A;    &lt; John: Advantage&#x000A;    &lt; John: Winner&#x000A;    ASSERT:Expected output differs.&#x000A;    &#x000A;    Ran 1 test.&#x000A;    &#x000A;    FAILED (failures=1)&#x000A;    </pre>
    <hr>
    <h2>Implementation with TDD</h2>
    <p>Create another file called <code>unitTests.sh</code> for our unit tests. We don’t want to run our script for each test; we only want to run the functions that we test. So, we will make <code>tennisGame.sh</code> run only the functions that will reside in <code>functions.sh</code>:</p>
    <pre>#! /usr/bin/env sh&#x000A;    &#x000A;    ### unitTest.sh ###&#x000A;    &#x000A;    source ../functions.sh&#x000A;    &#x000A;    function testItCanProvideFirstPlayersName () {&#x000A;    	assertEquals 'John' `getFirstPlayerFrom 'John - Michael'`&#x000A;    }&#x000A;    &#x000A;    ## Call and Run all Tests&#x000A;    . "../shunit2-2.1.6/src/shunit2"&#x000A;    </pre>
    <p>Our first test is simple. We attempt to retrieve the first player’s name when a line contains two names separated by a hyphen. This test will fail because we do not yet have a <code>getFirstPlayerFrom</code> function:</p>
    <pre>$ ./unitTest.sh&#x000A;    testItCanProvideFirstPlayersName&#x000A;    ./unitTest.sh: line 8: getFirstPlayerFrom: command not found&#x000A;    shunit2:ERROR assertEquals() requires two or three arguments; 1 given&#x000A;    shunit2:ERROR 1: John 2:  3:&#x000A;    &#x000A;    Ran 1 test.&#x000A;    &#x000A;    OK&#x000A;    </pre>
    <p>The implementation for <code>getFirstPlayerFrom</code>is very simple. It’s a regular expression that is pushed through the <code>sed</code> command:</p>
    <pre>### functions.sh ###&#x000A;    &#x000A;    function getFirstPlayerFrom () {&#x000A;    	echo $1 | sed -e 's/-.*//'&#x000A;    }&#x000A;    </pre>
    <p>Now the test passes:</p>
    <pre>$ ./unitTest.sh&#x000A;    testItCanProvideFirstPlayersName&#x000A;    &#x000A;    Ran 1 test.&#x000A;    &#x000A;    OK&#x000A;    </pre>
    <p>Let’s write another test for the second player’s name:</p>
    <pre>### unitTest.sh ###&#x000A;    &#x000A;    [...]&#x000A;    &#x000A;    function testItCanProvideSecondPlayersName () {&#x000A;    	assertEquals 'Michael' `getSecondPlayerFrom 'John - Michael'`&#x000A;    }&#x000A;    </pre>
    <p>The failure:</p>
    <pre>./unitTest.sh&#x000A;    testItCanProvideFirstPlayersName&#x000A;    testItCanProvideSecondPlayersName&#x000A;    ASSERT:expected:&lt;Michael&gt; but was:&lt;John&gt;&#x000A;    &#x000A;    Ran 2 tests.&#x000A;    &#x000A;    FAILED (failures=1)&#x000A;    </pre>
    <p>And now the function implementation to make it pass:</p>
    <pre>### functions.sh ###&#x000A;    &#x000A;    [...]&#x000A;    &#x000A;    function getSecondPlayerFrom () {&#x000A;    	echo $1 | sed -e 's/.*-//'&#x000A;    }</pre>
    <p>Now we have passing tests:</p>
    <pre>$ ./unitTest.sh&#x000A;    testItCanProvideFirstPlayersName&#x000A;    testItCanProvideSecondPlayersName&#x000A;    &#x000A;    Ran 2 tests.&#x000A;    &#x000A;    OK&#x000A;    </pre>
    <hr>
    <h2>Let’s Speed Things Up</h2>
    <p>Starting at this point, we will write a test and the implementation, and I will explain only what deserves to be mentioned.</p>
    <p>Let’s test if we have a player with only one score. Added the following test:</p>
    <pre>function testItCanGetScoreForAPlayerWithOnlyOneWin () {&#x000A;    	standings=$'John - Michael\nJohn'&#x000A;    	assertEquals '1' `getScoreFor 'John' "$standings"`&#x000A;    }&#x000A;    </pre>
    <p>And the solution:</p>
    <pre>function getScoreFor () {&#x000A;    	player=$1&#x000A;    	standings=$2&#x000A;    	totalMatches=$(echo "$standings" | grep $player | wc -l)&#x000A;    	echo $(($totalMatches-1))&#x000A;    }&#x000A;    </pre>
    <p>We use some fancy-pants quoting to pass the newline sequence (<code>\n</code>) inside a string parameter. Then we use <code>grep</code> to find the lines that contain the player’s name and count them with <code>wc</code>. Finally, we subtract one from the result to counteract the presence of the first line (it contains only non-score related data).</p>
    <blockquote><p>Now we are at the refactoring phase of TDD.</p></blockquote>
    <p>I just realized that the code actually works for more than one point per player, and we can refactor our tests to reflect this. Change the above test function to the following:</p>
    <pre>function testItCanGetScoreForAPlayer () {&#x000A;    	standings=$'John - Michael\nJohn\nMichael\nJohn'&#x000A;    	assertEquals '2' `getScoreFor 'John' "$standings"`&#x000A;    }&#x000A;    </pre>
    <p>The tests still passes. Time to move on with our logic:</p>
    <pre>function testItCanOutputScoreAsInTennisForFirstPoint () {&#x000A;    	assertEquals 'John: 15 - Michael: 0' "`displayScore 'John' 1 'Michael' 0`"&#x000A;    }&#x000A;    </pre>
    <p>And the implementation:</p>
    <pre>function displayScore () {&#x000A;    	if [ "$2" -eq '1' ]; then&#x000A;    		playerOneScore='15'&#x000A;    	fi&#x000A;    &#x000A;    	echo "$1: $playerOneScore - $3: $4"&#x000A;    }&#x000A;    </pre>
    <p>I only check the second parameter. This looks like I’m cheating, but it is the simplest code to make the test pass. Writing another test forces us to add more logic, but what test should we write next?</p>
    <p>There are two paths we can take. Testing if the second player recieves a point forces us to write another <code>if</code> statement, but we only have to add an <code>else</code> statement if we choose to test the first player’s second point. The latter implies an easier implementation, so let’s try that:</p>
    <pre>function testItCanOutputScoreAsInTennisForSecondPointFirstPlayer () {&#x000A;    	assertEquals 'John: 30 - Michael: 0' "`displayScore 'John' 2 'Michael' 0`"&#x000A;    }&#x000A;    </pre>
    <p>And the implementation:</p>
    <pre>function displayScore () {&#x000A;    	if [ "$2" -eq '1' ]; then&#x000A;    		playerOneScore='15'&#x000A;    	else&#x000A;    		playerOneScore='30'&#x000A;    	fi&#x000A;    &#x000A;    	echo "$1: $playerOneScore - $3: $4"&#x000A;    }&#x000A;    </pre>
    <p>This still looks cheating, but it works perfectly. Continuing on for the third point:</p>
    <pre>function testItCanOutputScoreAsInTennisForTHIRDPointFirstPlayer () {&#x000A;    	assertEquals 'John: 40 - Michael: 0' "`displayScore 'John' 3 'Michael' 0`"&#x000A;    }&#x000A;    </pre>
    <p>The implementation:</p>
    <pre>function displayScore () {&#x000A;    	if [ "$2" -eq '1' ]; then&#x000A;    		playerOneScore='15'&#x000A;    	elif [ "$2" -eq '2' ]; then&#x000A;    		playerOneScore='30'&#x000A;    	else&#x000A;    		playerOneScore='40'&#x000A;    	fi&#x000A;    &#x000A;    	echo "$1: $playerOneScore - $3: $4"&#x000A;    }</pre>
    <p>This <code>if-elif-else</code> is starting to annoy me. I want to change it, but let’s first refactor our tests. We have three very similar tests; so let’s write them into a single test that makes three assertions:</p>
    <pre>function testItCanOutputScoreWhenFirstPlayerWinsFirst3Points () {&#x000A;    	assertEquals 'John: 15 - Michael: 0' "`displayScore 'John' 1 'Michael' 0`"&#x000A;    	assertEquals 'John: 30 - Michael: 0' "`displayScore 'John' 2 'Michael' 0`"&#x000A;    	assertEquals 'John: 40 - Michael: 0' "`displayScore 'John' 3 'Michael' 0`"&#x000A;    }&#x000A;    </pre>
    <p>That’s better, and it still passes. Now, let’s create a similar test for the second player:</p>
    <pre>function testItCanOutputScoreWhenSecondPlayerWinsFirst3Points () {&#x000A;    	assertEquals 'John: 0 - Michael: 15' "`displayScore 'John' 0 'Michael' 1`"&#x000A;    	assertEquals 'John: 0 - Michael: 30' "`displayScore 'John' 0 'Michael' 2`"&#x000A;    	assertEquals 'John: 0 - Michael: 40' "`displayScore 'John' 0 'Michael' 3`"&#x000A;    }&#x000A;    </pre>
    <p>Running this test results in interesting output:</p>
    <pre>testItCanOutputScoreWhenSecondPlayerWinsFirst3Points&#x000A;    ASSERT:expected:&lt;John: 0 - Michael: 15&gt; but was:&lt;John: 40 - Michael: 1&gt;&#x000A;    ASSERT:expected:&lt;John: 0 - Michael: 30&gt; but was:&lt;John: 40 - Michael: 2&gt;&#x000A;    ASSERT:expected:&lt;John: 0 - Michael: 40&gt; but was:&lt;John: 40 - Michael: 3&gt;&#x000A;    </pre>
    <p>Well that was unexpected. We knew that Michael would have incorrect scores. The surprise is John; he should have 0 not 40. Let’s fix that by first modifying the <code>if-elif-else</code> expression:</p>
    <pre>function displayScore () {&#x000A;    	if [ "$2" -eq '1' ]; then&#x000A;    		playerOneScore='15'&#x000A;    	elif [ "$2" -eq '2' ]; then&#x000A;    		playerOneScore='30'&#x000A;    	elif [ "$2" -eq '3' ]; then&#x000A;    		playerOneScore='40'&#x000A;    	else&#x000A;    		playerOneScore=$2&#x000A;    	fi&#x000A;    &#x000A;    	echo "$1: $playerOneScore - $3: $4"&#x000A;    }&#x000A;    </pre>
    <p>The <code>if-elif-else</code> is now more complex, but we at least fixed the John’s scores:</p>
    <pre>testItCanOutputScoreWhenSecondPlayerWinsFirst3Points&#x000A;    ASSERT:expected:&lt;John: 0 - Michael: 15&gt; but was:&lt;John: 0 - Michael: 1&gt;&#x000A;    ASSERT:expected:&lt;John: 0 - Michael: 30&gt; but was:&lt;John: 0 - Michael: 2&gt;&#x000A;    ASSERT:expected:&lt;John: 0 - Michael: 40&gt; but was:&lt;John: 0 - Michael: 3&gt;&#x000A;    </pre>
    <p>Now let’s fix Michael:</p>
    <pre>function displayScore () {&#x000A;    	echo "$1: `convertToTennisScore $2` - $3: `convertToTennisScore $4`"&#x000A;    }&#x000A;    &#x000A;    function convertToTennisScore () {&#x000A;    	if [ "$1" -eq '1' ]; then&#x000A;    		playerOneScore='15'&#x000A;    	elif [ "$1" -eq '2' ]; then&#x000A;    		playerOneScore='30'&#x000A;    	elif [ "$1" -eq '3' ]; then&#x000A;    		playerOneScore='40'&#x000A;    	else&#x000A;    		playerOneScore=$1&#x000A;    	fi&#x000A;    &#x000A;    	echo $playerOneScore;&#x000A;    }&#x000A;    </pre>
    <p>That worked well! Now it’s time to finally refactor that ugly <code>if-elif-else</code> expression:</p>
    <pre>function convertToTennisScore () {&#x000A;    	declare -a scoreMap=('0' '15' '30' '40')&#x000A;    	echo ${scoreMap[$1]};&#x000A;    }&#x000A;    </pre>
    <p>Value maps are wonderful! Let’s move on to the “Deuce” case:</p>
    <pre>function testItSayDeuceWhenPlayersAreEqualAndHaveEnoughPoinst () {&#x000A;    	assertEquals 'Deuce' "`displayScore 'John' 3 'Michael' 3`"&#x000A;    }&#x000A;    </pre>
    <p>We check for “Deuce” when all players have at least a score of 40.</p>
    <pre>function displayScore () {&#x000A;    	if [ $2 -gt 2 ] &amp;&amp; [ $4 -gt 2 ] &amp;&amp; [ $2 -eq $4 ]; then&#x000A;    		echo "Deuce"&#x000A;    	else&#x000A;    		echo "$1: `convertToTennisScore $2` - $3: `convertToTennisScore $4`"&#x000A;    	fi&#x000A;    }&#x000A;    </pre>
    <p>Now we test for the first player’s advantage:</p>
    <pre>function testItCanOutputAdvantageForFirstPlayer () {&#x000A;    	assertEquals 'John: Advantage' "`displayScore 'John' 4 'Michael' 3`"&#x000A;    }&#x000A;    </pre>
    <p>And to make it pass:</p>
    <pre>function displayScore () {&#x000A;    	if [ $2 -gt 2 ] &amp;&amp; [ $4 -gt 2 ] &amp;&amp; [ $2 -eq $4 ]; then&#x000A;    		echo "Deuce"&#x000A;    	elif [ $2 -gt 2 ] &amp;&amp; [ $4 -gt 2 ] &amp;&amp; [ $2 -gt $4 ]; then&#x000A;    		echo "$1: Advantage"&#x000A;    	else&#x000A;    		echo "$1: `convertToTennisScore $2` - $3: `convertToTennisScore $4`"&#x000A;    	fi&#x000A;    }&#x000A;    </pre>
    <p>There’s that ugly <code>if-elif-else</code> again, and we have a lot of duplication as well. All our tests pass, so let’s refactor:</p>
    <pre>function displayScore () {&#x000A;    	if outOfRegularScore $2 $4 ; then&#x000A;    		checkEquality $2 $4&#x000A;    		checkFirstPlayerAdv $1 $2 $4&#x000A;    	else&#x000A;    		echo "$1: `convertToTennisScore $2` - $3: `convertToTennisScore $4`"&#x000A;    	fi&#x000A;    }&#x000A;    &#x000A;    function outOfRegularScore () {&#x000A;    	[ $1 -gt 2 ] &amp;&amp; [ $2 -gt 2 ]&#x000A;    	return $?&#x000A;    }&#x000A;    &#x000A;    function checkEquality () {&#x000A;    	if [ $1 -eq $2 ]; then&#x000A;    		echo "Deuce"&#x000A;    	fi&#x000A;    }&#x000A;    &#x000A;    function checkFirstPlayerAdv () {&#x000A;    	if [ $2 -gt $3 ]; then&#x000A;    		echo "$1: Advantage"&#x000A;    	fi&#x000A;    }&#x000A;    </pre>
    <p>This’ll work for now. Let’s test the advantage for the second player:</p>
    <pre>function testItCanOutputAdvantageForSecondPlayer () {&#x000A;    	assertEquals 'Michael: Advantage' "`displayScore 'John' 3 'Michael' 4`"&#x000A;    }&#x000A;    </pre>
    <p>And the code:</p>
    <pre>function displayScore () {&#x000A;    	if outOfRegularScore $2 $4 ; then&#x000A;    		checkEquality $2 $4&#x000A;    		checkAdvantage $1 $2 $3 $4&#x000A;    	else&#x000A;    		echo "$1: `convertToTennisScore $2` - $3: `convertToTennisScore $4`"&#x000A;    	fi&#x000A;    }&#x000A;    &#x000A;    function checkAdvantage () {&#x000A;    	if [ $2 -gt $4 ]; then&#x000A;    		echo "$1: Advantage"&#x000A;    	elif [ $4 -gt $2 ]; then&#x000A;    		echo "$3: Advantage"&#x000A;    	fi&#x000A;    }&#x000A;    </pre>
    <p>This works, but we have some duplication in the <code>checkAdvantage</code> function. Let’s simplify it and call it twice:</p>
    <pre>function displayScore () {&#x000A;    	if outOfRegularScore $2 $4 ; then&#x000A;    		checkEquality $2 $4&#x000A;    		checkAdvantage $1 $2 $4&#x000A;    		checkAdvantage $3 $4 $2&#x000A;    	else&#x000A;    		echo "$1: `convertToTennisScore $2` - $3: `convertToTennisScore $4`"&#x000A;    	fi&#x000A;    }&#x000A;    &#x000A;    function checkAdvantage () {&#x000A;    	if [ $2 -gt $3 ]; then&#x000A;    		echo "$1: Advantage"&#x000A;    	fi&#x000A;    }</pre>
    <p>This is actually better than our previous solution, and it reverts to the original implementation of this method. But we now we have another problem: I feel uncomfortable with the <code>$1</code>, <code>$2</code>, <code>$3</code> and <code>$4</code> variables. They need meaningful names:</p>
    <pre>function displayScore () {&#x000A;    	firstPlayerName=$1; firstPlayerScore=$2&#x000A;    	secondPlayerName=$3; secondPlayerScore=$4&#x000A;    &#x000A;    	if outOfRegularScore $firstPlayerScore $secondPlayerScore; then&#x000A;    		checkEquality $firstPlayerScore $secondPlayerScore&#x000A;    		checkAdvantageFor $firstPlayerName $firstPlayerScore $secondPlayerScore&#x000A;    		checkAdvantageFor $secondPlayerName $secondPlayerScore $firstPlayerScore&#x000A;    	else&#x000A;    		echo "$1: `convertToTennisScore $2` - $3: `convertToTennisScore $4`"&#x000A;    	fi&#x000A;    }&#x000A;    &#x000A;    function checkAdvantageFor () {&#x000A;    	if [ $2 -gt $3 ]; then&#x000A;    		echo "$1: Advantage"&#x000A;    	fi&#x000A;    }&#x000A;    </pre>
    <p>This makes our code longer, but it is significantly more expressive. I like it.</p>
    <p>It’s time to find a winner:</p>
    <pre>function testItCanOutputWinnerForFirstPlayer () {&#x000A;    	assertEquals 'John: Winner' "`displayScore 'John' 5 'Michael' 3`"&#x000A;    }&#x000A;    </pre>
    <p>We only have to modify the <code>checkAdvantageFor</code> function:</p>
    <pre>function checkAdvantageFor () {&#x000A;    	if [ $2 -gt $3 ]; then&#x000A;    		if [ `expr $2 - $3` -gt 1 ]; then&#x000A;    			echo "$1: Winner"&#x000A;    		else&#x000A;    			echo "$1: Advantage"&#x000A;    		fi&#x000A;    	fi&#x000A;    }&#x000A;    </pre>
    <p>We are almost done! As our last step, we’ll write the code in <code>tennisGame.sh</code> to make the acceptance test pass. This will be fairly simple code:</p>
    <pre>#! /usr/bin/env sh&#x000A;    &#x000A;    ### tennisGame.sh ###&#x000A;    &#x000A;    . ./functions.sh&#x000A;    &#x000A;    playersLine=`head -n 1 $1`&#x000A;    echo "$playersLine"&#x000A;    firstPlayer=`getFirstPlayerFrom "$playersLine"`&#x000A;    secondPlayer=`getSecondPlayerFrom "$playersLine"`&#x000A;    &#x000A;    wholeScoreFileContent=`cat $1`&#x000A;    totalNoOfLines=`echo "$wholeScoreFileContent" | wc -l`&#x000A;    for currentLine in `seq 2 $totalNoOfLines`&#x000A;    	do&#x000A;    	firstPlayerScore=$(getScoreFor $firstPlayer "`echo \"$wholeScoreFileContent\" | head -n $currentLine`")&#x000A;    	secondPlayerScore=$(getScoreFor $secondPlayer "`echo \"$wholeScoreFileContent\" | head -n $currentLine`")&#x000A;    	displayScore $firstPlayer $firstPlayerScore $secondPlayer $secondPlayerScore&#x000A;    done&#x000A;    </pre>
    <p>We read the first line to retrieve the names of the two players, and then we incrementally read the file to compute the score.</p>
    <hr>
    <h2>Final Thoughts</h2>
    <p>Shell scripts can easily grow from a few lines of code to a few hundred of lines. When this happens, maintenance becomes increasingly difficult. Using TDD and unit testing can greatly help to make your complex script easier to maintain—not to mention that it forces you to build your complex scripts in a more professional manner.</p>
    </div>
]]>
</Body>
<Summary>Writing shell scripts is very much like programming. Some scripts require little time investment; whereas, other complex scripts may require thought, planning and a larger commitment. From this...</Summary>
<Website>http://feedproxy.google.com/~r/nettuts/~3/8e2tSC6ql7w/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/28330/guest@my.umbc.edu/4abfd4021e73b2d1aaa1fbfae9231770/api/pixel</TrackingUrl>
<Tag>bash</Tag>
<Tag>css</Tag>
<Tag>development</Tag>
<Tag>html</Tag>
<Tag>javascript</Tag>
<Tag>mysql</Tag>
<Tag>php</Tag>
<Tag>sql</Tag>
<Tag>tdd</Tag>
<Tag>tools-and-tips</Tag>
<Tag>wed</Tag>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 13:52:45 -0400</PostedAt>
<EditAt>Fri, 26 Apr 2013 13:52:45 -0400</EditAt>
</NewsItem>

<NewsItem contentIssues="false" id="28321" important="false" status="posted" url="https://my3.my.umbc.edu/posts/28321">
<Title>The Case for Revolutionizing How We Teach Web Design</Title>
<Body>
<![CDATA[
    <div class="html-content">"<a href="http://openmatt.wordpress.com/2010/11/10/epic-fail-the-sorry-state-of-web-education-in-schools/" rel="nofollow external" class="bo">Meet </a><strong><a href="http://maban.co.uk/" rel="nofollow external" class="bo">Anna Debenham</a></strong>, a 20-year-old self-taught web developer from the U.K., who never went to college. She recently delivered a keynote address at <a href="http://www.good.is/post/for-profits-and-open-education-make-for-uneasy-bedfellows-or-do-they/" rel="nofollow external" class="bo">Mozilla's Drumbeat Festival on the Future of Learning, Freedom and the Web</a> that inspired a standing ovation.<p>
    	Her treatise, on the pathetic state of web education (both at the high 
    school and college level) details how dated material is not only 
    creating a disinterested generation of web designers and developers, but
     negatively impacting the future economic viability of whole countries.</p>
    <p>
    	Of sticking kids in front of PCs and expecting an entrepreneurial 
    miracle, Debenham quotes a teacher as saying: “All we’re gearing our 
    kids up for is a life in an office. No wonder there’s no stampede for 
    that career path.”</p>
    <p>	At the end of her presentation, she proposes 
    the need for a fix. How do you suggest we do a better job of educating 
    future technologists?</p>
    <p>	Check out the full presentation, below:"</p>
    </div>
]]>
</Body>
<Summary>"Meet Anna Debenham, a 20-year-old self-taught web developer from the U.K., who never went to college. She recently delivered a keynote address at Mozilla's Drumbeat Festival on the Future of...</Summary>
<Website>http://www.good.is/posts/technology-moves-fast-academia-doesn-t/</Website>
<TrackingUrl>https://my3.my.umbc.edu/api/v0/pixel/news/28321/guest@my.umbc.edu/8409fb381deee514f68c7d22063989cf/api/pixel</TrackingUrl>
<Group token="retired-583">Web Developer - Build Group</Group>
<GroupUrl>https://my3.my.umbc.edu/groups/retired-583</GroupUrl>
<AvatarUrl>https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="original">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/original.jpg?1363101197</AvatarUrl>
<AvatarUrl size="xxlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="xlarge">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xlarge.png?1363101197</AvatarUrl>
<AvatarUrl size="large">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/large.png?1363101197</AvatarUrl>
<AvatarUrl size="medium">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/medium.png?1363101197</AvatarUrl>
<AvatarUrl size="small">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/small.png?1363101197</AvatarUrl>
<AvatarUrl size="xsmall">https://assets3-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xsmall.png?1363101197</AvatarUrl>
<AvatarUrl size="xxsmall">https://assets4-my.umbc.edu/system/shared/avatars/groups/000/000/583/fc60f5d7abc2e080599bb6dc465db54d/xxsmall.png?1363101197</AvatarUrl>
<Sponsor>Web Developer - Build Group</Sponsor>
<PawCount>0</PawCount>
<CommentCount>0</CommentCount>
<CommentsAllowed>true</CommentsAllowed>
<PostedAt>Fri, 26 Apr 2013 13:31:06 -0400</PostedAt>
</NewsItem>

</News>
