December 2, 2020

11 Tech Pros Share Their Best Tips For Writing Better Code

Those fresh to programming may know the languages and rules but lack the experience that leads to creating cleaner, more efficient code. A few years in the trenches writing, checking and debugging code—and seeing what others produce—can help developers learn some helpful tricks to write code that’s easier to update, debug and pass on. 

Luckily, new developers don’t have to wait years to learn some real pro tips. Below, 11 industry experts from Forbes Technology Council share their best advice on how new programmers can create more refined, efficient code.

1. Begin with the end in mind.

The biggest thing to remember when it comes to creating cleaner code is to begin with the end in mind. Whether you’re building an online ordering website for a restaurant chain or an app for back-of-house operations, programmers must understand the end-use case. This ensures the code is built to allow it to scale and be robust enough for different use cases that may come up during future pivots. - Tanvir BhangooTBX Digital Inc.

2. Study other developers’ code.

Don’t be afraid to learn from other people’s code—especially experienced developers. Understanding common design patterns for frameworks is generally a good next step once you’ve begun to grasp language and syntax fundamentals. Avoid bringing patterns and habits with you from other environments, as these tricks may be less efficient, especially across dynamically and statically typed languages. - Jack Mannino, nVisium

3. Adopt test-driven development.

Adopting test-driven development, in which you write a unit test before writing code, takes some getting used to, but it helps drive a cleaner and simpler design. For me, it took about a week to get used to it, but now I could never go back. Writing the test first forces me to think about what I want the code to do, and it keeps the code simple. This helps reduce complexity and cost. - Dave Todaro, Ascendle

4. Make it as simple as possible.

Simplify. Edit your code and then edit it again to pull out any excessive lines. The same rule applies to writing. You can probably accomplish your programming goal with half the lines of code that you develop on your first run. Having fewer lines of code produces a more resilient product. - Suzanne Russo, Pecan Street Inc.

5. First make it right, then make it fast.

Focusing on efficiency too early in the process will lead to code that’s hard to read and incorrect. Also, the code needs to be maintained over time by yourself and other engineers, so make sure you leave enough comments in key pieces of the code. - Fabrizio Blanco, Viant Technology

6. Don’t overlook security.

Fresh programmers tend to focus only on “making it work,” but not learning to code securely is a bad habit with horrible consequences in the long run. Make sure you learn the security guidelines needed to develop secure applications, such as the OWASP TOP 10. - Jaime ManteigaTapTok & Venkon Corp.

7. Break your code into smaller files.

If you have a thousand lines of code in a single file, you’re asking for trouble whenever you add a new team member. Smaller files are easier to understand and are likely more reusable. Testing, documentation and even code reviews are simpler when everything isn’t in one large file. - Luke Wallace, Bottle Rocket

8. Review open-source projects and contribute if possible.

The nature of open-source projects fosters better collaboration and communication and easier-to-understand code by design. There’s no need to come up with elegant solutions that make it harder for the next person to comprehend. Much like an author catering to the widest possible audience, try to write code at a fifth-grade reading level. - Chris Sullivan, Castellum.AI

9. Leverage automated scanning tools.

The use of automatic security and syntax scanning tools enables your developers to quickly and easily identify and fix common issues that crop up during the software development lifecycle. These tools can be included as part of the continuous integration process as a gate to adhere to strict code quality prior to releasing to production. - John Bellone, SS&C Health

10. Volunteer to review code.

With more teams using Agile, code reviews are happening more frequently. Still, many agile teams do not review code at all or only review one piece of code per sprint. Volunteer for the code review. No one likes being the center of a code review, but it is a great way to learn and get some peer respect. - David Moise, Decide Consulting

11. Practice, practice, practice.

Remember that “practice makes perfect.” I do not believe that there is a shortcut to gaining more experience in technology; one has to put in the hours to gain efficiency. My mentor used to say, “The more I practiced, the luckier I got.” As a security professional, I encourage new developers to perform static analysis on their code to identify any known vulnerabilities prior to deployment. - Bob Fabien ZingaDirectly, Inc./U.S. Navy Reserve

This article was published on Forbes.com

November 10, 2020

Server-Driven UI for Android with Jetpack Compose

Jetpack Compose is a new UI toolkit for native Android UI development that enables declarative UI. Traditional Android UI development is done either using a markup language to create and style native components, or with imperative Kotlin statements. With its declarative Domain-Specific Language (DSL) Jetpack Compose allows efficient development of UI with compact, easy-to-read statements.

One exciting capability of this new toolkit is the ability to more closely couple the UI with the business logic. With a traditional Android app, the entire presentation layer is deployed as part of the application. If the appearance of the app needs to change, a new version of the app must be deployed. We often struggle with the desire to build apps in such a way that we can make changes on the server and have them immediately reflected on the user’s device.

In the past, the most efficient way to achieve this has been to embed web pages within the app, but this requires a number of sacrifices. Because the web page rendering is mediated through a WebView, integrating the web and native pages can be a struggle. By developing with Compose, we can build components into our native UI that are a direct reflection of the endpoint results. This gives us much greater control over the appearance and behavior of our app without redeploying.

There are a great number of strategies for this, depending on the amount of control we hope to exercise remotely. Here, we present an example of a technique that directly renders API results in native screens. The focus here is on presenting the far end of the spectrum, where the server totally drives the UI, including building in server callbacks to submit form selections. The complete sample is available on GitHub.

A Simple Form

A form with two text fields

All of the UI in this form, displayed in an Android app, was generated from this JSON:

{
     "children" : [
         {
             "viewtype" : "TEXT",
             "label" : "Form Header"
         },
         {
             "viewtype" : "FORM",
             "children" : [
                 {
                     "viewtype" : "TEXT",
                     "label" : "Personal Information"
                 },
                 {
                     "viewtype" : "TEXTFIELD",
                     "label" : "First",
                     "data" : "first_name"
                 }, {
                     "viewtype" : "TEXTFIELD",
                     "label": "Last",
                     "data" : "last_name"
                 }
             ],
             "label" : "Submit",
             "data" : "/check"
         }
     ]
 }

To make it easier to follow, the objects are labeled with the type of view that they will produce. The screen root is a Column view that presents its list of children, each of which is converted into a @Composable. For instance, this is the code that generates the First Name text input:

class TextFieldElement(val elementDto: ElementDto) : ComposableElement {
     val fieldName = elementDto.data?:"value"
     @Composable
     override fun compose(hoist: Map<String, MutableState<String>>) {
         TextField(value = hoist.get(fieldName)?.value?:"", onValueChange = {hoist.get(fieldName)?.value = it}, label = { Text (elementDto.label?:"") })
     }
 
     override fun getHoist(): Map<String, MutableState<String>> {
         return mapOf(Pair(fieldName, mutableStateOf(elementDto.default?:"")))
     }
 }

When we parse the JSON, we transform each element from a Data Transfer Object (DTO) to an object that can return a @Composable. When the element accepts input, it also generates the hoists necessary to access and act on that data at a higher level in the view hierarchy. Here, our submit button is able to retrieve the text from the text input fields, and pass it on to our server. (In this case, the server is actually a fake built into the app for ease of portability.)

Building the Application

Our MainActivity is extremely small, because all it does is ask the server for the screen we will render. All the activity onCreate does is instantiate our base @Composable with the app theme:

setContent {
     MyApplicationTheme {
         MyScreenContent()
     }
 }

Our @Composable has an external holder for the server JSON result that it provides as an Ambient to allow screen elements to trigger loading a new screen:

data class StringHolder(var held: MutableState<String>)
 val ScreenJson = ambientOf<StringHolder>()

And here is our main @Composable that does the work of loading the screen from JSON. We use Moshi here instead of kotlinx serialization because kotlinx serialization is currently incompatible with Jetpack Compose. A workaround exists that will work for many situations, by separating the DTOs into a different module, but because we are converting our DTOs directly into @Composable, this will not work for us.

@Composable
 fun MyScreenContent() {
     // Load initial API endpoint
     val screenJson = ServiceLocator.resolve(BackEndService::class.java).getPage("/", mapOf())
     // Create the holder that can be updated by other @Composables
     val screenJsonString = StringHolder(remember {mutableStateOf(screenJson)})
     val screenAdapter: JsonAdapter<ScreenDto> = ServiceLocator.resolve(JsonAdapter::class.java) as JsonAdapter<ScreenDto>
     Providers(ScreenJson provides screenJsonString) {
         val holder = ScreenJson.current
         screenAdapter
             .fromJson(holder.held.value)?.let {
                 Screen(it).compose()
             }
     }
 }

The FORM element in the JSON is the most customized element. It expects a data field which is the URL to which the form submissions will be passed. Each element that hoists data is responsible for identifying the key that it will be passed as, and these are sent along as a map.

Button(onClick = {
     val parameters = children.flatMap { it.second.entries.map { Pair(it.key, it.value.value)  } }.toMap()
     val newPage = ServiceLocator.resolve(BackEndService::class.java).getPage(elementDto.data?:"", parameters)
     json.held.value = newPage
 }){
     Text(elementDto.label?:"")
 }

Another Form

When the JSON text holder is updated at the Button level, it triggers a new compose phase at the top level, in MyScreenContent. The JSON is read:

{
     "children" : [
         {
             "viewtype" : "TEXT",
             "label" : "Form Header"
         },
         {
             "viewtype" : "FORM",
             "children" : [
                 {
                     "viewtype" : "TEXT",
                     "label" : "Checkboxes"
                 },
                 {
                     "viewtype" : "CHECKBOX",
                     "label" : "First",
                     "data" : "first_check"
                 }, {
                     "viewtype" : "CHECKBOX",
                     "label": "Last",
                     "data" : "last_check"
                 }
             ],
             "label" : "Submit",
             "data" : "/welcome"
         }
     ]
 }

And we display a new screen:

Form with two checkboxes

Moving On

Obviously, there is a lot of work to do to make this look polished. We can choose to do that work on the app side, by applying consistent styling to our building blocks and allowing the backend to compose them. We can also defer those decisions to the backend by allowing the backend to specify Modifier attributes that we will apply to each element.

This is just a small glimpse into a totally different style of app development. It will not be a great match for every project, but for projects with a high degree of control over the backend, and constantly evolving business logic, it can allow the Android app to seem as responsive as a webpage.

May 9, 2019

Two To-Do’s and a Word of Caution for Brands from Google I/O 2019

If a tree falls in a forest and no one is around to hear it – does it make a sound? If a feature is added and nobody can find it – does it exist?

Read more

March 15, 2018

Bottle Rocket’s Olympic Hackathon

Over the past week, our developers have been hard at work on (loosely) Olympic-themed projects using the latest features and resources available from Apple, Google, and anything else that caught their attention. Before we dive into the projects and who ended up winning, we wanted to explain the importance of hackathons to Bottle Rocket's culture.

Learn about our yearly hackathon, Rocket Science.

Taking a Moment to Try: 3 Reasons Hackathons Matter

Reason 1: Trial by Tepid Fire

Each year, the tech giants that power the computers in our pockets release a wide range of new features and capabilities for their platforms – though some features you might not see until the following year. Whether the feature is in Beta or because we haven't found a need for it in a client's app, it is important to take the time to learn and play with them anyway. We’d rather constantly run into roadblocks building an app that literally has no purpose instead of discovering the problems in an active project.

Reason 2: They’re Fun

When asked about hackathons, a Rocketeer involved in the event said, “I used to think hackathons were just for kids and college students, but I couldn’t be more wrong. They’re fun, fast-paced, and exciting, which is a great way to get students involved, but they’re still just as fun for adults.” Hackathons are a time away from the pressure of client work, where failure is without consequence. There’s no breaking of keyboards, just laughing along with the insanity of it all.

Reason 3: They Reduce Time-to-Market

Unknowns are the bane of project estimations. The more we know about the tech in question, the fewer variables there are in planning. Instead of jumping into a project that suddenly doubles in duration due to unforeseen problems with a feature or how to best implement it, hackathons give us the time to learn everything we need to know. Then, when the time comes to add a new feature for a client, we already know what to expect.

But enough about hackathons, here’s what happened in our latest event.

Results of Our Olympic Hackathon

In First Place: The PIPlads

This team (seen in photo above) explored the new Android feature Picture-in-Picture mode. The goal was to have a live scoreboard of country medal counts displayed as you use your phone for other day-to-day tasks. They were able to get a functioning prototype completed and even discovered a few fun facts along the way. For instance, they found that if you make the aspect ratio of the minimized screen to extreme, it’ll crash. Also, they found that you could make the panel transparent – a totally useless feature unless you want to confuse your users, but a cool find nonetheless.

Testing Connectivity in iOS 11 by playing a game on two different, emulated devices

Second: The Gas House Gang

Seeking to better understand the capabilities of connectivity in iOS 11, The Gas House Gang made a curling(-like) game in which you slide pucks into area marked with a target. The reason this is interesting is that they had it running in two different applications – not the same application on two devices, but two different applications. While this might not sound like a feat, it shows the potential of having two completely different applications updating in real time to display information from each other.

taking pictures of a muffin and watching it post to the application

Third: The Things

Riding off the concept of tracking athletes’ diets, The Things explored one of the newer sides of IoT devices in the Android ecosystem – Android Things. Using a Raspberry Pi, the team had a functioning prototype that allowed them to photograph the food they were about to eat and then automatically post it to a channel of their choice. This could, for example, allow athletes to easily snap a photo and share it with their dietitian with the click of a button.

Honorable Mentions

Everyone’s a winner in our eyes when it comes to hackathons. While some may not have finished, others found that the technology they were trying to leverage was actually not ready for the spotlight.

Brand New Wizbangs

This team put Apple’s ARKit 2D image detection and face mapping to the test with this face-painting experience. However, they ran into a roadblock trying to merge some features as the application would not allow it and crashed during each attempt to do so.

Javelin

Leveraging Android’s Autofill Framework and Firebase Realtime Database, Javelin worked to create an up-to-date, real-time database that could update information and provide it as an autofill suggestion on the fly.

Alloy

Alloy explored Metal, Apple’s proprietary graphics processing engine, and was able to have the five rings of the Olympics animated used 1,000 triangles.

Monads

The Monads used GraphQL and gRPC to solve API request issues and better refine the answer to a single request from a database instead of having to pull data in multiple requests.

Got an idea for your business but not sure where or how to start? Reach out to Bottle Rocket. We may just have an answer for you.

October 10, 2017

Bottle Rocket QA: How Many Devices Is Too Many?

Never Too Many Devices

Mobile software testing involves many variables such as operating system versions, types of connectivity, networks, devices, and environments. To account for so many variables, the approach to testing apps poses an interesting dilemma: Should testing be performed on physical devices, simulators, emulators, or cloud-based devices? Is there a unique value in sticking to physical devices? At Bottle Rocket, we use a combination of these with an emphasis on physical devices—and we do mean emphasis. We recently surpassed 400 test devices in our library.

Device Alternatives?

Users expect apps, including those with the ability to sync between devices with shared accounts, to work flawlessly on their devices. So, a comprehensive library of devices to mimic the user experience is essential in testing. However, the number of combinations of devices and operating systems that users have is huge. For this reason, many companies opt to rely mostly on simulators, emulators, and/or cloud-based devices for their software testing.

These device alternatives can be very helpful in the beginning of the application development lifecycle, but they are not ideal as the sole testing resource. Many important pieces of mobile interaction are lost when physical devices are left out.

Real-world users are equipped with real devices in different environments, meaning the effects of the following items may vary:

  • Battery life
  • Network conditions
  • Memory limitations
  • Location services
  • Bluetooth
  • NFC
  • Device orientations
  • Accelerometer
  • Operating systems
  • Peripherals

Recreating the user experience as closely as possible is what Bottle Rocket strives for. In our efforts to do this, we recently surpassed four hundred test devices in our QA arsenal! This is a milestone in itself since one of the biggest challenges that exists in application testing is the cost of obtaining and maintaining such a large volume of physical devices for testing purposes.

Bottle Rocket Setup

Our device lab contains Griffin cabinets with a capacity to hold and charge up to eighty devices at a time. Rocketeers pick out the devices they need, check them out library-style with our device checkout software, and begin their testing. All Rocketeers can access the checkout software remotely, so devices can be easily located and accounted for conveniently.

This system allows testers to plan ahead and dedicate certain devices to their project for as long as they are needed. Once a project starts, the lead tester maps out which devices will be needed during the testing process. They are checked out from the device cabinets and used throughout the project, only being returned when all testing is completed. When finished, checking the devices back in is as easy as pushing a button.

Maintainability

Solely relying on physical devices to test requires a great deal of time and money. Maintaining such a library involves frequent upgrades in order to remain relevant and effective. If our system doesn’t contain the latest and greatest mobile devices, a big chunk of tech-savvy users and their experiences will be unaccounted for. We need to remain ahead when it comes to testing on the latest hardware. We pay close attention to mobile announcements such as Google I/O and WWDC every year to gather intel on what’s coming and plan ahead by preordering any new devices or scoping out the latest operating system and its release date. So why all the focus on what’s coming? It’s important to know the adoption trends, new hardware features, such as aspect ratios, or if any new peripherals are announced.

New operating systems are especially impactful as they can touch any part of the device and installed applications. New features and tweaks to existing operating systems can affect corresponding areas of our applications, so we must look into the patch notes of any release and test our applications accordingly. A recent example of this is the release of iOS 11 – for every new beta released, we update our device operating systems and run tests on all of our applications. It’s a quick sanity check to verify all features cooperate with the updates. Developers have taken advantage of these betas as well in order to research and experiment with the new ARKit.

It is beneficial to have varying device types - high end and low end, new and old. Keeping old operating systems on devices is part of this method. Android users especially are not pushed to upgrade operating systems as aggressively as other platforms. Android OS 6 is still the most widely used according to Android’s developer portal, despite OS 7 having been out for more than a year. Covering OS 4, 5, 6, and 7 is necessary to ensure quality for all users.

In summary, using physical devices will assure the most accurate testing and analysis since that is the only way to duplicate the diversity of users’ environments, network settings, operating system versions, and hardware. Keeping up with current and future devices and operating system versions will also ensure quality results. Bottle Rocket will continue to build its device library – we’re beyond 400 now, and have no plans of stopping!

Interested in testing your app in our device library? Let us know at [email protected]

© 2020 Bottle Rocket. All Rights Reserved.