Good Design vs Bad Design – Information overload

The Bad: Parking Signs in Los Angeles

Parking signs in Los Angeles (LA) have been the epitome of information overload for decades. They’ve always been notoriously hard to understand, because the traffic rules are complex, resulting in the need to convey a lot of information in a small area.

How confusing are these signs? Traditionally, very—look at this example from the 2010s:

Author/Copyright holder: Jorge Gonzalez. Copyright terms and licence: CC BY-SA 2.0

As LA parking signs go, this example is already a pretty simple one.

Imagine you are a driver along this road on a Tuesday morning at 9 a.m. Can you park at this spot? What sounds like a simple question takes a lot of mental processing to answer.

As designers, we’re often faced with situations where we have to design for a lot of information to be displayed in a small space. The parking signs in LA might be an extreme case, but many times designing for mobile apps means facing the same problems. Is there a way out—for both the parking signs and designers in general?

The Good: Nikki Sylianteng’s Parking Sign

Designing a sign to display all the information, while being easy to understand, sounds like an impossible task. But that’s exactly what Brooklyn designer Nikki Sylianteng did.

Author/Copyright holder: Nikki Sylianteng. Copyright terms and licence: CC BY-NC-SA 4.0

Nikki’s proposed parking sign was eventually used in LA as part of a trial run.

Part of why Nikki’s design1 works well is that it is user-centred: Nikki realised drivers simply want to know whether they can park at a spot. Yes or no—that’s all drivers needed, and that’s all the parking sign shows.

Her design also made use of visuals, rather than text, to convey information. The result is incredibly intuitive: green for OK, red for No Parking. It’s even designed for the colour blind, with stripes for No Parking.

Now when you look at the sign, you’ll know that on Tuesday at 9 a.m., parking is not allowed. The bars show what’s what at a glance—simple.

Lessons Learnt: Best Practice

  • Understand what your users need, then design based on that. This helps reduce information overload.
  • Have lots of information to convey to your users? Try using visuals instead of text. Learn more about data visualisation here.
Advertisements

Software Development AntiPatterns

Good software structure is essential for system extension and maintenance. Software development is a chaotic activity, therefore the implemented structure of systems tends to stray from the planned structure as determined by architecture, analysis, and design.

Software refactoring is an effective approach for improving software structure.

The resulting structure does not have to resemble the original planned structure.

The structure changes because programmers learn constraints and approaches that alter the context of the coded solutions. When used properly, refactoring is a natural activity in the programming process.

For example, the solution for the Spaghetti Code AntiPattern defines a software development process that incorporates refactoring. Refactoring is strongly recommended prior to performance optimization. Optimizations often involve compromises to program structure. Ideally, optimizations affect only small portions of a program. Prior refactoring helps partition optimized code from the majority of the software.

Development AntiPatterns utilize various formal and informal refactoring approaches. The following summaries provide an overview of the Development AntiPatterns found in this chapter and focus on the development AntiPattern problem. Included are descriptions of both development and mini-AntiPatterns. The refactored solutions appear in the appropriate AntiPattern templates that follow the summaries.

  • The Blob
    Procedural-style design leads to one object with a lion’s share of the responsibilities, while most other objects only hold data or execute simple processes. The solution includes refactoring the design to distribute responsibilities more uniformly and isolating the effect of changes.
  • Continuous Obsolescence
    Technology is changing so rapidly that developers often have trouble keeping up with current versions of software and finding combinations of product releases that work together. Given that every commercial product line evolves through new releases, the situation is becoming more difficult for developers to cope with. Finding compatible releases of products that successfully interoperate is even harder.
  • Lava Flow
    Dead code and forgotten design information is frozen in an ever-changing design. This is analogous to a Lava Flow with hardening globules of rocky material. The refactored solution includes a configuration management process that eliminates dead code and evolves or refactors design toward increasing quality.
  • Ambiguous Viewpoint
    Object-oriented analysis and design (OOA&D) models are often presented without clarifying the viewpoint represented by the model. By default, OOA&D models denote an implementation viewpoint that is potentially the least useful. Mixed viewpoints don’t allow the fundamental separation of interfaces from implementation details, which is one of the primary benefits of the object-oriented paradigm.
  • Functional Decomposition
    This AntiPattern is the output of experienced, nonobject-oriented developers who design and implement an application in an object-oriented language. The resulting code resembles a structural language (Pascal, FORTRAN) in class structure. It can be incredibly complex as smart procedural developers devise very “clever” ways to replicate their time-tested methods in an object-oriented architecture.
  • Poltergeists
    Poltergeists are classes with very limited roles and effective life cycles. They often start processes for other objects. The refactored solution includes a reallocation of responsibilities to longer-lived objects that eliminate the Poltergeists.
  • Boat Anchor
    A Boat Anchor is a piece of software or hardware that serves no useful purpose on the current project. Often, the Boat Anchor is a costly acquisition, which makes the purchase even more ironic.
  • Golden Hammer
    A Golden Hammer is a familiar technology or concept applied obsessively to many software problems. The solution involves expanding the knowledge of developers through education, training, and book study groups to expose developers to alternative technologies and approaches.
  • Dead End
    A Dead End is reached by modifying a reusable component if the modified component is no longer maintained and supported by the supplier. When these modifications are made, the support burden transfers to the application system developers and maintainers. Improvements in the reusable component are not easily integrated, and support problems can be blamed upon the modification.
  • Spaghetti Code
    Ad hoc software structure makes it difficult to extend and optimize code. Frequent code refactoring can improve software structure, support software maintenance, and enable iterative development.
  • Input Kludge
    Software that fails straightforward behavioral tests may be an example of an input kludge, which occurs when ad hoc algorithms are employed for handling program input.
  • Walking through a Minefield
    Using today’s software technology is analogous to walking through a high-tech mine field. Numerous bugs are found in released software products; in fact, experts estimate that original source code contains two to five bugs per line of code.
  • Cut-and-Paste Programming
    Code reused by copying source statements leads to significant maintenance problems. Alternative forms of reuse, including black-box reuse, reduce maintenance issues by having common source code, testing, and documentation.
  • Mushroom Management
    In some architecture and management circles, there is an explicit policy to keep system developers isolated from the system’s end users. Requirements are passed second-hand through intermediaries, including architects, managers, or requirements analysts.

Python : Dictionary comprehension

Before updating a no sql or mongo doc you need to ensure that you are not adding keys which are not part of initial doc then dictionary comprehension is really helpful.

What it means, is you are able to create a dict (json object) dynamically in single line of code using loops, condition, construction every thing together.

Single line comprehension

items_to_update = {key: value for key, value in payload.items() if key in req_items}

 

multi line interpretation

if key in req_items:

….for key, value in payload.items():

…….. dictionary[key]=value

Detailed example of created update doc dic before inserting in mongo db

try:
    req_items = ["property1","property2"]
    items_to_update = {key: value for key, value in payload.items() if key in req_items}
  
    if items_to_update:
        logger.info("Updating device collection with {}".format(items_to_update))
        self.db.update({"filter": filter}, {"$set": items_to_update}, multi=True)
        logger.info("Successfully updated product details")
except PyMongoError as e:
    logger.critical('Pymongo Exception {}'.format(str(e)))
except Exception as e:
    logger.critical('Exception {}'.format(str(e)))

 

asd

Loopback : How to create embedded document or create object type

Here is your Contact model and if you want embed another model called as Address inside it then you need to put relations as embedsOne.
Please note that if you are using mongodb then embeds document will be part of parent document which mean all child documents will not be part of different collections which are linked, rather they will all be part of single parent doc.

“relations”: {
“address”: {
“type”: “embedsOne”,
“model”: “Address”,
“property”: “address”,
“options”: {
“validate”: true,
“forceId”: false
}

Now Contacts.json would look like this

{
“name”: “Contact”,
“base”: “PersistedModel”,
“idInjection”: true,
“options”: {
“validateUpsert”: true
},
“properties”: {
“id”: {
“type”: “string”,
“id”: true,
“defaultFn”: “uuid”
},
“name”: {
“type”: “string”,
“required”: true
},
“phone”: {
“type”: “string”,
“required”: true
},
“email”: {
“type”: “string”
},
“relationship”: {
“type”: “string”
}
},
“validations”: [],
“relations”: {
“address”: {
“type”: “embedsOne”,
“model”: “Address”,
“property”: “address”,
“options”: {
“validate”: true,
“forceId”: false
}
}
},
“acls”: [],
“methods”: {}
}

Please note that default id creator or sub document is “defaultFn”: “uuid” which will add id.

Python : Converting unicode logs of dict into valid json format

While debugging, programmer goes through logs to grab request payload. The issue is payload is wrapped with u for unicode, ‘ and True and False and None which are python standards however fails to pass json validation.

Hence to use them, we need to convert the unicoded python dict into valid json to do crul call, for the same here is the simple trick :

{u’a’: u’aValue’, u’b’: u’bValue’, u’c’: u’cValue’} is a dictionary which you are calling as unicode json. Now, in your language if you want a regular json from this then just do something like this:

x={u'a': u'aValue', u'b': u'bValue', u'c': u'cValue'}
y=json.dumps(x)
print y

The output will be {“a”: “aValue”, “c”: “cValue”, “b”: “bValue”}

This will remove all u, convert False into false, True into true, None into null and convert ‘ into ”   🙂