Older blog entries for johnnyb (starting at number 172)

Hideous annoyances with IVR (voice and touch-tone interactive) systems:

  • If an IVR doesn't have a specific option to speak to a human, the IVR should be deactivated permanently, because the owners are too stupid to use one.
  • Unless there is a REALLY good reason, IVRs should make it _easy_ to do everything with the dial pad. Are you really doing secure banking over the phone if you have to speak your password or even your account number or your SSN? It is just easier for the entire interaction if you just push numbers.
  • Don't sound like you are being conversational. IVR systems ARE NOT conversational, so pretending to be so is just stupid and annoying. "Let me see" is a colloquialism of a human speaking. If you are not a human, you shouldn't be speaking this way. I hate using the phone anyway, and if you make me listen to idiocy while I'm on the phone I'm going to hate your company for all eternity.

If I'm going to bother to interact with an IVR, then I want it to be:

  • Serious. I'm making a serious call. If I wanted to talk to someone about a non-serious subject, I'd call my 4-year-old.
  • VERY CLEAR. Most IVR calls I make are about money or service. I want the communication to be clear and exact. If an IVR says "Ummm, okay", it is being personable. If they want the pretext of being personable, then GIVE ME A FREAKIN PERSON! Likewise for dialing versus speaking. Dialing is unambiguous. If I dial the wrong thing, it's my fault. But speaking is a different story. Speaking can be very ambiguous. So while I am not a big fan of any IVR, I _prefer_ those that can be dialed to those that you have to speak to. Both sides of the communication must be clear and exact. Don't BS around.
  • Optional. Computers are stupid, and computer systems are quirky. I don't know all of the quirks of your system, but I can bet that an operator does. So if there is some question, it should ALWAYS be an option to go to a real human being.
Simple Tabbed Pane/Panel using Rails

app/helpers/application.rb:


def tabbed_panel(base_id, &block)
	panels = []


concat("<div class='tabbed_panel' id='" + base_id + "'>\n", block.binding); concat("<ul class='tabselector' id='" + base_id + "_tabs'>\n", block.binding);

yield panels panels.each do |panel| concat("<li class='pane_tab tab_unselected' id='" + panel[2] + "_tab'>" + link_to_function(panel[0], "select_panel('" + base_id + "', '" + panel[2] + "')") + "</li>", block.binding) end

concat("</ul>\n", block.binding); concat("<ul class='tabpanes' id='" + base_id + "_panels'>\n", block.binding); panels.each do |panel| concat("<li class='panel_panel panel_unselected' id='" + panel[2] + "_panel'>" + panel[1] + "</li>\n", block.binding) end concat("</ul>\n", block.binding); concat("</div>\n", block.binding); end

public/javascripts/panel.js:


function select_panel(baseid, panel_id_base) {
	var tabs = $(baseid + "_tabs").childNodes;
	var tab_id = panel_id_base + "_tab";
	var panel_id = panel_id_base + "_panel";
	$A(tabs).each( 
		function(the_tab) {
			if(the_tab.nodeName == "LI") {
				the_tab.removeClassName("tab_unselected");
				the_tab.removeClassName("tab_selected");
				if(the_tab.id == tab_id) {
					the_tab.addClassName("tab_selected");
				} else {
					the_tab.addClassName("tab_unselected");
				}
			}
		}
	);
	var panels = $(baseid + "_panels").childNodes;
	$A(panels).each(
		function(the_panel) {
			if(the_panel.nodeName == "LI") {
				the_panel.removeClassName("panel_unselected");
				the_panel.removeClassName("panel_selected");
				if(the_panel.id == panel_id) {
					the_panel.addClassName("panel_selected");
				} else {
					the_panel.addClassName("panel_unselected");
				}
			}
		}
	);
}

public/stylesheets/panel.css:


/* Clearly you need better CSS, but this is a decent start */
.panel_selected { display: block; }
.panel_unselected { display: none; }
.tab_selected { background-color: gray; }
.tab_unselected { background-color: white; }

Then, to use it in your rails app, just put this in the view:


<% 
#3-panels to choose from in the following example:
tabbed_panel 'all_props' do |panels| 
	panels << ["Form Properties", render(:partial =>
"basic_info"), "fprops"]
	panels << ["Toolbox", render(:partial =>
"toolbox"), "tbox"]
	panels << ["Element Properties", render(:partial =>
"properties"), "eprops"]
end 
%>
PLEASE STOP USING THE HOLLY HACK FOR HASLAYOUT

If you need to get an IE element to get HasLayout, the method is very simply, and you don't need to hide it from any other browser. Add the following CSS property:


zoom: 1;

THAT'S IT. YOU DON'T NEED ANY OTHER HACKING WIZARDRY. IT doesn't need to be hidden from anyone. It actually does what it says it does. There's nothing even hacky about it. It just works, and it has the nice bonus of adding hasLayout on IE.

Getting VNC Working on Vista (fuzzy fonts and black screens)

There are several potential problems I've heard of getting VNC to run on Vista. There's firewalling which may prevent connections. But the more interesting one is the "black screen" problem, which, thankfully, is easy enough to fix. I'm running TightVNC, but it probably is the same for RealVNC and UltraVNC. The fix is this -- turn OFF the VNC service from the control panel/services menu. Services in Vista DO NOT have access to the console by default (there's probably some way to get it to work, but I'm not familiar with it). Once the service is off, launch the VNC server directly from the desktop. Now people can connect and they don't just get a black screen.

Also, if your fonts are coming through really, really fuzzy, that means you need to turn off JPEG compression. My guess is that previous VNC versions were able to detect direct font writing and send them as discreet font updates, but that Vista's rendering enginer requires that they get transmitted as images. Anyway, just turn off JPEG compression and it will work fine.

Programming the Playstation 3, part 3

Part 3 of my PS3-on-Linux programming series just got posted. This one focuses on communication between the PPU and the SPU. You can see it here:

http://www-128.ibm.com/developerworks/power/library/pa-linuxps3-3/

Part #2 and Part #3 were originally one article, so it probably makes the most sense if they are read together.

Part #2 is here: http://www-128.ibm.com/developerworks/power/library/pa-linuxps3-2/

Part #1 is here: http://www-128.ibm.com/developerworks/power/library/pa-linuxps3-1/

There is one more assembly-language article to go, and then the series will move up to C/C++.

Absolute Positioning and z-index on IE (Internet Explorer)

I come up with a new reason to hate IE every day. It turns out that using a position: absolute; creates a new layering context which means that z-index only works within the absolutely positioned elements and not anywhere else. In my own case, to fix it I just needed to bump out the z-index of the parent, which put the z-index of the child in the right place.

Problem with Rails, FastCGI, and Apache

It turns out that FastCGI (and I think both for mod_fastcgi and mod_fcgid) doesn't play well with many of the default Linux setups. fcgid sets up a directory in /var/log/httpd/fcgidsock (mod_fastcgi may be a slightly different directory). The problem is not that the permissions are wrong, but that the permissions of the parent directory are wrong. More to the point, the permissions of the parent directory are made for standard Linux security purposes, not for the purposes of running FastCGI.

The fix is simple. In my case it was a simple chmod 755 /var/log/httpd, which allows Apache to actually read its log directory! Before the change, I was getting "Service Unavailable" with a log error of [warn] mod_fcgid: can't apply process slot for [dispatch.fcgi full path]. Now it works!

Getting http and https connections to work on a blackberry with J2ME

If you are trying to run J2ME apps on the blackberry without the Blackberry Enterprise Server, there are several things you need to do to your blackberry first.

First of all, you need to setup TCP/IP. Once this is done, you can perform http (but not https) connections on your Blackberry. Here is a list of current gateways by cellular provider.

To setup, go into Options -> Advanced -> TCP

For HTTPS connections, you need to go into:

Options -> Security Options -> TLS

Then change the value of "TLS Default" from "Proxy" to "Handheld".

For anyone who is a cyclist or enjoys watching cyclists, you should check out Tulsa Tough.

Stupid things to avoid when coding for the Cell BE

I just spent about 8 hours trying to diagnose these problems, so I'll try to avoid someone else similar pain:

1) DO NOT perform DMA transfers _into_ read-only memory in the PPE. And remember, string constants get put in read-only memory. Apparently, this only triggers a bus error under certain conditions, and in others it works just fine. Also, it is nearly impossible to debug, because the "-g" flag makes the string areas read-write!

2) If the contents of your DMA transfers look like you got multiple buffers crossed, look to see if you are going out-of-bounds in your buffers in the SPU. This looks very much like a DMA problem, but its not, and it produces no errors.

3) Be careful of 32-bit/64-bit discrepancies in PPE/SPE communication. Use unsigned long long for pointers that are passed to SPE code. This will make your code easier to switch between 32-bit and 64-bit mode, as the memory layout will be the same.

And, for something positive:

If you want aligned data, try memalign or posix_memalign.

163 older entries...

New Advogato Features

New HTML Parser: The long-awaited libxml2 based HTML parser code is live. It needs further work but already handles most markup better than the original parser.

Keep up with the latest Advogato features by reading the Advogato status blog.

If you're a C programmer with some spare time, take a look at the mod_virgule project page and help us with one of the tasks on the ToDo list!