tag:blogger.com,1999:blog-131001882009-02-21T04:49:58.443-08:00Workspace of JonketoA little corner of the web to document my journey into the work world.Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comBlogger25125tag:blogger.com,1999:blog-13100188.post-9215839227906547122007-02-15T14:30:00.000-08:002007-02-15T14:39:15.230-08:00A little Business Etiquette<p>This etiquette is only really appropriate for Western companies and should not be applied all over the world.</p><p><strong>Introductions</strong><br />When introducing yourself:<br /></p><ul><li>Say Hello.<br /></li><li>Introduce yourself without title (i.e. Mr. Mrs.).<br /></li><li>Add some info about yourself, your position/responsibilities.<br /></li><li>Try to repeat their name, so you can remember it.<br /></li><li>Use other persons title (i.e. Mr. Mrs.) until they invite you to use their first name.<br /></li></ul><p>When introducing two people to each other it is important to rank the two people according to the following criteria:<br /></p><ul><li>Rank, customer is most important<br /></li><li>Age<br /></li><li>Familiarity<br /></li><li>Once rank has been determined introduce the lower ranking person to the higher ranking person. Use the higher ranking person’s title to introduce them (i.e. Mr. Mrs.) and introduce the lower ranking person by the first and last name.<br /></li></ul><p><strong>Handshakes<br /></strong>Do:<br /></p><ul><li>Wipe hands if needed (try not to do it in front of other person)<br /></li><li>Stand close so elbows are slightly bent<br /></li><li>Begin as introductions are ending<br /></li><li>Be firm, but do not squeeze<br /></li><li>Make eye contact and smile<br /></li><li>Continue for 2-3 seconds (2-3 shakes) </li></ul><p><br />Don’t:<br /></p><ul><li>Grab the other person’s hand with two hands<br /></li><li>Grab the other person’s elbow<br /></li><li>Drag the other person’s hand around<br /></li></ul><p><strong>Entering Cubicles</strong><br /></p><ul><li>Knock/announce yourself<br /></li><li>Ask permission to enter<br /></li><li>Enter cubicle to converse if allowed<br /></li><li>Do not hover when occupant is busy<br /></li><li>Do not handle personal or work items on desks<br /></li></ul><strong></strong><p><strong>Deflecting work when busy<br /></strong>If you are busy and someone comes to discuss unrelated or less important work you can use the following techniques to end the conversation without offending anyone:<br /></p><ul><li>Greet the interrupter<br /></li><li>Show interest<br /></li><li>Assert your priority (what you are working on is more important)<br /></li><li>Offer an alternative (i.e. different time to discuss)<br />1. If it is not work related discuss during lunch or after hours<br /></li><strong></strong></ul><p><strong>Offering Opinions<br /></strong></p><ul><li>Limit negative opinions to small audiences<br /></li><li>Open positive opinions to large audiences<br /></li><li>Focus comments to make them appropriate for specific acts or results<br /></li><li>Do not overstate or understate, use moderate language </li></ul><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-921583922790654712?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1145082754038919902006-04-14T23:28:00.000-07:002007-02-15T14:45:52.194-08:00Adjacency Matrix in LaTeXHere is some LaTeX markup to write an Adjancency Matrix.<br /><br /><pre style="FONT-SIZE: 8pt; FONT-FAMILY: courier"><br />\begin{math}<br /> \begin{array}{cc}<br /> &<br /> \begin{array}{ccccccc}<br /> A & B & C & D & E & F & G<br /> \end{array}<br /> \ \begin{array}{c}<br /> A \\ B \\ C \\ D \\ E \\ F \\ G<br /> \end{array}<br /> &<br /> \left[<br /> \begin{array}{ccccccc}<br /> 0 \; & 1 \; & 0 \; & 0 \; & 0 \; & 0 \; & 0 \ <br /> 0 \; & 0 \; & 1 \; & 0 \; & 0 \; & 1 \; & 0 \ <br /> 0 \; & 0 \; & 0 \; & 1 \; & 0 \; & 0 \; & 0 \ <br /> 0 \; & 0 \; & 0 \; & 0 \; & 1 \; & 0 \; & 0 \ <br /> 0 \; & 0 \; & 0 \; & 0 \; & 0 \; & 1 \; & 0 \ <br /> 0 \; & 0 \; & 0 \; & 0 \; & 0 \; & 0 \; & 1 \ <br /> 1 \; & 0 \; & 1 \; & 0 \; & 1 \; & 0 \; & 0<br /> \end{array}<br /> \right]<br /> \end{array}<br />\end{math}<br /></pre><br /><br />On a mathematical note. You can use the Adjacency Matrix to find the number of paths of length <code>n</code> between two nodes when you calculate <code>A</code><sup>n</sup>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-114508275403891990?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1140828472153142052006-02-24T16:47:00.000-08:002006-02-24T16:48:53.420-08:00BlueDot Safari HacksBlueDot is a new social search network, it is fun and useful, check it out at <a target='new' href='http://www.blue.us'>Blue.us</a>.<br /><br />A quick hack to dot in Safari is to save the stylesheet (http://www.blue.us/css/Authoring.css) to your computer and store it in your custom css for Safari (Preferences > Advanced >Style Sheet). <br /><br />If you don't want to do it this way, you can make a bookmark like this to open up the Dot from Anywhere form at http://www.blue.us/DotFromAnywhere.aspx. To do this go to Bookmarks > Manage All Bookmarks. Select Bookmarks Bar and then make a new bookmark. Add the javascript code below as the url of the bookmark.<br /><pre style="font: 12px Courier;"><br />javascript:<br />{ <br /> var dotForm = document.getElementById("retroDotForm"); <br /> if (dotForm) <br /> { <br /> dotForm.style.display = "block"; <br /> } <br />}<br /></pre><br />They don't work together though. Once you add the BlueDot stylesheet to you custom stylesheet it will cause the Dot from Anywhere form to not display properly, so you have to choose your hack carefully.<br /><br />The hack to reveal the Dot anywhere is slightly better in that you won't be left in the dust with changes to the css used by the website. It might be useful to update your local css file any major updates to the site or when you notice something going wrong.<br /><br />Hopefully a better solution will be found.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-114082847215314205?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1140420159145973632006-02-19T21:47:00.000-08:002006-02-19T23:22:39.216-08:00Flash 8 PreloaderIf you are coming across this tutorial I will assume you already what a preloader is and why you use it. I am guessing you want to know the technical details the preloader, so I won't go into detail about what a preloader is. You can search Google for that answer.<br /><br />I will also admit there are many different ways to write a preloader. For example, you can have multiple scenes, code which counts through 100 frames before advancing to the frame of the media. Even with simple scripting techniques the structure of code can very greatly as well. For example you don't need to use a listener object, just write your listeners as functions. With this said, here is the method that I used. <br /><br /><h3>Step 1 - Make a .swf Movie File</h3><br />Create a .swf file from your movie. You can do this with Flash, by importing video (File > Import > Import Video), or with 3rd party software, and then exporting it (File > Export > Export Movie). You can test the .swf file by opening it in a web browser.<br /><br /><h3>Step 2 - Make a Flash File to Load your Movie</h3><br />Here comes the fun part. I set up a new Flash document with 5 layers.<br /><br /><div align='center'><img src='http://totally.surrealistic.net/jonketo/images/flash/Layers.png' /></div><br /><br />The layers are broken down into the following components<br /><ul><br /> <li>Functions - Auxillary actionscript functions</li><br /> <li>Preloader - Actionsript code for the preloader (sets up listener)</li><br /> <li>Movie - Contains the Movie Clip instance where the .swf file is loaded to</li><br /> <li>TraceBox - Contains an HTML text area that debugging statements are printed to</li><br /> <li>LoadText - Contains a dynamic text area that displays percentage of movie that is loaded</li><br /></ul><br />The two layers, Functions and TraceBox are only used for debugging purposes and can be removed once the preloader works. Because they are used for debugging, I won't go into detail about them. So the layers we want to focus on are Preloader, Movie and LoadText.<br /><br /><h3>Step 3 - Make a Place for the Movie to Load</h3><br />First we want to make a place for our Movie to load. To do this we need to make an instance of a Movie Clip. First, let's make a symbol (Ctrl/⌘+F8).<br /><br /><div align='center'><img src='http://totally.surrealistic.net/jonketo/images/flash/MyMovieClip1.png' /></div><br /><br />The symbol is now in your library and you can drag it onto a layer in your stage.<br /><br /><div align='center'><img src='http://totally.surrealistic.net/jonketo/images/flash/MyMovieClip2.png' /></div><br /><br />Since the movie clip I am loading is of me bouldering, I named the instance 'Bouldering'.<br /><br /><div align='center'><img src='http://totally.surrealistic.net/jonketo/images/flash/MyMovieClip3.png' /></div><br /><br />Our movie will load into this Movie Clip instance.<br /><br /><h3>Step 4 - Create a Place to Display Loading Progress</h3><br />Now Flash has a place to put the movie, but there is still no place to display information about the progress of our movie being loaded. There are many different ways display this information. It could be strictly graphic, or simply just text. Whichever way you choose to do it, you must make change your <code>onLoadProgress</code> function accordingly, see below.<br /><br />In this simple example I create a piece of dynamic text on the LoadText layer. I set it to '0 %' initially since this is what will be displayed before any part of the file is loaded. I named the instance 'loadText'. <br /><br /><h3>Step 5 - Write the Preloader</h3><br />The method I used to load a movie was to use the new <code>MovieClipLoader</code> class. To use the <code>MovieClipLoader</code> class you must setup a listener before loading the movie with the <code>loadClip</code> method. The listener simply defines functions that will be called at certain events, for example when the loading is starting or ending. The methods I defined were <code>onLoadStart</code>,<code>onLoadProgress</code> and <code>onLoadComplete</code>. Once I add the listener to the <code>MovieClipLoader</code> I can load the clip. Now that the code has been explained, lets look at it:<br /><br /><pre style='font-size: 12px; font-family: courier;'><br />var mcl = new MovieClipLoader();<br />var listener = new Object();<br /><br />listener.onLoadStart = function (targetClip) {<br /> targetClip._visible = false;<br />}<br />listener.onLoadProgress = function (targetClip, loaded, total) {<br /> var percentage = (loaded / total) * 100;<br /> _root.loadText.value = percentage + " %";<br />}<br />listener.onLoadComplete = function (targetClip) {<br /> targetClip._visible = true;<br />}<br /><br />mcl.addListener(listener);<br />mcl.loadClip("bouldering.swf", _root.Bouldering);<br /></pre><br /><br />Now, lets break down the code:<br /><br /><pre style='font-size: 12px; font-family: courier;'><br />var mcl = new MovieClipLoader();<br />var listener = new Object();<br /></pre><br /><br />The code above simply creates a new variable of type <code>MovieClipLoader</code> and a generic object that will define listeners for our Movie Clip. The reason to use an <code>Object</code> to hold our listener functions is so we can create multiple movie clip loaders and make separate listeners for each of them without running into conflicts with function name. Or vice versa we can create multiple loaders and one listener that does something dynamic based on a variable set in the listener object.<br /><br /><pre style='font-size: 12px; font-family: courier;'><br />listener.onLoadStart = function (targetClip) {<br /> targetClip._visible = false;<br />}<br />listener.onLoadProgress = function (targetClip, loaded, total) {<br /> var percentage = (loaded / total) * 100;<br /> _root.loadText.value = percentage + " %";<br />}<br />listener.onLoadComplete = function (targetClip) {<br /> targetClip._visible = true;<br />}<br /></pre> <br /><br />This code creates the listeners for the three events of a movie clip getting loaded, the start event, progress event and the complete event. In reality there are more events, but for this simple example I left out the other events like the error event. <br /><br /><code>onLoadStart</code> gets called when the movie starts to load. I simple set our movie container to be hidden. The movie container will be revealed in the <code>onLoadComplete</code> method. <br /><br />The <code>onLoadProgress</code> method is where all of the important work is done. This is the method that allows us to give important feedback about the progress of the movie being loaded. The two arguments <code>loaded</code> and <code>total</code> allow us to calculate a percentage. In this method I simply update the content of my dynamic text area to reflect the current progress of the load. <code>_root.loadText</code> will points to the instance of the dynamic text area created in step 3. <br /><br /><pre style='font-size: 12px; font-family: courier;'><br />mcl.addListener(listener);<br />mcl.loadClip("bouldering.swf", _root.Bouldering);<br /></pre><br /><br />The first line of this code tells Flash that the listeners it is supposed to use when firing events is from the listener object we created. The second line tells flash to load the .swf movie (created in step 1) to be loaded into the Movie Clip instance created in step 3. It is important that argument 2 of <code>loadClip</code> corresponds with the name of the instance created on your stage. <br /><br /><h3>Recap</h3><br />So each part is relatively simple. The key is to make sure you relate your ActionScript to your Flash file properly through the name of the Movie Clip instance. In this case it was 'Bouldering', but you can change it to whatever you like, as long as it is the same in both places.<br /><br />Click here to <a target='new' href='http://totally.surrealistic.net/jonketo/flash/preloader/'>view all the Flash files included</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-114042015914597363?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1139464900531682842006-02-08T22:00:00.000-08:002006-02-08T22:01:40.543-08:00Checkerboard!Rather than do anything productive I thought I would make another image function to use with the scripts i had uploaded earlier. Here is the <a target='new' href='http://totally.surrealistic.net/jonketo/docs/javascript/photoshop/CheckerImage.js'>javascript to make a checkerboard</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113946490053168284?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1139459291480811332006-02-08T20:02:00.000-08:002006-02-08T20:28:11.500-08:00Script Your Images in Photoshop CSLately I have started to play around with scripting in Photoshop for my computer vision course. Here is something I came up with while working on a take home midterm. We had to describe an image described by an equation. Since our professor said we could write programs I decided to do it in photoshop. There are a total of 3 scripts, each of which I will describe next.<br /><br />The first script is <a target='new' href='http://totally.surrealistic.net/jonketo/docs/javascript/photoshop/Document.js'>Document.js</a>. This is simply a library function I created to make creating new documents a little easier. Rather than needing to specify all the arguments for a new image I can give a height and width and I will get a new photoshop document.<br /><br />The second script is called <a target='new' href='http://totally.surrealistic.net/jonketo/docs/javascript/photoshop/CreateImage.js'>CreateImage.js</a>. This is the script that does all the work in Photoshop. It creates the new document and then iterates over x and y. At each pixel (x,y) a region of the image is selected and filled in with a color. The color is of type RGBColor and is retured from a function called ColorEquation. This function is passed (in order) x, y, width and height. It is your job to define ColorEquation. The function should create and return a variable of type RGBColor.<br /><br />The third script is <a target='new' href='http://totally.surrealistic.net/jonketo/docs/javascript/photoshop/Image.js'>Image.js</a>. This file defines two variables and a function (the least information needed to make an image). The variables are the width and the height. The function is called ColorEquation. This function will be given the current pixel (x,y), width of the image and height of the image. You can use these 4 values to construct a color for the pixel (x,y). The color will be stored and returned in a variable of type RGBColor.<br /><br />Of course, since all of the source code is here for download, so you can it however you want. If you do make something cool please post a reply with some code. It will be cool to see.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113945929148081133?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1138091830020605562006-01-24T00:30:00.000-08:002006-01-24T00:38:53.356-08:00Forking in UNIX/Linux/OS XHere is some code to fork a new process in UNIX and similar operating systems. Note: Forking is not most efficient method for multiprogramming because it is inefficient, but it is easy. The problem with forking is that it copies the whole address space of the parent process before resuming execution. In most cases people want to execute another program after forking. When an exec (or some variant of exec) is called, the first thing that happens is the address space of that process is wiped out and the new program is loaded into that address space. This is very inefficient because the kernel has to do all of this for the processes. If you don't want to copy the whole address space, check out the <pre style='font-family: courier new; font-size: 11px;'>vfork()</pre> command. Here is the code anyways.<br /><br /><pre style='font-family: courier new; font-size: 11px;'><br />#include <stdio.h><br />#include <unistd.h><br /> <br />int main(void)<br />{<br /> pid_t pid;<br /> int wait_for_child = 1;<br /> int exec_res;<br /> int value = 1;<br /><br /> char* command = "/bin/ls";<br /> char* command_name = "ls";<br /> <br /> // Fork new process, copies address space of parent<br /> // process so static data, stack and heap are not shared.<br /> // See<br /> pid = fork();<br /> <br /> // Both child and parent processes start here after the<br /> // fork is called<br /> <br /> if (pid == 0)<br /> {<br /> // Increment value in childs address space<br /> value++;<br /> <br /> // This is the child process<br /> printf("I am the child. [%i]\n", value);<br /> <br /> exec_res = execlp(command, command_name, NULL);<br /> <br /> // Need to exit on error<br /> if (!exec_res) <br /> {<br /> printf("Error. Could not exec.");<br /> }<br /> <br /> // Exit child process<br /> exit(0);<br /> <br /> }<br /> else if (pid > 0)<br /> {<br /> <br /> // wait_for_child if exec is synchronous<br /> if (wait_for_child)<br /> {<br /> printf("Wait for child to finish before resuming.\n");<br /> wait(NULL);<br /> }<br /> <br /> printf("I am the parent. My child is %i. [%i]\n", pid, value);<br /> }<br /> else<br /> {<br /> printf("Error. Could not fork.");<br /> }<br /><br /> return 1;<br />}<br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113809183002060556?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1137834293307279062006-01-21T01:01:00.000-08:002007-02-15T14:41:57.176-08:00Replace Colors with ImageMagickImageMagick has a great utility called convert. It allows you to do many things, including replacing one color in an image with another.<br /><pre><br />convert -fill #FFC232 -opaque #000000 inputfile outputfile<br /></pre><br />This will relace all the black pixels in an image with a dark yellow color. This is only a small part of what ImageMagick utilities can do. I recommend downloading them all.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113783429330727906?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1136872180652725022006-01-09T21:47:00.000-08:002006-01-17T18:12:11.586-08:00Reverse a linked listThis algorithm is a little more efficient than the last I posted about sorting a linked list, running in O(N) time. The algorithm requires a doubly linked list.<br /><br /><pre style='font-family: courier; size: 10;'><br />queue_length = queue_size(q);<br /><br />front = q->head;<br />back = q->tail;<br /><br />for (i = 0; i < queue_length / 2; i++) {<br /> <br /> temp = front->e;<br /> front->e = back->e;<br /> back->e = temp;<br /> <br /> front = front->next;<br /> back = back->prev;<br />}<br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113687218065272502?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1136872021261795612006-01-09T21:43:00.000-08:002007-02-15T14:42:33.552-08:00Sort a linked listThis is not an efficient way to sort a linked list (runs in O(N<sup>2</sup>), but it works when you don't care about efficiency (sometimes homework for a class). This code sorts a linked list in place with bubble sort.<br /><br /><pre style="FONT-FAMILY: courier; size: 10"><br />do {<br /> num_swaps = 0;<br /> cur = q->head;<br /> while (cur) {<br /> if (cur->next) {<br /> res = queue_element_compare(cur->e, cur->next->e);<br /> if (res == 1) {<br /> temp = cur->e;<br /> cur->e = cur->next->e;<br /> cur->next->e = temp;<br /> num_swaps++;<br /> }<br /> }<br /> cur = cur->next;<br /> }<br />} while (num_swaps > 0);<br /></pre><br /><br /><span style="size: 10;font-family:courier;" >queue_element_compare</span> returns 0 on equal, 1 if e1 > e2 and -1 when e1 < e2.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113687202126179561?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1135729258277676102005-12-27T16:05:00.000-08:002005-12-27T16:24:10.953-08:00Embed Google VideoMy friend had a little question for me about taking advantage of Google's great new service, <a target='new' href='http://video.google.com'>Google Video</a>. He wanted to put <a target='new' href='http://video.google.com/videosearch?q=propadata&btnG=Search+Video'>his DVD snippets</a> on his <a target='new' href='http://www.myspace.com/williamlemke'>myspace account</a>. So with a little googling, I was about to help him out. Here are the condensed instructions.<br /><span style="font-family: courier; font-size: 11px;"><br /><embed src="YOUR SRC HERE" quality="high" pluginspage="http://www.macromedia.com/shockwave/download/index.cgi?P1_Prod_Version=ShockwaveFlash" type="application/x-shockwave-flash" width="400" height="325"></embed><br /></span><br />YOUR SRC is the google player source. To find this easily, follow the instructions below.<br /><br />1. Open up video URL in Firefox or Mozilla<br />2. Get Page info (Tools > Menu > Page Info ⌘I)<br />3. Click Media Tab <br />4. Find Object with http://video.google.com/googleplayer.swf and click on it<br />5. Copy it, now you can paste it in the source code given as the src attribute in the emded tag<br />6. You can always view the source of this page to see as well.<br />7. If you want the video to not start automatically, in the source url, remove '&autoPlay=true'<br /><br />For longer instructions with pictures, check out this <a target='new' href='http://www.ovelha.org/pasteler0/2005/12/14/howto-google-videos-on-your-website/'>this article</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113572925827767610?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1130047157729336102005-10-22T22:56:00.000-07:002005-10-22T22:59:17.736-07:00Web StatsI just set up <a target='new' href='http://www.reportmagic.org/'>report magic</a> for analog on my server. If anyone cares to see them, <a target='new' href='http://totally.surrealistic.net/weblog/index.html'>http://totally.surrealistic.net/weblog/index.html</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-113004715772933610?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1129770106133090462005-10-19T17:46:00.000-07:002005-10-19T18:01:46.140-07:00MIPS Assembly Language TemplateBelow is a simple template for writing programs and procedures in MIPS assembly language. The stack pointer by convention can point to either the bytes on top of the stack or at the next available free set of bytes on the stack. In this template it points to the next available location. This means you need to add data to the stack, then move the stack pointer to the next free spot when pushing to it. When you pop from the stack you will move the stack pointer to point to the last bit of data on the stack, then remove it. <br /><br /><pre style='font-face: courier; font-size: 11px;'><br />#####################################################################<br /># Static data is defined here<br />#####################################################################<br /><br />.data<br /><br />######################################################################<br /># Program is defined here<br />#####################################################################<br /><br />.text<br />.globl main # make main a global label<br /><br />main:<br /> sw $ra, 0($sp) # Move the return address of caller<br /> # onto stack. Necessary in case this<br /> # code calls another procedure<br /> <br /> subu $sp, $sp, 4 # Move stack pointer to next available<br /> # free space. Must subtract since stack<br /> # grows down.<br /> <br />#####################################################################<br /># Begin program<br /># Note: It is good practice to list the registers used and their<br /># what they are used for.<br />##################################################################### <br /># add your program code here<br /><br />#####################################################################<br /># End Program<br />#####################################################################<br /><br />#####################################################################<br /># Exit Program and return to location it was called from<br />#####################################################################<br />exit:<br /> addiu $sp, $sp, 4 # Move stack pointer 4 bytes up,<br /> # Stack grows down, so adding actually<br /> # removes data from the stack<br /> <br /> lw $ra, 0($sp) # Move return address from stack into<br /> # reserved return address register $ra<br /> <br /> jr $ra # Return<br /></pre><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112977010613309046?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1129710115335099172005-10-19T00:43:00.000-07:002005-10-19T01:21:55.343-07:00Dual Boot Fedora Core 4 & Windows XPWill the fun never end!? Some of you guys *cough* Sandra *cough* might ask, has it started yet? My response is, just let me play with computers. It really is fun.<br /><br />This weekend I started up another little project. Mainly I needed to get a PC up and running for doing homework at home, rather than in the labs at school. Below are the steps I followed to get my PC dual booting Windows XP and Fedora on a single drive.<br /><ol><br /><li><p>First I installed windows. Before installation I partioned my 40 Gb hard drive into two partitions, roughly 20 Gb each. Then I installed windows as normal on the first partition (C:). It is important to note that certain format types traditionally are not compatible with certain operating systems, i.e. Linux and NTFS. Although there are some interesting new projects which allow NTFS to be mounted from linux.</p></li><br /><li><p>Once installation is complete I restarted the computer (and made sure the BIOS were set to boot from CD first) and booted off of my Fedora Core install CD.</p></li><br /><li><p>Again I had to format and partition the remaining 20Gb, so I could install linux on it. I made a minimal partition setup with only two partitions of the remaining space. One as the primary partion ( '/' ) and one as swap. Your partitioning can be much more complicated depending on your system and the number of disks, but for me, this is all I needed. For an introduction to partitioning for Linux see <a target='new' href='http://www.linux.com/howtos/Partition/intro.shtml'>Linux.com's Introduction to Partitioning</a></p></li><br /><li><p>Make sure that you choose to format and install on the part of the drive that does not have windows already installed on it. If you installed Windows to the C drive, that will be hda1. The partition you want to install on would be hda2.</p></li><br /><li><p>The next step was to decided where to store the Fedora boot record. The easiest place is to store it on the master boot record (MBR). You can store it on the drive that linux installed on as well, but that may require a little more configuration to get the boot loader to work properly.</p></li><br /><li><p>Having not used the windows boot loader I decided to use GRUB</p></li><br /><li><p>Here is where the fun begins. I had chosen to use GRUB, so I figured the boot loader would appear after a reboot. From there I could decided which OS to boot. Nope! After a little googling I found out how to edit the GRUB config file. Belwo is an example file:</p></li><br /><p><pre style='font-family: courier; font-size: 11px;'><br />default=0<br />timeout=10<br />splashimage=(hd1,2)/grub/splash.xpm.gz<br />hiddenmenu<br />title Linux<br /> root (hd1,2)<br /> kernel /vmlinuz-2.4.18-14 ro root=LABEL=/<br /> initrd /initrd-2.4.18-14.img<br />title Windows XP<br /> rootnoverify (hd0,0)<br /> chainloader +1<br /></pre></p><br /><li><p><code>code</code> denotes which OS is default. <code>timeout</code> denotes the length of time before the default OS is loaded. <code>title</code> blocks start the description of each OS and how to load it. The last command of note is the <code>hiddenmenu</code> command. This tells the boot loader whether or not to actually display the boot loader screen ... or hide it. When installing Fedora Core 4, this was enabled, so I was never able to see the boot loader screen to choose my operating system. Once this line was removed the boot loader worked properly and I was able to choose which OS to load.</li><br /><li>That's it!</li><br /></ol><br />I am now a happy user of Windows and Fedora.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112971011533509917?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1129104090917013622005-10-12T00:35:00.000-07:002005-10-12T01:01:30.930-07:00Array IntersectionSo finding the intersection of two arrays can be trivial, but it may not be so 'trivial' if it is asked to you by the recruiter of a company. Here are three algorithms to solve the problem.<br /><br />The first solution is to brute force the problem by marching through the first array and then march through the second. If the value is found in the second array, then simply move to the next value in the first array. This algorithm assumes the values in the first array are unique. The runtime for this algorithm is O(N<sup>2</sup>).<br /><pre style="font-size: 10px; font-family: courier;"><br />for ($i = 0; $i < count($a); $i++) {<br /> for ($j = 0; $j < count($b); $j++) {<br /> if ($a[$i] == $b[$j]) {<br /> $intersection[] = $a[$i];<br /> break;<br /> }<br /> }<br />}<br /></pre><br />The second solution, assuming the arrays are sorted, is to proceed as before, except use a binary search while searching the second array. Hopefully you would be smart and iterate through the smaller array and use binary search on the larger. Otherwise your hardwork would be wasted. This algorithm also makes the uniqueness assumption. The runtime for this algorithm is O(N*Log(N));<br /><pre style="font-size: 10px; font-family: courier;"><br />$lo = 0;<br />$mid = floor(count($b) / 2);<br />$hi = count($b)-1;<br />for ($i = 0; $i < count($a); $i++) {<br /> while($lo <= $hi) { <br /> if ($b[$mid] == $a[$i]) {<br /> $intersection[] = $a[$i];<br /> break;<br /> } else if ($a[$i] < $b[$mid]) {<br /> $hi = $mid - 1;<br /> } else if ($a[$i] > $b[$mid]) {<br /> $lo = $mid + 1;<br /> }<br /> $mid = floor(($hi + $lo) / 2);<br /> }<br /> $lo = 0;<br /> $mid = floor(count($b) / 2);<br /> $hi = count($b)-1;<br />}<br /></pre><br />Lastly, we have the efficient algorithm, but only possible with hash tables. In practice, this algorithm could be slower than the previous algorithm if N and M are small, but this post is not a proof, so simple as it may be I won't bore you with the details (use two arrays of length <= 100 to see). This algorithm simply involves 'marking' the values you have seen in each array as you iterate through them seperately. This algorithm will handle the case of each array not having unique values as well.<br /><pre style="font-size: 10px; font-family: courier;"><br />$temp_hash = array();<br />$intersection = array();<br />for ($i = 0; $i < count($a); $i++) {<br /> if (!isset($temp_hash[$a[$i]])) {<br /> $temp_hash[$a[$i]] = 1;<br /> } else {<br /> $intersection[] = $a[$i];<br /> }<br />}<br />for ($i = 0; $i < count($b); $i++) {<br /> if (!isset($temp_hash[$b[$i]])) {<br /> $temp_hash[$b[$i]] = 1;<br /> } else {<br /> $intersection[] = $b[$i];<br /> }<br />}<br /></pre><br />So, those are the three solutions. The first is pretty bad in most all cases, except for a few cases where both of the arrays are small and you may not want a binary search because of the extra memory and arithmetic commands. The best solution may be to switch between the three algorithms depending on the size of the inputs.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112910409091701362?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1128973617012149722005-10-10T12:34:00.000-07:002005-10-10T12:46:57.023-07:00Reverse the words in a string!This weekend I was talking to David, who is moving to Mountain View, CA for his new job at Google. He was telling me about some the interviews he has had recently. This conversation sparked me to start doing some more of those programming exercises, which are commonly used during interviews. I was bored today, so I wrote up a short algorithm to reverse the words in a string, but not the characters in the words. (Disclaimer: works upon brief inspection. I will not be responsible for anyone getting or not getting a job). Hehe.<br /><br /><pre style='font-size: 10px; font-family: courier'><br />#include <stdio.h><br />#include <string.h><br /><br />int main(void) {<br /> char *str = "Hello World I Am Here";<br /> char new_str[strlen(str)]; // String to copy to<br /> char word_str[strlen(str)]; // Temp string to hold words<br /> char t_char; // Temp character<br /><br /> int i = 0; // str counter<br /> int j = 0; // word_str counter<br /> int k = 0; // copy word_str to new_str counter<br /> int m = 0; // new_str counter<br /> <br /> for (i = 0; i < strlen(str); i++) {<br /> t_char = str[strlen(str) - 1 - i];<br /> <br /> // Is this character a space. Yes, then copy the las<br /> // word saved, otherwise add the character to the word<br /> // we are saving<br /> if (t_char == ' ') {<br /><br /> // Add the word to the new string, in reverse order<br /> for (k = 0; k < j; k++) {<br /> new_str[m] = word_str[j - k - 1];<br /> m++;<br /> }<br /> <br /> // Add the space<br /> new_str[m] = t_char; <br /> m++;<br /> <br /> j = 0;<br /> <br /> } else {<br /> word_str[j] = t_char; <br /> j++;<br /> }<br /> }<br /> <br /> // Add the last word, if any<br /> for (k = 0; k < j; k++) {<br /> new_str[m] = word_str[j - k - 1];<br /> m++;<br /> }<br /> <br /> // Print the word, done character by character, so unset<br /> // array indexes won't give an ugly print out<br /> for (i = 0; i < m; i++) {<br /> printf("%c", new_str[i]);<br /> }<br /> <br /> printf("\n"); <br /> return 0;<br /><br />}<br /></pre><br /><br />Last night I also did some array intersection algorithms. I will post those this evening. These ones are written in PHP as opposed to C, since I used hash tables for one of the algorithms. <br /><br />This code could probably be optimized, as I am repeatedly making calls to str_len, but this is more of a proof of concept than an optimal piece of code, so I am not going to worry about it. Feel free to comment, I can only learn from them.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112897361701214972?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1128765489695288332005-10-08T02:37:00.000-07:002005-10-08T03:03:38.703-07:00XCode and the MySQL C APIThis evening, see as how it was a Friday, I decided to do a little programming. Since I have worked with MySQL databases in PHP, Java, Visual Basic .NET, C# and Javascript, I thought it was only right to do some MySQL programming in C. This was a good chance for me to kill two birds with one stone since I want to do more C/C++ programming in XCode.<br /><br />Everything was working well. Last night I installed MySQL and it's development libraries with fink. I edited the Active Target in XCode, so I could add the proper header and library paths, /sw/include/mysql & /sw/lib/mysql respectively. So I specified '-lmysqlclient' as an Other Linker Flag, so that the appropriate library was linked in during the compiling process. Sweet, this is similar to coding in Visual Studio. Why do I keep getting this error?<br /><code><br />[Session started at 2005-10-08 02:39:02 -0700.]<br />ZeroLink: unknown symbol '_mysql_init'<br /><br />MySQL has exited due to signal 6 (SIGABRT).<br /></code><br />I guess the ZeroLink prefix is a good indicator. The problem here is that <a target='new' href='http://developer.apple.com/documentation/DeveloperTools/Conceptual/XcodeUserGuide21/Contents/Resources/en.lproj/05_08_bs_linking/chapter_35_section_9.html'>ZeroLink</a> does not actually link the library appropriately. To solve the problem I had to change the Active Build Style to deployment. That was it, then it compiled and I could make some progress. <br /><br />So to make a long story short, to use the MySQL C API with XCode, follow these steps:<br /><ol><br /><li>Edit Active Target</li><br /><li>Go to Build -> Search Paths</li><br /><li>Set 'Header Search Paths' to the include directory of MySQL (usuall /usr/local/mysql/include)</li><br /><li>Set 'Library Search Paths' to the include lib of MySQL (usuall /usr/local/mysql/lib)</li><br /><li>Go to Build -> Linking</li><br /><li>Set 'Other Linker Flags' to '-lmysqlclient'</li><br /><li>Close this window</li><br /><li>Set Project -> Set Active Build Style to 'deployment'</li><br /></ol><br />Next Step, <a target='new' href='http://developer.apple.com/documentation/DeveloperTools/Reference/Assembler/PPCInstructions/chapter_6_section_6.html'>assembly on my powerbook</a>! This will take a little while to learn though.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112876548969528833?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1128040661547320882005-09-29T17:33:00.000-07:002005-09-29T17:37:41.560-07:00Sorry for the delayI have not been able to post anything technical for a while. I was really busy at work since I had to prepare to move back to Seattle from San Clemente. My post in the R&D department is now vacant. I wish I could go back some days, but at other times I sit back and enjoy the Asian literature courses I am taking.<br /><br />I will note that one of the projects I worked on was to add read support for tga, pic and sgi image files into the php-gd library. That was a fun little project. Thanks to Andi and Mike for teaching me so much.<br /><br />I may post a little php class to convert a database into an xml file .... but that might be just as easy for someone to write themselves. I might modify it, so that will read and write the database table. Should I add synchronization between files and tables. Well, we will see how bored I get that day.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112804066154732088?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1124782489446068112005-08-23T00:23:00.000-07:002005-08-23T00:35:35.996-07:00Testing MentalRay RendersTesting command line mental ray renders can be tough at times, but here are a couple of tips to help smooth out the process. <br /><h4>1. Using imf_disp</h4><br />imf_disp is a great little application bundled with mental ray to allow you to view rendered images. It updates as renders complete, so you can rerender to the same image and watch the progress of the render. If you want to see the output on the command line as tiles come in it is super convenient to use.<br /><h4>2. Render a region</h4><br />ray3 has a command line argument (-window XL YL XU YU) to render only a portion of the rendered image. If you only want to render a section of a 2K image, this is perfect. Note: (0,0) is the lower left hand corner, which is different from Photoshop, which use the upper left hand corner. (Thanks Adam)<br /><h4>3. Other ray3 arguments</h4><br />Some other useful ray3 command line arguments are -verbose (turns on more logging), -memory (set max memory in MB), -threads (set max # of threads) and -file_name (specify output, default is tga). If you want to test memory management or threading issues, these are what you should use.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112478248944606811?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1123466451741887122005-08-07T18:54:00.000-07:002005-08-07T19:13:50.913-07:00Test your network Apps with this PHP DaemonDoing a little work on a distributed computing application I needed to script a simple TCP server that listen to a specified port. I came up with a little solution in php.<br /><br />To run it you must have php installed with support for sockets. Here is the command to run it:<br /><br /><code>php simple_server.php -port 2021 -message "got your message"</code><br /><br />The default port is 2020 and the default message is "message received", but they can be overridden as shown above. There is also a constant defined for the EOP. Anyways, go ahead and have fun. Take this script and change as much as you would like.<br /><br />The script is available here: <a href='http://totally.surrealistic.net/jonketo/code/php/simple_server/simple_server_code.php'>simple_server_code.php</a><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112346645174188712?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1120422820504738732005-07-03T13:32:00.000-07:002005-07-03T13:33:40.510-07:00Javascript Console in SafariIn Safari 1.3 there was a debug menu added. This menu is turned off by default, so you have to turn it on yourself. If you would like to turn it on, simply run this commend through terminal while Safari is not running.<br /><br /><code>defaults write com.apple.Safari IncludeDebugMenu 1</code><div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-112042282050473873?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1117920216940985602005-06-04T14:04:00.000-07:002005-06-04T14:28:01.033-07:00XML and 3D ApplicationsLately I have seen the importance of XML in applications other than the .NET framework and RSS feeds. At Omation XML is utilized to represent assets, so they can be updated and changed easily. Most importantly it is used to manage assets on a production level as well as a scene level. <br /><br />Helge Mathee wrote an article about the <a href="http://www.xsi-blog.com/?p=15" target="new">importance of XML</a> on XSIBlog, so I won't bore you with any details here. Also, he did a much better job explaining it that I might have.<br /><br />Anyways, I think it would be great for 3D applications to jump on the XML bandwagon and start producing importers and exporters in XML. Even though a lot of software packages have importers and exporters for different types of ASCII formats, it would be amazing for the companies to come together to produce a standard for 3D representation of data in XML, much like the RSS standard came about. Since each there are many different XML handlers in just about any language you want, it would be easy for the software companies to integrate this solution into their already existing codebase. <br /><br />For years VRML has been around. In it's original form it was formatted with brackets and curly braces:<br /><pre style="font-size: 10px"><br /> Transform {<br /> translation 3.0 0.0 1.0<br /> children [<br /> Shape {<br /> geometry Sphere { <br /> radius 2.3<br /> }<br /> appearance Appearance {<br /> material Material { <br /> diffuseColor 1.0 0.0 0.0<br /> }<br /> }<br /> }<br /> ]<br /> }<br /></pre><br />but now there has been a conversion to using XML:<br /><pre style="font-size: 10px"><br /> <Transform translation='3.0 0.0 1.0'><br /> <Shape><br /> <Sphere radius='2.3'/><br /> <Appearance><br /> <Material diffuseColor='1.0 0.0 0.0'/><br /> </Appearance><br /> </Shape><br /> </Transform><br /></pre><br />So now, there does not even need to be a standard for representation of 3D objects, only a need for application specific instructions to be stored as well. For all it matters, this can be decided by each company and shared with the others. I think at that point, the number of custom exporters needed will drop significantly.<br /><br />These examples were taken <a href="http://www.xml.com/lpt/a/2003/08/06/x3d.html" target="new">xsi.com's article on 3D meeting XML</a>.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-111792021694098560?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1117009522266328072005-05-25T01:21:00.000-07:002005-05-25T01:25:22.266-07:00AppleScript DictionariesFor a quick and easy way to see the "API" for an application in OS X for AppleScript, simply open the Script Editor, go to File -> Open Dictionary. Choose the application you would like to see the dictionary for and you will be able to see methods and properties available in that application.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-111700952226632807?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1117009248874661722005-05-25T00:52:00.000-07:002005-05-25T01:20:48.880-07:00Command Line Compiling on WindowsFor anyone familiar with Linux or Unix and loves to compile code on the command line, but you have to use Windows, there is a solution for you yet. Microsoft has a C++ command line compiler for download. The compiler is part of the <a href="http://msdn.microsoft.com/visualc/vctoolkit2003/" target="new">Microsoft Visual C++ Toolkit 2003</a>. <br /><br />I have been playing around with this compiler to do a few things. One of the first things I noticed was that the library directory of the Toolkit is limited as compared to the library files available from a full install of Visual Studio .NET or any other MS IDE. This makes sense because the Toolkit is limited because it is simply used to compile code on the command line, however, there are times when you need to link in MSVCRT.LIB and it is not available.<br /><br />There is an easy solution to this problem. Simply download the <a href="http://lab.msdn.microsoft.com/express/visualc/default.aspx" target="new">beta express version of Visual Studio .NET 2005</a> and you will have important library files that may be available in the toolkit. Of course if you already another version of Visual Studio installed on your computer, you can use those files too.<br /><br />Here are some examples of how the command line compiler can be used once it is installed properly.<br /><code style="font-size: 9px;"><br />cl /c /O2 /G6 /MD /nologo /W3 -DWINNT example.c<br />link /nologo /nodefaultlib:LIBC.LIB /OPT:NOREF /INCREMENTAL:NO /DLL /OUT:example.dll example.obj someexternallib.lib<br /></code><br /><code>/LIBPATH</code> and <code>/I</code> can be used to specify additional library and include paths. <br /><br />Hope you guys enjoy this one. No more having to deal with the troublesome project options anymore. I have never enjoyed that part of the MS IDE's because there is no way to (or I have not found it yet) import and export a project's settings. I think it would be super sweet if you could import project settings as an xml file. Then you could save your settings as a template for different project types ...... like for example.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-111700924887466172?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.comtag:blogger.com,1999:blog-13100188.post-1116808664128952452005-05-22T17:24:00.000-07:002005-05-22T17:37:52.536-07:00Welcome to Codespace 1.0In an effort to help myself in 3D programming and hopefully help anyone programming in the XSI community, I have started my own blog to document my learning process as I travel down a new road in my short life as a programmer.<br /><br />My first endeavours have included writing tools in XSI with javascript and some mental ray shaders. I don't have anything amazing yet, but I am working on it.<br /><br />I am short of things to post as of late, but I assue that I will have more code snippets, ideas and examples to come.<div class="blogger-post-footer"><img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/13100188-111680866412895245?l=ketox.org%2Fjon%2Fblog%2Fcodespace%2Findex.php'/></div>Jon Ketohttp://www.blogger.com/profile/14277677932640322778noreply@blogger.com