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

<channel>
	<title>RobG3D</title>
	<atom:link href="http://www.robg3d.com/?feed=rss2" rel="self" type="application/rss+xml" />
	<link>http://www.robg3d.com</link>
	<description>Website and Blog of Rob Galanakis: Tools Programmer, Technical Artist/Animator</description>
	<lastBuildDate>Fri, 18 Jan 2013 16:39:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5.1</generator>
		<item>
		<title>Python Enrichment and PitP</title>
		<link>http://www.robg3d.com/?p=1071</link>
		<comments>http://www.robg3d.com/?p=1071#comments</comments>
		<pubDate>Fri, 18 Jan 2013 16:38:50 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Culture]]></category>
		<category><![CDATA[Leadership]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[Tech Artists]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1071</guid>
		<description><![CDATA[When I was starting my job at CCP, I posted about some things I wanted to do as a lead. I've been through two releases with the Tech Art Group in Iceland (and for the past 6 months or so been the Tech Art Director here) and figured I'd measure my performance against my expectations]]></description>
				<content:encoded><![CDATA[<p>When I was starting my job at CCP, I posted about some <a title="A lead shouldn’t lead like lead." href="http://www.robg3d.com/?p=404">things I wanted to do as a lead</a>. I&#8217;ve been through two releases with the Tech Art Group in Iceland (and for the past 6 months or so been the Tech Art Director here) and figured I&#8217;d measure my performance against my expectations.</p>
<p><b>Training sessions: </b>I&#8217;m proud to say this is a definite success. I was the initial Coordinator for our Reykjavik Python Community of Practice (studio-wide volunteer group that discusses python in general and its use at CCP), where I started two initiatives I&#8217;m very proud of. One is the weekly &#8216;enrichment session&#8217; where we watch a PyCon video, go through a demonstration or tutorial, etc. These have gone over great, the trick is to do them even if only 4 people show up :) The other is <strong>Python in the Pisser</strong>, a python version of Google&#8217;s Testing in the Toilet. I hope we can open source the newsletters and maybe share content with the outside world. More information on that coming in the future.</p>
<p><strong>Collective vision/tasking</strong>: We run an XP-style team on tech art so I like to think my TAs feel ownership of what they are working on. In reality, that ownership and vision increases with seniority. We are actively improving this by doing more pairing and having more code reviews- the team is at a level now where they can review each other&#8217;s work and it isn&#8217;t all up to me to mentor/train them.</p>
<p><strong>Evolving standards and practices: </strong>We started in Hansoft, moved to Outlook Tasks, and settled on Trello. We&#8217;ve discovered our own comfortable conventions and can discuss and evolve them without getting into arguments or &#8216;pulling rank&#8217;.</p>
<p><strong>Community engagement</strong>: The CoP and mentoring has definitely done some work here. I try and give everyone 10%/10% time, where 10% is for &#8216;mandatory&#8217; training or non-sprint tasks, and 10% is for their personal enrichment.</p>
<p><strong>Move people around</strong>: We haven&#8217;t had much of an opportunity for this but we did change desk positions recently :) The art team is too small to have many opportunities and all graphics development is on one scrum team.</p>
<p><strong>Code katas: </strong>We had one and it was mildly successful. We plan to do more but scheduling has been difficult- we do two releases a year, and DUST introduces complications in the middle of those releases, but we&#8217;ll be doing more things like it for sure.</p>
<p>I&#8217;ve also been doing very regular 1-on-1&#8242;s and, I hope, been getting honest feedback. Overall I am happy with my performance but can improve in all areas, even if that means doing more of the same (and becoming a better XP team).</p>
<p>Anyone want to share what successful cultural practices they have on their team/at their studio?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1071</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Maya and PyCharm</title>
		<link>http://www.robg3d.com/?p=1061</link>
		<comments>http://www.robg3d.com/?p=1061#comments</comments>
		<pubDate>Tue, 15 Jan 2013 16:09:16 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[server/client]]></category>
		<category><![CDATA[Tech Artists]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[Tools and Pipeline]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1061</guid>
		<description><![CDATA[Recently at work I had the opportunity of spending a day to get Maya and PyCharm working nicely. It took some tweaking but we're at a point now where we're totally happy with our Maya/Python integration]]></description>
				<content:encoded><![CDATA[<p>Recently at work I had the opportunity of spending a day to get Maya and PyCharm working nicely. It took some tweaking but we&#8217;re at a point now where we&#8217;re totally happy with our Maya/Python integration.</p>
<p><strong>Remote Debugger</strong>: Just follow the instructions here: http://tech-artists.org/forum/showthread.php?3153-Setting-up-PyCharm-for-use-with-Maya-2013. We ended up making a Maya menu item that will add the PyCharm helpers to the syspath and start the pydev debugger client (basically, the only in-Maya instructions in that link).</p>
<p><strong>Autocomplete</strong>: To get autocomplete working, we just copied the stubs from &#8220;C:\Program Files\Autodesk\Maya2013\devkit\other\pymel\extras\completion\py&#8221; and put them into <strong>all</strong> of the subfolders under: &#8220;C:\Users\rgalanakis\.PyCharm20\system\python_stubs&#8221; (obviously, change your paths to what you need). We don&#8217;t use the mayapy.exe because we do mostly pure-python development (more on that below), and we can&#8217;t add the stubs folder to the syspath (see below), so this works well enough, even if it&#8217;s a little hacky.</p>
<p><strong>Remote Commands</strong>: We didn&#8217;t set up the ability to control Maya from PyCharm, we prefer not to develop that way. Setting that up (commandPort stuff, PMIP PyCharm plugin, etc.)  was not worth it for us.</p>
<p><strong>Copy/Paste:</strong> To get copy/paste from PyCharm into Maya working, we followed the advice here:  http://forum.jetbrains.com/thread/PyCharm-671 Note, we made a minor change to the code in the last post, because we found screenshots weren&#8217;t working at all when Maya was running. We early-out the function if &#8220;oldMimeData.hasImage()&#8221;.</p>
<p>And that was it. We&#8217;re very, very happy with the result, and now we&#8217;re running PyCharm only (some of us were using WingIDE or Eclipse or other stuff to remote-debug Maya or work with autocomplete).</p>
<p>&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;</p>
<p>A note about the way we work- we try to make as much code as possible work standalone (pure python), which means very little of our codebase is in Maya. Furthermore we do TDD, and we extend that to Maya, by having a base TestCase class that sends commands to Maya under the hood (so the tests run in Maya and report their results back to the pure-python host process). So we can do TDD in PyCharm while writing Maya code. It is confusing to describe but trivial to use (inherit from MayaTestCase, write code that executes in Maya, otherwise treat it exactly like regular python). One day I&#8217;ll write up how it works in more depth.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1061</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Best practices for temp files</title>
		<link>http://www.robg3d.com/?p=1060</link>
		<comments>http://www.robg3d.com/?p=1060#comments</comments>
		<pubDate>Sun, 13 Jan 2013 15:34:58 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1060</guid>
		<description><![CDATA[It seems the more middleware we use, the more we need to work with temporary files. So for Tech Artists, we usually work with temp files a lot! So it's important we follow best practices when we need to work with temporary files]]></description>
				<content:encoded><![CDATA[<p>It seems the more middleware we use, the more we need to work with temporary files. So for Tech Artists, we usually work with temp files a lot! So it&#8217;s important we follow best practices when we need to work with temporary files.</p>
<p>Note: I&#8217;ll be using python functions and terminology but this applies to any language.</p>
<p>It goes without saying but, use the tempfile module. Don&#8217;t use environment variables or roll something yourself (I&#8217;ve seen both done).</p>
<p>Never hard-code the location of a temporary file. I&#8217;ve used middleware that does an equivalent of &#8220;os.path.join(gettempdir(), &#8216;myscratch.foo&#8217;)&#8220; to get some path. Which means running multiple processes at the same time causes file lock errors! I&#8217;ve had to change the temp directory before calling these processes.</p>
<p>Either your directory or your filename should always be programmatically looked up: so &#8220;mkstemp(dir=os.path.join(gettempdir(), &#8216;myscratchfiles&#8217;)&#8220; is acceptable, as is &#8220;os.path.join(mkdtemp(), &#8216;myfile.foo&#8217;)&#8220;.</p>
<p>Try and clean up your files and folders! I say &#8216;try&#8217; because it isn&#8217;t always possible. Sometimes your library may need to return the path to some file it generates. In that case, rather than rely on the caller to clean up the file (which would be a bizarre dependency and docstring!), you&#8217;re better off to take in the &#8216;output path&#8217; to your library, and write the result file there. And your library can clean up the intermediate temp files. That way the caller can be responsible for deleting the result file if it needs (hopefully it doesn&#8217;t) because it knows more about the path.</p>
<p>In a lot of cases, I don&#8217;t bother cleaning up temp files for internal software. Management of temp files takes a non-negligible amount of work, and if I can keep the software simpler by not worrying about it, I will. I&#8217;d rather rely on the developers to keep their hard drives in good shape, which they&#8217;ll do anyway.</p>
<p>If you&#8217;re running something that will generate a lot of temp files (maybe your test running script), you can also set your temporary directory to a temporary subdir, and then clean that up. Something like:</p>
<pre>oldtemp = tempfile.gettempdir()
newtemp = tempfile.tempdir = tempfile.mkdtemp() # Maybe set os.environs TMPDIR/TMP/TEMP as well?
try:
    nose.run() # Or whatever processing you need to do
finally:
    tempfile.tempdir = oldtemp
    shutil.rmtree(newtemp)</pre>
<p>And lastly (it&#8217;s last because I&#8217;m sure people have some religious objection to it), I&#8217;ve actually created a custom mktemp function that just calls mkstemp and closes the file descriptor. Just getting a path is useful and worth the performance overhead in (IMO) the vast majority of cases, especially since we often just need the filename to pass to some external process.</p>
<p>What advice do you have for working with temp files (and where is my advice poor)?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1060</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>How wide are your interviews?</title>
		<link>http://www.robg3d.com/?p=1050</link>
		<comments>http://www.robg3d.com/?p=1050#comments</comments>
		<pubDate>Thu, 20 Dec 2012 11:47:38 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Culture]]></category>
		<category><![CDATA[Leadership]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1050</guid>
		<description><![CDATA[I&#8217;ve been a part of  and interviewed at companies where the interview process was not just long but also very wide- people from different teams and departments interview a candidate. (ie, a Microsoft-style interview process) At my current company, our last two Art hires have had a much more abbreviated hiring process- the Art Manager, ]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve been a part of  and interviewed at companies where the interview process was not just long but also very wide- people from different teams and departments interview a candidate. (ie, a Microsoft-style interview process)</p>
<p>At my current company, our last two Art hires have had a much more abbreviated hiring process- the Art Manager, myself, and the Art Producer (and the Art Director if needed).</p>
<p>So I&#8217;ve been through and a part of interviews at both ends of the complexity spectrum. I&#8217;ve been thinking about it recently and I&#8217;ll share some thoughts (and I&#8217;d also love people&#8217;s own opinions and experiences).</p>
<ul>
<li><span style="line-height: 13px;" data-mce-mark="1">Only a few people are generally good interviewers. If this doesn&#8217;t correspond with your Leads/Directors/Managers, there&#8217;s a problem. So I am not sure the depth of the interview varies greatly between the two styles.</span></li>
<li>On the other hand, interview experience is important for more junior members, and if they don&#8217;t get experience they&#8217;ll not turn into good interviewers.</li>
<li>Only a few people are generally responsible for making the decision anyway, and I&#8217;ve never actually seen a contentious decision: if one or two people have a thumbs down opinion, it&#8217;s enough of a red flag for everyone else. What&#8217;s the point of six or twelve people sitting around and pretending to decide?</li>
<li>How often are interviews really surprising? You know in the first couple minutes whether you&#8217;ll accept someone or not, or whether they&#8217;re in the middle (usually meaning you need to find a better candidate).</li>
</ul>
<p>So given those experiences I&#8217;m going to try do the following for the interview process for Tech Artists:</p>
<ul>
<li><span style="line-height: 13px;">See who wants to be part of the interview. Cultivating this skill is vital, but it isn&#8217;t for everyone, and people who have no interest shouldn&#8217;t waste their time.</span></li>
<li>Expand the interview to include those people- it should definitely extend past the manager/lead level.</li>
<li>Be rigorous, and don&#8217;t bother hiring anyone that isn&#8217;t unanimously liked. When the candidate pool is thin or work is slipping, it&#8217;s tempting to take a chance. It&#8217;s not worth the risk (in my opinion, of course).</li>
</ul>
<p>I&#8217;m curious how other studios handle it, and what people think of those processes?</p>
<p><span style="font-size: 8pt;">*I feel obligated to mention that if your studio is a management-run people-churner, please gripe at your managers and not me for writing this post!</span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1050</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Development directors?</title>
		<link>http://www.robg3d.com/?p=1051</link>
		<comments>http://www.robg3d.com/?p=1051#comments</comments>
		<pubDate>Tue, 18 Dec 2012 10:57:47 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rant]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1051</guid>
		<description><![CDATA[I&#8217;ve worked with (for?) several development directors. Some have been talented individuals, some incompetent. But invariably, the role has (in my experience) been useless. I&#8217;ve always seen it as a needless position on the producer/PM hierarchy. And oftentimes an add-on position due to explosive producer/PM headcount growth. I understand what creative/technical/art/design/qa/(product&#124;game) direction is. I have ]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve worked with (for?) several development directors. Some have been talented individuals, some incompetent. But invariably, the role has (in my experience) been useless. I&#8217;ve always seen it as a needless position on the producer/PM hierarchy. And oftentimes an add-on position due to explosive producer/PM headcount growth.</p>
<p>I understand what creative/technical/art/design/qa/(product|game) direction is. I have no idea what &#8220;development direction&#8221; is. And if I do, I have no idea how it&#8217;d be beneficial. I mean, the few decisions like &#8220;we are using Hansoft for scheduling and backlog management&#8221; can be made at the project producer level, and most other &#8216;development direction&#8217; I can think of negatively infringes on team autonomy.</p>
<p>Has anyone actually had success with the role of development director? Not just a super-talented individual who happened to do a good job, but an actual use for the role?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1051</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Python Singletons</title>
		<link>http://www.robg3d.com/?p=1021</link>
		<comments>http://www.robg3d.com/?p=1021#comments</comments>
		<pubDate>Sun, 18 Nov 2012 15:47:41 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[functional programming]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[threading]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1021</guid>
		<description><![CDATA[In my opinion, good python libraries and frameworks should spend effort guiding you towards the &#8216;pit of success&#8217;, rather than trying to keep you from failing. They do this by spending most effort on things related to the critical path- clear interfaces, simple implementations, thorough documentation. Which is why singletons are, to me, the worst ]]></description>
				<content:encoded><![CDATA[<p>In my opinion, good python libraries and frameworks should spend effort guiding you towards the &#8216;pit of success&#8217;, rather than trying to keep you from failing. They do this by spending most effort on things related to the critical path- clear interfaces, simple implementations, thorough documentation.</p>
<p>Which is why singletons are, to me, the worst form of framework masturbation in python. You will never be able to stop people from doing something stupid if they&#8217;re determined (in pure python). In the case of a singleton, that means instantiating more than one instance of a type. So spending effort on &#8216;designing&#8217; singletons is not just a waste of effort, but actively harmful. Just provide a clear way to use a single instance, and your system should fail clearly if it detects an actual problem due to multiple instances (as opposed to, trying to detect multiple instances to keep said problem from happening).</p>
<p>The best method for singletons in python, then, is- whatever is simplest!</p>
<ol>
<li>Some form of module or class state is, to me, the clearest. It requires someone reading or using your code to know nothing more than the most basic python. Just prefix your class def with an underscore, and expose an accessor function to an instance stored on the module (or on the class). The capacity for failure is minimal and the behavior is clear (it requires no behavior modification to the type itself).</li>
<li>Overriding __new__ is pretty bad but OK. It requires someone to understand the subtleties of __new__, which is a useful thing to teach someone but, are singletons really the time and place?</li>
<li>Using a metaclass is a terrible solution. It has a higher likelihood of failure (how many people understand the nuances of metaclasses!?). Misdirection even for people just reading your code, trying to understand your type&#8217;s behavior. Avoid.</li>
</ol>
<div>The question to ask yourself before doing any of this is, &#8220;is a singleton a technical requirement or an architectural preference?&#8221; Ie, a single instance of an application event loop (QApplication, etc) I&#8217;d consider a technical requirement and make it foolproof (in C?). But technical requirements are few and far between and should be driven by underlying system/OS requirements rather than your code&#8217;s design or architecture. If it&#8217;s an architectural preference- &#8220;there should only be one instance of this manager/window/cache&#8221;- there&#8217;s absolutely no reason to confuse your code (especially you object&#8217;s behavior!) to achieve it. Just use design, documentation, and examples, to show people the right way to use it.</div>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1021</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Taking your dog to Iceland</title>
		<link>http://www.robg3d.com/?p=1044</link>
		<comments>http://www.robg3d.com/?p=1044#comments</comments>
		<pubDate>Sat, 17 Nov 2012 12:38:32 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1044</guid>
		<description><![CDATA[In late 2011, my wife and I imported our Boston Terrier, Shoni, to Iceland. Since importing pets commonly comes up on foreigner discussions, I thought I&#8217;d dedicate a post to our experiences (sorry, no tech writing today!). I&#8217;ll also mention, this is specifically for dogs, at the time we did it. Cats may be different ]]></description>
				<content:encoded><![CDATA[<p>In late 2011, my wife and I imported our Boston Terrier, Shoni, to Iceland. Since importing pets commonly comes up on foreigner discussions, I thought I&#8217;d dedicate a post to our experiences (sorry, no tech writing today!). I&#8217;ll also mention, this is specifically for dogs, at the time we did it. Cats may be different (easier and more people have done it, from what I hear), and rules may change. I&#8217;m also not going to bother linking to forms- this is a personal experience, not a guide, and there is some amount of work involved in moving your pet to Iceland!</p>
<p>Overall, the process isn&#8217;t too hard. Information is pretty clear (and in English), everyone was very accommodating, and there were no surprises from Iceland&#8217;s side. I wouldn&#8217;t bother getting a service to do it, I&#8217;d just do it myself. And our dog came out no worse for the wear.</p>
<p>Anyway, on to the timeline (I&#8217;ll list prices at the end):</p>
<p>1. In early September, I applied for a permit from MAST, which is good for up to a year. I should have done this much earlier. I needed to get the permit at least 30 days (something like that) before importing Shoni, which meant by the time I got the permit, she couldn&#8217;t come with us in October. This threw everything off and caused a lot of stress and extra shots. So get your permit ASAP. The rest of the process is filled with timing restrictions, don&#8217;t mess this one up.</p>
<p>2. There are two quarantine places. Once is in the far north (Hrisey, near Akueyri), one is nearer to Keflavik. They stagger their intake, so one takes pets for a few days in the middle of the month, the other at the end/start of the month. If you have a choice (and are living in the capital area), I&#8217;d choose the one near Keflavik, to avoid an extra return flight and less transport overall. I&#8217;ve also heard their English is better. Shoni ended up going to Hrisey though, because I screwed up the permit and that&#8217;s what worked out timing-wise.</p>
<p>3. There are certain shots that the dog needs to have <em>at least</em> 60 days from departure. There are other shots that she needs <em>no more than</em> 30 or 60 days from departure. Read everything and schedule everything in advance. Don&#8217;t mess this up! Though we did a little bit but talked to MAST and everything was fine.</p>
<p>4. Make sure you have an airline-ready travel crate, and make sure your dog is used to sleeping in it! A regular crate won&#8217;t do, you may need a special crate for air travel. We lucked out, Casady&#8217;s aunt and uncle had one they weren&#8217;t using, from their recent international move.</p>
<p>5. Shoni flew from Texas to New York in mid-October, after our wedding, in coach with my Aunts. This was the least harrowing part of the entire trip, even though a 10kg dog in the cabin is too big! If you can book your pet in the cabin, do it (it&#8217;ll also be cheaper). Try it even if they may be too big- she flew Jet Blue, and it made me like that airline even more. If she must go cargo, I&#8217;ll note that airlines have restrictions and cautions for certain dog breeds during certain months. Boston Terriers are brachiocyphallic (snub-nosed), so they can overheat and die during travel, especially during summer months (usually sitting out on the tarmac). Different airlines have different records and different breeds have different accident rates. But do your research and be safe (if the dog is worth the price you&#8217;re going to pay to move her, she&#8217;s worth this risk, I&#8217;d say). We sent Shoni&#8217;s (empty) crate as baggage.</p>
<p>6. It was difficult and a huge burden to place on someone (my Aunts) to prep a dog for an international move. We did a bunch of stuff in Austin, but there was stuff that needed to be done 30/10 days before departure, that my Aunts needed to do. Shoni ended up getting several unnecessary shots; there was lots of confusion and stress in the month she was with my Aunts. On the other hand, breaking the trip into two parts was easier on Shoni. I would have been scared for her life if she went on an 18 hour trip in her crate. The key takeaway is that better planning and less procrastination would have made things easier, but even with mistakes along the way everything turned out fine.</p>
<p>7. Again, read the paperwork. There&#8217;s stuff you need to fax 5 days before your pet arrives. There was, not surprisingly, a lot of stress in the last few days. Lots of calls with MAST and my family and making sure everything was good to go.</p>
<p>8. With everything set, Shoni flew Icelandair cargo in mid-November from JFK to Keflavik. It was painless and we got confirmation she arrived, the worst parts were over. The quarantine people picked her (and presumably other pets) up, drives them to Hrisey (or wherever your quarantine is), and they start their quarantine. There is no way to interact with your pets AFAIK, even if you are on the same flight (sometimes you may see them in the luggage area but it isn&#8217;t like you can take them out to pee!).</p>
<p>9. Once in quarantine, we asked for updates/photos, and got them. The &#8220;warden&#8217;s&#8221; English was not great so it was difficult to communicate, so I needed to have a friend translate some emails between English and Icelandic. Shoni looked nervous and the place was obviously pretty sterile, but she looked safe and healthy. Shoni is very well-adjusted and adaptable, so if you have a nervous pet she may fare worse. Also, I think you can visit your pets- but I wasn&#8217;t about to go to Akureyri as a new resident in December, but I probably would have visited her in Keflavik.</p>
<p>10. After 4 weeks (right before Christmas, for us!), Shoni&#8217;s time was up. And here&#8217;s another reason to choose Keflavik over Hrisey- Icelandic winter weather is fickle and her flight was delayed several times. She was on one of the last flights from Akureyri. We picked her up from the airport, took her home in a cab, and all was well. She didn&#8217;t have any of her toys or blankets she was sent with- the stuff has to be boiled and rarely survives it.</p>
<p>11. Costs. All are approximate.</p>
<ul>
<li>Permit: $240 (including transfer fee)</li>
<li>Flight Austin-&gt;JFK: $100</li>
<li>Flight JFK-&gt;Keflavik: $450</li>
<li>Akureyri-&gt;Reykjavik: $100</li>
<li>Quarantine: $1600 (varies with pet size)</li>
<li>Customs fee: $100</li>
<li>Vet bills: $700 or so, not sure</li>
<li>Total: About $3500</li>
</ul>
<p>In the end, it wasn&#8217;t a question of whether or not it was worth it- there was no question, she was coming. However, procrastination complicated things. And it is expensive. Bigger dogs will be more expensive, cats are smaller and require less shots so would be cheaper.</p>
<p>Anyway, I hope this post is helpful, and feel free to ask me any questions about my experience.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1044</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Is QA a good stepping stone?</title>
		<link>http://www.robg3d.com/?p=1035</link>
		<comments>http://www.robg3d.com/?p=1035#comments</comments>
		<pubDate>Fri, 09 Nov 2012 22:08:40 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1035</guid>
		<description><![CDATA[I&#8217;ve always heard that it was difficult to move from QA into development (game design/programming/art/production). I thought this was smart- QA people should be there to be QA people, not doing a job only because they hope it would lead to something else. And at some companies, it works. My previous job was at a ]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve always heard that it was difficult to move from QA into development (game design/programming/art/production). I thought this was smart- QA people should be there to be QA people, not doing a job only because they hope it would lead to something else.</p>
<p>And at some companies, it works. My previous job was at a well-regarded studio, working on a huge game and IP, in a wonderful city, and lots of developers were looking for work (and we had the money to hire them, if not keep them after ship&#8230;). People <em>really</em> wanted to work there (I once interviewed someone as I was near the end of my tenure there, and told him pretty clearly, &#8220;you won&#8217;t like programming here.&#8221; And of course he took the job anyway). It didn&#8217;t make sense to spend effort training QA people when you could just hire the people you wanted directly.</p>
<p>However, I now work at a place that is much more difficult to hire for. Outside people respect the company and know the game, but the audience is smaller than one of the biggest IPs and most successful game studios of all time. And especially, it&#8217;s in Iceland. Iceland is a wonderful country, but we&#8217;ve had several people turn down offers or on-site interviews because their family said &#8220;no way&#8221; (myself almost included).</p>
<p>In my opinion, it makes more sense to hire QA people (often out of the EVE or local Icelandic community), and set them up on a career path that leads <em>outside</em> of QA. There will never be a serious shortage of applications for a QA job, but it can take a year to hire and relocate a senior person (and you are taking a big risk on that time and expense!). And to a large extent, this is what we do (and while we have sometimes failed at providing career paths, I still think it remains the goal).</p>
<p>I quite like this new strategy- not only does it produce good results over time, it also seems to have more integrity- QA people are too often treated like second class citizens, rather than devs-to-be. I&#8217;m not sure if my mind will change if I move on to another studio, but it&#8217;s at least how I feel now. I wonder how other studios approach this issue?</p>
<p>(Side note- I am not saying there isn&#8217;t a need for senior and permanent QA people, I&#8217;m just saying, there are lots of people in QA that don&#8217;t want a career in QA. There should also be career development inside of QA, but that shouldn&#8217;t be the only career development)</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1035</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Teaching python decorators</title>
		<link>http://www.robg3d.com/?p=1032</link>
		<comments>http://www.robg3d.com/?p=1032#comments</comments>
		<pubDate>Mon, 05 Nov 2012 21:58:59 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1032</guid>
		<description><![CDATA[A few weeks ago, I held a demo about context managers and decorators. Teaching context managers was straightforward, as expected. Decorators, however, are a much more complex concept. So I used Steve Ferg&#8217;s article about the right way to explain python decorators. This was a live demo with little preparation (just wrote down his steps and ]]></description>
				<content:encoded><![CDATA[<p>A few weeks ago, I held a demo about context managers and decorators. Teaching context managers was straightforward, as expected. Decorators, however, are a much more complex concept. So I used Steve Ferg&#8217;s article about <a href="http://pythonconquerstheuniverse.wordpress.com/2012/04/29/python-decorators/">the <em>right</em> way to explain python decorators</a>. This was a live demo with little preparation (just wrote down his steps and knew I would write decorators to cache and timeout), to a variety of skill levels, and it was unanimously successful. Everyone came away with a much clearer idea of how decorators work- I saw a lightbulb go off in everyone&#8217;s head.</p>
<p>I don&#8217;t know why it took so long to figure out how to teach decorators (even harder than first figuring out how to use them!), but Steve&#8217;s method works, and I&#8217;d encourage you to use it to teach anyone who&#8217;s interested.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1032</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PSA: It isn&#8217;t dark magic, it&#8217;s your anti-virus software</title>
		<link>http://www.robg3d.com/?p=1029</link>
		<comments>http://www.robg3d.com/?p=1029#comments</comments>
		<pubDate>Fri, 02 Nov 2012 21:07:40 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1029</guid>
		<description><![CDATA[We&#8217;ve all had it- sometimes, under certain conditions, your code errors with an IOError because Windows can&#8217;t delete a file. It seems random, and it is. Well, in case you weren&#8217;t aware, it&#8217;s almost definitely your anti virus software (http://blogs.msdn.com/b/oldnewthing/archive/2012/09/07/10347136.aspx) or at least, some other crazy shit going on. So a few weeks ago I ]]></description>
				<content:encoded><![CDATA[<p>We&#8217;ve all had it- sometimes, under certain conditions, your code errors with an IOError because Windows can&#8217;t delete a file. It seems random, and it is. Well, in case you weren&#8217;t aware, it&#8217;s almost definitely your anti virus software (<a href="http://blogs.msdn.com/b/oldnewthing/archive/2012/09/07/10347136.aspx">http://blogs.msdn.com/b/oldnewthing/archive/2012/09/07/10347136.aspx</a>) or at least, some other crazy shit going on.</p>
<p>So a few weeks ago I gave up and said, forget it, I&#8217;m just going to write retrying rmtree/remove functions. It took a long time because I refuse to do cargo-cult programming on problems like this, so once I saw that article, I went ahead with it.</p>
<p>I just wanted to spread this information in case you&#8217;re in the same situation I was in. You may as well harden and test your little helper retying-delete function I know you have hidden away somewhere, and make it a part of your core libraries.</p>
<p>&lt;No code provided- this is the hacky shit that cannot have a straightforward design and IMO shouldn&#8217;t leave your studio, so you&#8217;re on your own to figure out an acceptable design and implementation!&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1029</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to deal with being a negative developer</title>
		<link>http://www.robg3d.com/?p=1025</link>
		<comments>http://www.robg3d.com/?p=1025#comments</comments>
		<pubDate>Tue, 30 Oct 2012 20:51:37 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[career]]></category>
		<category><![CDATA[Culture]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[project management]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1025</guid>
		<description><![CDATA[There was a recent AltDevBlogADay post about Negative Developers and Team Stability that hit home. It&#8217;s not that I think the advice was particularly interesting (good, standard stuff), it&#8217;s that it reminded be that I&#8217;ve been a negative developer. I don&#8217;t know what I could have done differently. I just wasn&#8217;t happy at work, and there was ]]></description>
				<content:encoded><![CDATA[<p>There was a recent AltDevBlogADay post about <a href="http://www.altdevblogaday.com/2012/10/05/negative-developers-and-team-stability/">Negative Developers and Team Stability</a> that hit home. It&#8217;s not that I think the advice was particularly interesting (good, standard stuff), it&#8217;s that it reminded be that <strong>I&#8217;ve been a negative developer.</strong></p>
<p>I don&#8217;t know what I could have done differently. I just wasn&#8217;t happy at work, and there was little I could do to change it. The quality of my work was apparently very good, I was just terrible for morale, because I was either 1) pissing people off or 2) encouraging people to be pissed off at the problems I/we saw. Eventually I got the best advice I&#8217;ve ever gotten (which deserves its own blog post), and left the company. I went to the right place and became a positive developer.</p>
<p>And that&#8217;s sort of what struck me about the article and about how we typically deal with negative developers. Some developers are just not a good fit, regardless of how amazing their work is. If someone is negative because she is &#8220;culturally incompatible&#8221;, because there&#8217;s nothing you or your manager can do to fix it. And it is worth it to have a frank discussion about whether that person can ever be happy without changes to the studio, and if that person says &#8216;no&#8217;, you should discuss plans to part with mutual respect at a mutually agreed date.</p>
<p>I had to put in my two weeks at my last job to have this advice given to me by the President (GM? Can&#8217;t remember) at the time. It convinced me to un-quit, and to stay on another year. It ended up being a miserable year in many ways, but it was the right thing to do and worked out for the best. As managers- and friends and team members of negative developers- we need to keep this advice in mind when dealing with negative developers (and ourselves).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1025</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Decisions, decisions</title>
		<link>http://www.robg3d.com/?p=1022</link>
		<comments>http://www.robg3d.com/?p=1022#comments</comments>
		<pubDate>Sat, 27 Oct 2012 21:26:19 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Culture]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[Tech Artists]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1022</guid>
		<description><![CDATA[Some people can find me a bit over-earnest in my quest for automation. I&#8217;ve finally figured out how to know whether something is worthwhile to automate. Are you making any decisions when you do this? And if someone is making decisions that may be unnecessary: Can we get from A to B without making any ]]></description>
				<content:encoded><![CDATA[<p>Some people can find me a bit over-earnest in my quest for automation. I&#8217;ve finally figured out how to know whether something is worthwhile to automate.</p>
<p><strong>Are you making any decisions when you do this?</strong></p>
<p>And if someone is making decisions that may be unnecessary:</p>
<p><strong>Can we get from A to B without making any decisions?</strong></p>
<p>I value the people I work with and I want them to be more effective. Sometimes people are afraid I&#8217;ll automate them out of a job, or they like a manual part of their workflow. More often they take pride in being the manual bottleneck behind a tricky or brittle process.</p>
<p>Humans are valuable because we can make complex decisions very quickly. When I automate an area someone isn&#8217;t immediately comfortable with, it&#8217;s not because I don&#8217;t value what he or she does. On the contrary: because I value their skills and time, I want to see them doing something that requires their unique abilities.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1022</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Python for programmers?</title>
		<link>http://www.robg3d.com/?p=1019</link>
		<comments>http://www.robg3d.com/?p=1019#comments</comments>
		<pubDate>Sat, 13 Oct 2012 12:14:55 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1019</guid>
		<description><![CDATA[Writing up some performance reviews reminded me of my opinionated fact that a minority of people programming python really understand python. I think in statically typed languages, this is somewhat more acceptable. I think of how interesting &#8220;CLR via C#&#8221; was. It helped me understand the CLR and IL, as well as some much more ]]></description>
				<content:encoded><![CDATA[<p>Writing up some performance reviews reminded me of my opinionated fact that a minority of people programming python really understand python. I think in statically typed languages, this is somewhat more acceptable. I think of how interesting &#8220;CLR via C#&#8221; was. It helped me understand the CLR and IL, as well as some much more general design patterns (damn you, properties!), but had minimal impact for how I used C# (except perhaps regarding performance and GC).</p>
<p>But in a fully dynamic language that has so much power- not understand how the language itself works puts you at a severe disadvantage. I&#8217;m not just talking about the one thousand aspects of meta-programming, but even just taking advantage of duck-typing (ie, instead of creating/passing a type, can you just pass a callable that returns a new instance?). Or how decorators work, or how importing works.</p>
<p>I am pretty sure I asked this when I started python but, are there any books (or courses) about python, written for more-or-less experienced programmers (even python programmers), that aren&#8217;t about &#8216;teaching python&#8217; in the normal introductory (or cookbook/reference) way? More along the lines of CLR via C#, or some of the better python guides out there (Idiomatic Python). I am sure there are a large number of people out there who would get huge benefit from such a book or comprehensive guide.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1019</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Through the eyes of a newbie</title>
		<link>http://www.robg3d.com/?p=1013</link>
		<comments>http://www.robg3d.com/?p=1013#comments</comments>
		<pubDate>Tue, 11 Sep 2012 21:27:37 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1013</guid>
		<description><![CDATA[The wife is interested in learning programming so she has been doing the Code Academy JavaScript course. It&#8217;s incredible to observe a person learning programming from the ground up, and how their mind works. It&#8217;s almost impossible to remember those early weeks of learning how to code yourself. It&#8217;s been fun to see the frustrations, ]]></description>
				<content:encoded><![CDATA[<p>The wife is interested in learning programming so she has been doing the <a href="www.codeacademy.com">Code Academy</a> JavaScript course. It&#8217;s incredible to observe a person learning programming from the ground up, and how their mind works. It&#8217;s almost impossible to remember those early weeks of learning how to code yourself.</p>
<p>It&#8217;s been fun to see the frustrations, problems, and questions she&#8217;s had:</p>
<ul>
<li>For loops. So hideous. I don&#8217;t know who invented such the syntax &#8220;for (i=0; i&lt;100;i++)&#8221;, but really I blame the people that continued the tradition into later languages where it is a truly stupid syntax.</li>
<li>Speaking of i++/i&#8211;. What are these things and why do they exist?</li>
<li>Curly braces. What a waste of space!</li>
<li>var. When do I use it and when do I not use it?</li>
<li>Why do I need to end my lines with semicolons?</li>
</ul>
<p>They also have a python course, I&#8217;ll be interested to see how that one goes. I suspect it&#8217;ll make less sense since she&#8217;ll now expect all languages to work as poorly as Javascript :)</p>
<p>Also to preempt the comments about how this doesn&#8217;t mean anything about a language and we shouldn&#8217;t design languages for complete programming newbies- yes, I agree. Mostly I found this interesting because the grievances she&#8217;s had all have their roots in C-style languages yet they are found in JavaScript which was designed to be novice-friendly. Though admittedly the novice in 1995 and 2012 start with very different dispositions.</p>
<p>I&#8217;ll certainly have much more to say once she moves into the rest of JS, and then into Python.</p>
<p>Also, Code Academy is really awesome.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1013</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>always lowercase py files, always</title>
		<link>http://www.robg3d.com/?p=1007</link>
		<comments>http://www.robg3d.com/?p=1007#comments</comments>
		<pubDate>Mon, 13 Aug 2012 22:27:23 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1007</guid>
		<description><![CDATA[In my line of work I deal with junior programmers constantly. One of the most common non-code mistakes I see them make is using capital letters in their python file names. I&#8217;m not sure why it happens so often, to such a diverse crowd, but I guess it comes down to bad examples, and stylistic ]]></description>
				<content:encoded><![CDATA[<p>In my line of work I deal with junior programmers constantly. One of the most common non-code mistakes I see them make is using capital letters in their python file names. I&#8217;m not sure why it happens so often, to such a diverse crowd, but I guess it comes down to bad examples, and stylistic preference.</p>
<p>Except it isn&#8217;t stylistic preference. And unlike my rant about <a title="Tabs vs. Spaces" href="http://www.robg3d.com/?p=917">tabs-vs-spaces</a>, it isn&#8217;t easy to fix either.</p>
<p>Imagine a simple scenario (note, this only applies to Windows- I should mention in my line of work we are usually on Windows) :</p>
<ol>
<li>You create a file, myModule.py, you put some awesome code in it, and check it into source control (probably Perforce but AFAIK any source control has the same problems).</li>
<li>A while later, you rename it to mymodule.py, fix up your code references, and check it in.</li>
<li>The code breaks on all your users machines, and you can&#8217;t clean it up without manual intervention, or changing your module to be called something else.</li>
</ol>
<p>Did you see what happened? When you checked in the code, everyone synced down &#8216;myModule.py.&#8217; When you changed the capitalization, everyone else&#8217;s VCS synced down the new file contents but, because the file was already there, didn&#8217;t delete myModule.py. So everyone else got the <strong>new code</strong> calling &#8216;import mymodule&#8217; but keeps the <strong>old filename</strong> &#8216;myModule.py&#8217;. Fixing this problem either requires removing the file from people&#8217;s client and force syncing (manually or by mass-deploying a fixup script), or just renaming &#8216;mymodule&#8217; to something else entirely.</p>
<p>The problem stems from <strong>python, which is case-sensitive</strong>, relying on the filenames of paths, which rely on <strong>Windows, which is case insensitive.</strong> Don&#8217;t bother blaming anyone, it&#8217;s just the way it is.</p>
<p>So the way to deal with it? Always use lowercase, which is <a href="http://www.python.org/dev/peps/pep-0008/#package-and-module-names">exactly what the PEP8 style guide suggests</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1007</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Including test files in coverage reports</title>
		<link>http://www.robg3d.com/?p=1003</link>
		<comments>http://www.robg3d.com/?p=1003#comments</comments>
		<pubDate>Thu, 09 Aug 2012 19:56:07 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1003</guid>
		<description><![CDATA[We&#8217;ve finally gotten our test coverage reports published to an accessible place and I&#8217;ve been wondering whether including test files as part of the coverage report is generally preferable to excluding them. Initially I thought they should be excluded- after all, it&#8217;s your &#8216;real&#8217; code people are generally worried about- but now I&#8217;m not so ]]></description>
				<content:encoded><![CDATA[<p>We&#8217;ve finally gotten our test coverage reports published to an accessible place and I&#8217;ve been wondering whether including test files as part of the coverage report is generally preferable to excluding them.</p>
<p>Initially I thought they should be excluded- after all, it&#8217;s your &#8216;real&#8217; code people are generally worried about- but now I&#8217;m not so sure. You should probably make sure your test files are actually run and covered, as once you have a large amount of tests that often bend in various ways, it isn&#8217;t always a given. And actually that&#8217;s just the case  we were in today, we have tests that are still not runnable on our CI server, but the report doesn&#8217;t show which ones.</p>
<p>Not to mention having your test source easily browseable in the form of a coverage report, which is easier for test-curious people to browse than a source depot.</p>
<p>I think I&#8217;m going to re-include tests in the report, despite it skewing our coverage percentage (favorably :)). But I&#8217;m really curious if there&#8217;s accepted practice or good reasons either way I haven&#8217;t thought of.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1003</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why bother with python and config files?</title>
		<link>http://www.robg3d.com/?p=1000</link>
		<comments>http://www.robg3d.com/?p=1000#comments</comments>
		<pubDate>Tue, 26 Jun 2012 21:34:43 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[Tools and Pipeline]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=1000</guid>
		<description><![CDATA[I&#8217;ve never understood why people design systems in python to use config files. IMO there are two types of data and we can handle them both in dead simple ways: First: Read/write data, like UI/user preferences. I say, just use python dictionaries, and serialize them however the hell you want (json, yaml, pickle, cPickle, I ]]></description>
				<content:encoded><![CDATA[<p>I&#8217;ve never understood why people design systems in python to use config files. IMO there are two types of data and we can handle them both in dead simple ways:</p>
<p><strong>First: Read/write data, like UI/user preferences.</strong> I say, just use python dictionaries, and serialize them however the hell you want (json, yaml, pickle, cPickle, I don&#8217;t care). I don&#8217;t understand why anyone would build anything more complex (except maybe a wrapper over this functionality), and especially why anyone would bother using a non-serialized format like ini or cfg. Can there be a good reason?</p>
<p><strong>Second: Read-only data, like application configuration</strong> (nothing that is edited by your app). This, too, is very commonly in config files with special like xml or ini. Well in this case I say, why bother even with serialized data at all? Just make it code! This data, by definition, does not have to be statically known and serialized, it is only needed at runtime. So why not make it a python module, have your code import/exec the python file, and access attributes from the python module? There&#8217;s a good deal of data we may only know at runtime, or we cannot statically represent, so we end up making the systems that consume this configuration data much more complex. (For an example, see Sphinx&#8217;s config, I think it does it right).</p>
<p>An example of where I think python-as-configuration has huge power is with complex configuration data like for a plugin system. Instead of relying on some static functionality, the configuration can even be callables that return a plugin instance- so now you don&#8217;t have to refer to globals inside of your plugins, you can have your own initializer with a much larger signature, and the plugin system can have its well-defined initialization interface.</p>
<p>I&#8217;m not sure I did a great job explaining that example- it deserves its own post. We&#8217;ve used it extensively for new tools and systems we&#8217;ve developed and it seems to work great (and results in zero globals or singletons used by the plugins, which is an artifact of most plugin systems I&#8217;ve seen).</p>
<p>These are my opinions and practices and I know there are plenty good modules which rely on ini/xml/config files. Other than legacy decisions or to be compatible with pre-existing systems, why would someone choose a config file/format over 1) serialized python objects and/or 2) python code?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=1000</wfw:commentRss>
		<slash:comments>23</slash:comments>
		</item>
		<item>
		<title>Never build upon closed-source frameworks</title>
		<link>http://www.robg3d.com/?p=991</link>
		<comments>http://www.robg3d.com/?p=991#comments</comments>
		<pubDate>Wed, 20 Jun 2012 22:04:51 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[project management]]></category>
		<category><![CDATA[Tech Artists]]></category>
		<category><![CDATA[Tools and Pipeline]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=991</guid>
		<description><![CDATA[A poster on tech-artists.org who is using Autodesk&#8217;s CAT asks:  The problem I´m having: I can control the ears now manually, after setting up the reactions, but apparently the CAT system isn´t respecting any keyframes I set on the facial controls, neither in setup nor animation mode. He already hinted at the answer in the same ]]></description>
				<content:encoded><![CDATA[<p>A poster on tech-artists.org who is using Autodesk&#8217;s CAT <a href="http://tech-artists.org/forum/showthread.php?2778-Customizing-CAT-rig-in-3ds-Max-2012&amp;p=16665#post16665">asks</a>:</p>
<blockquote><p> The problem I´m having: I can control the ears now manually, after setting up the reactions, but apparently the CAT system isn´t respecting any keyframes I set on the facial controls, neither in setup nor animation mode.</p></blockquote>
<p>He already hinted at the answer in the same post:</p>
<blockquote><p>Even though I´ve heard a couple of times not to rely on CAT in production&#8230;</p></blockquote>
<p>So there&#8217;s your answer.</p>
<p style="padding-left: 30px;"><strong>Never depend upon closed-source frameworks that aren&#8217;t ubiquitous and proven.</strong></p>
<p>It&#8217;s true of CAT, it&#8217;s true of everything. And in fact it is one reason I&#8217;ll never go back to developing with .NET on Windows (the 3rd party ecosystem, not the framework itself). If you don&#8217;t have the source for something, you 1) will never fully understand it, and 2) never be able to sustain your use of it. When I was at BioWare Austin, and the Edmonton guys decided to switch to CAT, I was up in arms for exactly this reason. We had an aging framework- PuppetShop- but it worked well enough, we had the source, and acceptable levels of support (Kees, the author, is/was readily available). Instead, they switched to a closed-source product (CAT) from a vendor that has repeatedly showcased its awful support (Autodesk), and headache ensued. Fortunately I never had to deal with it and left some months after that. Without the source, you&#8217;re dependent upon someone whose job it is to provide support just good enough so you don&#8217;t leave their product (which is difficult since they own everything), and bad enough that you have to hire them to fix problems (they pride themselves on this level of support, which I call extortion).</p>
<p>As for the ubiquitous and proven part: unless this closed source solution is incredibly widespread (think Max, Maya, etc.), and has a lot of involved power users (ie, Biped is widespread but difficult to get good community support for because it attracts so many novices), it means you have to figure out <em>every single workaround</em> because you can&#8217;t actually fix the problem because <em>you don&#8217;t have source.</em> Imagine working with no Google- that&#8217;s what you give up when you use a closed-source framework that isn&#8217;t an industry standard.</p>
<p>So don&#8217;t do it. Don&#8217;t let others do it. If you&#8217;re currently doing it, think about getting the source and if you can&#8217;t do that, start making a backup plan.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=991</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Someone has a hat to eat</title>
		<link>http://www.robg3d.com/?p=988</link>
		<comments>http://www.robg3d.com/?p=988#comments</comments>
		<pubDate>Wed, 30 May 2012 23:10:44 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Culture]]></category>
		<category><![CDATA[Personal]]></category>
		<category><![CDATA[project management]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=988</guid>
		<description><![CDATA[In December, I made a blog post about being happy. A anonymous (of course) commenter said: Hey Rob. 5 months? Are you really this shortsighted? It’s like watching a kid say he’ll NEVER get tired of THIS toy. Frankly, if you don’t get tired of it you stopped growing. Take it as a good learning ]]></description>
				<content:encoded><![CDATA[<p>In December, I made a blog post about <a href="http://www.robg3d.com/?p=814">being happy</a>. A anonymous (of course) commenter said:</p>
<p style="padding-left: 30px;">Hey Rob. 5 months? Are you really this shortsighted? It’s like watching a kid say he’ll NEVER get tired of THIS toy. Frankly, if you don’t get tired of it you stopped growing. Take it as a good learning experience for the time when you forge your own destiny, but if you aren’t back to being a grumpy asshole in 6 months I’ll eat my hat. Not that I wear hats.</p>
<p>So 6 months (and <a href="http://www.eveonline.com/inferno">a released expansion</a>) later, have things changed? No, not one bit. In fact, late-night-drunk-rants have growth even more positive all around. Few of the bitch-sessions I&#8217;ve been used to in my career. It is an unfamiliar feeling. But addictive.</p>
<p>So why am I not back to being a &#8216;grumpy asshole&#8217;? Because there&#8217;s nothing to be grumpy about. There&#8217;s plenty wrong, but we&#8217;re moving at a steady pace in the right direction. And everyone is on board that it&#8217;s the right direction. No &#8220;we&#8217;ve decided this is the right direction so STFU and do what you&#8217;re told&#8221;. This happens because the talented people that complain loudly have several constructive outlets (I put myself in that group, at the risk of sounding egotistical).</p>
<p>One of the most exciting are <a href="http://en.wikipedia.org/wiki/Community_of_practice">communities of practice</a>. Read the Wikipedia article if you like, but really they are a company-sanctioned forum for people with axes to grind to argue. Then we figure out what we want to do, and how to do it. And then we do it on some 15% time for skunkworks projects we&#8217;re able to reserve. Being able to talk about our common problems, across teams and responsibilities- we have everyone from tech artists to server programmers to the CTO there- is a refreshing experience.</p>
<p>(If you&#8217;re at a large company with lots of programmers who all aren&#8217;t on the same team, I&#8217;d highly suggest forming your own communities of practice).</p>
<p>The people who get shit done and can convince you of the way forward are given the responsibility to get more shit done. It&#8217;s nice. I think it has to do with the open source and python mentality.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=988</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Why GUI&#8217;s Lock Up</title>
		<link>http://www.robg3d.com/?p=958</link>
		<comments>http://www.robg3d.com/?p=958#comments</comments>
		<pubDate>Sun, 08 Apr 2012 22:58:48 +0000</pubDate>
		<dc:creator>Rob Galanakis</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[threading]]></category>
		<category><![CDATA[Tools and Pipeline]]></category>

		<guid isPermaLink="false">http://www.robg3d.com/?p=958</guid>
		<description><![CDATA[This is a post for the Tech Artists and new programmers out there. I am going to answer the common question &#8220;why do my GUI&#8217;s lock up&#8221; and, to a lesser extent, &#8220;what can I do about it.&#8221; I&#8217;m going to tell a story of a mouse click event. It is born when a user ]]></description>
				<content:encoded><![CDATA[<p>This is a post for the Tech Artists and new programmers out there. I am going to answer the common question &#8220;why do my GUI&#8217;s lock up&#8221; and, to a lesser extent, &#8220;what can I do about it.&#8221;</p>
<p>I&#8217;m going to tell a story of a mouse click event. It is born when a user clicks her mouse button. This mouse click goes from the hardware, to the OS. The OS determines that the user wants to interact with your GUI, so it sends the mouse click event to your GUI&#8217;s process. Here, the mouse click sits in a queue of other similar events, just hanging out. At some point, usually almost immediately, your process (actually the main thread in the process) goes through and, one by one, dispatches the items (messages) in the queue. It has determined our mouse click is over a button and then tells the button it&#8217;s been clicked. The button then usually repaints itself so it looks pressed, and then invokes any callbacks that are hooked up. The process (main thread) goes into one such callback you hooked up, that will look at 1000 files on disk. This takes a while. In the mean time, the user is clicking, but the messages are just piling up in the queue. And then someone drags a window over your GUI, because they&#8217;re tired of their clicks not doing anything and want to see what&#8217;s new on G+. The OS sends a message to your UI that it needs to repaint itself, but that message, too, just sits in the queue. At some point, your OS may even realize your window is not responding, and fade it out and change the title bar. Finally your on-button-click callback finishes, the process (thread) is done processing our initial mouse click, and then goes back to processing the messages that may have accumulated in the queue, and your UI will refresh and start responding again.</p>
<p>All this happens because the thread that processes messages to draw the UI was also responsible for looking at 1000 files on disk, so it wasn&#8217;t around to respond to the paint and click messages. A few pieces of info:</p>
<ol>
<li>You can&#8217;t just &#8216;update the UI&#8217; from the middle of your code. In addition to being terrible form code-wise, clearing the message queue would just cause other things to block the main thread, and it&#8217;d all get into one giant asynchronous mess. Some programs may have their own UI framework that supports this. Don&#8217;t trust it. You really just need the main/GUI thread clear as much as possible to respond to events.</li>
<li>Your GUI process has a single &#8216;main thread.&#8217; A thread roughly corresponds to, and I&#8217;m being not nuanced here, the software concept of a hardware CPU core. Your GUI objects can only be created and manipulated by the main thread.</li>
</ol>
<p>This means, you want to keep your main thread free so it can act on GUI stuff (paint events, mouse clicks) only. The processing, such as your callback that looks at 1000 files, should happen on another thread (a background thread). When the processing is complete, it can tell the GUI thread that it is finished, and the GUI thread can update the UI. Your background thread can also fire events or invoke a callback that will be picked up by the GUI thread, so the GUI can update a progress bar or whatever.</p>
<p>How you actually do this varies with each UI framework. .NET, including WinForms and WPF, is quite easy to use (look at the BackgroundWorker class, but the Tasks Parallel Library and Async CTP make that less necessary). Python GUI frameworks are a bit worse off- multithreading in python in general is worse off- so it&#8217;ll be different for each one, and probably not as simple as .NET. There&#8217;s no excuse for python GUI&#8217;s to lock up, it just takes a little more effort to get it completely right (like callbacks to update a UI are a bit tricky).</p>
<p>There is one other vital thing to keep in mind- DCC programs generally require you to interact with the API or run all their script on the main thread, which as discussed should also be kept clear. Bummer! So the best thing we can do is block while we get our data from the scene, put the processing on a background thread, and report back to the main thread when done, applying the new data back to the scene if necessary. Unfortunately, if your processing interacts with the API in any way, you probably need to put it in the main thread as well. So, right now, your GUI&#8217;s in DCC apps may need to lock up, by design. There are, in theory, ways to avoid this, but they&#8217;re well outside of the scope of what you can handle if you&#8217;re learning anything from this article.</p>
<p>Whatever your language and program, those are the essentials of why your GUI locks up.</p>
<h6>Note: This info is not nuanced (and is less accurate the lower down things go), may not be terminologically perfect (though it should be vulgarly comprehensible), and is Windows-only, though it should be enough to know how any higher-level GUI framework (such as Qt) would work on a non-Windows system).</h6>
]]></content:encoded>
			<wfw:commentRss>http://www.robg3d.com/?feed=rss2&#038;p=958</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
