<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" version="2.0"> 

<channel> 
	<title>Shin.ws</title> 
	<atom:link href="http://shin.ws/feed/" type="application/rss+xml" /> 
	<link>http://shin.ws</link> 
	<description>Science, philosophy, programming, and humor for a long and prosperous life</description> 
	<lastBuildDate>Sun, 20 Feb 2011 10:49:16 +0000</lastBuildDate> 
	<language>en</language> 
	<sy:updatePeriod>hourly</sy:updatePeriod> 
	<sy:updateFrequency>1</sy:updateFrequency> 
	
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/daeyun" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="daeyun" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Multi-threaded Java Web Crawler</title>
		<link>http://shin.ws/multi-threaded-java-web-crawler/</link>
		<comments>http://shin.ws/multi-threaded-java-web-crawler/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 07:22:16 -0600</pubDate>

		<content:encoded><![CDATA[ <p>I accidentally found this code in my old USB drive and decided to share in case someone finds it helpful.</p>

<p>This is basically a program that mass-downloads files in a list. In this  example code, the list of the files is generated using a specific syntax: a URL input of http://shin.ws/[!&lt;-1,100->!], for example, is a list containing http://shin.ws/1, http://shin.ws/2, ... http://shin.ws/100. I just arbitrarily chose ask.com in the example below. It can be easily expanded so that it imports the list from different sources.</p>

<p>Download queries are saved in a DownInfo object, and they are stacked in the DownloadQueue queue. The default number of threads is 16.</p>

<pre>
/* Daeyun Shin */

/* M_HTTPDown.java */
import java.io.*;
import java.util.ArrayList;
import java.util.regex.Pattern;
import java.util.regex.Matcher;
public class M_HTTPDown {
  final static int maxThreadCount = 16;
  public static void main(String[] args){
    String regex="\\[!<-[0-9]*,.[0-9]*->!\\]";
    String fURL = "http://www.ask.com/web?q=[!<-20001,50000->!]&page=1";
    String temp=null;
    int n1,n2;
    Pattern r = Pattern.compile(regex);
    Matcher m = r.matcher(fURL);
    if (m.find()) {
      temp=m.group();
    }else{
      System.out.println("Wrong regex format: " + fURL);
      System.exit(0);
    }
    System.out.println(temp);
    r = Pattern.compile("[0-9]+");
    m = r.matcher(temp);
    m.find();
    n1=Integer.parseInt(m.group());
    m.find();
    n2=Integer.parseInt(m.group());
    for(int i=n1;i&#60;=n2;i++){
      DownInfo d= new DownInfo(fURL.replaceFirst(regex, Integer.toString(i))
              ,getUA(), "UTF-8","UTF-8", "HTTPDown/"+i+".html");
      DownloadQueue.add(d);
    }
    for(int i=maxThreadCount;i>0;i--){
      Thread downloadThread = new Thread(new URLDownload());
      downloadThread.start();
    }

  }
    public static String getUA(){
      BufferedReader UA_reader;
      ArrayList&#60;String> UA_list=new ArrayList&#60;String>();
      String line;
      try{
        UA_reader=new BufferedReader(new FileReader(new File("UA-list.txt")));
        while((line=UA_reader.readLine())!=null){
          UA_list.add(line);
            }
      }catch(Exception ex){
        System.out.println("Failed to read UA-list.txt");
        ex.printStackTrace();
        return "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;" +
                "rv:1.9.0.10)Gecko/2009042316 Firefox/3.0.10";
      }
      return "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US;" +
            "rv:1.9.0.10) Gecko/2009042316 Firefox/3.0.10";
      //return UA_list.get((int)(Math.random()*(UA_list.size())));
      //reading from file temporarily disabled.
    }
}

/* DownloadQueue.java */
import java.util.Queue;
import java.util.LinkedList;
public class DownloadQueue {
  public static Queue&#60;DownInfo> downloadList = new LinkedList&#60;DownInfo>();
  public static synchronized void add(DownInfo di){
    downloadList.add(di);
  }
  public static synchronized DownInfo poll(){
    return downloadList.poll();
  }
  public static DownInfo peek(){
    return downloadList.peek();
  }
}

/*
 * DownInfo.java
 * */
public class DownInfo {
  String url, userAgent, inputEncoding, outputEncoding, fileName;
  public DownInfo(String u,String ua,String iEncoding,
          String oEncoding, String fName){
    url=u;
    userAgent=ua;
    inputEncoding=iEncoding;
    outputEncoding=oEncoding;
    fileName=fName;
  }
}

/* URLDownload.java */
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.SocketTimeoutException;
import java.net.URL;
public class URLDownload implements Runnable{
  URL u;
  HttpURLConnection httpConnection;
  String line,content="";
  BufferedReader reader;
  BufferedWriter writer;
  String url, userAgent, inputEncoding, outputEncoding, fileName;
  DownInfo tempD;
  int oSize;
  int threadID=(int)(Math.random()*9999);
  public void initialize(DownInfo d){
    url=d.url;
    userAgent=d.userAgent;
    inputEncoding=d.inputEncoding;
    outputEncoding=d.outputEncoding;
    fileName=d.fileName;
  }
  public void run(){
    System.out.println("Thread "+threadID+" has started.");
    while((tempD=DownloadQueue.poll())!=null){
      initialize(tempD);
      try{
        u = new URL(url);
        httpConnection = (HttpURLConnection) u.openConnection(); 
        httpConnection.setRequestProperty("User-Agent", userAgent);
        httpConnection.setReadTimeout(10000);
        if(httpConnection.getResponseCode()==200){
          reader = new BufferedReader(new InputStreamReader(
                  httpConnection.getInputStream(), inputEncoding ));
          writer = new BufferedWriter(new OutputStreamWriter(
                  new FileOutputStream(fileName), outputEncoding));
          content="";
          oSize=0;
          while((line=reader.readLine())!=null){
            writer.write(line+"\n");
            oSize+=line.length()+1;
          }
          reader.close();
          writer.close();

        }else{
          System.out.println("httpConnection Error: "
                  +httpConnection.getResponseCode());
        }
      }catch(SocketTimeoutException ex){
        System.out.println("Connection timed out.");
      }catch(Exception ex){
        ex.printStackTrace();
      }
      System.out.println(threadID+": "+u.toString() + "["+oSize+"]");
    }
    System.out.println("End of thread"+threadID+".");
  }
}
</pre>
 ]]></content:encoded>
	</item>
		<item>
		<title>Approximate e^x without the math library in C</title>
		<link>http://shin.ws/ex-without-the-math-library-in-c/</link>
		<comments>http://shin.ws/ex-without-the-math-library-in-c/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 07:20:18 -0600</pubDate>

		<content:encoded><![CDATA[ <p>This is a simple C program that approximates e^x based on its Taylor series. It guarantees that the error is smaller than the input value r.</p>

<pre>
/* Daeyun Shin */
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
double power(double x, int y){ 
    int i;
    double result=1;
    for(i=0;i&lt;y;i++) result*=x;
    return result;
}
int factorial(int x){ 
    int result=1;
    for(;x&gt;1;x--) result*=x;
    return result;
}
double nth_taylor(double x,int n,int errorChecking){
    if (errorChecking && x&lt;0) x=-x;
    return power(x,n-1)/factorial(n-1);
}
int main(){
    int n=0;
    double ans=0,r,x;
    printf("Enter in the value of x:");
    scanf("%lf",&x);
    printf("Enter in the value of r:");
    scanf("%lf",&r);
    while(nth_taylor(x,n,1)&gt;=r){
        n++; 
        ans+=nth_taylor(x,n,0);
    }   
    printf("Number of terms = %d\nAnswer = %lf",n,ans);
    return 0;
}
</pre>
 ]]></content:encoded>
	</item>
		<item>
		<title>IRC KickBan Bot</title>
		<link>http://shin.ws/irc-kickban-bot/</link>
		<comments>http://shin.ws/irc-kickban-bot/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 20:54:15 -0600</pubDate>

		<content:encoded><![CDATA[ <p>I wrote a simple IRC bot in Python. Whenever a user joins a channel, it immediately bans and kicks the user. It is useful for channel squatting and pranks. It can be easily expanded so that it kickbans under certain conditions.</p>

<p>You can PM the bot to make it join or leave a channel.</p>

<p>For example, <code>/msg iKickban join #testchannel</code>, <code>/msg iKickban leave #testchannel</code></p>

<pre>
#!/usr/bin/python2
import socket, string, re

host="irc.freenode.net"
port=6667
nick="iKickban"
ident="iKickban"
realname="kickban"
readbuffer=""

kickmsg="hi"
channels=["#channel1", "#channel2"] #list of channnels to auto join
owner="daeyun" #the bot will ignore commands from other users

s=socket.socket()
s.connect((host,port))
s.send("NICK %s\n" % nick)
s.send("USER %s %s abc :%s\n" % (ident, host, realname))
for channel in channels:
    s.send("JOIN %s\n" % channel)

while 1:
    readbuffer=readbuffer+s.recv(1024)
    temp=string.split(readbuffer, "\n")
    readbuffer=temp.pop( )
    for line in temp:
        line=string.rstrip(line)
        line=string.split(line)
    try:
        m = re.search(':([0-9a-zA-z-_\'`\^]+)!', line[0])
        user=m.group(1)
    except:
        pass
    if line[0]=="PING":
        s.send("PONG %s\n" % line[1])
    elif line[1]=="PRIVMSG" and line[2]==nick:
        try:
            if user==owner:
                if line[3]==":join":
                    s.send("JOIN %s\n" % line[4])
                if line[3]==":leave":
                    s.send("PART %s\n" % line[4])
        except:
            pass
    elif line[1]=="JOIN":
        if user!=nick:
            channel=line[2]
            s.send("MODE %s +b %s\n" % (channel,user))
            s.send("KICK %s %s :%s\n" % (channel,user,kickmsg))
</pre>
 ]]></content:encoded>
	</item>
		<item>
		<title>Simple Irssi Window Navigation</title>
		<link>http://shin.ws/simple-irssi-window-navigation-hack/</link>
		<comments>http://shin.ws/simple-irssi-window-navigation-hack/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 18:37:32 -0600</pubDate>

		<content:encoded><![CDATA[ <p>If you use Irssi as your IRC client and are in a lot of channels like me, sometimes it is hard to quickly navigate to the window you want. I found it convenient to set aliases to , . and ;.</p>

<h2>Set Aliases</h2>

<pre>
/alias . window goto
/alias , window number
/alias ; window name
</pre>

<h2>Example Usage</h2>

<p><code>/. 23</code> (go to the 23rd window)
<br />
<code>/. #freenode</code> (go to channel #freenode)
<br />
<code>/; f</code> (rename the current window to f)
<br />
<code>/. f</code> (go to window f)
<br />
<code>/, 2</code> (make the current window number 2 - you can do Alt-2 to go to this window then)</p>
 ]]></content:encoded>
	</item>
		<item>
		<title>Random Maze Generator</title>
		<link>http://shin.ws/random-micromouse-maze-generator/</link>
		<comments>http://shin.ws/random-micromouse-maze-generator/#comments</comments>
		<pubDate>Sat, 14 Jan 2012 07:15:39 -0600</pubDate>

		<content:encoded><![CDATA[ <p>I made a page using Javascript and HTML5 that visualizes the output of a maze generation program written in C.</p>

<p><a href="http://shin.ws/apps/maze/mazegen_visualizer/visualizer.html">http://shin.ws/apps/maze/mazegen_visualizer/visualizer.html</a></p>

<p>The web UI only includes the visualization part, so until I run the C program on my server again, it will keep showing the same maze. I plan on improving the UI so that it can execute the program on demand.</p>

<h2>Edit</h2>

<p>Oh it's no longer working. I installed another visualizer (maze solving) and that messed it up.</p>

<p><a href="http://shin.ws/apps/maze/visualizer/visualizer.html">http://shin.ws/apps/maze/visualizer/visualizer.html</a></p>
 ]]></content:encoded>
	</item>
		<item>
		<title>How to: Set up a Subversion Repository</title>
		<link>http://shin.ws/how-to-set-up-a-subversion-repository/</link>
		<comments>http://shin.ws/how-to-set-up-a-subversion-repository/#comments</comments>
		<pubDate>Sun, 08 Jan 2012 12:35:53 -0600</pubDate>

		<content:encoded><![CDATA[ <p>This is a simple guide to setting up a Subversion repository on a Debian server. Although I prefer using Git for version control, my partner in a project wanted to use Subversion, so I had to research a little, and here is the summary.</p>

<h2>Install Subversion</h2>

<p>Make sure that Subversion is installed.</p>

<blockquote class="code">which svn
which svnadmin
</blockquote>

<p>If they are not available, install the packages with</p>

<blockquote class="code">apt-get update
apt-get install subversion
</blockquote>

<h2>Create a Repository</h2>

<p>Create a folder for the repository and register.</p>

<blockquote class="code">mkdir /var/svn-repos/
svnadmin create --fs-type fsfs /var/svn-repos/[repository name]
</blockquote>

<h2>Permissions</h2>

<blockquote class="code">groupadd svn-users
addgroup username1 svn-users
addgroup username2 svn-users

chown -R root:svn-users /var/svn-repos/
chmod -R 770 /var/svn-repos/
</blockquote>

<h2>Test</h2>

<blockquote class="code">svn info svn+ssh://username@example.com/var/svn-repos/[repository name]
</blockquote>

<h2>Related Links</h2>

<p><a href="http://www.howtoforge.com/debian_subversion_websvn">Setting up Subversion and websvn on Debian</a></p>

<p><a href="http://wordpress.org/extend/plugins/about/svn/">How to Use Subversion</a></p>
 ]]></content:encoded>
	</item>
		<item>
		<title>The Hitchhiker's Guide to Git</title>
		<link>http://shin.ws/the-hitchhikers-guide-to-git/</link>
		<comments>http://shin.ws/the-hitchhikers-guide-to-git/#comments</comments>
		<pubDate>Mon, 02 Jan 2012 12:41:41 -0600</pubDate>

		<content:encoded><![CDATA[ <p>This is a beginner's guide to the Git version control system. This is mostly a note to myself, but I hope it's useful to others as well.</p>

<h2>Getting Started</h2>

<p>Before using Git, you need to set the user info. It will be displayed in the commit log.
<pre>
git config --glocal user.name "your name"
git config --glocal user.email "email"
</pre></p>

<p>Check the config file with <code>git config --list</code> or <code>cat ~/.gitconfig</code></p>

<p>There are two ways to have a git repository.</p>

<ol>
<li>Creating a new repository: <code>git init</code></li>
<li>Copying from a remote repository: <code>git clone git@example.tld:/project.git</code></li>
</ol>

<p>After editing files (created gpacalculator.py in the example), check the tracking status with <code>git status</code></p>

<p>Example output:</p>

<blockquote class="code"># On branch master
#
# Initial commit
#
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   gpacalculator.py
</blockquote>

<h2>Recording Changes</h2>

<p>Start tracking <em>gpacalculator.py</em> with <code>git add gpacalculator.py</code></p>

<ul>
<li><code>git add .</code> will add everything in the working directory and the subdirectories.</li>
</ul>

<p>Now <code>git status</code> will show:</p>

<blockquote class="code"># Changes to be committed:
#   (use "git rm --cached <file>..." to unstage)
#
#   new file:   gpacalculator.py
</blockquote>

<p><code>git commit -m "comment"</code> will record the change to the repository. Comments are required.</p>

<p>Alternatively, <code>git commit -a</code> will commit with all changes added and <code>git commit -v</code> will show the differences. See <code>man git-commit</code> for more options.</p>

<h2>Logging</h2>

<h2>Branching</h2>

<h2>Remote Repositories</h2>

<p><br /></p>

<p>This guide is currently being updated.</p>

<p><br /></p>

<h2>Tips</h2>

<p><code>git config --global alias.co checkout</code></p>

<p>Check Git version with <code>git --version</code></p>
 ]]></content:encoded>
	</item>
		<item>
		<title>Simple Introduction</title>
		<link>http://shin.ws/random-facts/</link>
		<comments>http://shin.ws/random-facts/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 21:56:38 -0600</pubDate>

		<content:encoded><![CDATA[ <p>Not many people will find it interesting, but here is my Facebook/Google+ style info table. This is just a fast way to know about me.</p>

<table class="infotable">


<tr>
<th class="left">Personality Type</th>
<th>INTJ <span><a href="http://en.wikipedia.org/wiki/INTJ">(?)</a></span></th>
</tr>


<tr>
<th class="left">Favorite Books</th>
<th>The Selfish Gene, The Hitchhiker's Guide to the Galaxy</th>
</tr>


<tr>
<th class="left">Favorite OS</th>
<th>Arch Linux with KDE 4 and Awesome Window Manager</th>
</tr>
<tr>




<th class="left">Text Editor</th>
<th>Vim/gVim</th>
</tr>

<tr>
<th class="left">Hobbies</th>
<th>Web designing, cooking, tennis, web surfing, online shopping, debating, trolling, chatting, photography</th>
</tr>


<tr>
<th class="left">Hometown</th>
<th>Seoul, South Korea</th>
</tr>

<tr>
<th class="left">Places lived</th>
<th>Illinois, Michigan, Seoul</th>
</tr>


<tr>
<th class="left">Favorite Movies</th>
<th>The Matrix Series, Star Wars</th>
</tr>




<tr>
<th class="left">Places I want to live</th>
<th>San Francisco, somewhere in Europe, Singapore, Seoul</th>
</tr>


<tr>
<th class="left">Political Views</th>
<th>Moderate liberal, semi-libertarian</th>
</tr>

<tr>
<th class="left">Games</th>
<th>Starcraft 2, Civilization 5</th>
</tr>

<tr>
<th class="left">Location</th>
<th>Champaign, Illinois</th>
</tr>

<tr>
<th class="left">Age</th>
<th>19</th>
</tr>

</table>

<p><style type="text/css">
table.infotable{
width:100%;
margin-top:20px;
}
.infotable th{
text-align:left;
font-weight:normal;
color:#333;
line-height:1.5;
padding-bottom:15px;
font-size:90%;
}
.infotable th span{
color:#999;
font-size:65%;
position:relative;
top:-5px;
}
.infotable th a{
text-decoration:none;
}
.infotable th.left{
width:140px;
text-align:right;
padding-right:17px;
color:#888;
}
</style></p>
 ]]></content:encoded>
	</item>
		<item>
		<title>ECE110 - Tape Following Car</title>
		<link>http://shin.ws/ece110-tape-following-car/</link>
		<comments>http://shin.ws/ece110-tape-following-car/#comments</comments>
		<pubDate>Sat, 10 Dec 2011 16:19:13 -0600</pubDate>

		<content:encoded><![CDATA[ <p>I designed a small electric car that follows a white piece of tape on a black table. Six infrared sensors and an Ardiuno microcontroller were used.
This is a video from a test run. Unfortunately, I wasn't able to take a video of the final run.</p>

<iframe width="640" height="360" src="http://www.youtube.com/embed/l1SGAGkotIw" frameborder="0" allowfullscreen></iframe>
 ]]></content:encoded>
	</item>
		<item>
		<title>Shinlog</title>
		<link>http://shin.ws/shinlog/</link>
		<comments>http://shin.ws/shinlog/#comments</comments>
		<pubDate>Sat, 10 Dec 2011 16:09:02 -0600</pubDate>

		<content:encoded><![CDATA[ <p>Shinlog is a content management system written in PHP. I started this project in 2010 because I wanted to have a customized website that fits my taste. It is now being used for shin.ws. — <a href="https://github.com/daeyun/Shinlog">available on Github</a></p>

<h2>Features</h2>

<ol>
<li><strong>Admin Interface</strong> - Shinlog allows users to easily modify the content of the website through a minimalistic admin interface. It uses <a href="http://daringfireball.net/projects/markdown/">markdown</a> to generate the HTML. Any part of the website such as the sidebar or the footer can be customized for each post. </li>
<li><strong>Tagging System</strong> - Shinlog automatically links pages according to the tags.</li>
<li><strong>Caching</strong> - Shinlog delivers static pages without making a connection to the database until the content changes.</li>
<li><strong>Hot Keys</strong> - When logged in as admin, you can use hot keys to add, edit, save, and view posts.

<ul>
<li><em>Default Key Bindings</em>: F7 - New Post, F8 - Edit, F9 - Save, F10 - View.</li>
</ul></li>
<li><strong>Post Rank</strong> - Each post has an importance level from 0 to 9. It can be used for search engine optimization or improving the "related posts" result. This feature is yet to be fully implemented.</li>
</ol>

<h2>Changelog</h2>

<ol>
<li><strong>Jan 01, 2012</strong>

<ul>
<li>The wysiwyg text editor was replaced by markdown</li>
<li>Improved template</li>
<li>Widgets can be shown or hidden through the admin panel for each post. Register widgets in config.php</li>
<li>Improved permalink system</li>
<li>Hot Keys</li>
<li>Code syntax highlighting using <a href="http://code.google.com/p/google-code-prettify/">Prettify</a></li>
</ul></li>
</ol>
 ]]></content:encoded>
	</item>
		
	
	</channel>
</rss>

