Sebastian Weigand : Design and Development http://www.sw-dd.com (Posterous Version) posterous.com Tue, 01 Nov 2011 11:32:00 -0700 Better Fancy Formatting and Printing with Python http://www.sw-dd.com/better-fancy-formatting-and-printing-with-pyt http://www.sw-dd.com/better-fancy-formatting-and-printing-with-pyt

A while back, I came up with a great way to print boxed text to the screen in a way that wrapped the lines, and allowed the justification of the text. I've reworked the code since then, revisiting my random libraries as I do, and came up with a much better implementation: View on GitHub.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Sun, 17 Jul 2011 14:01:43 -0700 Fancy Table Printing With Python http://www.sw-dd.com/fancy-table-printing-with-python-73267 http://www.sw-dd.com/fancy-table-printing-with-python-73267

Ever want to print out a nice table, maybe have it spaced out nicely? Have you run into a situation where the length of something you want to print differs by more than a tab-length? Stuck in a for loop, with no hope in sight of getting those columns printed nicely? Fear no more!

fancyTable() will accept a multi-dimensional array, and make sure each item in each column is spaced to be as long as the longest element in that column.

For example, should you build up an array of arrays like this:

a = [['Text', '1', 'a'], ['Longer Text', '123', 'abc'], ['Even longer text!', '123456789', 'abcdefghi']]

You'd get this:

Text              1         a         
Longer Text       123       abc       
Even longer text! 123456789 abcdefghi

Amazing, isn't it!

def fancyTable(arrays):

 def areAllEqual(lst):
     return not lst or [lst[0]] * len(lst) == lst

 if not areAllEqual(map(len, arrays)):
  exit('Cannot print a table with unequal array lengths.')

 #lengths = [map(len, a) for a in myar]
 #sizes = map(lambda * x:x, *lengths)
 #maxSize = [max(a) for a in sizes]

 verticalMaxLengths = [max(value) for value in map(lambda * x:x, *[map(len, a) for a in arrays])]

 spacedLines = []

 for array in arrays:
  spacedLine = ''
  for i, field in enumerate(array):
   diff = verticalMaxLengths[i] - len(field)
   spacedLine += field + ' ' * diff + '\t'
  spacedLines.append(spacedLine)

 return '\n'.join(spacedLines)

Let me know what you think! I'm sure there's a better way of doing it.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Sun, 17 Jul 2011 14:00:00 -0700 Fancy Table Printing With Python http://www.sw-dd.com/fancy-table-printing-with-python http://www.sw-dd.com/fancy-table-printing-with-python

Ever want to print out a nice table, maybe have it spaced out nicely? Have you run into a situation where the length of something you want to print differs by more than a tab-length? Stuck in a for loop, with no hope in sight of getting those columns printed nicely? Fear no more!

 

fancyTable() will accept a multi-dimensional array, and make sure each item in each column is spaced to be as long as the longest element in that column.

For example, should you build up an array of arrays like this:

a = [['Text', '1', 'a'], ['Longer Text', '123', 'abc'], ['Even longer text!', '123456789', 'abcdefghi']]

 

You'd get this:

Text              1         a         
Longer Text       123       abc       
Even longer text! 123456789 abcdefghi

Amazing, isn't it!

def fancyTable(arrays):

 def areAllEqual(lst):
     return not lst or [lst[0]] * len(lst) == lst

 if not areAllEqual(map(len, arrays)):
  exit('Cannot print a table with unequal array lengths.')

 #lengths = [map(len, a) for a in myar]
 #sizes = map(lambda * x:x, *lengths)
 #maxSize = [max(a) for a in sizes]

 verticalMaxLengths = [max(value) for value in map(lambda * x:x, *[map(len, a) for a in arrays])]

 spacedLines = []

 for array in arrays:
  spacedLine = ''
  for i, field in enumerate(array):
   diff = verticalMaxLengths[i] - len(field)
   spacedLine += field + ' ' * diff + '\t'
  spacedLines.append(spacedLine)

 return '\n'.join(spacedLines)

Let me know what you think! I'm sure there's a better way of doing it.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Mon, 09 May 2011 17:15:00 -0700 Fancy Printing with Python http://www.sw-dd.com/fancy-printing-with-python http://www.sw-dd.com/fancy-printing-with-python

Box Printing and More!

From time to time, I need to print something nice and fancy, like say a box in a terminal:

=================
= Hello, world! =
=================

But, the task of printing these things becomes tedious, especially if you want to say, center the text:

==============================
=       Hello, world!        =
==============================

But what if you wanted to change all of that: not have it in a box, specify arbitrary widths, specify filler characters, specify line characters, margins, padding, etc?

Here's the output of: fancyPrinter('Hello, world!', centered = True, width = 50, char = '*', mode = 'box', filler = 'X', margin = 1, padding = 1):

 
**************************************************
*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*
*XXXXXXXXXXXXXXXX Hello, world! XXXXXXXXXXXXXXXXX*
*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX*
**************************************************
 

Or what about multiple lines? That are longer than your width?

Try this out: fancyPrinter('Wow, this sure is a lot of text.\nQuite a bit of text, actually.\nWhy would anyone have this much text to output?', centered = True, width = 20)

====================
=  Wow, this sure  =
=   is a lot of    =
=      text.       =
=  Quite a bit of  =
=      text,       =
=    actually.     =
=    Why would     =
=   anyone have    =
=  this much text  =
=    to output?    =
====================

And here's the same thing, not centered, with no width specified:

===================================================
= Wow, this sure is a lot of text.                =
= Quite a bit of text, actually.                  =
= Why would anyone have this much text to output? =
===================================================

Then you would need my fancyPrinter() method:

def fancyPrinter(text, filler = ' ', char = None, centered = False, width = None, margin = None, padding = None, mode = 'box', output = sys.stdout):
 
 '''
 Copyright 2011 Sebastian Weigand, released under the GPLv3
 Print text in a fancier fashion.
 print >> output,  text in a fancier fashion.
 
 Accepts multiple lines, and will fit a box (if that is the mode) around it, and truncate
 each line which is over the specified width (maximum of terminal, or specified; minimum
 of the longest word in the text).
 '''
 
 textLength = max(map(len, text.splitlines()))
 textArray = text.split()
 maxWordLength = max(map(len, textArray))
 rows, columns = os.popen('stty size', 'r').read().split()
 termWidth = int(columns)
 modes = ['box', 'overline', 'underline', 'simple']

 if mode not in modes:
  raise TypeError('\'' + mode + '\' is an invalid mode for boxprint >> output, er().')

 if 'line' in mode:
  if not char:
   char = '-'
 elif mode == 'center':
  if not char:
   char = ' '
  centered = True
  if not width:
   width = termWidth
 else:
  if not char:
   char = '='

 if centered and not width:
  width = termWidth

 if width:
  if width < maxWordLength + 4:
   width = maxWordLength + 4
 else:
  width = textLength + 4
 
 # Set maximum width to that of terminal:
 if textLength >= termWidth + 4 or width >= termWidth + 4:
  width = termWidth
 
 lines = []

 # Chop up lines to fit within confines of width, or max width (terminal):
 if width < textLength + 4:
  
  for line in text.splitlines():
   sentence = ''

   for word in line.split():

    word = word + ' '

    newSentence = sentence + word
    
    if len(newSentence) < width - 4:
     sentence = newSentence
    else:
     if len(sentence) > 0:
      lines.append(sentence)
     sentence = word

   lines.append(sentence)
 else:
  lines = (text + ' ').splitlines()

 if margin:
  print >> output,  '\n' * (margin - 1)

 if centered:
  if mode == 'box' or mode == 'overline':
   print >> output,  char * width
  
  if padding:
   for i in xrange(0, padding):
    if 'box' in mode:
     print >> output,  char + filler * (width - 2) + char
    else:
     print >> output,  filler * width
  
  for line in lines:
   # "line" is text + :
   spacing = (width - len(line) - 2)
   
   # Prefer extra right spaces when width is not even:
   leftSpacing = (spacing / 2) + (spacing % 2) - 1
   rightSpacing = (spacing / 2)
   
   if mode == 'box':
    print >> output,  char + (filler * leftSpacing) + ' ' + line + (filler * rightSpacing) + char
   else:
    # Extra padding, as there's no preceeding char:
    print >> output,  (filler * (leftSpacing + 1)) + ' ' + line + (filler * (rightSpacing + 1))
  
  if padding:
   for i in xrange(0, padding):
    if 'box' in mode:
     print >> output,  char + filler * (width - 2) + char
    else:
     print >> output,  filler * width
  
  if mode == 'box' or mode == 'underline':
   print >> output,  char * width
  
 else:
  if mode == 'box' or mode == 'overline':
   print >> output,  char * width
  
  if padding:
   for i in xrange(0, padding):
    if 'box' in mode:
     print >> output,  char + filler * (width - 2) + char
    else:
     print >> output,  filler * width
  
  for line in lines:
   if mode == 'box':
    print >> output,  char + ' ' + line + filler * (width - len(line) - 3) + char
   else:
    print >> output,  ' ' + line
  
  if padding:
   for i in xrange(0, padding):
    if 'box' in mode:
     print >> output,  char + filler * (width - 2) + char
    else:
     print >> output,  filler * width
  
  if mode == 'box' or mode == 'underline':
   # This will produce a line which is slighlty longer on the right,
   #  but it looks nice in underline.
   print >> output,  char * width  

 if margin:
  print >> output,  '\n' * (margin - 1)

I hope you enjoy :)

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Thu, 03 Feb 2011 16:21:00 -0800 Password Generator http://www.sw-dd.com/password-generator http://www.sw-dd.com/password-generator

I needed a script to generate arbitrary-sized passwords which may or
may not include specific characters. Nothing really worked, so I ended
up writing one: Available on my Dropbox.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Sun, 14 Nov 2010 17:39:00 -0800 Finalized Layout Design http://www.sw-dd.com/finalized-layout-design http://www.sw-dd.com/finalized-layout-design

I've decided to take on something quite difficult: I'm going to *attempt* to create an HTML5+CSS3 (graceful fallback) template which works beautifully on both Blogger and Posterous for my blog, SWDD. I've got a preliminary Webkit-centric layout mocked up already (complete with subtle, yet enjoyable webkit-transitions), and I just need to correlate the Webkit-centric code to Mozilla-centric code, and then futz around with the wonderful hell that is Internet Explorer. Until then, enjoy some of the theme designers best work I've seen on both Blogger and Posterous.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Wed, 12 May 2010 20:27:00 -0700 Simple Media Jukebox http://www.sw-dd.com/2010/05/simple-media-jukebox.html http://www.sw-dd.com/2010/05/simple-media-jukebox.html

I, upon dealing with the myriad frustrations of iTunes, pondered the difficulty of a simple, drop-anywhere jukebox. I just wanted something to scan a directory, organize the files in a meaningful way, and let me choose which one to play (given that I have the ability to decode them). So, I set about throwing together some code.

SWDD: SMJ is my 'simple media jukebox'. To use it, simply execute it on your favorite platform (Linux and Mac OS X supported, though Windows is too, if you give it the right media player binary). It then asks for a media player to use (defaults to mplayer), and a directory in which to search for media files.

Here's where it gets brilliant: If you're using a modern Linux distribution, or OS X, you can alternatively enter 'locate' for the location, and it will query the system indexing service for a list of media files. Then, simply give it a song you wish to play, and voi-la!

Of course, it only bases its limited information on file name, file extension, and location; if you were to give it a mount point of an iPod, for example, it wouldn't be quite so useful. It also does not parse metadata, and the way it handles the printing of matching songs is unordered (because of the way we retrieve them from the disk), but all-in-all, it's a Simple Media Jukebox. Give it a whirl!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Tue, 09 Mar 2010 02:04:00 -0800 ssh-keyscan-aliases.py - A smarter ssh-keyscan http://www.sw-dd.com/2010/03/keyaddpy-smarter-ssh-keyscan.html http://www.sw-dd.com/2010/03/keyaddpy-smarter-ssh-keyscan.html

I've been playing around with a wrapper for 'ssh-keyscan' at work, and thought I would share my script with the world.

Motivations

While at work, we have servers which need to have their SSH known-hosts file updated with the various machines we deal with. Additionally (as SSH is very specific), aliases of machines are not added to the known_hosts file unless you specify them. This script seeks to address each of these issues, while providing a more robust command in general (like comparing SSH keys of hosts).

Take a look at the code, available on my GitHub.

If you have any comments, suggestions, or notice a bug: Please feel free to comment, and I'll be sure to fix it.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Mon, 09 Nov 2009 21:24:00 -0800 Compression Algorithms and their Performance http://www.sw-dd.com/2009/11/compression-algorithms-and-their.html http://www.sw-dd.com/2009/11/compression-algorithms-and-their.html

The Premise: GZIP vs BZIP2 vs XZ (the new LZMA)

I was asking myself the other day (as often as I do), what are the relative differences between the available FOSS compression mechanisms available today? Now, apart from having a recent class in language processing about the matter, I took it upon myself to give a few of them a try, and report it here.

The Data

I needed some data which would work to the compressor's advantage. To that end, I decided that I needed a substantially large corpus with which to play around. The word list which comes on OS X is large, but I wanted something massive. Then I thought, perhaps XML would be great. But where to find a gigantic XML file?

I took a look at xmark, and set it with a scaling factor of 5 (download the source for more info). This is a well-formed XML generator. Setting it as I did produced over 500 megabytes worth of XML.

The Compressors

For the test, I decided to skip compress and zip, and focus on the newer ones. These include gzip, mgzip (a mutli-threaded version), bzip2, and xz. I used the latest versions (at the time of this posting) of each, and set off to see how well they did.

The Results

First, the run time:

time gzip -9 BIG.xml       : real 0m48.609s
time mgzip -t 2 -9 BIG.xml : real 0m24.941s
time bzip2 BIG.xml         : real 1m31.825s
time xz -9 BIG.xml         : real 9m51.624s

Next, for the compression:

585540595 BIG.xml
128643043 BIG.xml.bz2
191123758 BIG.xml.gz
 28386648 BIG.xml.xz

Conclusion

Yes, that does say that a 559 MB file was compressed to 28 MB. If you're willing to wait for it, XZ is by far the best choice out there. On a related note, it uses a heck of a lot of memory in '-9' mode (just shy of 700 MB). But then again, the developers did warn you in the man page!

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Fri, 06 Nov 2009 02:59:00 -0800 My Issue with Microsoft (Part 2) http://www.sw-dd.com/2009/11/my-issue-with-microsoft-part-2.html http://www.sw-dd.com/2009/11/my-issue-with-microsoft-part-2.html

I've been meaning to update this post, and over the ages, I've come across this particular, well-formed essay-like rant which sums up most of my complaints with the Microsoft: Why I Hate Microsoft

I think it's a pretty good read, especially if you're like me.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Sun, 23 Aug 2009 19:39:00 -0700 My Issue With Microsoft (Part 1) http://www.sw-dd.com/2009/08/my-issue-with-microsoft-part-1.html http://www.sw-dd.com/2009/08/my-issue-with-microsoft-part-1.html

I've been called various things in the past with regards to my personal likes or dislikes with technology. I've been called an Apple Fanboy, a Linux Nut, and various synonyms for each. I'd like to take a few moments to correct people's misconceptions about me, and perhaps people who think like me.

About Me

The early years

First off, you have to know the kind of person I am, before you can appropriately judge my opinions. I grew up loving technology. I'd love taking apart random things and attempting to reassemble them. I've always had a fondness for computers, partially because I was mystified by their companion-like nature: they're something to play with, learn from, or talk to your friends with. They're just great.

I grew up using Macs in my elementary school's "computer lab" (I use quotes here because it consisted of a meager dozen computers, no Internet (obviously), and that's about it). However, I grew to dislike them from their lack of reliability. That, coupled with their annoying location of the power button, made rebooting these all-in-ones a terrible chore. I was excited, when a little after 1995, the school's new technology person decided to replace the aging Macs with IBMs running Windows 95. "Finally", I thought, "we'd have computers that wouldn't freeze!".

My first computer(s)

Fast forward a few years, to November of 1998. This is when my family got their first computer. Since my parents spent the 80's overseas, and missed out on the whole "technological revolution" thing, they weren't to eager to get a computer. I remember the feeling, like Christmas had come early. We had gone to the then-new Gateway Country stores, and picked out a beauty of a machine. A 450 MHz Pentium II, 128 MB of RAM, a Voodoo 2 with an ATI and hardware MPEG decoder for the (then-new) DVD-ROM drive, a 19" Hitachi monitor, and awesome Boston Acoustics speakers (which I still have, and still use, they just have an amazing sound). It was --awesome--. It came with Windows 98 (first edition), and I loved that computer to death.

I spent most of my adolescent life fiddling with that Gateway, until a couple years later I got my very own Walmart-sold HP. It was faster, had more RAM (after a trip to Staples), and it ran Windows Me. Now, I'm probably the only person in the world to say this, but I thought Windows Me was a great operating system. I never had any problems with it (or the 100 MB Iomega Zip drive from the Gateway, a drive notorious for problems). To me, it was the most amazing thing in the universe. Coupled with our local-yocal dial-up ISP (and subsequent second phone line), I felt like the king of the world.

A few years later, I really got into computers. All I did, and all the money I made in high school went into my computer. I didn't really like video games (except for the few on the PC), so it got 100% of my attention. I bought motherboard after motherboard, DIMM after DIMM, and of course, power supply after power supply. I remember transitioning from Voodoo to GeForce, and when a gigabyte of RAM was expensive. I memorized all the different Pentium 4 models, their speeds and costs, RAM prices from online and local stores, cache latencies, CPU voltages, the best heatsinks and cases. At one point, I even bought case lights to make it look "cool".

At this point, me and Microsoft were pals.

Then along came Linux

It was at this point that I started expanding my geekiness. I started hearing about this thing called "Linux", a completely different operating system you could run on your computer!? Around this time too, I started looking at what Apple was doing, now that its operating system had moved to OS X. I gave Knoppix a try, and eventually Red Hat 8 (9, and all the Fedoras). I was so amazed at how different Linux was; how odd it felt to use, weird it was to install programs (what's this compiling thing again?), and how X-window-y it looked (or UNIX-y, if you prefer). But, when I started playing around, I started understanding all the little subcomponents, and discovered services like FTP, telnet, and then SSH. The fact that Apache was available too boosted my interest. And to think, all of this is free!

Enter Apple

When it came time to head to college, I really wanted a laptop. As you can't really build your own laptop, I decided to look around at what was available. I did my homework (well, at least when it came to computers), compared models from HP, Compaq, Dell, Gateway, IBM, and my favorite: Apple. Oddly enough, what drew me into Apple wasn't their operating system (it was the second biggest thing), but their hardware. I, even to this day, adore the PowerPC G4 processor. The entire concept of the processor, from its conception to its implementation astonished me. For me, the 'Velocity Engine' (what real geeks refer to as the AltiVec instruction set) is what sealed the deal. To think, all the supposed power of the Pentium, and my little 1.5 GHz PPC G4 could smite it. I ordered my first Mac, the Aluminum PowerBook G4 15". It was one of the first laptops Apple shipped with Panther, a fairly large upgrade of OS X. I remember hijacking the FedEx guy when he stopped at my high school. I was eating lunch, and grabbed my package and opened it in the cafeteria. "It probably doesn't have a charge" I thought as I took out the gorgeous laptop and hit the power button. A few seconds later, a welcome video was playing, and I had a grin on my face larger than my face itself. From then on, I fell in love with Macintosh, and slowly stopped using my frankensteinian PC until I got to college. The PC had, at any given time, 5 different combinations of Linux and Windows on it. I found myself relying more and more on the Mac to get things done. Inevitably, the PC had problem after problem until one day in my sophomore year, I just said "screw it", and gave up on it. It was the best thing that ever happened to me. I was forced to use my laptop fully for the next couple of years.

Maturity

I kept up-to-date with the latest Linux distro, and was there for the Ubuntu uprising. I followed what Microsoft was doing with XP, advances in Direct X, the latest Intel and AMD processors, and random hardware components and their new specs. I had grown tired of tinkering with my computer, putting it all together, and constantly upgrading components. It was time that I settle down and just use a computer for computing, and stop worrying about all the little bits inside of it. I bought the first Intel-based iMac, and was blown-away again. Tiger showcased even more improvements, EFI provided quick-as-hell startup times, and the computer looked gorgeous. Not letting my geekdom stagnate, I was constantly looking at new Apple-like things, from Quicksilver to (now) MacPorts. I was pleased that my Intel Mac could just download the source tarballs of my favorite Linux applications and compile them with little hiccuping. In the meantime, my friends and I collected old computers the university was throwing out. We threw Vector Linux on them, and donated their computing time to projects like Folding@Home and later BOINC projects.

To this day...

I have 4 Macintosh LC-775s, a G3 all-in-one, two Apple ][s, a Tandy (complete with plotter), a dual-CPU Pentium II-based server (in its really tall case), 3 or so Apple printers, a few more HP printers, and the components with which to build 3 or 4 functional PCs. I have an endless supply of random computer cables and peripherals, the mini-CD Compaq iPaq music player, a Sony Clié PDA (with infrared keyboard), and a 5-foot box of floppy disks with random commercial software (like Autocad v1). Add to that the nearly 800 burnt CDs, zip disks, and hard drives, and I have quite a collection -- and these are just the bits that I don't use anymore (though they all work).

My original PowerBook, Athenia, still gets used today as a guest laptop at my apartment. It's fully up-to-date, but needs a new DC/sound board after a recent accident left it unable to play sounds. My frankensteinian PC still boots, and was its own domain for a while, but motherboard faults have left it a collection of outdated parts. My iMac is my main desktop, and as for a laptop, I am very happy with my unibody MacBook Pro. Oh, and then there's the hundred or so Linux boxes I use at work.

So, I hope that this is enough of a background to stand on to deliver the next bit of rant...

I'm only biased in favor of quality. If it causes problems, it's not for me.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Wed, 08 Jul 2009 18:57:00 -0700 Apple Responds to my Bug Report http://www.sw-dd.com/2009/07/apple-responds-to-my-bug-report.html http://www.sw-dd.com/2009/07/apple-responds-to-my-bug-report.html

It was really cool today, when my Google notifier informed me I had mail from the bug report people over at Apple. You may remember an older post of mine where I describe a potential bug with Apple's Time Machine system. Here's what they had to say:

Basically, Apple wants to keep the way it works because of the way Time Machine works to begin with. Consider this: the Time Machine backup is not an actual file system, rather an abstracted storage container, wherein bits of data are stored and referenced. As such, the data is stored (more or less) in one location, and simply referenced by future back-ups. Changing permissions on a particular reference would ultimately end up changing the past, and that's bad (think hard links).

This is all fine-and-dandy, and I completely understand where they're coming from, but I still think it would be cool to develop the low-level granularity into the next release of Time Machine and OS X. It would awesome to have ridiculously efficient file back-up. But then again, how many geeks out there are suffering from my issues? I'm pretty sure I'm in the minority on this one ;).

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Wed, 08 Jul 2009 05:52:00 -0700 The Trouble with Advertising http://www.sw-dd.com/2009/07/trouble-with-advertising.html http://www.sw-dd.com/2009/07/trouble-with-advertising.html

I get frustrated when surfing sites nowadays which are a bit too gung-ho when it comes to advertising. Specifically, online streaming services, such as Hulu, Fox OnDemand, and most others.

The problem is, it's difficult for the older generation (particularly those involved in making large executive decisions) to understand how the modern twentysomething thinks (and it's only getting worse with the next generation). We are an impatient bunch, with piercingly-accurate detectors of product BS, and "fake-cool".

We don't want some guy rapping about the best deals in wireless prepaid cell phone service, nor do we need some 'clever' advertisement which is supposed to be 'funny' and purposefully stupid. We know what we want, and what we want is content. Especially when it comes to online video, we really couldn't care less about the ads, we just want the content. And, more and more, if it's too much hassle to deal with your site, and the steps it takes to get to the content, we'll just grab the content elsewhere (quasi- or il-legally if need be).

The Big Irritators

I don't care about some things at all

I'm not sure about other people, but irrelevant ads can go take a hike altogether. It doesn't matter how clever they are, or how fascinatingly awesome I, or anyone else thinks they are. There are just some products I'm never, ever going to buy. Relevant ads, on the other hand, tend to be half-decent (so long as the algorithms are up to the challenge). How they appear, however, is a different matter entirely.

Animations and Flash are distracting and annoying

Anytime an ad, wherever it's placed on a site, is moving or flashing at me, I get annoyed. It detracts from my browsing experience, and forces me into a state of irritation. Trying to get my attention by flashing or animating something isn't going to work, instead, it's going to make me angry.

The big files

Going along with animations are the ads which are either way too large (as in filesize), or way too complicated (as in CPU intensive). A simple three-to-four word phrase and a logo is all an ad needs to convey. "Product Y: It's awesome stuff" That's it, not a 2-minute long animation with HD audio or advanced AI simulator on its backend. It's not that people aren't on broadband (which a large percentage still aren't), it's that they're wasting my bandwidth downloading something I don't care about.

The neo-pop-up

It used to be that pop-ups were a big problem. Then, we figured out a way to block them. Then, they figured out a way of bringing them back. Then, we blocked them again. Then, out of spite, they've moved them into the actual page. It's an in-window pop-up, done with either Javascript or Flash. Some floating box or other such nonsense appears and blocks your ability to do what you want. Now, I ask you, if constantly getting people to click on the big 'X' in the corner is the behavior advertisers are instilling, won't that just teach us to ignore, or quickly pass-off the products being advertised? It's the same philosophy regarding dialog boxes and computers. Too many people just click 'OK' that UI designers have had to change up their language to make people actually read the darn things (which is only part of the solution).

The "your show will begin in XX seconds..."

This one is for me, the worst. I absolutely hate when a site will deliberately prolong the display of content to show me an intrusive ad. What they're really getting across is, "product X doesn't want you to watch this video". That gets really annoying, and really, really annoying over time. The easy fix to this is to simply place an ad below the content, and add the words "Brought to you by:" next to it. That way, I notice it, and associate my favorite content with the advertised product. Keeping it the content-prohibitive way it is now only makes me develop spite for the products. Seriously, there are a few products I will deliberately avoid because they've prolonged me watching something online.

The Shining Stars

The clever, "hey dude, have you seen the latest ad from ... " ad

These include ads like the wonderful Wario Land Shake It Youtube page, and the Apple / NY Times ads (of which there are many). These ads are fun to watch, creative, and non-obtrusive. Even the Apple ad doesn't interrupt with audio, and doesn't start until you click play (or at least they used to).

Google AdSense and AdWords

In what has become a recurring theme, I keep going back to Google for how to get things right on the Internet. When it comes to advertising, I think they've got a great thing going. On their main site, searching for something provides ads related to what you're searching for, clearly marked as ads, with easy-to-read URLs. This keeps you aware that these aren't 'search' results, but ads, and allows you to make a judgement call on their reputability based on who they're from. If I'm searching for "hotels in las vegas", chances are I want to find hotels to do business with, which is the perfect opportunity for advertising. If not, Google then provides all the (hopefully forever) bias-free search results below.

On the other hand, Google also provides contextual ads via AdSense. A few lines of text here or there similar to the text on your site. Have a Linux enthusiast site? Ads will appear relevant to the content, and without much flare or distraction. They appear as sort of a, "oh by the way, here are some places that do business related to your interests..."

Final Thoughts

My plea to content owners

Listen up content-owners: people will get your content however they want to, if they want it. You need to put yourself in their shoes to make sure that your site is the place where they get it. It isn't hard to design, just be respectful, relevant, and understand the power of brand and content loyalty.

Social networking = free advertising

It's weird nowadays. People love to advertise for free! It's called 'brand association'. I love company X, so I want to help them do well, and associate with the lifestyle company X is associated with. Take, for instance every clothing manufacturer ever. It's just a tee shirt. It costs less than $5 to make, distribute, and sell. Yet, people want to associate themselves with a particular brand or group because of the social impact. Now, take this logic online, where advertising is as simple as creating a Facebook page. I'll admit it, I do it. I'm a fan of a few things on Facebook, namely because I support whatever it may be. Did I get paid to advertise? No. Did the people pay to create the page? No. Did it spread virally like wildfire? Yes.

Beware the power of the intarwebs

This new-fangled technology requires much appreciation. Take a moment to realize that the theoretical sum of of human collective consciousness can be transmitted to and from any connected human, instantaneously. That's quite a thing to behold. Now imagine that a popular person liked your product, and decided to give you a 'bump'. Potentially, every person in the world could know of it. Now, imagine this person is fed up with your product. The same grand power can be felt, just in the negative. This is the power of the Internet. Just look at the Tweets during or soon after the latest Apple keynote which mentioned "AT&T". People were utterly pissed off. That kind of emotion will be very hard to combat with traditional marketing know-how. My advice? Focus on the customer, and quality of your product. The rest will always follow. Don't lie, don't PR BS, just speak the truth. An apology goes a lot further than does an evade.

Truth in advertising is a must

Maybe Wikipedia said it best: "[citation needed]". With the aforementioned instantaneous dispersal of knowledge comes the responsibility to make sure claims are substantiated with fact. It only takes one person to call BS on something for another person to agree, and so on. Pretty soon, whatever company wrought the fury of scrutiny upon them will soon have to address it, and this time get it right. Like Microsoft's hideous IE 8 "Get the facts" page. It's downright funny! Remember this, there may be people out there that will be fooled, but all they have to do is ask a geek what the deal with Safari, Chrome, or Firefox is to be convinced IE8 is a hunk of junk. Similarly, Wikipedia's got the inside info on so many BS products out there. It's surprising to see how many articles have a "Controversies" or "Criticisms" section. Like I said earlier, focus on the people, what they want, and then ultimately the product.

The Big Take Away

Respect your patrons.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Fri, 05 Jun 2009 21:49:00 -0700 Language Benchmarks and Psyco Python http://www.sw-dd.com/2009/06/psyco-python.html http://www.sw-dd.com/2009/06/psyco-python.html

Ever wonder about how fast certain programming or scripting languages are, versus one another? Well, I have...

The Premise

So, being that MacPorts has Psyco available to it, I've been playing around with it. For those of you not in the know, Psyco is a JIT compiler and optimizer for Python. I came across this page of benchmarks and thought it would be fun to play around with the various implementations and see how fast they got.

The Machine

For the tests, I'm using my MacBook Pro (2.8 GHz Intel Core 2 Duo w/6MB L2, 4 GB DDR3 @ 1 GHz). As for the software:

ruby 1.8.6 (2008-08-11 patchlevel 287) [universal-darwin9.0]
This is perl, v5.8.9 built for darwin-2level
Python 2.6.2 (r262:71600, Jun  5 2009, 17:59:46)
    [GCC 4.0.1 (Apple Inc. build 5490)] on darwin
Java(TM) SE Runtime Environment (build 1.6.0_07-b06-153)
    Java HotSpot(TM) 64-Bit Server VM (build 1.6.0_07-b06-57, mixed mode)
gcc (GCC) 4.4.0

Additional parameters passed to GCC:

c-regular: gcc bench.c
c-nocona:  gcc -O3 -march=nocona -m64 bench.c
c-tuned:   gcc -O3 bench.c

The Code (with Psyco)

I modified all of the scripts to get rid of their built-in timing, preferring instead the time UNIX command (real). Also, I stopped them from actually printing the fractal, but kept in the various 'print' commands as some of the implementations require at least something in their if-else block.

#!/usr/bin/env python
# by Daniel Rosengren
# Modified by Sebastian Weigand

import sys, psyco
stdout = sys.stdout

psyco.full()

BAILOUT = 16
MAX_ITERATIONS = 1000

class Iterator:
  def __init__(self):
    for y in range(-39, 39):
      for x in range(-39, 39):
        i = self.mandelbrot(x/40.0, y/40.0)
        
        if i == 0:
          stdout.write('')
        else:
          stdout.write('')
    
  def mandelbrot(self, x, y):
    cr = y - 0.5
    ci = x
    zi = 0.0
    zr = 0.0
    i = 0

    while True:
      i += 1
      temp = zr * zi
      zr2 = zr * zr
      zi2 = zi * zi
      zr = zr2 - zi2 + cr
      zi = temp + temp + ci
     
      if zi2 + zr2 > BAILOUT:
        return i
      if i > MAX_ITERATIONS:
        return 0

Iterator()

The Results

Well, as you might expect, they are a tad bit faster than the PowerBook in question. I just took a few of the tests, and came out with these results:

Media_httpwwwpagesdre_cfxca

It's amazing just how much faster Psyco can make Python!

Interesting too, how unless you've got some really high-end SSE3 or higher code, with lots of matrices and whatnot, GCC won't make your code that much faster if you have it match your current high-end CPU. This holds true for a lot of things actually (like Vorbis). See what I mean by adjusting the MAX ITERATIONS to something like 100,000 or so.

Any thoughts on Psyco?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Mon, 01 Jun 2009 00:43:00 -0700 iPhoto '09 and Facebook http://www.sw-dd.com/2009/05/iphoto-09-and-facebook.html http://www.sw-dd.com/2009/05/iphoto-09-and-facebook.html

I've been playing around with iPhoto '09 recently (specifically for Apple's implementation of facial detection and recognition), and (almost obviously) I have a big complaint.

Facebook contact misconnections

After I tagged people via Faces, and uploaded them to Facebook, I was surprised that several of my contacts, though having the exact same name as they do on FB, were not matching up.

I wondered why, then I wondered how. I believe the methodology of 'matching' contacts is done via email. Unfortunately, my address book on my laptop (which acts as my master book, because it synchronizes with Google and my iPhone) does not contain all the oddball email addresses used by my friends with their Facebook accounts. Even me, when I set up my Facebook account, didn't use my good email account, and used an alternative. This goes for a lot of people, really. Now, here are some solutions

Assume people take pictures of friends

For the most part, people will be taking pictures of their friends, which would theoretically limit the amount of duplicate names which can sprout up from attempting to match my friend 'Joe Schmoe' with all the 'Joe Schmoes' on Facebook.

Use Bayesian statistics to pinpoint contact matching

Instead of matching contacts via true or false, 1 or 0 boolean hits based on email addresses, use a combination of first name, last name, screen name, and email address to come up with a significant percentage chance of this 'Joe' matching my friend Joe.

Cache contact matching information

Once the database of matches is created, confirm with the user that the contacts are the same (probably for any low-confidence matches, to avoid annoyance), and store the details. Facebook assigns a GUID to every account, which can be used to more accurately pinpoint contacts should their information either on the client or the server changes. This way, when iPhoto 'tags' someone, it does so via the GUID, and always hits its mark. Note: Here, it doesn't really matter if the client or the server (ideally the server) stores the cached matches, just that someone does.

Allow for modification of the database

If we need to change something down the line, or make errors, let's make sure we can. This way, if the GUID scheme changes, we can rebuild the database with the new naming convention.

Provide address book synchronization capabilities

Seriously Facebook, you need to get on this. As nice as you are for keeping in touch with friends (and having them annoy the hell out of me via crappy applications which litter up my home page), all of the information about my friends store on FB is practically irretrievable when it comes to my devices. Wouldn't it be great to click 'export' and have all the data merged into my Address Book on my Mac, and synchronized to my Google accounts? Nearly all other contact-storing services from other companies allow for this functionality, get with the ball!

Of course, I'd be willing to fix it for you, just hire me.

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Sun, 24 May 2009 22:54:00 -0700 CSS Vertical Centering and Rounding Demo http://www.sw-dd.com/2009/05/css-vertical-centering-and-rounding.html http://www.sw-dd.com/2009/05/css-vertical-centering-and-rounding.html

So I was scrounging the net for the easiest way of both vertical centering a div and rounding its corners.

To my dismay, there are tons of results, but none that are as clean or as simple as I'd like them to be. So, I figured I'd do it myself.

The HTML

First of all, you can download an archive containing the HTML and requisite images and see it for yourself, or you could view a live demo here.

The interesting thing about doing it this way is that it's pretty straight-forward, and doesn't require an overabundance of div elements, nor JavaScript in order to function appropriately--it just puts your images where you want them.

Caveats

There are one or two to point out using this method (which I'm fine with):

Transparency is not maintained
This means you'll have to manually ensure the rounded corner backdrop color matches that of the adjacent element. I have yet to run into a situation where this can't be done.

Images are present in the foreground
Well, unless you need rediculously close text to the edge of your div, this shouldn't be a problem. The rounded corner picture is 25x25 pixels, and a simple padding: 25px; takes care of that nicely.

The Code

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>CSS Centering and Rounding Demo : SWDD</title>
 <style type="text/css">
 <!--
 
 /* This acts as our primary reset, to override browser defaults */
  
 * {
  margin: 0px;
  padding: 0px;
  font-family: sans-serif;
  border: none;
 }
 
 /* Our main div we want rounded */
 
 .outside {
 
  /* To vertically and horizontally center the div: */

  /* Give dimensions for the div */
  height: 250px;
  width: 250px;
    
  /* Specify different positioning */
  position: absolute;
  
  /* Specify equidistant spacing */
  left: 0px;
  right: 0px;
  top: 0px;
  bottom: 0px;
  
  /* Specify automatic margining for positioning */
  margin: auto;
  
  /* Adjust colors */
  background: #eee;
  color: #555;
  
  /* Keep text away from the corners */
  padding: 25px;
  
  /* For use with centering inner items vertically */
  display: table;
 }
 
 .inside {
 
  /* To enable vertical centering: */
  display: table-cell;
  vertical-align: middle;
  
  /* And horizontal centering: */
  margin: auto;
  text-align: center;
 }
 
 /* Stacked classes for use with our images */
 
 .top {
  position: absolute;
  top: 0px;
 }
 
 .bottom {
  position: absolute;
  bottom: 0px;
 }
 
 .right {
  right: 0px;
 }
 
 .left {
  left: 0px;
 }
 -->
 </style>
</head>
<body>

 <div class="outside"> 
  <img src="images/top-left.png" alt="img" class="top left" />
  <img src="images/top-right.png" alt="img" class="top right"/>
  <img src="images/bottom-left.png" alt="img" class="bottom left"/>
  <img src="images/bottom-right.png" alt="img" class="bottom right" />
  
  <div class="inside">
   <p>A rounded div.</p>
   <img src="images/swdd-logo-small.png" alt="SWDD" />
   <p>Cool, isn't it?</p>
  </div>

 </div>

</body>
</html>

Colorize your code.

Got any feedback?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Thu, 21 May 2009 22:56:00 -0700 Silly Apple, CHMODs are for Kids! http://www.sw-dd.com/2009/05/silly-apple-chmods-are-for-kids.html http://www.sw-dd.com/2009/05/silly-apple-chmods-are-for-kids.html

My iMac is configured to dual-boot OS X and Jaunty Jackelope (though I suspect that will soon become Leonidas). As such, I like having the ability to listen to music no matter which OS I'm booted into. On Mac, because everything's in iTunes, it's not that big of a deal (obviously). Linux, on the other hand, has a bit of a difficulty negotiating with HFS+ volumes.

It's not that it can't read them, no, it's that it respects UIDs, and UNIX permissions. For whatever the reason, Mac selects a UID of 501 instead of 500 for normal users, and disallows group and other access to items placed within the user's home directory (as it should).

It used to be the case that simply firing up any number of media players (originally XMMS, now Audacious, and more recently Rhythmbox) as root would work fine in reading the HFS+ partition mount. Of course, more and more players have decided running as root is a no-no (which for the most part it is), so what is a person to do?

Well, the easiest solution is a simple chmod -R a+rx. It's quick, easy, and effective. Writing isn't fully (super-duper fully) liked by Linux on HFS+ (something about the catalog files, I think), but just for Mac's security sake as well we're not throwing in write permissions. Now, this is only on the 'Music' parent directory (and all its children), so I fell relatively safe modifying it. And wouldn't you know, it works fine. So why, then, this blog post?

Time machine. It recognizes a different file structure for the data stored in the affected directories, and thus determines it needs to be added to the backup directory. The thing is, the only piece of data which has changed is the metadata relative to the file data! My iTunes library is around 55 GB, and I really don't feel like backing up all that data, again!

Oh well, perhaps in the future Apple will correct the delta methodology to divorce file data from metadata.

Got any other interesting tidbits related to Time Machine?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Thu, 21 May 2009 02:07:00 -0700 Rosetta, Still? http://www.sw-dd.com/2009/05/rosetta-still.html http://www.sw-dd.com/2009/05/rosetta-still.html

So, in the process of redoing my iMac (I'm very bored, and it needed cleaning), I decided to actually install Microsoft Office 2007 (some teachers at Drexel create the most hideously-proprietary documents which NOTHING but Office can open). What's interesting is that the updating process (to update the AutoUpdater) is still PowerPC.

Seriously, can we please move forward now?

On a related note: As many people have pleaded - Adobe, FFS, please optimize your updater! It takes nearly an hour to update CS3! I can have an entire enterprise-class operating system installed, updated, and configured in the time it takes to update 7 applications and their shared components!

Got any apps lingering around that force Mac OS X to begrudgingly load the Rosetta framework?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand
Mon, 18 May 2009 19:38:00 -0700 How's that for off-the-cuff SEO? http://www.sw-dd.com/2009/05/hows-that-for-off-cuff-seo.html http://www.sw-dd.com/2009/05/hows-that-for-off-cuff-seo.html

So, I was just wondering how Google was doing in ranking my page. To my amazement, halfway through typing my name into Safari 4's Google search box (on the 'e' in Weigand), it had a suggestion for "Sebastian Weigand"!

Needless to say, I was stunned! Then, I wondered, how relevant was it? Well, I'm pleased to say that a search for Sebastian Weigand on Google nearly fills up the page with appropriate results!

Nifty, eh?

Permalink | Leave a comment  »

]]>
http://files.posterous.com/user_profile_pics/887898/me-suit.jpg http://posterous.com/users/YMHErVbw8rD Sebastian Weigand swdd Sebastian Weigand