<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2138644806777257073</id><updated>2024-10-07T09:16:52.986+03:00</updated><category term="datastructure"/><category term="games"/><category term="java"/><category term="junit"/><title type='text'>Code How Tos</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://codehowtos.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://codehowtos.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Lagi</name><uri>http://www.blogger.com/profile/06115049194000560865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>4</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2138644806777257073.post-160753045674628530</id><published>2020-12-20T18:45:00.001+02:00</published><updated>2020-12-20T18:45:08.202+02:00</updated><title type='text'>Migrating issues from GitHub to Jira</title><content type='html'>&lt;p&gt;Recently we made the transition from managing our issues in GitHub Projects to Jira.&lt;/p&gt;&lt;p&gt;After finding out the plugin that was previously available was deprecated and the scripts out there supported GitHub API V2 (that was deprecated in 2012), I adapted it for the V3 API and had nice results, so here it is for whoever wants to use it.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Basically, the current available flow for a one time migration from GitHub to Jira is to use GitHub&#39;s API to export the issues and then do a bulk import in Jira.&amp;nbsp; Here&#39;s a walk through of what you&#39;ll need to do:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Create a Personal Access Token in GitHub that will allow to pull issues:&amp;nbsp;&lt;a href=&quot;https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/creating-a-personal-access-token&quot; target=&quot;_blank&quot;&gt;How To&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Copy the following script locally (it&#39;s in Ruby, so make sure you have a ruby env):&lt;br /&gt;
&lt;pre style=&quot;text-align: left;&quot;&gt;&lt;code&gt;require &#39;json&#39;
require &#39;open-uri&#39;
require &#39;csv&#39;
require &#39;date&#39;

# Github credentials to access your private project
USERNAME=&quot;[username]&quot;
PASSWORD=&quot;[Personal Access Token]&quot;

# Project you want to export issues from
USER=&quot;[user/org that owns the repo]&quot;
PROJECT=&quot;[repo name]&quot;

# Your local timezone offset to convert times
TIMEZONE_OFFSET=&quot;+3&quot;

BASE_URL=&quot;https://api.github.com/repos/#{USER}/#{PROJECT}/issues&quot;

GITHIB_CACHE=File.dirname(__FILE__) + &quot;/gh_issues.json&quot;

USERS={
  &quot;[GitHub username]&quot; =&amp;gt; &quot;[Jira user/email]&quot;,
  ...
}

SAMPLE_ISSUES=[
  # List of issue IDs you&#39;d like to test with
]

LABEL_BLACKLIST=[
  # List of labels that shouldn&#39;t be copied, such as those that were used for type/priority
]

def markdown(str)
  return str.gsub(&#39;```&#39;, &#39;{code}&#39;)
end

if File.exists? GITHIB_CACHE
  puts &quot;Getting issues from Cache...&quot;
  issues = JSON.parse(File.open(GITHIB_CACHE).read)
else
  puts &quot;Getting issues from Github...&quot;

  page = 1
  issues = []
  last = [{}]
  while issues.size &amp;lt; page*100 and last.size &amp;gt; 0
    URI.open(
      &quot;#{BASE_URL}?status=open&amp;amp;per_page=100&amp;amp;page=#{page}&quot;,
      http_basic_authentication: [USERNAME, PASSWORD]
    ) { |f|
      last = JSON.parse(f.read)

      last.each { |issue|
        if issue[&#39;comments&#39;] &amp;gt; 0
          puts &quot;Getting #{issue[&#39;comments&#39;]} comments for issue #{issue[&#39;number&#39;]} from Github...&quot;
          # Get the comments
          URI.open(issue[&quot;comments_url&quot;], http_basic_authentication: [USERNAME, PASSWORD]) { |f|
            issue[&#39;comments_content&#39;] = JSON.parse(f.read)
          }
        end
      }

      issues += last
      puts &quot;Got #{issues.size} issues so far...&quot;
    }
    page += 1
  end

  File.open(GITHIB_CACHE, &#39;w&#39;) { |f|
    f.write(issues.to_json)
  }
end

puts
puts
puts &quot;Processing #{issues.size} issues...&quot;

csv = CSV.new(File.open(File.dirname(__FILE__) + &quot;/issues.csv&quot;, &#39;w&#39;))
sample = CSV.new(File.open(File.dirname(__FILE__) + &quot;/sample.csv&quot;, &#39;w&#39;))

puts &quot;Initialising CSV file...&quot;
# CSV Headers
header = [
  &quot;Summary&quot;,
  &quot;Description&quot;,
  &quot;Date created&quot;,
  &quot;Date modified&quot;,
  &quot;Issue type&quot;,
  &quot;Priority&quot;,
  &quot;Reporter&quot;,
  &quot;Assignee&quot;,
  &quot;Labels&quot;
]
# We need to add a column for each comment, so this dictates how many comments for each issue you want to support
20.times { header &amp;lt;&amp;lt; &quot;Comments&quot; }
csv &amp;lt;&amp;lt; header
sample &amp;lt;&amp;lt; header

issues.each do |issue|
  puts &quot;Processing issue #{issue[&#39;number&#39;]}...&quot;

  if issue[&#39;pull_request&#39;]
    puts &quot;  PR found, skipping&quot;
    next
  end

  # Work out the type based on our existing labels
  case
    when issue[&#39;labels&#39;].any? { |l| l[&#39;name&#39;] == &#39;Bug&#39; }
      type = &quot;Bug&quot;
    when issue[&#39;labels&#39;].any? { |l| l[&#39;name&#39;] == &#39;Epic&#39; }
      type = &quot;Epic&quot;
    when issue[&#39;labels&#39;].any? { |l| l[&#39;name&#39;] == &#39;Feature&#39; }
      type = &quot;Story&quot;
    else
      type = &quot;Task&quot;
  end

  # Work out the priority based on our existing labels
  case
    when issue[&#39;labels&#39;].any? { |l| [&#39;Priority&#39;, &#39;Prod&#39;].include? l[&#39;name&#39;] }
      priority = &quot;High&quot;
  end

  # Needs to match the header order above, date format are based on Jira default
  row = [
    issue[&#39;title&#39;],
    &quot;#{issue[&#39;body&#39;].empty? ? &quot;&quot; : markdown(issue[&#39;body&#39;]) + &quot;; &quot;}[GitHub Link|#{issue[&quot;html_url&quot;]}]&quot;,
    DateTime.parse(issue[&#39;created_at&#39;]).new_offset(TIMEZONE_OFFSET).strftime(&quot;%d/%b/%y %l:%M %p&quot;),
    DateTime.parse(issue[&#39;updated_at&#39;]).new_offset(TIMEZONE_OFFSET).strftime(&quot;%d/%b/%y %l:%M %p&quot;),
    type,
    priority,
    USERS[issue[&#39;user&#39;][&#39;login&#39;]],
    USERS[(issue[&#39;assignee&#39;] || {})[&#39;login&#39;]],
    issue[&#39;labels&#39;].map { |label| label[&#39;name&#39;] }.filter { |label| !LABEL_BLACKLIST.include?(label) }.map { |label| label.gsub(&#39; &#39;, &#39;-&#39;) }.join(&quot; &quot;)
  ]

  if issue[&#39;comments_content&#39;]
    issue[&#39;comments_content&#39;].each do |c|
      # Date format needs to match hard coded format in the Jira importer
      comment_time = DateTime.parse(c[&#39;created_at&#39;]).new_offset(TIMEZONE_OFFSET).strftime(&quot;%d/%b/%y %l:%M %p&quot;)

      # Put the comment in a format Jira can parse, removing #s as Jira thinks they&#39;re comments
      comment = &quot;#{comment_time}; #{USERS[c[&#39;user&#39;][&#39;login&#39;]]}; #{markdown(c[&#39;body&#39;]).gsub(&#39;#&#39;, &#39;&#39;).gsub(&#39;,&#39;, &#39;;&#39;)[0...1024]}&quot;

      row &amp;lt;&amp;lt; comment
    end
  end

  csv &amp;lt;&amp;lt; row
  if SAMPLE_ISSUES.include? issue[&#39;number&#39;]
    sample &amp;lt;&amp;lt; row
  end
end
&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;li&gt;Fill in the fields in the script, like user name, access token, etc.&lt;/li&gt;&lt;li&gt;Run the script with: &quot;ruby &amp;lt;script name&amp;gt;&quot;. You&#39;ll see 3 files created:&lt;/li&gt;&lt;ol&gt;&lt;li&gt;gh_issues.json - that&#39;s a cache of the issues from GitHub.&amp;nbsp; As long as it exists, the script will not download the info again but rather reuse this.&amp;nbsp; Delete the file to re-download.&lt;/li&gt;&lt;li&gt;sample.csv - a short list of issues that&#39;s used for import testing so you can check all your fields are translated properly.&lt;/li&gt;&lt;li&gt;issues.csv - that&#39;s the full fledged list of all issues.&amp;nbsp; Only import it in the end when you&#39;re done with all the validations.&lt;/li&gt;&lt;/ol&gt;&lt;li&gt;Follow the Jira instructions&amp;nbsp;&lt;a href=&quot;https://support.atlassian.com/jira-cloud-administration/docs/import-data-from-a-csv-file/&quot; target=&quot;_blank&quot;&gt;Here&lt;/a&gt;&amp;nbsp;to import the issues into Jira (use sample.csv to test, issues.csv to do the full import)&lt;/li&gt;
&lt;/ol&gt;&lt;div&gt;That&#39;s it.&amp;nbsp; Last version I found and picked up from was from 2012.&lt;/div&gt;&lt;div&gt;I updated it to the 2020 APIs. Let&#39;s see how long those last :)&lt;/div&gt;
&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://codehowtos.blogspot.com/feeds/160753045674628530/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codehowtos.blogspot.com/2020/12/migrating-issues-from-github-to-jira.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/160753045674628530'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/160753045674628530'/><link rel='alternate' type='text/html' href='http://codehowtos.blogspot.com/2020/12/migrating-issues-from-github-to-jira.html' title='Migrating issues from GitHub to Jira'/><author><name>Lagi</name><uri>http://www.blogger.com/profile/06115049194000560865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2138644806777257073.post-1651382192248556313</id><published>2011-11-10T11:49:00.000+02:00</published><updated>2011-11-10T11:49:32.535+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="java"/><title type='text'>Introduction to LambdaJ: Get rid of those pesky loops</title><content type='html'>After a very long pause, I thought it&#39;d be nice to introduce some cool Java technologies I stumbled upon lately.&lt;br /&gt;
&lt;br /&gt;
So, straight to business, I want to talk a bit about &lt;a href=&quot;http://code.google.com/p/lambdaj/&quot;&gt;LambdaJ&lt;/a&gt;. It&#39;s a super cool infrastructure which is targeting those loops you always end up writing in Java.&lt;br /&gt;
&lt;br /&gt;
Let&#39;s see some examples.&lt;br /&gt;
Say you&#39;ve got an address book, and it&#39;s saved in a List&amp;lt;Person&amp;gt; where Person has a getSurname() method.&lt;br /&gt;
We wish to get all those Smiths among the members of the address book.&lt;br /&gt;
Now, usually you find yourself writing something like:&lt;br /&gt;
&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;List&amp;lt;Person&amp;gt; smiths = new ArrayList&amp;lt;person&amp;gt;();
for (Person person : addressBook) {
    if (person.getSurname().equals(&quot;Smith&quot;)) {
        smiths.add(person);
    }
}
&lt;/pre&gt;
&lt;br /&gt;
Instead, we like this clean Python syntax:&lt;br /&gt;
&lt;pre class=&quot;python&quot; name=&quot;code&quot;&gt;smiths = [person for person in addressBook if person.getSurname() == &quot;Smith&quot;]
&lt;/pre&gt;
&lt;br /&gt;
So, Java is not the most flexible language there is, but this LambdaJ syntax really nears perfection.&lt;br /&gt;
This will look like:&lt;br /&gt;
&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;List&amp;lt;Person&amp;gt; smiths = select(addressBook, having(on(Person.class).getSurname().equals(&quot;Smith&quot;)));
&lt;/pre&gt;
&lt;br /&gt;
Ok, that was nice. Now let&#39;s look at a foreach block.&lt;br /&gt;
Regularly, we&#39;d see something like:&lt;br /&gt;
&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;for (Person knight : newKnights) {
    knight.setTitle(&quot;Sir&quot;);
}
&lt;/pre&gt;
&lt;br /&gt;
We could do this instead:&lt;br /&gt;
&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;forEach(newKnights).setTitle(&quot;Sir&quot;);
&lt;/pre&gt;
&lt;br /&gt;
Finally, lets sort. I won&#39;t even write the code that sorts the address book by first name without LambdaJ.&lt;br /&gt;
With LambdaJ it looks really cool:&lt;br /&gt;
&lt;pre class=&quot;java&quot; name=&quot;code&quot;&gt;sort(addressBook, on(Person.class).getFirstName());
&lt;/pre&gt;
&lt;br /&gt;
So, many thanks to the developers who wrote this project, and for making it open source.&lt;br /&gt;
That&#39;s all for now, thanks for reading.</content><link rel='replies' type='application/atom+xml' href='http://codehowtos.blogspot.com/feeds/1651382192248556313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codehowtos.blogspot.com/2011/11/introduction-to-lambdaj-get-rid-of.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/1651382192248556313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/1651382192248556313'/><link rel='alternate' type='text/html' href='http://codehowtos.blogspot.com/2011/11/introduction-to-lambdaj-get-rid-of.html' title='Introduction to LambdaJ: Get rid of those pesky loops'/><author><name>Lagi</name><uri>http://www.blogger.com/profile/06115049194000560865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2138644806777257073.post-5613906235032085506</id><published>2011-04-03T20:51:00.002+03:00</published><updated>2011-04-03T20:53:33.646+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="junit"/><title type='text'>Run a JUnit test repeatedly</title><content type='html'>&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;I like JUnit. It&#39;s easy to extend, and easy to use.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;After reading abyx&#39;s post on&amp;nbsp;&lt;/span&gt;&lt;a href=&quot;https://gist.github.com/897229&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #6fa8dc; font-family: Arial, Helvetica, sans-serif;&quot;&gt;Retry Rule&lt;/span&gt;&lt;/a&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;, I decided to write a post about running repeating tests with JUnit.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Hope you enjoy this:&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Sometimes you wish to run a test many times. For example, it might have some random factor in it. To cover many cases, you&#39;d like to run it a lot of times. What options are there?&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;First, and the most obvious, is a loop. Run a for loop, and see it fail:&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiak3Poky6zU-ZGq4YScAVQvEgrJyPb_5Jf-B8Qcea8w-lyTu4VfLWLdZlydR3T-9g8xTGPhoru72qJhjTrQo5dDwhkbpE-UAo6buNsSG41yrVjHSjFNfM9hw-WND1uzKEBHdUOtkLPcrTI/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIVwdRAKkE-FZYokpL5L_vGyiLBN38d2t0mNCxUt-t2yzBEnbZraOiJUJbe6HU085uTWGPAU_mJh2AHou-ukm-Z5bC61lUvdHrHZNH4VkpkgcdeUS8tDQ6a07j3uHZpQv-QEAXq3YCZsjo/s1600/Example1.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;116&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIVwdRAKkE-FZYokpL5L_vGyiLBN38d2t0mNCxUt-t2yzBEnbZraOiJUJbe6HU085uTWGPAU_mJh2AHou-ukm-Z5bC61lUvdHrHZNH4VkpkgcdeUS8tDQ6a07j3uHZpQv-QEAXq3YCZsjo/s200/Example1.jpg&quot; width=&quot;200&quot; /&gt;&lt;/a&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; public class ExampleTest {  
      @Test  
      public void sometimesFail() {  
           for (int i = 0; i &amp;lt; 10; i++) {  
                int rand = new Random().nextInt(3);  
                if (rand % 3 == 0) {  
                     fail();  
                }  
           }  
      }  
 }  
&lt;/code&gt;&lt;/pre&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;This will generate a single test in the tree. It will fail on the first error and won&#39;t give you an&amp;nbsp;assessment of&amp;nbsp;how many times it took till it failed.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Another option is the Parametrized Runner. That would look like this:&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiak3Poky6zU-ZGq4YScAVQvEgrJyPb_5Jf-B8Qcea8w-lyTu4VfLWLdZlydR3T-9g8xTGPhoru72qJhjTrQo5dDwhkbpE-UAo6buNsSG41yrVjHSjFNfM9hw-WND1uzKEBHdUOtkLPcrTI/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCPtX6vtcOElVjYu-TjHevzVvlEtV-xCcydnURH6no7R-L5F8ujAijj3Opmoz76ZyagpQ_DSiX_ZU9g73uVdJS5hqc5hjEdqPOZhAZA2e0XiOQPvPRopGLMxQ6BEvzyW5udOJAVG3uMEu3/s1600/Example2.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiCPtX6vtcOElVjYu-TjHevzVvlEtV-xCcydnURH6no7R-L5F8ujAijj3Opmoz76ZyagpQ_DSiX_ZU9g73uVdJS5hqc5hjEdqPOZhAZA2e0XiOQPvPRopGLMxQ6BEvzyW5udOJAVG3uMEu3/s200/Example2.jpg&quot; width=&quot;173&quot; /&gt;&lt;/a&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; @RunWith(Parameterized.class)  
 public class ExampleTest2 {  
      @Parameters  
      public static Collection&amp;lt;Object[]&amp;gt;
                                 generateParams() {  
           List&amp;lt;Object[]&amp;gt; params =
                   new ArrayList&amp;lt;Object[]&amp;gt;();  
           for (int i = 1; i &amp;lt;= 10; i++) {  
                params.add(new Object[] {i});  
           }  
           return params;  
      }  
        
      public ExampleTest2(int param) {}  
        
      @Test  
      public void sometimesFail() {  
           int rand = new Random().nextInt(3);  
           if (rand % 3 == 0) {  
                fail();  
           }  
      }  
 }  
&lt;/code&gt;&lt;/pre&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;This is a nice solution, but the test is filled with&amp;nbsp;unnecessary code. Also, all the tests in the class will run for each parameter. What if I only want to repeat a single method?&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Here is a nice solution, in my opinion:&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiak3Poky6zU-ZGq4YScAVQvEgrJyPb_5Jf-B8Qcea8w-lyTu4VfLWLdZlydR3T-9g8xTGPhoru72qJhjTrQo5dDwhkbpE-UAo6buNsSG41yrVjHSjFNfM9hw-WND1uzKEBHdUOtkLPcrTI/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4lC2a-K3D1O4l44t9Y7oLmRGq6LyBELh7M5vGg2uH58U0SJr3XIyx7HwSzIlGweGMOKRtgsrPKG9RDMCL1TSses8I4pjMBdpesvzuzs4x0WdyCjvd4Hnqq_nuRfltzfTzHUPR1AnZezW/s1600/Example3.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: right; float: right; margin-bottom: 1em; margin-left: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEir4lC2a-K3D1O4l44t9Y7oLmRGq6LyBELh7M5vGg2uH58U0SJr3XIyx7HwSzIlGweGMOKRtgsrPKG9RDMCL1TSses8I4pjMBdpesvzuzs4x0WdyCjvd4Hnqq_nuRfltzfTzHUPR1AnZezW/s200/Example3.jpg&quot; width=&quot;171&quot; /&gt;&lt;/a&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; @RunWith(ExtendedRunner.class)  
 public class ExampleTest3 {  
      @Test  
      @Repeat(10)  
      public void sometimesFail() {  
           int rand = new Random().nextInt(3);  
           if (rand % 3 == 0) {  
                fail();  
           }  
      }  
 }  
&lt;/code&gt;&lt;/pre&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&amp;nbsp;Only state the method you want to repeat, and how many times to do this. The rest is done for you.&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;So, whats behind this code?&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;First, add an Annotation:&lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiak3Poky6zU-ZGq4YScAVQvEgrJyPb_5Jf-B8Qcea8w-lyTu4VfLWLdZlydR3T-9g8xTGPhoru72qJhjTrQo5dDwhkbpE-UAo6buNsSG41yrVjHSjFNfM9hw-WND1uzKEBHdUOtkLPcrTI/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; @Retention(RetentionPolicy.RUNTIME)  
 @Target({ElementType.METHOD})  
 public @interface Repeat {  
      int value();  
 }  
&lt;/code&gt;&lt;/pre&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;Finally, lets add the Runner. This simply overrides the default JUnit runner (its a bit long, but not too much): &lt;/span&gt;&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiak3Poky6zU-ZGq4YScAVQvEgrJyPb_5Jf-B8Qcea8w-lyTu4VfLWLdZlydR3T-9g8xTGPhoru72qJhjTrQo5dDwhkbpE-UAo6buNsSG41yrVjHSjFNfM9hw-WND1uzKEBHdUOtkLPcrTI/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; public class ExtendedRunner extends BlockJUnit4ClassRunner {  
   
      public ExtendedRunner(Class&amp;lt;?&amp;gt; klass) throws InitializationError {  
           super(klass);  
      }  
   
      @Override  
      protected Description describeChild(FrameworkMethod method) {  
           if (method.getAnnotation(Repeat.class) != null &amp;amp;&amp;amp;  
                     method.getAnnotation(Ignore.class) == null) {  
                return describeRepeatTest(method);  
           }  
           return super.describeChild(method);  
      }  
   
      private Description describeRepeatTest(FrameworkMethod method) {  
           int times = method.getAnnotation(Repeat.class).value();  
   
           Description description = Description.createSuiteDescription(  
                     testName(method) + &quot; [&quot; + times + &quot; times]&quot;,  
                     method.getAnnotations());  
   
           for (int i = 1; i &amp;lt;= times; i++) {  
                description.addChild(Description.createTestDescription(  
                          getTestClass().getJavaClass(),  
                          &quot;[&quot; + i + &quot;] &quot; + testName(method)));  
           }  
           return description;  
      }  
   
      @Override  
      protected void runChild(final FrameworkMethod method, RunNotifier notifier) {  
           Description description = describeChild(method);  
             
           if (method.getAnnotation(Repeat.class) != null &amp;amp;&amp;amp;  
                     method.getAnnotation(Ignore.class) == null) {  
                runRepeatedly(methodBlock(method), description, notifier);  
           }  
           super.runChild(method, notifier);  
      }  
   
      private void runRepeatedly(Statement statement, Description description,  
                RunNotifier notifier) {  
           for (Description desc : description.getChildren()) {  
                runLeaf(statement, desc, notifier);  
           }  
      }  
        
 }  &lt;/code&gt;&lt;/pre&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;As always, here is the source code:&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #3d85c6;&quot;&gt;&amp;nbsp;&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; color: #3d85c6; font-family: Verdana, Geneva, Arial, Helvetica, sans-serif; font-size: 13px;&quot;&gt;&lt;a href=&quot;http://tinyurl.com/3mu2zbc&quot;&gt;http://tinyurl.com/3mu2zbc&lt;/a&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-style-span&quot; style=&quot;-webkit-border-horizontal-spacing: 2px; -webkit-border-vertical-spacing: 2px; font-family: Arial, Helvetica, sans-serif;&quot;&gt;Also, you can&amp;nbsp;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;a href=&quot;http://www.amazon.com/s/?ie=UTF8&amp;amp;tag=code4kids-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;search-alias=aps&amp;amp;field-keywords=junit&quot; target=&quot;_blank&quot;&gt;Search Amazon.com for JUnit books&lt;/a&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=code4kids-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=&quot; style=&quot;border-bottom-style: none !important; border-color: initial !important; border-left-style: none !important; border-right-style: none !important; border-top-style: none !important; border-width: initial !important; cursor: move; margin-bottom: 0px !important; margin-left: 0px !important; margin-right: 0px !important; margin-top: 0px !important; padding-bottom: 0px !important; padding-left: 0px !important; padding-right: 0px !important; padding-top: 0px !important;&quot; width=&quot;1&quot; /&gt;&lt;/span&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;font-family: Arial, Helvetica, sans-serif;&quot;&gt;.&lt;/span&gt;</content><link rel='replies' type='application/atom+xml' href='http://codehowtos.blogspot.com/feeds/5613906235032085506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codehowtos.blogspot.com/2011/04/run-junit-test-repeatedly.html#comment-form' title='19 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/5613906235032085506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/5613906235032085506'/><link rel='alternate' type='text/html' href='http://codehowtos.blogspot.com/2011/04/run-junit-test-repeatedly.html' title='Run a JUnit test repeatedly'/><author><name>Lagi</name><uri>http://www.blogger.com/profile/06115049194000560865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiIVwdRAKkE-FZYokpL5L_vGyiLBN38d2t0mNCxUt-t2yzBEnbZraOiJUJbe6HU085uTWGPAU_mJh2AHou-ukm-Z5bC61lUvdHrHZNH4VkpkgcdeUS8tDQ6a07j3uHZpQv-QEAXq3YCZsjo/s72-c/Example1.jpg" height="72" width="72"/><thr:total>19</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2138644806777257073.post-265238723492301030</id><published>2011-04-01T23:42:00.010+03:00</published><updated>2011-04-20T17:10:12.530+03:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="datastructure"/><category scheme="http://www.blogger.com/atom/ns#" term="games"/><title type='text'>Building a Maze</title><content type='html'>I always like to discover some cool ways of using a simple data structure or algorithm to simplify a piece of code.&amp;nbsp;Yesterday I overheard a conversation about Maze construction and the Disjoint-Set data structure, often considered used for optimization purposes only. So, I decided to try and implement this small example of how to quickly create a maze using this data structure.&lt;br /&gt;
&lt;br /&gt;
The Disjoint-Set, for those who are not familiar, is a data structure that allows to keep track of groups, letting you join groups and find the group to which a specific component belongs, all in O(Log*(n)).&lt;br /&gt;
For more info, read:&amp;nbsp;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #3d85c6;&quot;&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Disjoint-set_data_structure&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #3d85c6;&quot;&gt;http://en.wikipedia.org/wiki/Disjoint-set_data_structure&lt;/span&gt;&lt;/a&gt;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Now, lets think of a maze as a grid of cells. For cells X and Y, you can reach from X to Y through the winding maze if there is a&amp;nbsp;continuous&amp;nbsp;route without walls between the two. So, lets start with a maze in which each cell has all its 4 walls built. The goal is to get a maze in which there is exactly 1 way to get from any cell X to any cell Y. Now lets add the data structure into the image. We start with a Disjoint-set that has a group for each of the cells. Each turn we destroy a wall between 2 cells that belong to different groups. This way we open exactly 1 passage between each of the cells in one group to each in the other. We know we&#39;ve finished when there is exactly one group in the set.&lt;br /&gt;
&lt;br /&gt;
For those who like algorithms, this is&amp;nbsp;actually&amp;nbsp;an implementation of the Kruskal algorithm for finding Minimal Spanning Trees in graphs (if you take the grid cells as vertices and the walls as edges).&lt;br /&gt;
You can read more here:&amp;nbsp;&lt;a href=&quot;http://en.wikipedia.org/wiki/Kruskal%27s_algorithm&quot;&gt;http://en.wikipedia.org/wiki/Kruskal%27s_algorithm&lt;/a&gt;&lt;br /&gt;
or you can look at some boos here:&amp;nbsp;&lt;a href=&quot;http://www.amazon.com/s/?ie=UTF8&amp;amp;tag=code4kids-20&amp;amp;link_code=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;search-alias=aps&amp;amp;field-keywords=algorithms&quot; target=&quot;_blank&quot;&gt;Books on Algorithms on Amazon&lt;/a&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;1&quot; src=&quot;http://www.assoc-amazon.com/e/ir?t=code4kids-20&amp;amp;l=btl&amp;amp;camp=213689&amp;amp;creative=392969&amp;amp;o=1&amp;amp;a=&quot; style=&quot;border: none !important; margin: 0px !important; padding: 0px !important;&quot; width=&quot;1&quot; /&gt;&lt;br /&gt;
&lt;br /&gt;
Lets look at some code.&lt;br /&gt;
A simple implementation of the Disjoint-set:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiak3Poky6zU-ZGq4YScAVQvEgrJyPb_5Jf-B8Qcea8w-lyTu4VfLWLdZlydR3T-9g8xTGPhoru72qJhjTrQo5dDwhkbpE-UAo6buNsSG41yrVjHSjFNfM9hw-WND1uzKEBHdUOtkLPcrTI/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; public class DisjointSet {  
      private int[] set;  
      private int[] sizes;  
      private int size;  
      public DisjointSet(int size) {  
           this.set = new int[size];  
           for (int i = 0; i &amp;lt; size; i++) {  this.set[i] = i;  }  
           this.sizes = new int[size];  
           for (int i = 0; i &amp;lt; size; i++) {  this.sizes[i] = 1; }  
           this.size = size;  
      }  
      public int find(int item) {
           int root = item;
           // find the root
           while (set[root] != root) {
                 root = set[root];
           }
           // now shorten the paths
           int curr = item;
           while (set[curr] != root) {
                 set[curr] = root;
           }
           return root;
      }
      public int join(int item1, int item2) {  
           int group1 = find(item1);  
           int group2 = find(item2);  
           --size;  
           if (sizes[group1] &amp;gt; sizes[group2]) {  
                set[group2] = group1;  
                sizes[group1] += sizes[group2];  
                return group1;  
           } else {  
                set[group1] = group2;  
                sizes[group2] += sizes[group1];                 
                return group2;  
           }  
      }  
 }  
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
Now, lets build the maze:&lt;br /&gt;
&lt;br /&gt;
&lt;pre style=&quot;background-image: URL(https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiak3Poky6zU-ZGq4YScAVQvEgrJyPb_5Jf-B8Qcea8w-lyTu4VfLWLdZlydR3T-9g8xTGPhoru72qJhjTrQo5dDwhkbpE-UAo6buNsSG41yrVjHSjFNfM9hw-WND1uzKEBHdUOtkLPcrTI/s320/codebg.gif); background: #f0f0f0; border: 1px dashed #CCCCCC; color: black; font-family: arial; font-size: 12px; height: auto; line-height: 20px; overflow: auto; padding: 0px; text-align: left; width: 99%;&quot;&gt;&lt;code style=&quot;color: black; word-wrap: normal;&quot;&gt; Maze createRandomMaze(int rows, int columns) {  
           Maze maze = new Maze(rows, columns);  
           // create all walls  
           List&amp;lt;Wall&amp;gt; walls = maze.getAllInnerWalls();  
           // remove all the walls you can  
           DisjointSet diset = new DisjointSet(rows*columns);  
           while (diset.size() &amp;gt; 1) {  
                int wallIndex = random.nextInt(walls.size());  
                int cell1 = walls.get(wallIndex).cell1;  
                int cell2 = walls.get(wallIndex).cell2;  
                if (diset.find(cell1) != diset.find(cell2)) {  
                     // we can remove the wall  
                     maze.removeWall(walls.get(wallIndex));  
                     diset.join(cell1, cell2);  
                }  
                walls.remove(wallIndex);  
           }  
           return maze;  
      }  
&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;
And here is the result:&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk7kQzLGluQ8qugX7FFQdcICNp0FC0Ecxu8Z4A5MSE_jrJinvpxCwSSCaEGz-ceD2WcFM_JFhiEiNFlnq7QAtOyWwuHuuxbJQ-vWnavCSejUpnveu-yI8myuup6SRuiAq9TUAgZfAV4gLJ/s1600/maze.jpg&quot; imageanchor=&quot;1&quot; style=&quot;clear: left; float: left; margin-bottom: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk7kQzLGluQ8qugX7FFQdcICNp0FC0Ecxu8Z4A5MSE_jrJinvpxCwSSCaEGz-ceD2WcFM_JFhiEiNFlnq7QAtOyWwuHuuxbJQ-vWnavCSejUpnveu-yI8myuup6SRuiAq9TUAgZfAV4gLJ/s320/maze.jpg&quot; width=&quot;307&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
For the full code and much much more, visit my open-source project at:&amp;nbsp;&lt;a href=&quot;https://code.google.com/p/ai4u/&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #3d85c6;&quot;&gt;https://code.google.com/p/ai4u/&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
The code in this post is located at:&lt;br /&gt;
Disjoint-Set:&amp;nbsp;&lt;a href=&quot;https://code.google.com/p/ai4u/source/browse/com.ai4u.util/trunk/src/com/ai4u/util/disjointSet/ArrayDisjointSet.java&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #3d85c6;&quot;&gt;https://code.google.com/p/ai4u/source/browse/com.ai4u.util/trunk/src/com/ai4u/util/disjointSet/ArrayDisjointSet.java&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
Maze:&amp;nbsp;&lt;a href=&quot;https://code.google.com/p/ai4u/source/browse/com.ai4u.util/trunk/src/com/ai4u/util/games/maze/Maze.java&quot;&gt;&lt;span class=&quot;Apple-style-span&quot; style=&quot;color: #3d85c6;&quot;&gt;https://code.google.com/p/ai4u/source/browse/com.ai4u.util/trunk/src/com/ai4u/util/games/maze/Maze.java&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Well, this is it for my first post.&lt;br /&gt;
Please, send me any ideas, questions or comments to&amp;nbsp;&lt;a href=&quot;mailto:igal1987+blog@gmail.com&quot;&gt;My Email&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://codehowtos.blogspot.com/feeds/265238723492301030/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://codehowtos.blogspot.com/2011/04/building-maze.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/265238723492301030'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2138644806777257073/posts/default/265238723492301030'/><link rel='alternate' type='text/html' href='http://codehowtos.blogspot.com/2011/04/building-maze.html' title='Building a Maze'/><author><name>Lagi</name><uri>http://www.blogger.com/profile/06115049194000560865</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk7kQzLGluQ8qugX7FFQdcICNp0FC0Ecxu8Z4A5MSE_jrJinvpxCwSSCaEGz-ceD2WcFM_JFhiEiNFlnq7QAtOyWwuHuuxbJQ-vWnavCSejUpnveu-yI8myuup6SRuiAq9TUAgZfAV4gLJ/s72-c/maze.jpg" height="72" width="72"/><thr:total>5</thr:total></entry></feed>