diff --git a/data/careers.yml b/data/careers.yml index 246f42d..0f41538 100644 --- a/data/careers.yml +++ b/data/careers.yml @@ -14,7 +14,9 @@ item : - name : Senior Software Developer - Java linkToImage: ../images/jobdescriptions/20-senior-java-developer.pdf - name : Software Engineer - IoT - linkToImage: ../images/jobdescriptions/19-software-engineer-iot.pdf + linkToImage: ../images/jobdescriptions/19-software-engineer-iot.pdf + - name : System Analyst + linkToImage: ../images/jobdescriptions/21-system-analyst.pdf - name : Scrum Master linkToImage: ../images/jobdescriptions/5-scrum-master.pdf - name : Agile Business Analyst - Team Lead diff --git a/public/404.html b/public/404.html index b7ca313..b48e4e8 100644 --- a/public/404.html +++ b/public/404.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/about/index.html b/public/about/index.html index aebc252..3dbdd80 100644 --- a/public/about/index.html +++ b/public/about/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/about/index.xml b/public/about/index.xml index 92a7a2f..198b950 100644 --- a/public/about/index.xml +++ b/public/about/index.xml @@ -1,4 +1,4 @@ - + About Us on Bravo LT | Learning & Technology diff --git a/public/agile/index.html b/public/agile/index.html index 5bde132..3a87189 100644 --- a/public/agile/index.html +++ b/public/agile/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/agile/index.xml b/public/agile/index.xml index 624bdc0..894fe4c 100644 --- a/public/agile/index.xml +++ b/public/agile/index.xml @@ -1,4 +1,4 @@ - + Agile Training on Bravo LT | Learning & Technology diff --git a/public/blog/2016-raspberry-pi-youth-camp-recap/index.html b/public/blog/2016-raspberry-pi-youth-camp-recap/index.html index 9880d27..3360a23 100644 --- a/public/blog/2016-raspberry-pi-youth-camp-recap/index.html +++ b/public/blog/2016-raspberry-pi-youth-camp-recap/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,14 +149,24 @@

Bravo LT Hosts Raspberry Pi Camp

-
At Bravo LT, we believe STEM education is key to strengthening West Michigan from the inside out.
+ + +
At Bravo LT, we believe STEM education is key to strengthening West Michigan from the inside out.
+

That’s why we were pleased to host our second-annual free Raspberry Pi Youth Camp which gave local students an opportunity to explore computer programming in a fun and engaging way.

+

The free event, held August 9 and 11, 2016 at Davenport University in Grand Rapids, was powered by our developers, who generously volunteered their time to teach camp participants about the Python programming language and Raspberry Pi devices—inexpensive credit card-sized computers that plug into TVs or monitors and use keyboards and mice.

+

This year’s camp kicked off with an inspiring, informative presentation by Bravo LT developer Mike Nishizawa on the history—and the sheer power—of computer programming. Mike walked campers through some of the amazing innovations that took us from Turing Machines to the 1969 moon landing to the future of quantum computing.

+

Following Mike’s presentation, Bravo LT president and founder Ed Nausieda wrapped up the day by helping students assemble their Raspberry Pi devices. It was fun watching the children excitedly explore the NOOBS operating system’s built-in features, such as LibreOffice, the command-line interface, and—last but not least—games!

+

On day two, Bravo LT developers Dustin Clifford and Dave Schoutens introduced campers to the world of programming. During Dustin’s presentation, students worked in Scratch and Python to create a sequence for an actual toy rocket launch!

+

And if programming a rocket launch wasn’t cool enough, the students also used Python to hack Minecraft during Dave’s engrossing presentation. Given the incredible popularity of Minecraft, this lesson was—not surprisingly—a huge hit with the campers!

+

Following the Minecraft presentation, the countdown was on, and students were able to finally to “Blast Off!” After traveling to a nearby park, the campers used their Raspberry Pi devices to send a rocket into orbit! It was an exciting ending to an action-packed two days.

+

We’d like to extend a heartfelt “thank you” to the Bravo LT staff who came together to promote and volunteer at the event, Minda Joi for donating her time and photography services, Davenport University for allowing us to use their facilities, and the parents and children who helped make this year’s camp a resounding success!

diff --git a/public/blog/2017-raspberry-pi-youth-camp-recap/index.html b/public/blog/2017-raspberry-pi-youth-camp-recap/index.html index 56cb6a8..febd83d 100644 --- a/public/blog/2017-raspberry-pi-youth-camp-recap/index.html +++ b/public/blog/2017-raspberry-pi-youth-camp-recap/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -151,17 +151,26 @@

2017 Raspberry Pi Youth Computer Camp Recap

At Bravo LT, we believe STEM (Science, Technology, Engineering, Math) education is key to strengthening the future for the next generation. As a technology and e-Learning company in West Michigan, we love introducing the next generation of children to technology. Last month we hosted our third-annual Raspberry Pi Youth Camp which gave local students (ages 10-14) an opportunity to explore computer programming in a fun and engaging way.

+
- + +


+

We hosted this free event at Davenport University in Grand Rapids. The two night event was powered by our developers, who generously volunteer their time to teach camp participants about the Python programming language and Raspberry Pi devices—inexpensive credit card-sized computers that plug into TVs or monitors and use keyboards and mice.

+

Camp kicked off with an inspiring, informative presentation by developer Mike Nishizawa on the history, and sheer power, of computer programming. Mike walked campers through some of the amazing innovations that took us from Turing Machines to the 1969 moon landing to the future of quantum computing.

+

Following Mike’s presentation, Bravo LT president and founder Ed Nausieda helped students assemble their Raspberry Pi devices.

+

Bravo LT developer Jacob Weber and Scrum Master Brad Nelson introduced campers to the world of programming. During Jacob and Brad’s presentations, students were introduced to Scratch and Python (which created a sequence to run their GoPiGo cars)! They carefully installed their Raspberry Pi devices into their GoPiGo cars.

+

And if remotely controlling their GoPiGo cars with their Raspberry Pi computers wasn’t cool enough, the students tested out Minecraft during Jacob’s engrossing presentation. Given the incredible popularity of Minecraft, this lesson was a huge hit with the campers!

+

Bravo Lt’s Digital Media Designer, Alysa Passage, fueled the children with fresh pizza and homemade brownies. After dinner the students unleashed their cars on the nicely carpeted race track to “Drive to the Future!” The campers used their Raspberry Pi devices to navigate their GoPiGo cars through a series of obstacles courses and race to the finish line. More than once, an unexpected and hilarious demolition derby broke out on the track. It was an exciting ending to an action-packed two days.

+

We’d like to extend a heartfelt “thank you” to the Bravo LT staff who came together to promote and volunteer at the event, Davenport University for the use of their facilities, Byrne and Lacks Enterprises, INC. for their generous donations, and the parents and children who helped make this year’s camp a wonderful experience!

diff --git a/public/blog/agile-in-grand-rapids/index.html b/public/blog/agile-in-grand-rapids/index.html index 823d59e..d605d5d 100644 --- a/public/blog/agile-in-grand-rapids/index.html +++ b/public/blog/agile-in-grand-rapids/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,84 +149,41 @@

Agile Training in Grand Rapids

-
Equip Your Teams with Agile
+ + +
Equip Your Teams with Agile
+

We’re passionate about equipping your teams with the cutting-edge Lean Agile Certification training they need!

+

This summer we hosted an Agile Advanced Scrum Master Certification course in down-town Grand Rapids. We had a blast hosting and teaching participants from Gordon Food Service, Meijer, Spectrum Health, and more. Most beneficially, great discussions formed across the varying industries which created a learning environment filled with collaboration.

+

During the two day certification course we covered such things as:

+
    -
  • -
      -
    • Scrum Master Role in the Enterprise
    • -
    -
  • -
  • -
      -
    • Applying Agile Principles: a Scrum Master’s Perspective
    • -
    -
  • -
  • -
      -
    • Agile and Scrum Anti-Patterns
    • -
    -
  • -
  • -
      -
    • Facilitating Program Execution
    • -
    -
  • -
  • -
      -
    • Improving Flow with Kanban and XP
    • -
    -
  • -
  • -
      -
    • Building High-Performing Teams
    • -
    -
  • -
  • -
      -
    • Improving Program Performance with Inspect and Adapt -
    • -
    -
  • +
  • - Scrum Master Role in the Enterprise
  • +
  • - Applying Agile Principles: a Scrum Master’s Perspective
  • +
  • - Agile and Scrum Anti-Patterns
  • +
  • - Facilitating Program Execution
  • +
  • - Improving Flow with Kanban and XP
  • +
  • - Building High-Performing Teams
  • +
  • - Improving Program Performance with Inspect and Adapt +
+

Our Bronze Partnership in Agile allows us to advise our clients on the Scaled Agile Framework to help them reach their business goals more effectively. We’re excited to continue to offer Lean Agile training locally since we’ve seen first hand how applying Agile project management methodologies creates big wins for our clients in various enterprises.

+
Lean Agile Courses in Michigan
+
    -
  • -
      -
    • Leading Agile
    • -
    -
  • -
  • -
      -
    • Agile for Teams
    • -
    -
  • -
  • -
      -
    • Scrum Master
    • -
    -
  • -
  • -
      -
    • Advanced Scrum Master
    • -
    -
  • -
  • -
      -
    • DevOps
    • -
    -
  • -
  • -
      -
    • Product Owner/Product Manager - +
    • - Leading Agile
    • +
    • - Agile for Teams
    • +
    • - Scrum Master
    • +
    • - Advanced Scrum Master
    • +
    • - DevOps
    • +
    • - Product Owner/Product Manager +
      Email us about tailor-made Agile training, transformations, or coaching for your organization. -Connect with us via agile@bravolt.com to learn more.
    • -
    -
  • +Connect with us via agile@bravolt.com to learn more.
diff --git a/public/blog/bravo-open-source-symposium/index.html b/public/blog/bravo-open-source-symposium/index.html index 9db7fd7..5a22ecc 100644 --- a/public/blog/bravo-open-source-symposium/index.html +++ b/public/blog/bravo-open-source-symposium/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,26 +149,42 @@

Bravo Open Source Symposium

-
Bravo Open Source Symposium
+ + +
Bravo Open Source Symposium
+

October 26, November 2, 9, and 16 5:00 - 7:00 PM

-
Event Description:
+ +
Event Description:
+

BOSS 2015 explores specific open source topics, to include:

+
  1. Data Grids: To Infinispan and Beyond (Day 1)
  2. Introduction to Docker (Day 2)
  3. Maven for Power Users (Day 3)
  4. Introduction to Clojure (Day 4)
- + +


+

This free four-day symposium, held on alternating Mondays in September and October, features highly interactive training sessions to include the following delivery methods: traditional lecture and demonstration, video, case studies, hands-on activities and group discussion.

-
Who Should Attend?
+ +
Who Should Attend?
+

BOSS welcomes anyone who’s passionate about open source, including: developers and programmers, architects, engineers, designers, system admins, business and system analysts, IT managers and IT directors.

-
Event Speakers:
+ +
Event Speakers:
+

Dave Schoutens, Senior Java Developer

+

Mike Nishizawa, Lead Senior Software Developer

+

Ryan Graffy, Lead Senior Software Developer

-
Location:
+ +
Location:
+

Bravo LT | 660 Cascade West Parkway SE | Grand Rapids, MI 49546

diff --git a/public/blog/bravos-pillars/index.html b/public/blog/bravos-pillars/index.html index 462009d..1248936 100644 --- a/public/blog/bravos-pillars/index.html +++ b/public/blog/bravos-pillars/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,17 +149,30 @@

Bravo LT's Four Pillars

-
Doing Things Differently
+ + +
Doing Things Differently
+

We’ve worked hard to earn our reputation as an elite learning and technology solutions provider in the growing West Michigan tech scene. How? We like to do things differently. From the way we invest in our employees, to the strong relationships we foster with clients, we empower the community in all that we do.

+

Below are the Four Pillars with which we’ve built our foundation. We’ve leveraged our extensive industry knowledge and innovative practices to establish trust with our partners and create synergy within their businesses.

+

Contact us today to see how we can help you get the job done right the first time.

-
Trust
+ +
Trust
+

When you work with us, you gain a partner you can trust every step of the way. Our ability to integrate functional expertise and technical capabilities with well-founded talent-management practices creates performance that works. You can also trust in our commitment to doing the job right, and seeing it through to the finish line because we believe your success is our success. Period.

-
Synergy
+ +
Synergy
+

“Synergy” might sound like a corporate buzzword, but it’s a concept we swear by. Recent studies show that pure outsourcing is ineffective, while outsourcing locally actually reduces operating costs. How? The answer lies in expertise. By combining our people and skills with your business, we form a synergistic partnership with you that results in higher-quality work done in less time.

-
Knowledge
+ +
Knowledge
+

Our people are the best at what they do—and we’re not just saying that. Bravo LT’s talented IT staff meets rigorous education, experience, and soft-skill requirements. Our team members are also out-of-the-box thinkers, each with a bachelor’s or master’s degree in a technology-related discipline. They boast proven track records and have worked for organizations such as Microsoft, Ford, GM, Meijer, and Herman Miller.

-
Innovation
+ +
Innovation
+

Diverting in-house resources to creating and maintaining applications costs you time and money. We help you solve that challenge through our own innovation, including state-of-the-art processes and solutions to meet your industry-specific needs. Our software processes, based on sound business analysis, agile project management, and test-driven development, enable your success.

diff --git a/public/blog/bravos-ribbon-cutting-open-house/index.html b/public/blog/bravos-ribbon-cutting-open-house/index.html index 760a624..203ae25 100644 --- a/public/blog/bravos-ribbon-cutting-open-house/index.html +++ b/public/blog/bravos-ribbon-cutting-open-house/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,12 +149,19 @@

Welcome Bravo to the Block

-
Save the Date#####
+ + +
Save the Date
+

You’re invited to Bravo LT’s Ribbon Cutting & Open House Thursday, August 15th, 3pm - 5pm

+

Join us as we celebrate our recent move downtown. Ribbon Cutting at 4pm.

+

We can’t wait to meet our neighbors and catch up with clients and friends!

+

Snacks and drinks provided.

+

Bravo LT, 40 Monroe Center NW, Suite 11, Grand Rapids, MI 49503

diff --git a/public/blog/go-local/index.html b/public/blog/go-local/index.html index 5ff54c3..5952426 100644 --- a/public/blog/go-local/index.html +++ b/public/blog/go-local/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -150,25 +150,23 @@

Go Local

We like supporting local businesses—after all, it creates new jobs, encourages innovation, and strengthens our community. The truth is, though, that’s not the main reason we’re so committed to anything and everything local. Really, we’re just in love with what West Michigan has to offer—the unique people and products that populate every corner of the region.

+

Bursting with amazing talent, innovation, and services, our area has an answer to every business need, craving, or wish list. We love our Herman Miller furniture, our Prospector’s coffee, our burgeoning tech scene, and—yes—our Founders beer (as well as brews from dozens of other local breweries).

+

Do you want to do your part? Here are just a few easy ways to get the most out of your community.

+
    -
  • -

    Get to know your area. Check out sites like Experience Grand Rapids to find new places to go, including hidden gems you may have overlooked.

    -
  • -
  • -

    Join local networking groups. We like using Meetup and Experience Grand Rapids to connect with like-minded people who share our passion.

    -
  • -
  • -

    Eat local. This one’s easy. Chow down on really good food from the local artisans and chefs who make up our increasingly hot food scene. Here is a list of the top-rated restaurants in the area from 2016!

    -
  • -
  • -

    Shop local. West Michigan is home to some top shops. Check out our maker’s fair or any one of the area’s other fantastic locally run businesses.

    -
  • -
  • -

    Hire local. Tap into West Michigan’s rich local talent to meet whatever need your business has. MLive’s job board is a great place to find some of the region’s best and brightest candidates.

    -
  • +
  • Get to know your area. Check out sites like Experience Grand Rapids to find new places to go, including hidden gems you may have overlooked.

  • + +
  • Join local networking groups. We like using Meetup and Experience Grand Rapids to connect with like-minded people who share our passion.

  • + +
  • Eat local. This one’s easy. Chow down on really good food from the local artisans and chefs who make up our increasingly hot food scene. Here is a list of the top-rated restaurants in the area from 2016!

  • + +
  • Shop local. West Michigan is home to some top shops. Check out our maker’s fair or any one of the area’s other fantastic locally run businesses.

  • + +
  • Hire local. Tap into West Michigan’s rich local talent to meet whatever need your business has. MLive’s job board is a great place to find some of the region’s best and brightest candidates.

+

So what are some ways you support your community? Take our #GoLocalMI challenge and show us your favorite West Michigan people, places, and products on Twitter or Facebook!

diff --git a/public/blog/going-local/index.html b/public/blog/going-local/index.html index 23206f8..cbd90bb 100644 --- a/public/blog/going-local/index.html +++ b/public/blog/going-local/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,16 +149,28 @@

The Importance of Outsourcing Locally

-
Going Local
+ + +
Going Local
+

We all know businesses can outsource cheap work overseas in exchange for second-rate results. But Bravo LT wants your company, and our shared community, to thrive. That’s why we are so passionate about delivering exceptional services to businesses in the area. We believe that investing in your community is the best way to ensure a bright future for West Michigan. Here are just a few of the many reasons why we think it’s so important to outsource locally:

-
Creating Community
+ +
Creating Community
+

Our community is home to a wealth of first-rate talent—tap into it. By contracting Bravo LT, you can ensure your resources remain close to home. This means more jobs, and, as a result, a growing customer base in the community.

-
Eliminating Barriers
+ +
Eliminating Barriers
+

If you want to have a cup of coffee with us, we’re here. If you want us to swing by your office, we’re here for that, too. Being local means being available. Let us deploy our team of specialists to your location for seamless integration and quick results, without the hassles of global outsourcing, like poor communication or scheduling across different time zones.

-
Lowering Costs
+ +
Lowering Costs
+

Recent studies suggest that pure outsourcing is ineffective, while outsourcing locally actually reduces operating costs. How? The answer lies in expertise. With Bravo LT’s carefully curated team of specialists at your side, your organization will get things done right the first time, which frees you up to focus on the big picture.

-
Meeting Higher Standards
+ +
Meeting Higher Standards
+

Bravo LT has established a reputation as being a leading technology company in West Michigan. We pride ourselves on dependability, innovation, and passion, and with satisfied clients across the area, such as Herman Miller, Spectrum Health, and Amway, you can rest assured your business is in good hands.

+

By outsourcing locally, you’re outsourcing responsibly. Invest in your business and your community by investing in Bravo LT.

diff --git a/public/blog/google-io-2016/index.html b/public/blog/google-io-2016/index.html index 670eaef..228df43 100644 --- a/public/blog/google-io-2016/index.html +++ b/public/blog/google-io-2016/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,9 +149,14 @@

Google IO Extended Code Art Prize

-
Code Art Prize
+ + +
Code Art Prize
+

Google I/O Extended GR Gold Sponsor Bravo LT is excited to announce Code-Art Prize, our Code Challenge, just in time for this year’s big event! Code-Art Prize is a contest with an emphasis on functional code that is, also, beautiful. The problems will be posted on GitHub Tuesday, May 17, and the Challenge closes Wednesday, May 18, at 3pm. Participants who design the most elegant code will be entered into a raffle to win a Google Home.

+

Be sure to visit the Bravo LT booth at I/O GR for even more fun, prizes, and surprises.

+

We hope to see you there!

diff --git a/public/blog/google-io-2018/index.html b/public/blog/google-io-2018/index.html index 2ce8e1e..99c9950 100644 --- a/public/blog/google-io-2018/index.html +++ b/public/blog/google-io-2018/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,10 +149,16 @@

Google I/O Extended

-
#BravoDoesIO
+ + +
#BravoDoesIO
+

This summer’s Google I/O Extended was held at the Knickerbocker in Grand Rapids. Bravo LT was excited to participate as a Gold Sponsor and host several talks as well as the Game of Drones Code Challenge.

+

Google brought a lot to the table through their livestream event. Many were amazed to see the Google Assistant make a phone call to book a restaurant on behalf of the user. Google was also quite focused on #DigitalWellbeing so everyone can enjoy technology that improves life and doesn’t distract from it, which seems like an important initiative. They’re certainly reimagining many Google tools to increase the quality of life.

+

One of our project managers discussed the benefits of Lean Agile principles in enterprise environments. Our Salseforce Analyst and Developer, Michael Haberlein, led a talk on the Salesforce Google partnership, and the current capabilities it makes possible. Several of our Senior Software Engineers walked attendees through Bravo LT’s 2018 Code Challenge and shared the game play boundaries. Many talented developers submitted code for Game of Drones and we had a ruckus time watching each developer’s code go head to head in the challenge. With an entry like ‘SkyNet’, how could we not be on the edge of our seats?

+

We loved the opportunity to meet many local developers, IT leads, managers, and more during speed networking. It was great to continue the conversations over a tasty lunch, provided by the Knickerbocker.

diff --git a/public/blog/google-io-2019-recap/index.html b/public/blog/google-io-2019-recap/index.html index 4185d53..0ce7a02 100644 --- a/public/blog/google-io-2019-recap/index.html +++ b/public/blog/google-io-2019-recap/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,13 +149,22 @@

Google I/O Extended Recap

-
#BravoDoesIO
+ + +
#BravoDoesIO
+

About a month and half ago we weren’t sure Google I/O Extended was going to happen. We met with Dan, Sam, and Dan of the Grand Rapids Google Developer Group and they willingly passed the I/O Extended torch to Bravo. They’ve done an amazing job hosting a spectacular event for local developers over the past 5 years.

+

With 40 days to plan an event of this magnitude, we knew we were pure crazy. It was only possible because of the support of the local community. West Michigan companies quickly stepped up to the plate to support I/O Extended. We’re grateful for generous sponsorship from Google Developer Group Grand Rapids, Gordon Food Service, Spectrum Health, Start Garden, MEDC SmartZone, Byrne Electrical, and Neo4j.

+

This summer’s Google I/O Extended was held at the Grand Rapids Chamber. (If you’re looking for a classy event space for your next gig, be sure to connect with Tori. Working with her was fabulous.)

+

The day began with speaker Mark Andrews, from Neo4j who shared an “Intro To Graphs and Neo4j”. Next up our software developer, Matthew Underhill, presented on OpenCV and the “Notion of Motion Tracking”. Three of our software developers participated in a lightning round and shared quick presentations. Sam Berry talked about Free Programming and the power of a positive mindset. Ed Devires shared a great code demonstration on “Getting Started with Nullable Reference Types in C# 8”. Matt Armand shared a talk called, “Scrum is not a Skateboard”. Several alternate titles for his talk were: “Matt Vents to a Sympathetic Audience,” “Matt Rants to a Captive Audience,” or, “How He Learned to Stop Worrying and Re-Frame Misplaced Messaging.” The last local talk for the day was given by our software developer, Dave Schoutens, who provided a deep dive into several unique features of Git.

+

As always, Google brought a lot to the table through their live steam, which filled much of the afternoon. We’re grateful to Google for the awesome giveaways they provided for our local event.

+

The after party, sponsored by Start Garden and MEDC SmartZone, was hosted at Uccello’s downtown.

+

Thanks to everyone who attended and participated in the event. We couldn’t have done this without you or the support of Team Bravo!

diff --git a/public/blog/google-io-2019/index.html b/public/blog/google-io-2019/index.html index c7eff4c..0135865 100644 --- a/public/blog/google-io-2019/index.html +++ b/public/blog/google-io-2019/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,10 +149,16 @@

Google I/O Extended 2019, Coming May 7!

-
BravoDoesIO
+ + +
BravoDoesIO
+

Bravo LT is excited host this summer’s Google I/O Extended. The one-day event will be held at the Grand Rapids Chamber, Steelcase Conference Center on Tuesday, May 7, 2019.

+

We’ll have local talks in the morning, developer talks from Google streaming in the afternoon, and an after-party event downtown.

+

You’ll love this opportunity to be under one roof with the local developer/designer community. Don’t miss your chance to connect, grow, learn, and play! Register Today!

+

2018 Recap

diff --git a/public/blog/happy-new-year/index.html b/public/blog/happy-new-year/index.html index 1653c91..416ce00 100644 --- a/public/blog/happy-new-year/index.html +++ b/public/blog/happy-new-year/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -150,10 +150,15 @@

Happy New Year

2016 was a big year for Bravo LT—a year of profound growth. That growth was demonstrated not only through several valuable new business partnerships, but also through the personal development of our employees. Whether they were brushing up on their professional and team-building skills or volunteering their time to support local causes, our team members showed a willingness and commitment to grow as individuals.

+

Over the course of the year, Bravo LT grew by two project managers, two e-learning experts, and four exciting new partnerships with organizations across Michigan. Through these moves, we have laid the foundation for what we feel will be fruitful development well into the future.

+

On a more personal level, our employees focused on individual growth. Together, our team engaged in reading and discussing Stephen Covey’s 7 Habits of Highly Effective People—one of the most influential books of our time—in an effort to improve themselves. They also launched and participated in our new community outreach initiative, Care. Through this program, we collected donations for the Kent County Animal Shelter, sponsored the 2016 Spectrum Health Gala, participated in a bowl-painting party to benefit local food pantry God’s Kitchen, and worked tirelessly to host successful events such as our Raspberry Pi Youth Camp and BOSS educational talks.

+

This past year, we were fortunate to grow our partnerships with some of the most dynamic businesses in Michigan, and to see our hard-working, talented employees give so generously.

+

As we reflect on 2016, we’d like to wish all of our friends, family, teammates, and clients a happy holiday season and a prosperous new year!

+

Best Wishes, Team Bravo

diff --git a/public/blog/how-i-spent-my-summer-vacation/index.html b/public/blog/how-i-spent-my-summer-vacation/index.html index f9c1b44..12b394d 100644 --- a/public/blog/how-i-spent-my-summer-vacation/index.html +++ b/public/blog/how-i-spent-my-summer-vacation/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -150,10 +150,15 @@

How I Spent My Summer Vacation

In the contracting world, it’s pretty common for client work to slow down in the warmer months. Summertime is a welcome reprieve from the brutally cold Michigan winters, so I don’t exactly blame clients for wanting to enjoy a little time outside of the office! In fact, as a self-proclaimed beach bum, I, too, find myself distracted by a hot and sunny day when Lake Michigan is above 70 degrees.

+

During these slower months, I view my downtime as an opportunity to learn new things. In between those moments of dreamily gazing out the window at the perfectly blue sky, I’m actually quite productive exploring new techniques and technologies!

+

This summer in particular, I’ve spent my time researching mobile learning development, a field rapidly growing in importance and popularity in the learning community. And in my hunt, I’ve come across a game-changing new authoring tool: Adapt. So, what’s so innovative about it? Well, first of all, it’s a free, intuitive, and open-source web application. But even better, it excels in responsive design, expertly creating learning modules that play well with mobile devices of all makes and models—something that is really important these days.

+

Thanks to the time I’ve been able to invest in my professional development, I’ve since become proficient in Adapt and now feel confident in my abilities to offer this service to our clients and provide new opportunities to engage learners on their mobile devices at their moment of need! Whether we’re creating a traditional e-learning course, mobile course, or a mobile performance support option, we have the ability to engage learners who may not have the ability to sit in a classroom for traditional training.

+

My story is just one example of why it’s beneficial to partner with the Bravo LT team. We love what we do and always strive to gain expertise in new technologies and methodologies, keeping our clients up to speed with new solutions to business problems.

+

If you’re interested in how Bravo LT can help you meet your mobile learning needs, drop us a line—but don’t forget to spend some time outside while the weather’s still nice!

diff --git a/public/blog/index.html b/public/blog/index.html index d1cea25..7f11697 100644 --- a/public/blog/index.html +++ b/public/blog/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -211,7 +211,7 @@

-

Save the Date##### You’re invited to Bravo LT’s Ribbon Cutting & Open House Thursday, August 15th, 3pm - 5pm +

Save the Date You’re invited to Bravo LT’s Ribbon Cutting & Open House Thursday, August 15th, 3pm - 5pm Join us as we celebrate our recent move downtown. Ribbon Cutting at 4pm. We can’t wait to meet our neighbors and catch up with clients and friends! Snacks and drinks provided. @@ -278,7 +278,7 @@

-

Our New Location##### Bravo has officially moved downtown Grand Rapids! Last month we said goodbye to our Cascade Parkway location and (after a few construction projects and a bit of cosmetic work in the new space) hello to Monroe Center. Our official signage is in the works, but in the meantime, we are the dark gray building located at the corner of Division and Monroe Center. More specifically: +

Our New Location Bravo has officially moved downtown Grand Rapids! Last month we said goodbye to our Cascade Parkway location and (after a few construction projects and a bit of cosmetic work in the new space) hello to Monroe Center. Our official signage is in the works, but in the meantime, we are the dark gray building located at the corner of Division and Monroe Center. More specifically: Bravo LT, 40 Monroe Center NW, Suite 11, Grand Rapids, MI 49503

Read more diff --git a/public/blog/index.xml b/public/blog/index.xml index 2d2cb29..7e1cd52 100644 --- a/public/blog/index.xml +++ b/public/blog/index.xml @@ -1,4 +1,4 @@ - + Blog on Bravo LT | Learning & Technology @@ -26,7 +26,7 @@ Fri, 12 Jul 2019 12:11:29 +0600 //www.bravolt.com/blog/bravos-ribbon-cutting-open-house/ - Save the Date##### You’re invited to Bravo LT’s Ribbon Cutting & Open House Thursday, August 15th, 3pm - 5pm + Save the Date You’re invited to Bravo LT’s Ribbon Cutting & Open House Thursday, August 15th, 3pm - 5pm Join us as we celebrate our recent move downtown. Ribbon Cutting at 4pm. We can’t wait to meet our neighbors and catch up with clients and friends! Snacks and drinks provided. @@ -49,7 +49,7 @@ The free event will be held on August 12 & 13, 2019 at the Bravo office Wed, 29 May 2019 12:11:29 +0600 //www.bravolt.com/blog/we-moved-downtown-grand-rapids/ - Our New Location##### Bravo has officially moved downtown Grand Rapids! Last month we said goodbye to our Cascade Parkway location and (after a few construction projects and a bit of cosmetic work in the new space) hello to Monroe Center. Our official signage is in the works, but in the meantime, we are the dark gray building located at the corner of Division and Monroe Center. More specifically: + Our New Location Bravo has officially moved downtown Grand Rapids! Last month we said goodbye to our Cascade Parkway location and (after a few construction projects and a bit of cosmetic work in the new space) hello to Monroe Center. Our official signage is in the works, but in the meantime, we are the dark gray building located at the corner of Division and Monroe Center. More specifically: Bravo LT, 40 Monroe Center NW, Suite 11, Grand Rapids, MI 49503 @@ -121,8 +121,7 @@ The free event will be held on September 11 & 12, 2018 at Calvin College //www.bravolt.com/blog/agile-in-grand-rapids/ Equip Your Teams with Agile We’re passionate about equipping your teams with the cutting-edge Lean Agile Certification training they need! -This summer we hosted an Agile Advanced Scrum Master Certification course in down-town Grand Rapids. We had a blast hosting and teaching participants from Gordon Food Service, Meijer, Spectrum Health, and more. Most beneficially, great discussions formed across the varying industries which created a learning environment filled with collaboration. -During the two day certification course we covered such things as: +This summer we hosted an Agile Advanced Scrum Master Certification course in down-town Grand Rapids. We had a blast hosting and teaching participants from Gordon Food Service, Meijer, Spectrum Health, and more. Most beneficially, great discussions formed across the varying industries which created a learning environment filled with collaboration. @@ -141,8 +140,7 @@ Google brought a lot to the table through their livestream event. Many were amaz Fri, 22 Sep 2017 12:11:29 +0600 //www.bravolt.com/blog/2017-raspberry-pi-youth-camp-recap/ - At Bravo LT, we believe STEM (Science, Technology, Engineering, Math) education is key to strengthening the future for the next generation. As a technology and e-Learning company in West Michigan, we love introducing the next generation of children to technology. Last month we hosted our third-annual Raspberry Pi Youth Camp which gave local students (ages 10-14) an opportunity to explore computer programming in a fun and engaging way. - We hosted this free event at Davenport University in Grand Rapids. + At Bravo LT, we believe STEM (Science, Technology, Engineering, Math) education is key to strengthening the future for the next generation. As a technology and e-Learning company in West Michigan, we love introducing the next generation of children to technology. Last month we hosted our third-annual Raspberry Pi Youth Camp which gave local students (ages 10-14) an opportunity to explore computer programming in a fun and engaging way. @@ -239,7 +237,8 @@ The free event, held August 9 and 11, 2016 at Davenport University in Grand Rapi //www.bravolt.com/blog/bravo-open-source-symposium/ Bravo Open Source Symposium October 26, November 2, 9, and 16 5:00 - 7:00 PM Event Description: BOSS 2015 explores specific open source topics, to include: - Data Grids: To Infinispan and Beyond (Day 1) Introduction to Docker (Day 2) Maven for Power Users (Day 3) Introduction to Clojure (Day 4) This free four-day symposium, held on alternating Mondays in September and October, features highly interactive training sessions to include the following delivery methods: traditional lecture and demonstration, video, case studies, hands-on activities and group discussion. + Data Grids: To Infinispan and Beyond (Day 1) Introduction to Docker (Day 2) Maven for Power Users (Day 3) Introduction to Clojure (Day 4) +This free four-day symposium, held on alternating Mondays in September and October, features highly interactive training sessions to include the following delivery methods: traditional lecture and demonstration, video, case studies, hands-on activities and group discussion. diff --git a/public/blog/nullable-reference-types/index.html b/public/blog/nullable-reference-types/index.html index c3af5b5..9775163 100644 --- a/public/blog/nullable-reference-types/index.html +++ b/public/blog/nullable-reference-types/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,285 +149,445 @@

Getting Started with Nullable Reference Types in C# 8

-

The next version of the C# language, C# 8, is scheduled to ship in September 2019 along with .NET Core 3. + + +

The next version of the C# language, C# 8, is scheduled to ship in September 2019 along with .NET Core 3. C# 8 brings some pretty cool features to the language. One of the features I’m most excited about is Nullable Reference Types, which enables developers to prevent many of the problems that often come along with null values.

+

C# 8 and .NET Core 3 are already in public preview, so you can give them a whirl right now. In this post, I’m going to walk you through a simple example to demonstrate how to take advantage of Nullable Reference Types.

+

But first, a bit of background.

+
Value types and reference types
+

Data types in C# fall into two broad categories: value types and reference types.

+

Value types are the simpler kind: integers, Booleans, characters, and so forth. When you create a variable of a value type, you can think of the variable as “holding” the value (disclaimer: this is a mental model, not a robust description of your computer’s memory).

+

For instance, the statement

-
int x = 4;
-

creates the variable x of type int and gives it the value 4. + +

int x = 4;
+
+ +

creates the variable x of type int and gives it the value 4. If you were to do something to x, say,

-
x++;
-

then x would hold the value 5 and the value 4 would be gone.

+ +
x++;
+
+ +

then x would hold the value 5 and the value 4 would be gone.

+

Reference types are the more complicated kind: objects, strings, etc. When you create a variable of a reference type, the variable doesn’t so much “hold” the value as “point to” (or “reference”) the value.

+

For instance, the statement

-
Person p = new Person { FirstName = "Bowser", LastName = "Castle" };
-

creates the variable p of type Person, places the object data somewhere in memory, and gives p the location of that data.

+ +
Person p = new Person { FirstName = "Bowser", LastName = "Castle" };
+
+ +

creates the variable p of type Person, places the object data somewhere in memory, and gives p the location of that data.

+

If you were to do something to a property of p, say,

-
p.Age = 62;
-

p would still hold the same value: a reference to the object. + +

p.Age = 62;
+
+ +

p would still hold the same value: a reference to the object. Only the object data would change.

+

On the other hand, if you were to do something to p itself, say,

-
p = new Person { FirstName = "Ganon", LastName = "Tower" };
-

a new object would be created in memory (Ganon Tower) and p would be updated with the location of the new object. + +

p = new Person { FirstName = "Ganon", LastName = "Tower" };
+
+ +

a new object would be created in memory (Ganon Tower) and p would be updated with the location of the new object. The old object (Bowser Castle) would be left hanging around in memory with no variable pointing to it - at least until the plumber garbage collector got around to cleaning it up.

+

The way that reference types work - pointing to the data rather than holding the data - has a strange consequence: a reference type variable can point to nothing.

+
Null values
+

In C#, value types cannot be null unless you explicitly declare a variable as nullable. A statement like

-
bool b = null;
-

will not compile. + +

bool b = null;
+
+ +

will not compile. There is no such thing as a bool with no value - it has to be either true or false. In fact, if you fail to provide a value, you’ll get a sensible default. A declaration like

-
bool b;
-

will give b the value false, which is the default for Booleans.

+ +
bool b;
+
+ +

will give b the value false, which is the default for Booleans.

+

Usually, this is a good thing. In the off chance that you want a nullable value type, you can declare it with a question mark:

-
bool? b = null;
-

Reference types, on the other hand, are nullable right from the start. + +

bool? b = null;
+
+ +

Reference types, on the other hand, are nullable right from the start. Let’s make that same traditional declaration with a reference type:

-
string s;
-

We now have a string type variable called s, but we haven’t yet created a real string object in memory, so s points to nothing. + +

string s;
+
+ +

We now have a string type variable called s, but we haven’t yet created a real string object in memory, so s points to nothing. This is represented by s getting the value null.

+

Oddly, even though s does not point to an actual string, the compiler allows you to write expressions like s.Length. This throws a NullReferenceException because you are attempting to dereference a null reference. In other words, you are trying to access a member of an object that doesn’t exist, so your program blows up.

+

All the compiler knows is that s is of type string, and objects of type string have a Length property. Unfortunately, in this case, we have no object, and thus no Length property.

+

I won’t go into why languages like C# allow null references in the first place, partly because it’s beyond the scope of this post, but also because the lead designer of C# wrote an excellent article that covers that very topic. I would recommend it if you’re interested in the design rationale behind Nullable Reference Types (which we really will be getting to in just a moment).

+

For now, all I hope to demonstrate is that we have a conundrum: reference type variables can be null, but the compiler doesn’t have a good way to help us to deal with those nulls responsibly. We are human beings and sometimes we are irresponsible, so we end up with a NullReferenceException at runtime.

+
Nullable Reference Types
+

To solve this problem, C# 8 introduces a feature called “Nullable Reference Types”. The feature has two main parts that work together: some familiar syntax you can use to declare which reference types should be nullable and some compiler warnings to help you to follow through on that intent.

+

Let’s see it in action. If you’d like to paint along with us at home, here are the tools we’ll be using (all of which are cross-platform):

+ +

To begin, we’ll open a terminal, create an empty directory, and scaffold a new .NET Core console app:

-
mkdir nullable-sample
+
+
mkdir nullable-sample
 cd nullable-sample
 dotnet new console
-

There are two new files in our directory. + + +

There are two new files in our directory. We’ll run code . to inspect them in VS Code.

+

The project file is nullable-sample.csproj:

-
<Project Sdk="Microsoft.NET.Sdk">
 
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
-    <RootNamespace>nullable_sample</RootNamespace>
-  </PropertyGroup>
+
<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <RootNamespace>nullable_sample</RootNamespace>
+  </PropertyGroup>
+
+</Project>
+
-</Project> -

The main program is Program.cs:

-
using System;
+

The main program is Program.cs:

-namespace nullable_sample +
using System;
+
+namespace nullable_sample
 {
-    class Program
+    class Program
     {
-        static void Main(string[] args)
+        static void Main(string[] args)
         {
-            Console.WriteLine("Hello World!");
+            Console.WriteLine("Hello World!");
         }
     }
 }
-

As you can see, dotnet new console created a simple “hello world” app. + + +

As you can see, dotnet new console created a simple “hello world” app. Let’s build it and run it, just to get a baseline of the output we expect.

+

dotnet build compiles the code and shows us if it found any problems:

-
Build succeeded.
+
+
Build succeeded.
     0 Warning(s)
     0 Error(s)
-

dotnet run both compiles and runs the code, displaying the program’s console output:

-
Hello World!
-

Now that we have a running sample, let’s add some code.

+
+ +

dotnet run both compiles and runs the code, displaying the program’s console output:

+ +
Hello World!
+
+ +

Now that we have a running sample, let’s add some code.

+

To demonstrate handling null references, we’ll start by defining a Person class to represent someone’s full name.

-
public class Person
+
+
public class Person
 {
-    public string FirstName { get; set; }
-    public string MiddleName { get; set; }
-    public string LastName { get; set; }
+    public string FirstName { get; set; }
+    public string MiddleName { get; set; }
+    public string LastName { get; set; }
 }
-

Many people have at least a given name and a surname, but middle names are not common in all cultures, and even where they are common, people do not always provide their middle name. + + +

Many people have at least a given name and a surname, but middle names are not common in all cultures, and even where they are common, people do not always provide their middle name. If we have a database of people, it might have a lot of nulls in the middle name column. Let’s create a mock data access class to pretend like we’re retrieving the first record we find in a database full of people.

-
public class PersonStore
+
+
public class PersonStore
 {
-    public static Person GetFirstPerson()
-        => new Person { FirstName = "Pat", LastName = "McTest" };
+    public static Person GetFirstPerson()
+        => new Person { FirstName = "Pat", LastName = "McTest" };
 }
-

Now we can use this data access code in our main program to do something interesting with a Person object, like counting the number of characters in the person’s full name and displaying it to the console.

-
static void Main(string[] args)
+
+ +

Now we can use this data access code in our main program to do something interesting with a Person object, like counting the number of characters in the person’s full name and displaying it to the console.

+ +
static void Main(string[] args)
 {
     Person p = PersonStore.GetFirstPerson();
 
-    int letterCount =
+    int letterCount =
         p.FirstName.Length +
         p.MiddleName.Length +
         p.LastName.Length;
 
-    Console.WriteLine($"Hello, {p.FirstName}");
-    Console.WriteLine($"You have {letterCount} letters in your full name");
+    Console.WriteLine($"Hello, {p.FirstName}");
+    Console.WriteLine($"You have {letterCount} letters in your full name");
 }
-

That seems easy enough. + + +

That seems easy enough. However, there is a sneaky bug lurking in this code. Before we address it, let’s see how our program behaves.

+

The code compiles without issue. The output of dotnet build is no different than before:

-
Build succeeded.
+
+
Build succeeded.
     0 Warning(s)
     0 Error(s)
-

When we run the code, however, we encounter a problem. + + +

When we run the code, however, we encounter a problem. Here is the output of dotnet run:

-
Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
-

The problem here is that we neglected to check for null before accessing the Length property of p.MiddleName. + +

Unhandled Exception: System.NullReferenceException: Object reference not set to an instance of an object.
+
+ +

The problem here is that we neglected to check for null before accessing the Length property of p.MiddleName. Our mock person record lacks a middle name, so at runtime, p.MiddlName was null. Let’s sweep this bug under the rug by giving Pat a middle initial. I’m feeling lazy today and I need to ship this code.

-
public static Person GetFirstPerson()
-    => new Person { FirstName = "Pat", MiddleName = "Q", LastName = "McTest" };
-

If we run the code, it works! Hooray!

-
Hello, Pat
+
+
public static Person GetFirstPerson()
+    => new Person { FirstName = "Pat", MiddleName = "Q", LastName = "McTest" };
+
+ +

If we run the code, it works! Hooray!

+ +
Hello, Pat
 You have 10 letters in your full name
-

Unfortunately, we now have a more insidious problem. + + +

Unfortunately, we now have a more insidious problem. Our code works fine with our test data, but what will happen when we load a record from a real database and the middle name is missing?

+

We could uncover the bug by adding more tests - and indeed, we absolutely should - but wouldn’t it be great if the compiler could help us fix it right now?

+

Let’s enable the Nullable Reference Types feature. To do this, we have to add two lines to our project file: one to specify that we’re using C# 8 and one to turn on the feature.

-
<LangVersion>8.0</LangVersion>
-<NullableContextOptions>enable</NullableContextOptions>
-

Just to see that in context, here is our modified nullable-sample.csproj file:

-
<Project Sdk="Microsoft.NET.Sdk">
-
-  <PropertyGroup>
-    <OutputType>Exe</OutputType>
-    <TargetFramework>netcoreapp3.0</TargetFramework>
-    <RootNamespace>nullable_sample</RootNamespace>
-    <LangVersion>8.0</LangVersion>
-    <NullableContextOptions>enable</NullableContextOptions>
-  </PropertyGroup>
-
-</Project>
-

With the feature enabled, let’s try to compile our code again. Here is the output of dotnet build:

-
Build succeeded.
-
-Program.cs(23,23): warning CS8618: Non-nullable property 'FirstName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj]
-Program.cs(24,23): warning CS8618: Non-nullable property 'MiddleName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj]
-Program.cs(25,23): warning CS8618: Non-nullable property 'LastName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj]
+
+
<LangVersion>8.0</LangVersion>
+<NullableContextOptions>enable</NullableContextOptions>
+
+ +

Just to see that in context, here is our modified nullable-sample.csproj file:

+ +
<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp3.0</TargetFramework>
+    <RootNamespace>nullable_sample</RootNamespace>
+    <LangVersion>8.0</LangVersion>
+    <NullableContextOptions>enable</NullableContextOptions>
+  </PropertyGroup>
+
+</Project>
+
+ +

With the feature enabled, let’s try to compile our code again. Here is the output of dotnet build:

+ +
Build succeeded.
+
+Program.cs(23,23): warning CS8618: Non-nullable property 'FirstName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj]
+Program.cs(24,23): warning CS8618: Non-nullable property 'MiddleName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj]
+Program.cs(25,23): warning CS8618: Non-nullable property 'LastName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj]
     3 Warning(s)
     0 Error(s)
-

The build succeeded, just as before, but now we have some warnings. Progress!

+ + +

The build succeeded, just as before, but now we have some warnings. Progress!

+

The compiler is telling us two things:

+
  • The properties of our Person class are all considered “non-nullable”
  • Given that they’re non-nullable, they should be initialized
+

Wait a minute. All three properties of Person are strings. Strings are nullable, right?

+

Yes, it is just as possible as ever to assign null to a string. The warnings we received are speaking about our intent. When the Nullable Reference Types feature is enabled, the compiler considers reference types to be non-nullable by default, just like value types. If you want a property to be nullable, you have to declare it that way.

+

Let’s say that our application requires each person to have a first and last name but makes the middle name optional. This means that FirstName and LastName should be initialized to ensure they always have a value. The empty string would be a sensible default.

-
public class Person
+
+
public class Person
 {
-    public string FirstName { get; set; } = string.Empty;
-    public string MiddleName { get; set; }
-    public string LastName { get; set; } = string.Empty;
+    public string FirstName { get; set; } = string.Empty;
+    public string MiddleName { get; set; }
+    public string LastName { get; set; } = string.Empty;
 }
-

dotnet build now generates only one warning:

-
Build succeeded.
+
+ +

dotnet build now generates only one warning:

-Program.cs(24,23): warning CS8618: Non-nullable property 'MiddleName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj] +
Build succeeded.
+
+Program.cs(24,23): warning CS8618: Non-nullable property 'MiddleName' is uninitialized. [/home/ed/source/nullable-sample/nullable-sample.csproj]
     1 Warning(s)
     0 Error(s)
-

Because MiddleName is optional in our application, instead of initializing it, we’ll mark it as nullable. + + +

Because MiddleName is optional in our application, instead of initializing it, we’ll mark it as nullable. We do this by appending a question mark to the type, which is the same syntax we used earlier to make a value type nullable.

-
public string? MiddleName { get; set; }
-

Now we have a more expressive domain model. + +

public string? MiddleName { get; set; }
+
+ +

Now we have a more expressive domain model. FirstName and LastName are required, so we initialize them. MiddleName is optional, so we mark it as nullable. The code looks better already.

+

Let’s see how it compiles.

-
Build succeeded.
+
+
Build succeeded.
 
 Program.cs(13,17): warning CS8602: Dereference of a possibly null reference. [/home/ed/source/nullable-sample/nullable-sample.csproj]
     1 Warning(s)
     0 Error(s)
-

Now we have a new warning. + + +

Now we have a new warning. “Dereference of a possibly null reference” means that we are accessing a member of an object that might be null, and we haven’t responsibly checked to make sure it isn’t null. Evidently, the culprit is on line 13.

-
Person p = PersonStore.GetFirstPerson();
 
-int letterCount =
+
Person p = PersonStore.GetFirstPerson();
+
+int letterCount =
     p.FirstName.Length +
     p.MiddleName.Length +
     p.LastName.Length;
-

Line 13 contains p.MiddleName.Length. + + +

Line 13 contains p.MiddleName.Length. This was the line that generated the NullReferenceException earlier, but now we’re getting a helpful warning about it. Because we marked MiddleName as nullable, we have to check to make sure it isn’t null before accessing any of its members, in this case its Length property.

+

Let’s add a null check (which we really should have done from the very beginning, had we not been in such a hurry).

-
int letterCount =
+
+
int letterCount =
     p.FirstName.Length +
-    (p.MiddleName?.Length ?? 0) +
+    (p.MiddleName?.Length ?? 0) +
     p.LastName.Length;
-

Now our code builds without warnings:

-
Build succeeded.
+
+ +

Now our code builds without warnings:

+ +
Build succeeded.
     0 Warning(s)
     0 Error(s)
-

The warning went away because the compiler is capable of analyzing the control flow of a program and determining where null values may occur. + + +

The warning went away because the compiler is capable of analyzing the control flow of a program and determining where null values may occur. By checking to make sure that p.MiddleName was non-null before accessing its Length property, we soothed the compiler’s fears.

+

Our program runs successfully:

-
Hello, Pat
+
+
Hello, Pat
 You have 10 letters in your full name
-

But is the bug really fixed? + + +

But is the bug really fixed? Recall that earlier, we added a middle name to our test person in order to prevent a NullReferenceException. Let’s remove that test middle name and find out if our code has actually improved.

-
public static Person GetFirstPerson()
-    => new Person { FirstName = "Pat", LastName = "McTest" };
-

The moment of truth. dotnet run:

-
Hello, Pat
+
+
public static Person GetFirstPerson()
+    => new Person { FirstName = "Pat", LastName = "McTest" };
+
+ +

The moment of truth. dotnet run:

+ +
Hello, Pat
 You have 9 letters in your full name
-

Success! + + +

Success! Even with a null value in our test data, our program ran safely.

+

Note that we converted our buggy code to null-safe code simply by following the indications provided to us by the compiler. This is the real value of the Nullable Reference Types feature: it helps you write safer and more expressive code.

+
Recap
+

You can try out C# 8 with Nullable Reference Types right now. However, keep in mind that .NET Core 3 still in preview as of the time of writing, so you might not want to use it for production code until the first stable release.

+

First, download the latest preview release of .NET Core 3.

+

Second, specify .NET Core 3, C# 8, and the “nullable context options” properties in your .csproj file:

-
<TargetFramework>netcoreapp3.0</TargetFramework>
-<LangVersion>8.0</LangVersion>
-<NullableContextOptions>enable</NullableContextOptions>
-

Third, explicitly indicate that a reference type should be allowed to carry null values by appending a question mark to the type:

-
public string? MiddleName { get; set; }
-

And finally, pay attention to the warnings you get from dotnet build and use them as a guide to improving your code.

+ +
<TargetFramework>netcoreapp3.0</TargetFramework>
+<LangVersion>8.0</LangVersion>
+<NullableContextOptions>enable</NullableContextOptions>
+
+ +

Third, explicitly indicate that a reference type should be allowed to carry null values by appending a question mark to the type:

+ +
public string? MiddleName { get; set; }
+
+ +

And finally, pay attention to the warnings you get from dotnet build and use them as a guide to improving your code.

+

If you’d like to see the full example app we walked through in this post, it’s available on GitHub.

+
Going further
+

By design, the Nullable Reference Types feature generates warnings, not errors. This is so that you can start fixing problems in existing code without spilling noisy red ink all over the place.

+

If you do want actual errors that fail the build, you can choose to treat all warnings as errors. This is an existing feature in current versions of .NET (not just in .NET Core 3), and it can be enabled by adding one more property to a PropertyGroup in your .csproj file:

-
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
-

We covered the basics of Nullable Reference Types in this post, but there is even more to the feature. + +

<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
+
+ +

We covered the basics of Nullable Reference Types in this post, but there is even more to the feature. If you’d like to dig deeper, check out these articles:

+
  • Introducing Nullable Reference Types in C# by Mads Torgerson
  • Microsoft’s official guide to Nullable Reference Types
  • diff --git a/public/blog/page/2/index.html b/public/blog/page/2/index.html index 8388f03..bc5e623 100644 --- a/public/blog/page/2/index.html +++ b/public/blog/page/2/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -310,8 +310,7 @@

    Equip Your Teams with Agile We’re passionate about equipping your teams with the cutting-edge Lean Agile Certification training they need! -This summer we hosted an Agile Advanced Scrum Master Certification course in down-town Grand Rapids. We had a blast hosting and teaching participants from Gordon Food Service, Meijer, Spectrum Health, and more. Most beneficially, great discussions formed across the varying industries which created a learning environment filled with collaboration. -During the two day certification course we covered such things as:

    +This summer we hosted an Agile Advanced Scrum Master Certification course in down-town Grand Rapids. We had a blast hosting and teaching participants from Gordon Food Service, Meijer, Spectrum Health, and more. Most beneficially, great discussions formed across the varying industries which created a learning environment filled with collaboration.

    Read more diff --git a/public/blog/page/3/index.html b/public/blog/page/3/index.html index 1ddbf78..d0a52fd 100644 --- a/public/blog/page/3/index.html +++ b/public/blog/page/3/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -180,8 +180,7 @@

-

At Bravo LT, we believe STEM (Science, Technology, Engineering, Math) education is key to strengthening the future for the next generation. As a technology and e-Learning company in West Michigan, we love introducing the next generation of children to technology. Last month we hosted our third-annual Raspberry Pi Youth Camp which gave local students (ages 10-14) an opportunity to explore computer programming in a fun and engaging way. - We hosted this free event at Davenport University in Grand Rapids.

+

At Bravo LT, we believe STEM (Science, Technology, Engineering, Math) education is key to strengthening the future for the next generation. As a technology and e-Learning company in West Michigan, we love introducing the next generation of children to technology. Last month we hosted our third-annual Raspberry Pi Youth Camp which gave local students (ages 10-14) an opportunity to explore computer programming in a fun and engaging way.

Read more diff --git a/public/blog/page/4/index.html b/public/blog/page/4/index.html index faa5c00..0a15df7 100644 --- a/public/blog/page/4/index.html +++ b/public/blog/page/4/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -308,7 +308,8 @@

Bravo Open Source Symposium October 26, November 2, 9, and 16 5:00 - 7:00 PM Event Description: BOSS 2015 explores specific open source topics, to include: - Data Grids: To Infinispan and Beyond (Day 1) Introduction to Docker (Day 2) Maven for Power Users (Day 3) Introduction to Clojure (Day 4) This free four-day symposium, held on alternating Mondays in September and October, features highly interactive training sessions to include the following delivery methods: traditional lecture and demonstration, video, case studies, hands-on activities and group discussion.

+ Data Grids: To Infinispan and Beyond (Day 1) Introduction to Docker (Day 2) Maven for Power Users (Day 3) Introduction to Clojure (Day 4) +This free four-day symposium, held on alternating Mondays in September and October, features highly interactive training sessions to include the following delivery methods: traditional lecture and demonstration, video, case studies, hands-on activities and group discussion.

Read more diff --git a/public/blog/pistons-vs-cavs/index.html b/public/blog/pistons-vs-cavs/index.html index c28daf3..36166fd 100644 --- a/public/blog/pistons-vs-cavs/index.html +++ b/public/blog/pistons-vs-cavs/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,8 +149,12 @@

Pistons vs Cavs

-
Friday Night Road Trip!
+ + +
Friday Night Road Trip!
+

A few of us from #TeamBravo headed south on Friday night, to the Breslin Center at MSU, to see the Pistons and Cavs face off! Since they’ve both lived in Ohio, Ben and Matthew are die-hard Cleveland fans. Ed and Tom cheered for the Pistons which made for a night of light-hearted rivalry between our cheering section of four.

+

Not only do all of us enjoy working together as a collaborative and united team – we have a heck of a lot of fun outside the office. We make a point to plan lively activities for the team on the regular. This summer about 20 of us from #TeamBravo took in a White Caps game with our spouses and friends. This fall and winter we’re looking forward to 80’s Night, our office Christmas party, and any impromptu fun that pops up between now and then.

diff --git a/public/blog/raspberry-pi-computer-programming-camp-is-back-2018/index.html b/public/blog/raspberry-pi-computer-programming-camp-is-back-2018/index.html index f685c61..295a346 100644 --- a/public/blog/raspberry-pi-computer-programming-camp-is-back-2018/index.html +++ b/public/blog/raspberry-pi-computer-programming-camp-is-back-2018/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -150,9 +150,13 @@

Raspberry Pi Youth Computer Programming Camp is Back!

At Bravo LT, we believe STEM education is key to strengthening West Michigan from the inside out. We’re excited to host another session of Raspberry Pi Youth Camp, this fall, which will give local students (ages 12-15) an opportunity to explore computer programming in a fun and engaging way.

+

The free event will be held on September 11 & 12, 2018 at Calvin College in Grand Rapids from 5pm – 8pm. The event is powered by our developers, who generously volunteer their time to lead camp. This session of camp will focus in on the Python programming language. Youth participants will explore exciting, hands-on projects and Raspberry Pi devices — inexpensive credit card-sized computers that plug into TVs or monitors and use keyboards and mice — to learn programming.

+

Registration filled up quickly for camp. Reach out to us if you’d like your son or daughter put on the wait-list.

-

If you’re a company, family, or individual who believes in inspiring students within STEM fields and bridging the gender and diversity gap in the tech sector — we invite you to support Pi Camp by becoming a Champion of Technology for Children, today! Email info@bravolt.com to learn about how you can support students with your donation to camp.

+ +

If you’re a company, family, or individual who believes in inspiring students within STEM fields and bridging the gender and diversity gap in the tech sector — we invite you to support Pi Camp by becoming a Champion of Technology for Children, today! Email info@bravolt.com to learn about how you can support students with your donation to camp.

+

Be sure to check out all the fun we had at our summer session of camp: ![Raspberry Pi Youth Computer Camp, Youth Computer Programming Camp Grand Rapids]

diff --git a/public/blog/raspberry-pi-computer-programming-this-august-2019/index.html b/public/blog/raspberry-pi-computer-programming-this-august-2019/index.html index cd0ea19..4320483 100644 --- a/public/blog/raspberry-pi-computer-programming-this-august-2019/index.html +++ b/public/blog/raspberry-pi-computer-programming-this-august-2019/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -150,9 +150,13 @@

Youth Pi Camp this August

At Bravo LT, we believe STEM education is key to strengthening West Michigan from the inside out. We’re excited to host another session of Raspberry Pi Youth Camp, this summer, which will give local students (ages 12-15) an opportunity to explore computer programming in a fun and engaging way.

+

The free event will be held on August 12 & 13, 2019 at the Bravo office in Grand Rapids from 5:30pm – 8pm. The event is powered by our developers, who generously volunteer their time to lead camp. This session of camp will focus on the Python programming language. Youth participants will explore exciting, hands-on projects and Raspberry Pi devices — inexpensive credit card-sized computers that plug into TVs or monitors and use keyboards and mice — to learn programming.

+

Registration filled up quickly for camp but we have a few spots left: Register Here

-

If you’re a company, family, or individual who believes in inspiring students within STEM fields and bridging the gender and diversity gap in the tech sector — we invite you to support Pi Camp by becoming a Champion of Technology for Children, today! Email info@bravolt.com to learn about how you can support students with your donation to camp.

+ +

If you’re a company, family, or individual who believes in inspiring students within STEM fields and bridging the gender and diversity gap in the tech sector — we invite you to support Pi Camp by becoming a Champion of Technology for Children, today! Email info@bravolt.com to learn about how you can support students with your donation to camp.

+

Be sure to check out all the fun we have at camp: Raspberry Pi Youth Computer Camp

diff --git a/public/blog/responsive-e-learning-one-size-does-not-fit-all/index.html b/public/blog/responsive-e-learning-one-size-does-not-fit-all/index.html index 692a892..f27236c 100644 --- a/public/blog/responsive-e-learning-one-size-does-not-fit-all/index.html +++ b/public/blog/responsive-e-learning-one-size-does-not-fit-all/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -150,11 +150,16 @@

Responsive e-Learning - One Size Does Not Fit All

e-Learning modules have traditionally been static—stiff, heavy courses that are not quite optimized for modern-day mobile devices. Designed in a constrained aspect ratio, these modules can technically fit on any size screen, but they are certainly not optimized to fit well—and that’s hardly the best option when you need to train employees on the go, or simply need to train them on a device other than a desktop computer or laptop.

+

Today, mobile is king. People across the globe heavily rely on their smartphones and tablets for everything—communicating with friends and family, reading the news, playing games, and, of course, learning! That’s where responsive training comes in.

+

Inspired by responsive web design, which targets design and development to a user’s behavior and device, responsive mobile learning (m-learning) consists of modules that are designed to “respond” to the individual devices they are being viewed on. So, how does that work? By using mobile-friendly e-learning authoring tools (we love Adapt!), our instructional designers here at Bravo LT can create modules that detect the kind of device they’re being viewed on and automatically reorganize themselves to perfectly fit on the screens of mobile devices. Plus, these courses use HTML5 instead of Flash, allowing for greater accessibility across devices—without sacrificing interactivity.

+

If that’s not impressive enough, these responsive modules also have cleaner navigation, larger font sizes, smaller file sizes, and more intuitive layouts, making on-the-go training easier than ever!

+

And like all of the training materials we create, our responsive modules, designed by our professional instructional designers and e-learning developers, are meticulously crafted to be engaging, memorable learning events catered to specific employee demographics. We always collaborate with subject matter experts (SMEs), managers, and other stakeholders to ensure training meets organizational goals and effectively transforms employees from the inside out.

-

Want to find out how responsive m-learning can improve your training program? Send us a message at info@bravolt.com. We’re ready to partner with you!

+ +

Want to find out how responsive m-learning can improve your training program? Send us a message at info@bravolt.com. We’re ready to partner with you!

diff --git a/public/blog/songs-of-the-product-owner/index.html b/public/blog/songs-of-the-product-owner/index.html index a0cf3f4..f08c4cc 100644 --- a/public/blog/songs-of-the-product-owner/index.html +++ b/public/blog/songs-of-the-product-owner/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,17 +149,27 @@

Songs of the Product Owner

-

Congrats! You just became a Product Owner. Your knowledge of the industry and the product in development caused the powers that be to put you in charge. Crafting this valuable product is similar to producing a hit song. You want to put out something that is loved by the audience and profitable for the company. You have control over the lyrics, the accompanying music, all the way down to the cover art. As a new Product Owner, you must be wondering, how do I start building the hook, avoid misunderstood lyrics, and deliver a platinum product?

+ + +

Congrats! You just became a Product Owner. Your knowledge of the industry and the product in development caused the powers that be to put you in charge. Crafting this valuable product is similar to producing a hit song. You want to put out something that is loved by the audience and profitable for the company. You have control over the lyrics, the accompanying music, all the way down to the cover art. As a new Product Owner, you must be wondering, how do I start building the hook, avoid misunderstood lyrics, and deliver a platinum product?

+

I Left my Brains Down in Africa

+

Without research into your market, what other competitors are doing, or thinking about the makeup of your key customers, even the best product will fail. Your hit song will fall on deaf ears. Through thoughtful research you can identify opportunities and insights that can help the team compose a hit feature. This goes beyond just asking a customer what they want and might involve prototyping or testing new features against a sample group. Continually researching throughout the life of the product helps prioritize your features and ideas and aids your team’s continuous improvement of the product. Combining your brains and research will ensure your product starts off on the right foot and continues to deliver value.

+

Hold me Closer, Tony Danza

+

All of the research and interactions with the product will lead to a backlog of work that your team will tackle. Composing a song might take a guitar riff and a small lyric written on a napkin, and by collaborating with your bandmates, that input is transformed into a fully formed song. A valuable product takes the same teamwork. You give your team the vision of what they are building and why they are building it. You give them the key elements of the song and help them understand why they are important. You work closely with them to provide clarification about questions the team might have about an element of the product. If a member of your band needs to know what something is supposed to sound like, it is up to you to clarify it. Clarifying saves time and energy and keeps the product moving forward.

-

Don’t go, Jason Waterfalls

+ +

Don’t go, Jason Waterfalls

+

A song or product develops and changes over time. Releasing a sample of the song or a small feature update to your product keeps the customer engaged and providing feedback. Reacting to this feedback in a timely manner means you need to construct stories for your team to work on that still produce value for the product but are small enough to be delivered in your defined iterations. If you create stories that are too large or all have the same importance, it will be hard for your team to deliver and you will slip into the waterfall versus your desired agile delivery method. Stories will move from iteration to iteration and product delivery and the feedback loop will suffer. Of course there are examples of songs and products that are a hit from the day of release, but a more surefire way to create is through incremental release and feedback. Instead of going over the waterfall, stick to the calmer rivers and lakes of agile. Good Product Owners have a lot of things to manage and consider to ensure their lyrics are both heard and understood. Make sure that you are not only considering product improvements but how you can improve your own skill set. Take classes, read, and converse with other Product Owners. Good luck in your new role, and now if you will excuse me, I’ve got two chickens to paralyze.

+
Interested in becoming a product owner?
+

Bravo LT is hosting a Certified Srum Product Owner Training on November 21 - 22, 2019. - Find more information here.

+
Find more information here.

diff --git a/public/blog/we-moved-downtown-grand-rapids/index.html b/public/blog/we-moved-downtown-grand-rapids/index.html index 49ad216..0af6d47 100644 --- a/public/blog/we-moved-downtown-grand-rapids/index.html +++ b/public/blog/we-moved-downtown-grand-rapids/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,13 +149,22 @@

We Moved Downtown Grand Rapids

-
Our New Location#####
+ + +
Our New Location
+

Bravo has officially moved downtown Grand Rapids! Last month we said goodbye to our Cascade Parkway location and (after a few construction projects and a bit of cosmetic work in the new space) hello to Monroe Center. Our official signage is in the works, but in the meantime, we are the dark gray building located at the corner of Division and Monroe Center. More specifically:

+

Bravo LT, 40 Monroe Center NW, Suite 11, Grand Rapids, MI 49503

+

We are thrilled to be downtown, closer to clients and Bravo LT teammates. We love when our team stops by to grab coffee or stays on site to collaborate on projects. It’s also been a bonus to have such great restaurants and coffee shops nearby. If you see anyone with Bravo LT swag out and about at Littlebird, Brick and Porter, Madcap, or The Paper Studio please say hello! We’re pumped our frequent visits support local businesses.

+

The biggest reason for moving downtown was to be immersed within the community. As a software development company, we’re always looking for ways to inspire and give back to the next generation of developers. Just last week we had the opportunity to tour Innovation Central and begin brainstorming ways our developers may be able to offer exploratory Raspberry Pi workshops to Innovation students.

+

If you find yourself walking down Monroe Center, please stop in for coffee or La Croix, to grab some Bravo LT swag, or to simply say hello. We’re thankful to our West Michigan clients, and beyond, for supporting Bravo LT throughout the years; we look forward to continued growth and serving you and your businesses in the future.

+

/////

+

What are some ways you support your local community? Take our #GoLocalMI challenge and show us your favorite West Michigan people, places, and businesses on Twitter or Instagram!

diff --git a/public/blog/what-is-rest/index.html b/public/blog/what-is-rest/index.html index 1032feb..2367a11 100644 --- a/public/blog/what-is-rest/index.html +++ b/public/blog/what-is-rest/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -149,41 +149,70 @@

What is REST?

-
What is REST?
+ + +
What is REST?
+

Representational State Transfer (REST) is a very popular term in web development today. REST is used to describe many things, kind of like “API”, and because of that I was very confused by the acronym. The goal of this post is to provide a high-level description of REST in hopes that you will navigate away with a better understanding of the architectural style.

-
What is RESTful?
-

If you have worked on web software, chances are you have been a part of a design discussion where somebody declared, “______ would be more RESTful”. *What does that mean?*

+ +
What is RESTful?
+ +

If you have worked on web software, chances are you have been a part of a design discussion where somebody declared, “______ would be more RESTful”. What does that mean?

+

It is important to note that REST is a specification not an implementation. In other words, REST defines the requirements for a system but does not define how you should write your code in order to meet those requirements. For example, to say that plural paths (/users) are more RESTful than singular paths (/user) is not necessarily true. Instead, it is more correct to say: it is RESTful to choose either plural or singular paths to use across the whole system in order to provide a consistent API. REST does not care what naming convention is used as long as the convention is consistent across all interfaces. This is defined by the Uniform Interface constraint.

+

Constraints are what define the requirements for REST. Once you understand the constraints you can confidently declare what is and is not RESTful.

-
Constraints
+ +
Constraints
+

There are six architectural constraints that define REST. Their original definition can be found in Roy Fielding’s dissertation, section 5.1 Deriving REST, and I will summarize them here.

-
Client-Server
+ +
Client-Server
+

The client-server constraint involves separating client concerns from server concerns. Let us simplify an application into two parts: user interface and business logic. Business logic stays the same whether a consumer is using an Apple or an Android phone, but the user interface code can be different. A client-server system separates business logic from the user interface so that server code can be written once and service a variety of clients.

-

Client Server

-
Stateless
+ +

Client Server

+ +
Stateless
+

The stateless constraint can be described as, “stateful client, stateless server” where statelessness is preserved on the server. An example of state is a user’s session. A common way to implement authentication in a web application is to utilize a session, which can look something like this:

+
  • User logs in with a username and password. This sends a request from the client to the server with the credentials.
  • If successful, the server creates a session and responds to the client with a session ID. The session is managed by the server.
  • While the user is logged in, every request must include the session ID. With each request, the server checks the session ID to authenticate the request.
+

This approach is not RESTful because it requires the server to keep track of sessions for each client. It also violates the stateless constraint because each request does not include all of the information needed in order to determine the full nature of the request. A more RESTful approach would look like:

+
  • User logs in with a username and password. This sends a request from the client to the server with the credentials.
  • If successful, the client saves the username and password. Every request going forward includes the username and password.
  • For each request, the server verifies the username and password. No session is managed by the server.
+

There are trade-offs to each approach. A stateful server can be more efficient, a stateless server can be more scalable. Do what makes the most sense for your business case, but know that REST specifically calls for stateless server.

-

Stateless

-
Cache
+ +

Stateless

+ +
Cache
+

Web applications are bound to networks by nature. A consequence of network communication is that it takes time to transfer information through a wire. In order to provide an efficient system, it is important to utilize mechanisms that optimize the amount of information that must be transferred. One optimization strategy is caching, the third constraint of REST.

+

Caching involves storing server data on the client. This enables a client to avoid repetitive requests to the server to retrieve the same data. When implementing a cache, it is important to understand when cached data should expire. Caching is great for increasing performance, but has the consequence of providing out-of-date information if not managed correctly. Seek to implement caches where data rarely changes or where there is a reliable way to refresh the cache when data does change.

+

According to REST, caching should always be done client-side. Note: a server can be both a server and a client!

-

Cache

-
Uniform Interface
+ +

Cache

+ +
Uniform Interface
+

The uniform interface constraint focuses on the manner in which a system communicates itself to other systems or clients. This focuses on the API layer and is described through four sub-constraints.

-
Identification of Resources
+ +
Identification of Resources
+

Identification of resources deals with how the functionality of an API is described. For an example, let us look at an application that allows creating and managing users. The following functions are available:

+
  • Get all users
  • Add a new user
  • @@ -192,28 +221,50 @@
    Identification of Resources
  • Update a user’s birthday
  • Delete a user
- - + +


+Let us examine two potential HTTP API designs: +

+ +

Function

+

Design A represents what is commonly found in SOAP or other non-REST architectures. Design B is typically preferred in a RESTful design because it identifies operations in a more uniform and predictable manner.

-
Manipulation of Resources Through Representations
+ +
Manipulation of Resources Through Representations
+

A “representation” can be thought of as a JSON structure. To continue the user example from above, the request to GET /users/{id} might return a response of:

+
{
   “id”: 1,
   “name”: “Joseph”
   “bday”: “1992/09/25”
 }
-

This is the user representation. The manipulation of resources through representations constraint defines that an interface should use consistent structures when referring to the same entity. So when a user is being created, updated, retrieved, or referenced; its structure remains the same.

-
Self-Descriptive Messages
+ + +

This is the user representation. The manipulation of resources through representations constraint defines that an interface should use consistent structures when referring to the same entity. So when a user is being created, updated, retrieved, or referenced; its structure remains the same.

+ +
Self-Descriptive Messages
+

The self-descriptive messages constraint requires requests and responses to define all of the information needed to understand the purpose of the request/response. In HTTP, this includes the use of headers, status codes, and HTTP methods (GET, PUT, POST, etc).

+

A redirect response is a good example of this constraint. Let us pretend that a client is requesting a user’s profile picture, but the location of the picture has moved. The proper service response would include a 302 HTTP status code (Object Moved) with a Location header that points to the new location of the picture. Browsers are programmed to automatically handle this interaction so that a user sees no difference. If a server is improperly programmed and the Location header is missing, the response will not include all of the required information and the user will be left with an incomplete view.

-
Hypermedia as the Engine of Application State (HATEOAS)
+ +
Hypermedia as the Engine of Application State (HATEOAS)
+

HATEOAS sounds complicated, but really what it means is that links (URLs) should be provided by a server to direct clients through available functionality. A way to illustrate this is to think of a homepage. Let us use StackOverflow.com as an example. When a client requests the StackOverflow homepage, there are many routes the user can navigate from there: top posts, profile page, hot questions, etc. It is the server’s job to provide URLs to navigate to each of those available functions. The idea being, the only URL a client should need to know is the root/home page. From there, the client can navigate through the links provided in the server’s response. Another example to think about is a website that mimics a book. If the browser requests page 50 from the server, the server should respond with page 50 and also include links to the previous and next page. This allows the client to navigate throughout the book.

-
Layered System
+ +
Layered System
+

A layered system architecture is a common best practice found across most software systems. This style is found internal to code bases as well as external across an entire system. Internally this is observed as separating code into controller, service, and database files. Externally this is observed as maintaining business logic on proprietary systems and delegating to 3rd parties for responsibilities like payment processing, for example. Service-oriented architectures fit nicely into this constraint as they require system components to be isolated by responsibility, creating layers between services.

- -
Code-On-Demand
+ +

Function

+ +
Code-On-Demand
+

The code-on-demand constraint opens the door for servers to provide packaged code to clients for client convenience. This is useful when a system expects all clients to require similar behavior. If a reservation system is used as an example, it could be expected that many clients will require a date picker in order to select a time period for reservations. Code-on-demand defines that it would be RESTful for that reservation system to provide a pre-built JavaScript widget for selecting dates.

-
Summary
+ +
Summary
+

Client-server, stateless, cache, uniform interface, layered system, and code-on-demand are the core principles that define REST. Hopefully this article provides some insight into the meaning of this popular acronym. If you are interested in diving deeper into the source of the REST architectural style, its origin can be found in Architectural Styles and the Design of Network-based Software Architectures by Roy Fielding.

diff --git a/public/blog/why-bravo-cares/index.html b/public/blog/why-bravo-cares/index.html index eaf2d7e..17f3bdb 100644 --- a/public/blog/why-bravo-cares/index.html +++ b/public/blog/why-bravo-cares/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -150,13 +150,20 @@

Giving Back - Why Bravo Cares

When I first interviewed for my position at Bravo LT a little more than a year ago, my interviewer—Bravo LT president Ed—asked me what some of my hobbies were. “Well, I really like listening to music…I like drawing…oh, and I volunteer at the local animal shelter,” I responded. Ed briefly commended me on my volunteering efforts—a nicety, I assumed—and the conversation moved right along.

+

Fast forward to a few days later when I received an email from Ed telling me I was a good fit for the gig—cool! And part of the reason I was a great fit, he said, was because of my devotion to animal rescue—wow, really? I guess I hadn’t realized during my interview how important that effort was to Bravo LT. Learning this, I knew right then that Bravo was exactly the kind of company I wanted to be a part of.

+

Since my hiring, I’ve learned that Bravo LT has a long history of being deeply involved in the West Michigan community, from offering free educational talks to the public to hosting STEM summer camps for kids, these functions have long been a part of our commitment to donating our time and resources to causes we believe in.

+

However, I noticed there wasn’t a formal name for all of this philanthropic work that we did. That was when my colleague, Ben, and I had an a-ha moment: What if we created an actual program for our charitable endeavors? And why couldn’t we kick it up a notch? So that’s exactly what we did!

+

We launched our Care initiative in the summer of 2016, and since then, I’m pretty proud to say we’ve done a whole lot of good—from sponsoring the Spectrum Health Foundation’s Gala 2016 to holding a supplies drive for the local animal shelter to supporting God’s Kitchen and volunteering at Kids’ Food Basket. We’ve also hosted several educational talks and held another summer camp for kids. How’s that for kicking it up a notch?

+

Thinking back to the day I accepted this job, I remember how excited I was to find out that Bravo LT’s community commitment aligned so closely with my own passion for volunteering. And now that we’ve launched our Care initiative, I’m even more excited—excited to see the program grow, and excited to find new ways we can give back to our amazing community!

-
-

Do you know of a great non-profit that could use a little help? Send your ideas to info@bravolt.com —we’d love to hear them!

+ +
+ +

Do you know of a great non-profit that could use a little help? Send your ideas to info@bravolt.com —we’d love to hear them!

diff --git a/public/care/index.html b/public/care/index.html index a3167ca..e6352bb 100644 --- a/public/care/index.html +++ b/public/care/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/care/index.xml b/public/care/index.xml index 1f2a3bd..048b18b 100644 --- a/public/care/index.xml +++ b/public/care/index.xml @@ -1,4 +1,4 @@ - + We Care on Bravo LT | Learning & Technology diff --git a/public/careers/index.html b/public/careers/index.html index 8443763..8dddc3a 100644 --- a/public/careers/index.html +++ b/public/careers/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology @@ -180,6 +180,8 @@

Open Positions

  • Software Engineer - IoT
  • +
  • System Analyst
  • +
  • Scrum Master
  • Agile Business Analyst - Team Lead
  • diff --git a/public/careers/index.xml b/public/careers/index.xml index f3fe835..97f239a 100644 --- a/public/careers/index.xml +++ b/public/careers/index.xml @@ -1,4 +1,4 @@ - + Careers on Bravo LT | Learning & Technology diff --git a/public/categories/index.html b/public/categories/index.html index 1b84ddb..9167fdd 100644 --- a/public/categories/index.html +++ b/public/categories/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/categories/index.xml b/public/categories/index.xml index e067930..84e5be1 100644 --- a/public/categories/index.xml +++ b/public/categories/index.xml @@ -1,4 +1,4 @@ - + Categories on Bravo LT | Learning & Technology diff --git a/public/contact/index.html b/public/contact/index.html index cc5e0af..577ef0b 100644 --- a/public/contact/index.html +++ b/public/contact/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/contact/index.xml b/public/contact/index.xml index faed22d..a13e9b5 100644 --- a/public/contact/index.xml +++ b/public/contact/index.xml @@ -1,4 +1,4 @@ - + Contact Us on Bravo LT | Learning & Technology diff --git a/public/csm/index.html b/public/csm/index.html index 1e101f1..325e8ae 100644 --- a/public/csm/index.html +++ b/public/csm/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/csm/index.xml b/public/csm/index.xml index d985fd8..e60311c 100644 --- a/public/csm/index.xml +++ b/public/csm/index.xml @@ -1,4 +1,4 @@ - + Certified Scrum Master Training on Bravo LT | Learning & Technology diff --git a/public/cspo/index.html b/public/cspo/index.html index 21481fb..61ea76e 100644 --- a/public/cspo/index.html +++ b/public/cspo/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/cspo/index.xml b/public/cspo/index.xml index f6382de..a3904a2 100644 --- a/public/cspo/index.xml +++ b/public/cspo/index.xml @@ -1,4 +1,4 @@ - + Certified Scrum Product Owner (CSPO®) Training on Bravo LT | Learning & Technology diff --git a/public/images/jobdescriptions/21-system-analyst.pdf b/public/images/jobdescriptions/21-system-analyst.pdf new file mode 100644 index 0000000..2bf9483 Binary files /dev/null and b/public/images/jobdescriptions/21-system-analyst.pdf differ diff --git a/public/index.html b/public/index.html index b8ae5f7..7e80d7b 100644 --- a/public/index.html +++ b/public/index.html @@ -7,7 +7,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/index.xml b/public/index.xml index 5e50299..7356471 100644 --- a/public/index.xml +++ b/public/index.xml @@ -1,4 +1,4 @@ - + Bravo LT | Learning & Technology @@ -6,7 +6,7 @@ Recent content on Bravo LT | Learning & Technology Hugo -- gohugo.io en-us - Mon, 27 Jan 2020 12:37:52 +0600 + Thu, 07 Nov 2019 12:11:29 +0600 @@ -26,7 +26,7 @@ Fri, 12 Jul 2019 12:11:29 +0600 //www.bravolt.com/blog/bravos-ribbon-cutting-open-house/ - Save the Date##### You&rsquo;re invited to Bravo LT&rsquo;s Ribbon Cutting &amp; Open House Thursday, August 15th, 3pm - 5pm + Save the Date You&rsquo;re invited to Bravo LT&rsquo;s Ribbon Cutting &amp; Open House Thursday, August 15th, 3pm - 5pm Join us as we celebrate our recent move downtown. Ribbon Cutting at 4pm. We can&rsquo;t wait to meet our neighbors and catch up with clients and friends! Snacks and drinks provided. @@ -49,7 +49,7 @@ The free event will be held on August 12 &amp; 13, 2019 at the Bravo office Wed, 29 May 2019 12:11:29 +0600 //www.bravolt.com/blog/we-moved-downtown-grand-rapids/ - Our New Location##### Bravo has officially moved downtown Grand Rapids! Last month we said goodbye to our Cascade Parkway location and (after a few construction projects and a bit of cosmetic work in the new space) hello to Monroe Center. Our official signage is in the works, but in the meantime, we are the dark gray building located at the corner of Division and Monroe Center. More specifically: + Our New Location Bravo has officially moved downtown Grand Rapids! Last month we said goodbye to our Cascade Parkway location and (after a few construction projects and a bit of cosmetic work in the new space) hello to Monroe Center. Our official signage is in the works, but in the meantime, we are the dark gray building located at the corner of Division and Monroe Center. More specifically: Bravo LT, 40 Monroe Center NW, Suite 11, Grand Rapids, MI 49503 @@ -121,8 +121,7 @@ The free event will be held on September 11 &amp; 12, 2018 at Calvin College //www.bravolt.com/blog/agile-in-grand-rapids/ Equip Your Teams with Agile We&rsquo;re passionate about equipping your teams with the cutting-edge Lean Agile Certification training they need! -This summer we hosted an Agile Advanced Scrum Master Certification course in down-town Grand Rapids. We had a blast hosting and teaching participants from Gordon Food Service, Meijer, Spectrum Health, and more. Most beneficially, great discussions formed across the varying industries which created a learning environment filled with collaboration. -During the two day certification course we covered such things as: +This summer we hosted an Agile Advanced Scrum Master Certification course in down-town Grand Rapids. We had a blast hosting and teaching participants from Gordon Food Service, Meijer, Spectrum Health, and more. Most beneficially, great discussions formed across the varying industries which created a learning environment filled with collaboration. @@ -141,8 +140,7 @@ Google brought a lot to the table through their livestream event. Many were amaz Fri, 22 Sep 2017 12:11:29 +0600 //www.bravolt.com/blog/2017-raspberry-pi-youth-camp-recap/ - At Bravo LT, we believe STEM (Science, Technology, Engineering, Math) education is key to strengthening the future for the next generation. As a technology and e-Learning company in West Michigan, we love introducing the next generation of children to technology. Last month we hosted our third-annual Raspberry Pi Youth Camp which gave local students (ages 10-14) an opportunity to explore computer programming in a fun and engaging way. - We hosted this free event at Davenport University in Grand Rapids. + At Bravo LT, we believe STEM (Science, Technology, Engineering, Math) education is key to strengthening the future for the next generation. As a technology and e-Learning company in West Michigan, we love introducing the next generation of children to technology. Last month we hosted our third-annual Raspberry Pi Youth Camp which gave local students (ages 10-14) an opportunity to explore computer programming in a fun and engaging way. @@ -239,7 +237,8 @@ The free event, held August 9 and 11, 2016 at Davenport University in Grand Rapi //www.bravolt.com/blog/bravo-open-source-symposium/ Bravo Open Source Symposium October 26, November 2, 9, and 16 5:00 - 7:00 PM Event Description: BOSS 2015 explores specific open source topics, to include: - Data Grids: To Infinispan and Beyond (Day 1) Introduction to Docker (Day 2) Maven for Power Users (Day 3) Introduction to Clojure (Day 4) This free four-day symposium, held on alternating Mondays in September and October, features highly interactive training sessions to include the following delivery methods: traditional lecture and demonstration, video, case studies, hands-on activities and group discussion. + Data Grids: To Infinispan and Beyond (Day 1) Introduction to Docker (Day 2) Maven for Power Users (Day 3) Introduction to Clojure (Day 4) +This free four-day symposium, held on alternating Mondays in September and October, features highly interactive training sessions to include the following delivery methods: traditional lecture and demonstration, video, case studies, hands-on activities and group discussion. diff --git a/public/portfolio/index.html b/public/portfolio/index.html index 1084caa..f3e85a8 100644 --- a/public/portfolio/index.html +++ b/public/portfolio/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/portfolio/index.xml b/public/portfolio/index.xml index 5795f64..fa34755 100644 --- a/public/portfolio/index.xml +++ b/public/portfolio/index.xml @@ -1,4 +1,4 @@ - + Portfolio on Bravo LT | Learning & Technology diff --git a/public/rpi/index.html b/public/rpi/index.html index ad338a6..7e69b62 100644 --- a/public/rpi/index.html +++ b/public/rpi/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/rpi/index.xml b/public/rpi/index.xml index b50b64d..9fec0c0 100644 --- a/public/rpi/index.xml +++ b/public/rpi/index.xml @@ -1,4 +1,4 @@ - + Raspberry Pi on Bravo LT | Learning & Technology diff --git a/public/service/index.html b/public/service/index.html index a7e274b..a14d29a 100644 --- a/public/service/index.html +++ b/public/service/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/service/index.xml b/public/service/index.xml index d8a6428..6e1701d 100644 --- a/public/service/index.xml +++ b/public/service/index.xml @@ -1,4 +1,4 @@ - + Our Services on Bravo LT | Learning & Technology diff --git a/public/sitemap.xml b/public/sitemap.xml index 9a9cf11..9a96ee8 100644 --- a/public/sitemap.xml +++ b/public/sitemap.xml @@ -1,15 +1,15 @@ - + - //www.bravolt.com/ + //www.bravolt.com/rpi/ 2020-01-27T12:37:52+06:00 - //www.bravolt.com/rpi/ - 2020-01-27T12:37:52+06:00 + //www.bravolt.com/ + 2019-11-07T12:11:29+06:00 diff --git a/public/tags/index.html b/public/tags/index.html index cf08c44..6acf520 100644 --- a/public/tags/index.html +++ b/public/tags/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/tags/index.xml b/public/tags/index.xml index dd9b284..bc29e34 100644 --- a/public/tags/index.xml +++ b/public/tags/index.xml @@ -1,4 +1,4 @@ - + Tags on Bravo LT | Learning & Technology diff --git a/public/technology/index.html b/public/technology/index.html index 1084caa..f3e85a8 100644 --- a/public/technology/index.html +++ b/public/technology/index.html @@ -6,7 +6,7 @@ - + Bravo LT | Learning & Technology diff --git a/public/technology/index.xml b/public/technology/index.xml index a10e498..e91cc5f 100644 --- a/public/technology/index.xml +++ b/public/technology/index.xml @@ -1,4 +1,4 @@ - + Portfolio on Bravo LT | Learning & Technology diff --git a/static/images/jobdescriptions/21-system-analyst.pdf b/static/images/jobdescriptions/21-system-analyst.pdf new file mode 100644 index 0000000..2bf9483 Binary files /dev/null and b/static/images/jobdescriptions/21-system-analyst.pdf differ