Many times, I take for granted all the opportunities that I have had to learn to write. My twelve years in public education, the time I spent in my university's Honor's Program, and even just communicating with others online. I have to write a lot as I communicate electronically with many people. Putting together proposals, coming up with a new design, or even just refuting a weak argument are all examples of things that I do frequently. I sometimes forget what it was like before experiencing these moments of refinement, I forgot how rough my writing used to be. All of my schooling before college, I loathed reading and writing. I disdained English as a subject, and had no desire to learn it further. My goal was to go to college and skip all of my English classes somehow.
I was naive and lacked an understanding of the real world. I felt communication and understanding were pointless and that with enough passion anything was possible. I still believe this to a point, but honestly I realize more and more that if I want to share that passion with others, or have them buy into my dreams that I must first share that with them in a way that they can comprehend. The skill of writing for a specific audience is one that I learned mainly in the business world, and it was a hard lesson to learn. Failed proposals and miscommunications betrayed my desires and abilities. My words were getting in my way, and I was losing opportunity to impact the world around me. I had to make a decision to become more deliberate in my writing and to really make it a focus.
It has been a hard battle over the years, but I have continued to grow and thrive in my ability to communicate and to share information in a way that allows me to make a difference in the world around me. The subject that I once loathed and despised has grown into something that I cannot really live without. It has been an interesting journey, and one that I hope to continue on.
4.22.2010
3.14.2010
Best 45 Lines of PHP to Optimize Joomla
Hey, so I realize this title may seem very ambitious, and honestly it is. It makes some simple assumptions about your site, which will probably be true for many web developers/designers, but not for all. So the base assumption is that your user site has no user specific content. This means that the pages are the same for all users. For many sites, and organizations, this should hold true. There might be some minor exceptions on the site, like password protected files, but there are some easy ways to work with those specific files, and optimize the heck out of the rest of your site. The other assumption is that you are using mod_rewrite. Mod_rewrite is the real hero of this endeavor as it allows the URLs to stay consistent, and behind the scenes delegate to caching mechanism. So that means that this change requires two steps. The first is to deploy the index.php cache wrapper.
Now you may ask, how does this compare to the system plugin for page caching. I have used all the different level caches that Joomla has to offer, page, module, manual, etc. and they all work, but they are still slow. When benchmarking on my local server, using as much of Joomla caching as possible, my average number of requests per second was around 30. With the above script that number is now around 700! Joomla has a lot of overhead on startup, and the goal of this script was to take Joomla completely out of the loop if possible. I have yet to have any issues with the script, and again assuming that your site could be exported as a pure html site, this code has a huge performance boost.
What I would ultimately like to see, is that this feature makes it into Joomla as an option for sites that do not need dynamic real time interaction, but mainly just content display. I realize this may not help everyone, but I believe it will help 70%+ of Joomla users.
define('DS',DIRECTORY_SEPARATOR);
define('ROOT', dirname(__FILE__));
define('MAIN_FILE', ROOT.DS.'index.php');
//Short circuit if posting or if in a secured connection
if (isset($_SERVER['HTTPS']) || $_SERVER['REQUEST_METHOD']!='GET') {
require(MAIN_FILE); exit();
}
include_once(ROOT.DS.'configuration.php'); $c = new JConfig();
define('CACHE_DIR', ROOT.DS.'cache'.DS.'pages_full');
define('TIMEOUT', $c->cachetime);
define('CACHE_URL', 'http://'.$_SERVER['SERVER_NAME']. $_SERVER['REQUEST_URI']);
define('CACHE_FILE', CACHE_DIR.DS.md5(CACHE_URL).'.html');
define('NEEDS_TO_CACHE', !file_exists(CACHE_FILE) ||
(time() - filemtime(CACHE_FILE)) > TIMEOUT);
//If Cached file doesn't exist or it's modified time is greater than timeout
if (NEEDS_TO_CACHE) {
//Call main file and cache output
ob_start();
require(MAIN_FILE);
$data = ob_get_contents();
ob_end_flush();
//Ensure Directory Exists
if (!file_exists(CACHE_DIR)) {
mkdir(CACHE_DIR, 0777, true);
}
//Try to Store data
$rnd = md5(rand());
$fp = @fopen(CACHE_FILE.$rnd, 'w');
if ($fp !== False) {
fwrite($fp, $data);
fclose($fp);
copy(CACHE_FILE.$rnd, CACHE_FILE);
unlink(CACHE_FILE.$rnd);
}
} else {
//Just show cached file
require(CACHE_FILE);
}
I reference the above file as index_cache.php. The next step is to modify your .htaccess to redirect all urls that you want to cache to go to index_cache.php. The cache wrapper already ignores POST and HTTPS requests, so any other areas of your site you want to prevent caching, just add rules to the .htaccess or modify the cache wrapper. That's it. Now your pages will cache the full output, and increase your serve times dramatically. One other caveat is that any custom http headers you send will be ignored. Again, for most people this won't matter, but for some, it might. Also note that the timeout for caching is pulled from the Joomla configuration.php, and is configurable through the Joomla admin configuration interface. Also note that the cached pages are stored in the Joomla cache directory and so this allows admins to clear the cache without any additional work.Now you may ask, how does this compare to the system plugin for page caching. I have used all the different level caches that Joomla has to offer, page, module, manual, etc. and they all work, but they are still slow. When benchmarking on my local server, using as much of Joomla caching as possible, my average number of requests per second was around 30. With the above script that number is now around 700! Joomla has a lot of overhead on startup, and the goal of this script was to take Joomla completely out of the loop if possible. I have yet to have any issues with the script, and again assuming that your site could be exported as a pure html site, this code has a huge performance boost.
What I would ultimately like to see, is that this feature makes it into Joomla as an option for sites that do not need dynamic real time interaction, but mainly just content display. I realize this may not help everyone, but I believe it will help 70%+ of Joomla users.
Labels:
caching,
html,
joomla,
optimization,
php,
programming
3.10.2010
CenterpointeChurch.com
So, I recently launched a new website for my church, Centerpointe Church (at Fair Oaks). You can check it out at http://centerpointechurch.com. The website is an extension of the Joomla Content Management System. It is written entirely in PHP with many custom extensions for the Joomla CMS. One of the goals of the website was to distribute the content as much as possible. One of the issues that comes from distributed content, is integrating it in a clean way, back into your site. Google, being the main web service provider for the website, has amazing data services for custom integration. Youtube, Google Calendar, Google Search, and Flickr all made integration a breeze, plus I got to learn a lot about all of those systems.
So technology aside, the entire site was really a lesson in forward thinking. I had spent over a year at Clearspring, working for my first product company, working with designers and user experience(UX) engineers on a daily basis. Design and UX were not in my training nor was it something I considered a personal strength. After the time I spent there, that statement may need to be changed. I grew so much in understanding with respect to information architecture, and user experience. I feel that I understand the world in a clearer way, and how to share information with people in a way that is useful and important to them. My goal with the website was to take the jumble of mess that the previous website had become and to introduce clarity, simplicity, and style.
Clarity and simplicity were things that I can excel at. As an engineer with pretty good communication skills, clarity and simplicity are my forte. I was able to come up with an information architecture that was simple and straightforward, as well as work on a layout that really emphasized the desired calls to action that we wanted. Our previous website had 40+ actionable items on the homepage, with none being given visual priority. I wanted the website to be focused on bringing in people who are new to the faith, new to the area, or just curious. I did not want the website to be a tool for internal church communication, but to be a resource to share the church with the world, and the community it has with the world.
So that addresses clarity and simplicity, but what about style? I am many things, but stylish just doesn't seem to make the cut. Luckily my good friend Kris has been with me on most of this journey of rebuilding and rebranding the website for Centerpointe Church. Kris is an extremely talented designer, and has learned a whole lot about web design during the process. It was a lot of back and forth between us, and I feel like I learned a lot about design from him as well. Kris' ability to transform though and desire into a visual representation of the church was just phenomenal.
It was a lot of hard work, the longest project I have ever worked consistently on (and owned from a project standpoint), and it is still ongoing. I learned a lot about project management, time management, and ultimately resource management with respect to people and their daily activities. I feel I have become a better engineer for going through this process, and that my new abilities and skills will be used to help share the Good News of Jesus Christ in more interesting and complex ways.
So technology aside, the entire site was really a lesson in forward thinking. I had spent over a year at Clearspring, working for my first product company, working with designers and user experience(UX) engineers on a daily basis. Design and UX were not in my training nor was it something I considered a personal strength. After the time I spent there, that statement may need to be changed. I grew so much in understanding with respect to information architecture, and user experience. I feel that I understand the world in a clearer way, and how to share information with people in a way that is useful and important to them. My goal with the website was to take the jumble of mess that the previous website had become and to introduce clarity, simplicity, and style.
Clarity and simplicity were things that I can excel at. As an engineer with pretty good communication skills, clarity and simplicity are my forte. I was able to come up with an information architecture that was simple and straightforward, as well as work on a layout that really emphasized the desired calls to action that we wanted. Our previous website had 40+ actionable items on the homepage, with none being given visual priority. I wanted the website to be focused on bringing in people who are new to the faith, new to the area, or just curious. I did not want the website to be a tool for internal church communication, but to be a resource to share the church with the world, and the community it has with the world.
So that addresses clarity and simplicity, but what about style? I am many things, but stylish just doesn't seem to make the cut. Luckily my good friend Kris has been with me on most of this journey of rebuilding and rebranding the website for Centerpointe Church. Kris is an extremely talented designer, and has learned a whole lot about web design during the process. It was a lot of back and forth between us, and I feel like I learned a lot about design from him as well. Kris' ability to transform though and desire into a visual representation of the church was just phenomenal.
It was a lot of hard work, the longest project I have ever worked consistently on (and owned from a project standpoint), and it is still ongoing. I learned a lot about project management, time management, and ultimately resource management with respect to people and their daily activities. I feel I have become a better engineer for going through this process, and that my new abilities and skills will be used to help share the Good News of Jesus Christ in more interesting and complex ways.
Labels:
church,
design,
God,
management,
php,
programming,
project,
website
12.31.2009
Windows 7: The Journey Continues
Ugh!! I hate to admit this, but I have recently converted my media center PC back to Windows. I have been running Mythbuntu for my media center PC for good portion of a year. I had previously run Windows with MediaPortal and GBPVR, and I had honestly never thought of running Windows Media Center. I am openly opposed to Windows and other closed source software, as well as the proprietary formats that come along with the closed source software.
Well after purchasing an Xbox360 earlier this year, I inadvertently set myself up for an easy transition to Windows Media Center. After getting fed up with how dated and kludgy the MythTV interface was (no offense to the MythTV team as they make a really solid product), I was looking at transition to XBMC. Something a little more modern and hip. Then I remembered that the Xbox360 can be used as a Media Center Extender (MCE), and so I started to dig into the idea a bit. I started discovering what was possible, e.g. recording/playback/music/etc. It had all the basic PVR software that I needed (along with free EPG, as I had previously been paying for it through SchedulesDirect).
After a long debate with myself, and looking at videos of the interface, I was ready to take the plunge. I ordered my copy of Windows 7 Home Premium (from NewEgg for like $100), and I ordered the Xbox 360 MCE Remote from Amazon for $20. Now it was just a waiting game. We had a huge snow storm hit the day I was expecting the packages, but unfortunately they didn't arrive until the Monday afterwards :( With this timing, I only had one day to setup the computer before I headed out on vacation.
So I did as much as I could in one day, but the system was lacking, and I wasn't sure how I felt about Windows Media Center. I already found myself missing the control/customization options of MythTV along with Linux. These features were not things that were readily visible to me in Windows Media Center, and I was feeling like a fish out of water. And to add insult to injury, I was having an issue with the Windows software not liking a hard drive that had worked fine for me under MythTV. It turns out linux can handle variances better in hardware than Windows (duh), and so I had to buy a new hard drive, and I am RMAing the non working one. So as I was leaving for vacation, I didn't have the greatest perspective on the Windows software setup, but I was still hopeful.
So, here comes today. I woke up at 4am (10am in Italy, which I had just come from) and the new hard drive had been delivered the day before, so I was raring to give it a second shot. I installed the new hardware (hard drive plus an extra 1gb of ram, as Windows 7 is more memory hungry than MythTV). I then proceeded to aim for feature parity with my MythTV system. The things on my checklist for today were:
Streaming between Vista and Windows 7 doesn't work so well (darn you MS), but I was able to share drives on my wife's computer to read the media. But another downer is that Windows Vista cannot read wtv files. Apparently only Windows 7 and Windows Vista Media Center can, which means I cannot share the tv recordings with my wife nor with my linux laptop. MythTV definitely had a better solution to this, but that is what you get for using open standards! So for the time being I am taking a loss on this one, but I will continue to press on.
Trailers and movie times I'm still in the mix for. I had a plugin for Windows Media Center that I thought would handle the trailers, but it hasn't panned out. The plugin seems to be pretty dodgy, and I am about to uninstall it for another.
So, all in all it has been a struggle, but a learning one. I haven't dealt to much with Windows software packages, and so it is good to get used to that world again, even if for a little. I will say I am pleased with Windows Media Center, but I know it is going to take as much tweaking as MythTV did to get it where I want it. Let's just hope that Windows allows for it ;-)
Well after purchasing an Xbox360 earlier this year, I inadvertently set myself up for an easy transition to Windows Media Center. After getting fed up with how dated and kludgy the MythTV interface was (no offense to the MythTV team as they make a really solid product), I was looking at transition to XBMC. Something a little more modern and hip. Then I remembered that the Xbox360 can be used as a Media Center Extender (MCE), and so I started to dig into the idea a bit. I started discovering what was possible, e.g. recording/playback/music/etc. It had all the basic PVR software that I needed (along with free EPG, as I had previously been paying for it through SchedulesDirect).
After a long debate with myself, and looking at videos of the interface, I was ready to take the plunge. I ordered my copy of Windows 7 Home Premium (from NewEgg for like $100), and I ordered the Xbox 360 MCE Remote from Amazon for $20. Now it was just a waiting game. We had a huge snow storm hit the day I was expecting the packages, but unfortunately they didn't arrive until the Monday afterwards :( With this timing, I only had one day to setup the computer before I headed out on vacation.
So I did as much as I could in one day, but the system was lacking, and I wasn't sure how I felt about Windows Media Center. I already found myself missing the control/customization options of MythTV along with Linux. These features were not things that were readily visible to me in Windows Media Center, and I was feeling like a fish out of water. And to add insult to injury, I was having an issue with the Windows software not liking a hard drive that had worked fine for me under MythTV. It turns out linux can handle variances better in hardware than Windows (duh), and so I had to buy a new hard drive, and I am RMAing the non working one. So as I was leaving for vacation, I didn't have the greatest perspective on the Windows software setup, but I was still hopeful.
So, here comes today. I woke up at 4am (10am in Italy, which I had just come from) and the new hard drive had been delivered the day before, so I was raring to give it a second shot. I installed the new hardware (hard drive plus an extra 1gb of ram, as Windows 7 is more memory hungry than MythTV). I then proceeded to aim for feature parity with my MythTV system. The things on my checklist for today were:
- Commercial Skipping
- DivX file play back
- Streaming media to PCs
- Trailers and Movie Times
Streaming between Vista and Windows 7 doesn't work so well (darn you MS), but I was able to share drives on my wife's computer to read the media. But another downer is that Windows Vista cannot read wtv files. Apparently only Windows 7 and Windows Vista Media Center can, which means I cannot share the tv recordings with my wife nor with my linux laptop. MythTV definitely had a better solution to this, but that is what you get for using open standards! So for the time being I am taking a loss on this one, but I will continue to press on.
Trailers and movie times I'm still in the mix for. I had a plugin for Windows Media Center that I thought would handle the trailers, but it hasn't panned out. The plugin seems to be pretty dodgy, and I am about to uninstall it for another.
So, all in all it has been a struggle, but a learning one. I haven't dealt to much with Windows software packages, and so it is good to get used to that world again, even if for a little. I will say I am pleased with Windows Media Center, but I know it is going to take as much tweaking as MythTV did to get it where I want it. Let's just hope that Windows allows for it ;-)
12.19.2009
Blogger Gadget: Syntax Highlighting
So I just spent the last hour battling Blogger. I recently updated my blog theme, and I quickly forgot that I had altered it to support syntax highlighting. And so I though to myself, why would I need to add the js/css files directly to the theme. Couldn't I just add it as a gadget (html/js) at the bottom of my page and not worry about it? Well the long answer is yes, but it was an arduous process. Blogger seems to do some Javascript parsing on it's side and caused me much heartache as I was trying to dynamically add the script/css tags (which is generally problematic on many large sites that take HTML input). So without further ado, if you just copy and paste the following code into a Blogger Html/JS gadget, (and have the syntax js/css files hosted on a server), you should be up and running in no time:
And now you can change themes without having to worry about losing your syntax highlighting changes. Enjoy!
<script type="text/javascript">
(function() {
var open = '<', right = '>', sclose = '/'+'>', close='<'+'/';
var root = '~~~Your Web Location for your Syntax Highlighting js/css files ~~~';
var towrite = [];
var toAdd= [
'Core',
'BrushCpp', 'BrushCss', 'BrushDelphi',
'BrushJava', 'BrushJScript', 'BrushPhp',
'BrushPython', 'BrushRuby', 'BrushSql',
'BrushXml'];
function writeTag(t, attr, b) {
var out = ['<'+t], line, k;
for (k in attr) out.push(k+'="'+attr[k]+'"');
if (b == undefined) out.push(sclose);
else {
out.push(right,b,close+t+right);
}
towrite.push(out.join(' '));
}
function addScript(p) {
writeTag('script', {type : 'text/javascript', src : root+p+'.js'}, '');
}
function addCss(p) {
writeTag('link', {type : 'text/css', href : root+p+'.css', rel : 'stylesheet'});
}
for (var i=0; i < toAdd.length;i++) addScript('sh'+toAdd[i]);
addCss('SyntaxHighlighter');
window.onload = function() {
dp.SyntaxHighlighter.BloggerMode();
dp.SyntaxHighlighter.HighlightAll('code');
}
document.write(towrite.join('\n'));
})();
</script>
And now you can change themes without having to worry about losing your syntax highlighting changes. Enjoy!
12.06.2009
Dmenu and SDL
So recently I have been doing a lot of work in C with SDL. I am working on a project called dmenu (http://code.google.com/p/dmenu/) which is a UI for the Dingoo A320 running Dingux. One of my recent goals is to provide some enhanced visuals for the UI. This entails the goal of adding animations as well as adding things like shadow, opacity, etc. The ultimate goal is to increase usability and also to make the UI seem more professional.
One of the major roadblocks is the processor speed on the Dingoo A320. It's easy to devise algorithms on a Pentium Core Duo2 that just aren't feasible on the Dingoo's limited MIPS processor. During one of my courses in college, I had the pleasure of implementing a simple encryption algorithm in C. I spent a lot of time optimizing the crap out of that (including bit twiddling, gnu C directives, and the likes), and so I feel I know a moderate amount of how to optimize C code (not to mention algorithm optimization in general). Even with this in hand somethings just happened to be too slow.
For example, I implemented an image viewer that is used for viewing wallpapers in the system as well as theme previews (for selecting different themes). Because SDL does not include scaled blitting, I had to implement a scaling solution myself. To optimize I had to make some gross assumptions (that just happen to be true for the Dingoo) and it made the algorithm much faster than if it had been general.
Unfortunately this process was too slow for a real time experience. Also the cost of pre-scaling all the images would have been too expensive in time and memory. So I ultimately had to rely upon disk caching to provide the ultimate user experience. This included scaling and exporting as a PNG to disk and using threads to accomplish this. This allowed the UI to return the image after it had scaled (if it wasn't already on disk). So it optimized for the general user experience but ensure the first time (on a cache miss) was not unbearable.
Another problem that I just had to tackle was that of alpha blending. SDL and alpha blending are not good friends. I've seen posts by many other people about their struggles with trying to alpha blend a surface that has per pixel alpha values (e.g. a PNG image ). It seems like SDL was designed with the mindset that the images used in the programs would be simple alpha channels (e.g. GIFs or images that rely upon colorkey alpha channels). It has stellar operations/performance when handling surfaces of this type, but it just falls apart when trying to do alpha filtering on a surface that has per pixel alpha values. So I took it upon myself to write an efficient algorithm that would allow me to blend alpha:
Again, this isn't anything special, but the reduced complexity of the algorithm (plus the smaller size of the components being addressed [screen subsections]) allows for this algorithm to run efficiently in real time. I might ultimately end up caching the results just as a trade off for time/memory, but I'm not sure if it is ultimately worth it. Anyways, its been a blast today working on C optimizations.
One of the major roadblocks is the processor speed on the Dingoo A320. It's easy to devise algorithms on a Pentium Core Duo2 that just aren't feasible on the Dingoo's limited MIPS processor. During one of my courses in college, I had the pleasure of implementing a simple encryption algorithm in C. I spent a lot of time optimizing the crap out of that (including bit twiddling, gnu C directives, and the likes), and so I feel I know a moderate amount of how to optimize C code (not to mention algorithm optimization in general). Even with this in hand somethings just happened to be too slow.
For example, I implemented an image viewer that is used for viewing wallpapers in the system as well as theme previews (for selecting different themes). Because SDL does not include scaled blitting, I had to implement a scaling solution myself. To optimize I had to make some gross assumptions (that just happen to be true for the Dingoo) and it made the algorithm much faster than if it had been general.
/**
* Optimized for 16bit images. Will not work any any others
*/
SDL_Surface* shrink_surface(SDL_Surface *src, int width, int height)
{
if (!src) return NULL;
int h = src-<h, w = src->w;
if(width>w || height>h || h <=0 || w <= 0) return NULL;
float fpx = (w*1.0f)/(width*1.0f), fpy =(h*1.0f)/(height*1.0f);
int y,x;
SDL_Surface *dst = SDL_CreateRGBSurface(
src->flags, width, height, 16,
src->format->Rmask, src->format->Gmask,
src->format->Bmask, src->format->Amask);
register int src_pitch = src->pitch, dst_pitch = dst->pitch;
register int src_y_off = 0, dst_y_off = 0, dst_x_off=0;
Uint16 *src_pixels = (Uint16*)src->pixels, *dst_pixels = (Uint16*)dst->pixels;
int max_w = 2*width;
y = height;
while (y--) {
dst_y_off = dst_pitch*y;
src_y_off = src_pitch*(int)(y*fpy);
dst_x_off = max_w;
x= width;
while (x--) {
dst_x_off -= 2;
*(Uint16*)((int)dst_pixels + dst_y_off+dst_x_off) =
*(Uint16*)((int)src_pixels + src_y_off+(int)(x*fpx)*2);
}
}
return dst;
}
Unfortunately this process was too slow for a real time experience. Also the cost of pre-scaling all the images would have been too expensive in time and memory. So I ultimately had to rely upon disk caching to provide the ultimate user experience. This included scaling and exporting as a PNG to disk and using threads to accomplish this. This allowed the UI to return the image after it had scaled (if it wasn't already on disk). So it optimized for the general user experience but ensure the first time (on a cache miss) was not unbearable.
Another problem that I just had to tackle was that of alpha blending. SDL and alpha blending are not good friends. I've seen posts by many other people about their struggles with trying to alpha blend a surface that has per pixel alpha values (e.g. a PNG image ). It seems like SDL was designed with the mindset that the images used in the programs would be simple alpha channels (e.g. GIFs or images that rely upon colorkey alpha channels). It has stellar operations/performance when handling surfaces of this type, but it just falls apart when trying to do alpha filtering on a surface that has per pixel alpha values. So I took it upon myself to write an efficient algorithm that would allow me to blend alpha:
/**
* Alpha blends a 32bit Surface using per pixel alpha blending. It will
* take any given surface and scale each pixel's alpha value down
* by alpha. If alpha is a power of 2 it should scale much faster than any
* other values as it can use bitwise shifting instead of multiplication. The
* following alpha values are the special values.
* 255 -> Does nothing (alpha blending by 100% is just ignored)
* 127, 63, 31, 15, 7, 3, 1 -> Quick divide using bitwise shifting
* 0 -> no math, just clears out alpha channel
* Everything else -> alpha/255 * pixel alpha
*/
void alphaBlendSurface( SDL_Surface* s, int alpha )
{
if (alpha == 255) return;
Uint32 *pixels = (Uint32*)s->pixels, *p;
float alpha_ratio;
const register int pitch = s->pitch;
register int off = 0;
register int x = 0;
int max_off = s->h*pitch,
max_x= pitch,
msk = s->format->Amask,
alpha_step = 8;
#define map_pixel(op)\
while (off<max_off) {\
while (x<max_x) {\
p = (Uint32*)((int)pixels + x);\
*p = op; x+=4; }\
off += pitch;max_x = off+pitch;}
switch (alpha) {
case 127: --alpha_step;
case 63: --alpha_step;
case 31: --alpha_step;
case 15: --alpha_step;
case 7: --alpha_step;
case 3: --alpha_step;
case 1: --alpha_step;
map_pixel((*p & ~msk) | (*p>>alpha_step & msk));
break;
case 0:
map_pixel((*p & ~msk));
break;
default:
alpha_ratio = alpha/255.0f;
#if SDL_BYTEORDER == SDL_BIG_ENDIAN
map_pixel((*p & ~msk) | (int)((*p>>24) * alpha_ratio) << 24);
#else
map_pixel((*p & ~msk) | ((int)(*p * alpha_ratio) & 0xFF));
#endif
break;
}
#undef map_pixel
}
Again, this isn't anything special, but the reduced complexity of the algorithm (plus the smaller size of the components being addressed [screen subsections]) allows for this algorithm to run efficiently in real time. I might ultimately end up caching the results just as a trade off for time/memory, but I'm not sure if it is ultimately worth it. Anyways, its been a blast today working on C optimizations.
Labels:
algorithms,
C,
development,
Dingoo,
dingux,
graphics,
sdl,
software
9.12.2009
Microserfs - Too real to be fiction?
So, I just recently finished reading a book called Microserfs by Douglas Coupland. The book was based in the time period of 1993 to 1995 and was written during the same time period. When I first started reading the book, I didn't realize it was almost 15 years in the past. The archetypes and the themes of the book resonated with my view of the world. I remember growing up in the world that he paints, and how he uniquely pinpoints my view of technology, and the role that it plays in my life.
Anyone who grew up in the 90s and grew up in technology will more than likely love this book as I know that I did.
Anyone who grew up in the 90s and grew up in technology will more than likely love this book as I know that I did.
8.29.2009
Levels of Software Development
So, I was out for a walk this morning, and realized (while I already knew this, I saw it more clearly this morning) that there are different levels of people in Software Development, in the same way there are different levels of people in the Armed Forces. In the Armed Forces, it isn't time in that matters, as much as rank. This seems to be a common misconception in the Software Industry that years of service implies rank. While it is true that there tends to be a positive correlation, causation is not a valid assumption.
In Software Development, you really have three types of people:
What I do have a disdain for, is the fact that Recruiters and Managers tend to view the world as one type of person, and so can hire a Programmer and Engineer to play the same role on a project. It would be akin to a Company saying: "We need to hire soldiers for or upcoming project", and then proceeding to recruit a General and a Foot Soldier for the same task. Its ridiculous in the sense of the Armed Forces, but why not for Software Development.
Some companies try to get past this by requiring X number of years of experience, or a degree in this or that. And that helps to an extent but again, causality is non existent. There really needs to be some distinction of the different types of Software Development folk out in the world, instead of lumping everyone together under one title. Until that point occurs, the world of hiring of Software Development teams is still a scary and messy place.
In Software Development, you really have three types of people:
- Engineers (Generals) - These tend to be the people that get the big picture. They understand the overall issues, but should have a good enough grasp of the fundamentals to be able to write the software. The defining characteristic of an Engineer is the ability to see the problem as a whole, derive a solution, and set a direction to accomplish.
- Developers (Lieutenants) - These are people who understand the fundamentals of overall design well enough to overcome obstacles in the development process. They do not necessarily live in the big picture world that the Engineer does, but it does not mean that they are unaware of the larger world. The defining characteristic of a Developer is the ability to fill in the gaps of the overall design that the Engineer sets forth.
- Programmers (Grunts) - These are the people who understand how to turn specifications into code. The same way a solider knows how to turn training and orders into an accomplished mission. These people are not known for their quick thinking or problem solving, but their ability to actually produce results.
What I do have a disdain for, is the fact that Recruiters and Managers tend to view the world as one type of person, and so can hire a Programmer and Engineer to play the same role on a project. It would be akin to a Company saying: "We need to hire soldiers for or upcoming project", and then proceeding to recruit a General and a Foot Soldier for the same task. Its ridiculous in the sense of the Armed Forces, but why not for Software Development.
Some companies try to get past this by requiring X number of years of experience, or a degree in this or that. And that helps to an extent but again, causality is non existent. There really needs to be some distinction of the different types of Software Development folk out in the world, instead of lumping everyone together under one title. Until that point occurs, the world of hiring of Software Development teams is still a scary and messy place.
Labels:
development,
software,
work
4.25.2009
My First Video Game
Hey, so this is a widgetized-version of my "first" video game. I have made many before, but this is the first that has ever really been fun and easy to use. So I hope you enjoy it as much as I have playing it.
9.20.2008
99 Bottles of Python
So, I don't know if you have ever been to 99 Bottles website,but it is a cool website that uses a single problem space to show off the strengths and individuality of each language. I spent some time this morning making my own version. I thought I would share it as I found it quite a fun project and allowed me to do some cool things.
Standard function and variable definitions. Here I have all the variables I need for the program:
Description
Arguments
Break down
After all these values are calculated, they are interpolated into the string '%s %s %s', basically equivalent to : size + ' ' + bottle(s) + ' ' + description.
Description
Arguments
Break down:
#! /usr/bin/python
''' Tail-Recursive, Booleans and Strings,
The goal of the this script is to have python behave like LISP with respect to
recursion, lambda usage, and ouptut building. The other optimization, which is
a favorite of mine, is using boolean operations in lieu of formal control flow
operations. I would have rather had a ternary operator, but I can live with the
pythonic 'test and true-value or false-value'
It is a bit terse, but that is beauty of the lisp aspects of the code,
intersecting with boolean operations for strings.
Email: timothy.soehnlin@gmail.com
to run: sing()
'''
def sing():
t,w,b,n = "Take one down and pass it around","of beer on the wall","bottles","no more"
c = lambda a,s='.':'%s %s %s'%(str(a or n),b[:a==1 and -1 or None],w.split(s)[0])
s = lambda b=99: b and '%s, %s.\n%s, %s.\n\n%s'%(c(b),c(b," on"),t,c(b-1),s(b-1)) or ''
print s()
Quick break down of how the code works:
Standard function and variable definitions. Here I have all the variables I need for the program:
Setup
def sing(): t,w,b,n = "Take one down and pass it around","of beer on the wall","bottles","no more"
Printing bottle count and location
c = lambda a,s='.':'%s %s %s'%(str(a or n),b[:a==1 and -1 or None],w.split(s)[0])Description
Here I am defining an anonymous function that is used for printing all permutations of 'N bottles of beer on the wall'.
Arguments
- a: is the current number of bottles we are on
- s(default is '.'): is the string to split "of beer on the wall" on.
Break down
- str(a or n) : What this does right here is it takes the number (a) given if it is greater than 0 (because python equates 0 with False), and if it is 0, then it takes the variable n (which is "no more").
- b[:a==1 and -1 or None] : What this line does is that when the number (a) is 1, we will drop off the last character in "bottles". If you pass None as b[:None], the array slice doesn't do anything and you get the whole "bottles".
- w.split(s)[0] : What happens here is that w ("of bottles of beer on the wall") will get split on s, and only the first element in the split array will be taken. If s is in the string (like ' on') then we get everything before on, otherwise we get the whole string.
After all these values are calculated, they are interpolated into the string '%s %s %s', basically equivalent to : size + ' ' + bottle(s) + ' ' + description.
Singing the song
s = lambda b=99: b and '%s, %s.\n%s, %s.\n\n%s'%(c(b),c(b," on"),t,c(b-1),s(b-1)) or ''Description
s is another anonymous function that is a recursive function, that will build the output of the song.
Arguments
- b (default is 99) : Number of bottles of beer on the wall
Break down:
- b and Print song, removed for effect or '': This basically says if b is greator than 0 then print song, else return an empty string. This also sets 0 as the limit in the recursion depth.
- c(b) : Prints "n bottles of beer on the wall"
- c(b, " on") : Prints "n bottles of beer" This is split on the " on"
- t : The string "Take one down and pass it around"
- c(b-1): Prints "n-1 bottles of beer on the wall"
- s(b-1): Prints the next chorus
After all these values are calculated, they are interpolated into the string '%s, %s.\n%s, %s.\n\n%s' to add the proper line breaks, and punctuation.
Making it run
And print s() just prints the song
Well there you have it. The code break down. It is simple and yet amusingly elegant (or so I think.)
Labels:
99 bottles,
programming,
python
Subscribe to:
Posts (Atom)