A few days ago, as I was browsing Twitter feeds of my friends, I came across an item that caught my eye: a resolution on making iOS apps accessible. Specifically, the resolution, known as “NFB resolution 2014-12” (which was passed on July 5th) calls on Apple to make all apps accessible for the blind by implementing accessibility standards and policies in collaboration with National Federation of the Blind (NFB). In describing the current situation, the resolution outlined how VoiceOver, Apple’s screen reader for OS X and iOS, was an integral tool for accessibility, and described how some apps were not accessible (or have become inaccessible in recent releases) with problems such as unlabeled buttons and so on.
At first, I felt uneasy about the resolution for several reasons. First, as a developer, I knew how some programmers would be burdened by implementing accessibility layer on top of their apps (techniques would have been labeling buttons, adding custom hints in addition to proper labels, etc.) and resources to be spent on such projects in an industry where cost is a key consideration in projects. Second, as some users pointed out, not all apps are guaranteed to be accessible (or accessibility would be incomplete), such as popular games like Angry Birds series despite advocacy efforts. Third, I believe in direct negotiations with app developers, as it allows a developer to become aware of the needs of their users, and if a famous developer would announce implementation of accessibility standards in his or her app, chances are that it’ll translate to a domino effect (other developers following the leader). Lastly, I feared that some app authors would leave iOS ecosystem due to accessibility requirement that Apple might impose as a result of passage of the said resolution, saying that some apps will never become accessible.
At the same time, I also thought about possible implications of this resolution in case it passes. First, although there were comments asking why Apple was singled out, some, including myself, also thought about the impact that this resolution might have on other industry giants such as Google, Microsoft, Amazon and so forth (particularly Google due to their mixed reputation of Android among blind users). Second, I worried that the reputation of the blindness community (represented by consumer advocacy groups such as NFB and ACB (American Council of the Blind)) might suffer as a result of demanding accessibility policies to a company such as Apple, seeing that people would misinterpret this as wanting more comfort. Third, NFB’s reputation among blindness community is mixed, with more people having negative views on this organization due to its history and patterns on their advocacy strategies, thus some were concerned by this resolution and its impact in the future.
Personally, I identify myself with those who oppose NFB resolution 2014-12. I’ve opposed the resolution due to the reasons outlined above: implementation resources, incomplete accessibility ecosystem, need for direct negotiations and departure of apps. I also agreed with sentiments raised on various social media (especially Twitter), such as flaws with the resolution, logic used, reputation and so on.
First, not all apps would be accessible in the long term for technical reasons. Some of the popular apps on app distribution channels are video games, and due to their nature, it becomes hard to implement accessibility with current development methods. One practical solution is to provide audio feedback and documentation on how a potential blind gamer would play the game. This becomes difficult when we have games which require fast response time and is CPU/GPU intensive. In this scenario, a phone’s processor would be busy not only servicing routines from the game, but also need to service output and input from blind gamer (this requires good design, even with dual core or quad core processors as they need to work together). Without good communications and accessibility design in place, we’ll never see a day when 100% of the apps (including games and professional apps which are very visual) are guaranteed to be accessible (and I use the word “guaranteed” to mean it’ll work out of the box). And that, folks, is current reality of programming mobile apps (solid design naturally leads to accessible app).
Second, I believe it is better to start from small things and allow others to learn from case studies. I once compared this statement to a waterfall and a boulder. A waterfall, with incredible sight to behold, starts from a small stream deep in the mountains. As other streams join the main stream, it creates massive body of force that cannot be stopped (unless something is blocking its path), culminating in a spectacular show of nature we call waterfall. Now suppose we have a boulder somewhere, blocking path to a stream’s progress. The stream, although struggling at first, eventually forces the boulder out of its way and continues downstream unless the boulder has more than enough force to repel forces from water (as a consequence of one of the famous physics laws). Or consider dominos where pushing a domino forward would cause others to fall.
In connection with app accessibility, I believe in direct negotiations for accessibility as opposed to forced policies. Although it may become necessary for a company to come up with design policies for accessibility, what really makes a difference (in my opinion) is if small steps are taken at first. By ensuring that an app is accessible, an app developer would have gained more customers, which would trigger a domino effect where other app writers in the similar genre would try to make theirs accessible. This would then be noticed by apps in other categories, thereby making them join the stream and creating a “virtual waterfall of accessibility”. In other words, it is far better (in the long term) to let app authors be creative and learn about accessibility when working with their customer base than for a company to institute accessibility policies after recommendations from a consumer organization (I must stress that I do believe in collective action, but for this case, I believe it is far better to go through direct negotiations, sitting with app authors and allowing them to have an intimate learning experience about accessibility needs).
With that said, I’d like to present some suggestions for all parties involved in this event, and offer some thoughts on what we can do next, now that the resolution is in the record books.
First, I’d like to kindly suggest that users approach app developers as friends and partners. App users and software developers (like myself, as I belong in both camps) are all consumers: users consume products made by programmers, and in turn, programmers consume suggestions, bug reports and improvements from users. I believe that better (I should add, ultimate) accessibility of an app comes through solid partnership between users and developers in understanding each other’s needs – accessibility for blind consumers and product feedback for developers. And I do kindly suggest that it be done in a friendly manner in order that reputation of both parties (consumers and developers) would improve.
Second, I’d like to kindly suggest that we look at consequences and long term goals and reputation about our community when we write resolutions and campaigns. I’m sure we don’t want reputation of the blindness community to suffer now and in years to come, particularly for our people to be misinterpreted by mainstream society, right? And since our posterity depends on our actions today, I believe it is important to not only consider our current reputation, but also the reputation of our community a few decades down the road as well, as well as consequences of our campaigns and resolutions so that our posterity can look up to us and learn from us, even if we make mistakes (if we do make mistakes, it’s better to acknowledge it for the benefit of future generations).
Third, I’d like to gently suggest to app authors to become our partners in accessibility to provide rich case studies for others to follow. A well-known Korean proverb says, “better is seeing once than to hear it a hundred times.” That is, a person would retain understanding of a concept once he or she sees it rather than hearing about it many times. By providing ready to use examples of accessibility (even small demos and case studies), an app author can open possibilities for other apps to become accessible for people with disabilities.
Lastly, I’d like to gently suggest that we have reality checks from time to time. We cannot pass through a mountain without knowing which way is the route to a safe camping location for the night, nor we cannot easily say that we can cross a desert without checking our water supplies and thinking about passing through this valley safely. Likewise, it is good to have dreams of an unseen accessible ecosystem down the road (and we do need visionaries in our generation), but we cannot make it there unless we have a sense of what we can and cannot do (a good example is braille system; although we cannot easily communicate with print, we can at least learn about the current affairs and express our opinions through alternates such as braille and related technologies). And we shouldn’t forget that there are talented individuals (I should add, all of us are talented in one way or another) who can bring ideas to reality, and that reality could be another reality check in a few years down the road.
In conclusion, some would say that we’ve spilled our beans of reputation, while others would say that we’ve laid the stepping stone for others to follow. Whatever it might be, I do acknowledge that NFB resolution 2014-12 is now in the record books, to be scrutinized in front of cameras and talked about on blogs and in social networks. Despite my uneasy feeling about its passage, I do realize that it has and will produce impact to be felt in software development and advocacy channels for years to come. At this stage, what we, the blind consumers of iOS (and other mobile operating systems) and their apps can do is to extend our offer of friendship and partnership to app developers, for both users and developers to work together in understanding their needs, be friendly for the sake of our reputation and keep an eye on what can be done. And please don’t forget that app developers are people and users, just like us, as I and other software developers who are blind can testify.
P.S. As I’m one of the young people who’ve debated about the resolution fiercely on social networks, I’m afraid that our “virtual war” could have brought not only our reputation down (I’d say, a lot), but also that of the blindness community. If this is the case, I’d like to formally apologize for our behavior.
For some time, I’ve been thinking about writing a book called “NonVisual Developer’s Aid to NVDA,” a comprehensive reference on NVDA’s source code. I sort of wrote an outline for it while I was writing the add-on development guide, but decided to post the actual documentation that comes with the source code in hopes that someone might learn something about NVDA, screen reading technology, accessible software design and perhaps contribute to NVDA (and perhaps write a book about nVDA with the source code docs). If you are a developer wishing to know the internals of NVDA, this is for you (and hats off to Mick Curran and Jamie Teh, who deserves the credits for writing the source code docs and NVDA in the first place).
A zip file is now available containing source code documentation for the latest master branch (June 2014). Note that this should be studied by programmers who are serious about extending NVDA’s core and/or interested in internals of how add-ons work their magic (in reality, anyone is welcome to study it, publish a book based on the source code, etc. (if you do plan to publish a book, I’d advise asking NVDA devs).
But first, for people who are just getting started with NVDA development should read the latest developer guide, which can be found at:
Now for the source code documentation (based on master branch as of June 2014):
For Mick and Jamie, I hope I’m not going against your rules…
An NVDA translator and add-on writer
One of the new features in upcoming SPL add-on 3.0 is Cart Explorer, a way to learn cart assignments in SPL Studio. Below is a section from the 3.0-dev add-on guide (not available yet) that explains how cart explorer works:
SPL Studio allows you to assign up to 96 carts, or jingle machines. When the cart command is pressed, Studio plays the assigned jingle. You can also edit jingle assignments while cart edit mode is active.
The cart commands are:
* F1 through F12 either by themselves, or in combination with Shift, Control or Alt (e.g. F2, Shift+F11, Control+F5, Alt+F12).
* Number row from 1 through 9, 0, hyphen (-) and equals (=) either by themselves or in combination with Shift, Control or Alt (e.g. 5, Shift+-, Control+=, Alt+0).
Hint: because Alt+F4 is a cart command, press Control+Alt+X to quit SPL Studio.
To help you learn what jingle will play when a given cart key is pressed, NVDA allows you to explore cart assignments. Press Control+NVDA+3 to enter Cart Explorer. When you press the cart key once, NVDA will tell you which jingle is assigned to that cart key. When pressed twice, the jingle associated with the cart command will be played. Once you've explored the cart assignments, press Control+NVDA+3 to leave Cart Explorer.
Let NVDA learn cart assignments
By default, Studio assigns F5 to a jingle called "Kewel". you can teach NVDA the actual cart assignments for each cart key. Follow these steps to let NVDA learn cart assignments:
1. From Start menu/screen, select "Explore NVDA User Configuration Directory".
2. Once the user configuration folder opens, look for a file named "splcarts.ini". If the file doesn't exist, create a text file named "splcarts.ini". Open either the existing or the new file.
3. For each line, write the cart assignments as follows:
where cart is the cart key and jingleName is the name of the jingle you want NVDA to announce when this key is pressed. For example, the default Kewel jingle (assigned to F5) entry would look like:
Enter your cart assignments, then once you're done, save and close the file.
4. Back at SPL Studio, enter Cart Explorer (if you were in cart Explorer, exit then reenter this mode). NVDA will now recognize your cart assignments and will announce them as you press the newly assigned cart keys.
5. To remove a cart from being announced, open splcarts.ini and remove the entries you no longer need. Save the file, reenter Cart Explorer and NVDA will learn that you have removed an entry from list of carts.
Note: If a cart is not assigned (either not assigned from the beginning or removed), NVDA will announce, "not assigned". Also, if splcarts.ini is not present in your user configuration folder, NVDA will tell you of this fact and will not enter cart explorer.
Hint: if you wish to preserve cart assignments (for example, if you have identical jingle sets in SPL Studio running on two or more computers), copy splcarts.ini from your first computer to the second computer (splcarts.ini will be used in version 3.0 or later).
Go to addons.nvda-project.org, select Station Playlist Studio link, then download the development version to try cart explorer (note: don’t use development version in a production environment; for production releases, use stable version, which is 2.x).
P.S. Blog post requested by an add-on tester.
One of the strengths of software development is ability for users and developers to participate in shaping a software. This is more important if this software is needed by the user (or users) for performing various tasks. But there are times when something comes up that makes programmers sigh and think, “hmmm, maybe I need to tell users how they can help me.” This is one of those posts, and for those who are NVDA (NonVisual Desktop Access) users, you might want to keep this in mind to help NVDA developers in understanding your needs. To address different user groups, I’ ve organized this post into sections so you can quickly jump to the desired section.
Bugs are bound to exist in any software project. Once a user finds a bug, he or she would tell the developer about the bug in hopes of getting it fixed.
For the most part, NVDA developers receive good amount of information about a bug when a user files a ticket (issue). However, there are times when programmers ask the user to provide more details such as version of the app, how to reproduce a problem and so on.
Here are some questions that might be asked when filing an issue with NVDA (or with any software):
· Steps to reproduce a problem: Sometimes, a user may not write how to reproduce a problem (if it is a recurring one). Just saying “… this problem exists …” or “… NVDA should do this and that …” does not provide the picture the developers need. The first and important information to provide (besides other info such as version of the program you’re using) is the procedure to reproduce a problem. This includes commands you’ve tried, expected behavior, actual behavior and so on.
· Is this specific to NVDA: a good way to test this is running multiple screen readers, with the user trying the problem steps with each screen reader. If ALL of them produce the same result, chances are that it might be the application that’s causing the issue. If the problem exists when NVDA is used, then the probability of this being an NVDA issue increases.
· Program version: a problem with one version of a program may not mean the problem exists with other versions (more so in Office applications and web browsers). If possible, please test for the issue with more than one version of the program in hopes of narrowing down the problem to a specific version.
· Do not paste the entire contents of your log file: if you need to paste a log fragment, try pasting only the relevant log fragment – that is, one minute prior to the start of the problem and up to one minute after, with the log level set to input/output from NVDA’s General Settings dialog.
· Search the tickets before filing the issue: it is important to remember that a feature that you’re suggesting may have been suggested before, hence searching the ticket system before posting a brand new suggestion.
One of the strengths of NVDA is add-ons, which allows programmers (and users) to extend NVDA’s functionality through Python modules.
Some do’s and don’ts about add-ons include:
· Learn Python: add-ons are Python code, so it is essential that you know Python and can use it (write some programs in Python first before writing import addonHandler).
· Get ready to write more English than Python: it may sound odd to say this, but throughout the life of your add-on, you’ll be talking with users, so be prepared to explain what you’re doing.
· Get intimate with your target system: no, not love. I’m talking about being familiar with the app you’re writing the app module for, feature for which you’ll be writing your next global plug-in, and features of your speech synthesizer and braille display you wish NVDA users to use.
· Invite your users along the ride: it is important to remember that your “passengers” (clients) are users who uses a particular app, a feature in NVDA, etc. Invite them along, listen to their suggestions, go through steps to reproduce bugs and what not.
· Don’t use fancy routine unless if you know what you’re doing: it is better to keep the code simple and make it run instead of using fancy functions and break your add-on. If you want to make your add-on work faster, don’t do it until the very end (I might add, “don’t try it”) after you know for sure your add-on works as advertised i.e. works 100%.
· Make a habit of visiting NVDA’s Python Console: test your routine in the console (especially if writing a routine in an app module) before writing your code in the add-on file.
· Always debug with multiple scenarios: your add-on may only work for certain app versions, or your synthesizer may not pronounce things right. Always debug your add-ons with multiple scenarios (different versions of an app, different braille display models, etc.).
· Most importantly, have fun.
That’s all for tonight. Hope this helps.
A close friend of mine sent a tweet a few days ago announcing:
I have solved some challenge at Code Eval…
Since I was preparing for my algorithms final, I decided to give Code Eval a try to review various algorithms I’ve learned in class.
How it works: Code Eval (www.codeeval.com) let’s you submit solutions to various challenges in your favorite language (for me, C++ and Python). Once you submit your solution, it’ll score your output, and if you solve it, gives you an opportunity to tweet about it. The aim of the site is to connect programmers and companies, as part of this purpose, Code Eval lists “package problems” where a company sponsors a challenge (some are easy, others are hard).
Now why do I mention the Pass Triangle challenge from Code Eval? Because it helped me understand what dynamic programming algorithms are and how they work. Dynamic programming allows building the solution to a problem by computing answers to subproblems. This is done by filling out a table based on a defined pattern, or it is called “recurrence relation.” Effectively, when you’re solving problems involving dynamic programming, you’re solving this recurrence relation.
The pass triangle challenge can be found at:
Here, one would be tempted to start with greedy choice, since you can add sums for each level and choose the maximum of two subtrees. But this will not work, hence dynamic programming is the way to go (you would fill out a solutions table, then choose the max once you’re done with the entire tree of numbers).
Let’s continue with add-on development…
Last time, we talked about preparing for add-on development. We left off at what kinds of add-ons are available. Let’s go over types of add-ons available.
Add-ons can be divided into three categories: global plug-ins, app modules and drivers. A global plug-in adds additional functionality for NVDA, such as OCR capability, support for controls seen in multiple apps and so on. Examples are OCR, emoticon announcements and so on. In contrast, an app module provides support for an app, with examples being GoldWave, Outlook and so forth. Lastly, drivers provide support for speech synthesizers and braille displays.
Each add-on type inherits from a base module. A typical initial code looks like this:
import globalPluginHandler/appModuleHandler/handlers for drivers
Then you would write:
I will not cover drivers here as they require extensive knowledge of how synthesizers/braille displays work (and I haven’t written any). We’ll start with similarities between global plugin and app modules, and we’ll dive into differences between them.
Welcome back to Musings of a Blind Highlander. It’s been a year since I posted about my life and other topics. Now that I’m learning about few advanced things, I’d like to take some time to share it with you.
So what was I doing for the past few months? I’ve been continuing with my computer science degree, wrote some NVDA code and what not. I hope to continue with NVDA add-ons series and continue with CS topics.