I have a number of presentations scheduled in the next few months. I hope you can make it to some of them.

Date Event Location Topic  
8/27/2016 PyData Chicago Chicago, IL Adding Image and Voice Intelligence to Your Apps with Microsoft Cognitive Services link
8/30/2016 University recruiting event Purdue University Adding Image and Voice Intelligence to Your Apps with Microsoft Cognitive Services  
9/20/2016 GeekFest Chicago, IL Building Powerful Enterprise Apps with Angular 2 and TypeScript link
9/28/2016 TechBash Pocono Manor, PA Adding Image and Voice Intelligence to Your Apps with Microsoft Cognitive Services link
9/28/2016 TechBash Pocono Manor, PA Building Powerful Applications with AngularJS and TypeScript link
10/5/2016 Dog Food Conference Columbus, OH Adding Image and Voice Intelligence to Your Apps with Microsoft Cognitive Services link
10/5/2016 Dog Food Conference Columbus, OH Microsoft Azure without Microsoft link
10/13/2016 Technology Hub Appleton, WI Open Source Technologies in Microsoft Azure link
10/20/2016 DevUp Conference St. Charles, MO Adding Image and Voice Intelligence to Your Apps with Microsoft Cognitive Services link
10/20/2016 DevUp Conference St. Charles, MO The Hitchhiker's Guide to Azure Mobile Apps link
11/28/2016 Mobile Monday East Lansing, MI The Hitchhiker's Guide to Azure Mobile Apps link

"Apprenticeship Patterns: Guidance for the Aspiring Software Craftsman" by Dave Hoover and Adewale Oshineye is written primarily for people entering the profession of software development.

Hoover and Oshineye draw upon their years in the industry to provide advice on how to succeed - how to advance your skills and improve your career.

They present this advice as "patterns" - a term taken from the software design patterns made  famous by Gamma, Helm, Johnson, and Vlissides. Like the software patterns, these Apprenticeship Patterns favor general guidance over explicit step-by-step instructions. Often a chapter will end with a qualifying sentence, warning the user not to be too dogmatic in following an approach to its logical extreme.

Each pattern is presented briefly and concisely and includes action items that the user can apply to his or her own career.

Many of the Patterns provide advice on how to approach education. They begin with learning your first language and "Unleash your Enthusiasm" to motivate your quest for knowledge; applying that education to "Concrete Skills" in your job and  "Confront Your Ignorance" to recognize and address gaps in your knowledge.

Later chapters provide advice as you begin to master skills, including "Reflect As You Work" and "Record What You Learn".

Ultimately the book promotes Software Craftsmanship - a growing movement designed to improve the overall quality of the software industry. The authors relate the book's patterns to how they achieved a level of craftsmanship in their own careers. Hoover and Oshineye provide numerous examples of times that they and people they know applied these patterns in real-world scenarios.

Apprenticeship Patterns was published in 2009, but remains relevant today as thousands of young people continue to pour into the software industry. In fact, this book is more relevant than the vast majority of technical books written at the same time. This advice does not go out of date as new technologies are developed.

People beginning their software careers will benefit from this book. So did I, despite the fact that I switched to this profession decades ago. I read  good advice on expanding my skill sets; and I read good advice to pass on as I mentor junior developers.

I wish this book had existed when I first entered this profession.



Last week, I interviewed Olivier de Jong of Airwave, a startup in the Netherlands that offers video conferencing. You can see the interview below or at this link.




July 2016 Gratitudes

Comments [0]

8/7
Today I am grateful for a walk along Loyola Beach last night.

8/6
Today I am grateful for dinner with Emilija last night.

8/5
Today I am grateful for 3 days in Sydney, Australia - my first visit since 1998.

8/4
Today I am grateful for the opportunity to speak at and attend #ndcsydney.

8/3
Today I am grateful for a cruise around Sydney Harbor last night.

8/2
Today I am grateful for dinner last night with Rowena and Sabrina at a revolving restaurant at the top of the Sydney Tower.

8/1
Today I am grateful for
-a day in Vancouver for the first time in years
-finally arriving in Sydney after many delays.

7/31
Today I am grateful to participate in a successful Nodebots Day yesterday in Chicago.

7/30
Today I am grateful to spend much of this week learning Xamarin.

7/29
Today I am grateful for the party last night hosted by CJUG, ChiPy, and ChicagoRuby that extended well past its scheduled time.

7/28
Today is the birthday of my friend William Fink, who passed away in December. Today I am grateful that I had the opportunity to visit him and become closer to him in the last months of his life, when we both knew he was dying. And I am grateful for the lessons he taught me about facing tragedy with courage and dignity. Happy birthday Bill. Rest in peace, my friend.

7/26
Today I am grateful to dine in Chicago's Greektown yesterday for the first time.

7/25
Today I am grateful for lunch and coffee yesterday with Sven and Ebony.

7/24
Today I am grateful to see "C.S. Lewis On Stage: The Most Reluctant Convert" at the Mercury Theater yesterday.

7/23
Today I am grateful for:
-Breakfast yesterday with Debbie and Diane
-A visit with my mother yesterday.
-A quick trip to my brother Doug's Pawn Shop
-An afternoon with Megan
-A stranger who stopped to help me yesterday evening
-An unscheduled dinner and outdoor concert in East Lansing, MI last night
-Arriving safely home, following a few days in Michigan and a long drive home.

7/22
Today I am grateful for:
-Drinks with Ondrej, Godfrey, and Ed last ngiht
-The hospitality of Debbie and her family
-A great crowd at the Troy .NET User Group last night.

7/21
Today I am grateful for:
-My first time back at #MIGANG this year
-The hospitality and kindness of Ondrej and his family.

7/19
Today I am grateful to go to a movie theater last night - my first visit this year. (I saw Ghostbusters)

7/18
Today I am grateful for:
-A Cubs game at Wrigley yesterday
-A weekend with my boys

7/17
Today I am grateful for
-An evening at the IO Theater in Old Town.
-Taking Nick and Adriana to their first-ever improv show.

7/16
Today I am grateful for dinner and drinks last night with Nick, Tim, and Adriana.

7/15
Today I am grateful to have Tim Giard in town for a few days.

7/14
Today I am grateful for:
-2 days at a resort in Orlando
-drinks with Joe and Chris
-presenting in front of a new audience
-help on my Angular project from John

7/13
Today I am grateful for fireworks outside my room last night.

7/12
Today I am grateful to make it safely to Orlando.

7/11
Today I am grateful I was able to get my laptop working again this morning.

7/10
Today I am grateful for my first time at the Taste of Chicago.

7/9
Today I am grateful for a good night sleep for the first time in weeks.

7/8
Today I am grateful to those who take the time to tell me they enjoyed one of my presentations.

7/7
Today I am grateful for coffee with Chris yesterday.

7/6
Today I am grateful for lunch yesterday with my new teammates.

7/5
Today I am grateful for a weekend in Lexington, KY.

7/4
Today I am grateful to celebrate the marriage of Christopher and Katie last night.


In The Stand, Stephen King tackles the question: What would become of society if nearly all of the people disappeared within a few weeks.

At the beginning of the novel a biological weapon leaks from a quarantined military base and people begin to get very ill very quickly. The U.S. government tries to cover up its error and the weapon it created - often through violent means - but within 2 months, over 99% of the world's population is dead.

In America, the survivors group together - drawn by visions in their dreams. Some travel to Boulder, CO to join with 108-year-old Mother Abigail and some go to Las Vegas, NV to follow the the mysterious Randall Flagg. Mother Abigail has a good heart and talks of love for one another;  Randall Flagg is a malevolent wizard who delights in the chaos created by this epidemic.

Along the way to Boulder and Las Vegas and the final confrontation between the two camps, King explores a myriad of characters and their journey to either the light side or dark side. Even many who end up in Boulder with Abigail are tempted by the dark wizard Flagg. The characters are rich and their back stories before the disaster help us to understand their actions after.

I loved the evolution of characters: Larry Underwood was a self-absorbed and irresponsible rock star before the plague, but found himself willing to sacrifice himself for those he loved after the tragedy; Trash Can Man and Nadine Cross cannot avoid the blackness of their souls and where their destiny takes them, but they still find a way to partially redeem their lives.

It's not surprising that many King fans list this as their favourite novel. King pits good against evil; God against the Devil; chaos against order; and the collapse of civilization against attempts to rebuild it. The climax is a long time coming, but the payoff is excellent.  I've read over a dozen of King's books and this is now my favourite.




Recently, I was interviewed by Matthew Groves for his Cross Cutting Concerns podcast. We talked about Machine Learning in general and Microsoft Cognitive Services in particular. You can listen to the interview here or in the embedded link below:

Or better yet, subscribe to this podcast!




The legend of King Arthur is so familiar to most of us that it is surprising to find a fresh re-telling of this story - particularly one as clever as T.H. White's The Once and Future King.

White recounts the life Arthur from his education as a boy by the string wizard Merlin to his rise to the throne, where he conquers England and attempts to use his power to bring a new age of peace and chivalry to his downfall at the hands of his enemies - particularly his son Mordred.

The story spans 4 books - The Sword in the Stone, The Queen of Air and Darkness, the Ill-Made Knight, and The Candle In The Wind. Originally, White planned a fifth book - The Book Merlyn, but he did not finish this before his death and many of the stories from this book found their way into the other volumes. The story is told chronologically and follows Arthur and his closest friends and enemies throughout his life. Each book stands on its own but is best read as an entire series, in order. (The Book of Merlyn is optional reading.)

White often omits details of Arthur's story, referring the reader to Sir Thomas Malory's "Le Morte d'Arthur". Instead, White focuses on the characters' thoughts and feelings and motivations. How did Merlin's training of the boy Arthur affect King Arthur's philosophy during his reign? What were psychological damaged was caused Lancelot when he was drugged and tricked into losing his virginity? Why does Mordred hate his father and plot revenge?

The books become darker as the series advances; The Sword in the Stone is a lighthearted story featuring bumbling knights and anthropomorphic animals; while the final 2 books focus on the cost of human sin and weakness.

Through it all, White maintains his wit and keeps the characters fresh and alive.

I recommend this series for any fan of the Arthurian Legend.

My notes on the individual books are below.

The Sword in the Stone

A fun story of the youth of King Arthur, when he went by the unflattering nickname "The Wort" and served at the castle of Sir Ector, doing the bidding of Ector's son Kay, until he met the wizard Merlin in the forest and convinced Ector to hire Merlin as his tutor.

Much of Merlin's tutelage consisted of turning the Wort into various animals and allowing him to interact with other animals, learning their ways and their values. We will see these lessons put into practice when Arthur later rises to become King of England.

The Queen of Air and Darkness

Arthur battles King Lot to gain control of Britain and decides to form his famous Knights of the Round Table, who will promote and enforce chivalry in his new kingdom. We are also introduced to Arthur's half-sister Morgause (the "queen" of the book's title), who plots to seduce Arthur through witchcraft and give birth to Mordred, leading to Arthur's destruction.

Although this book is short and contains less action than others in the series, its introduction of key characters and concepts make it an important book in the series.

The Ill-Made Knight

This volume follows Sir Lancelot - his arrival at Camelot and friendship with King Arthur; his affair with Arthur's wife - Queen Guinever; his wanderings in search of both the Holy Grail and redemption for betraying his friend's trust; and his return to Camelot and his battles with his own conscience.

Lancelot is universally regarded as the greatest knight in the world and he believes that his power comes from his purity. But when he loses that purity (he betrays his friend's trust and also fathers Gallahad out of wedlock), he loses not only his power, but his self-confidence and, for a while, his senses.

Candle in the Wind

The climax of the story in which Arthur's rivals (led by Mordred) convince Arthur to try and execute his wife for adultery and to go to war with Lancelot. Arthur's adherence to his law is tested against his love and loyalty to his wife and best friend.

The Book of Merlyn

Unpolished and incomplete, but published after White's death. Merlyn returns to Camelot when Arthur is an old man. He takes Arthur back to some of the animals who had originally taught him lessons of justice, peace, and war and Arthur begins to find meaning in his life, which he had suspected was wasted. Some of these stories found their way into The Sword in the Stone.



June 2016 Gratitudes

Comments [0]

7/3
Today I am grateful for dinner with Mike last night in Cincinnati.

7/2
Today I am grateful for an amazing month and year.

7/1
Today I am grateful for the very kind handwritten note from Jeff Yates that was in my mailbox yesterday.

6/30
Today I am grateful that Sharon's CT Scan yesterday revealed no sign of cancer.

6/29
Today I am grateful for:
-2 good interviews yesterday
-a walk around Northerly Island on a pleasant evening

6/28
Today I am grateful that Adam and Zsófia came to visit me in Chicago for 2 days.

6/27
Today I am grateful for: -An architecture cruise down the Chicago River -An afternoon at Navy Pier -A weekend with Rowena and Sabrina

6/26
Today I am grateful for a chance yesterday to take visitors to Grant Park, Lake Michigan, Buckingham Fountain, Millennium Park, Maggie Daly Park, Cloud Gate, Chase Fountain, and the Navy Pier fireworks.

6/25
Today I am grateful for: -My first visit to Lincoln Park Zoo -Seeing the SpongeBob Musical last night.

6/24
Today I am grateful for an evening in Chicago with my sister-in-law and niece.

6/23
Today I am grateful for lunch yesterday with Lora and her son.

6/22
Today I am grateful for a drive to Wisconsin yesterday.

6/21
Today I am grateful for dinner with John last night in Old Town.

6/20
Today I am grateful for lunch with Ayda yesterday.

6/19
Today I am grateful to attend my first Kane County Cougars baseball game last night.

6/18
Today I am grateful that I meet so many people that are willing to volunteer their time to help others.

6/17
Today I am grateful for an excellent audience last night for my Angular 2 & TypeScript presentation.

6/16
Today I am grateful -to be the most recent guest on the "Hello World" podcast. -to spend the afternoon hanging out with Shawn and Resa -to watch the Navy Pier fireworks from the 31st floor last night

6/15
Today I am grateful for a walk around the South Loop on a warm spring night.

6/14
Today I am grateful for the love and support of Jesus Christ, who helps me through the difficult times.

6/13
Today I am grateful to attend LitFest in my neighborhood this weekend.

6/12
Today I am grateful for -my first visit to Northerly Island -my first visit to FirstMerit Bank Pavilion -my first time seeing Steely Dan in concert -my first time seeing Steve Winwood in concert

6/11
Today I am grateful for breakfast with Derek in Minnesota yesterday.

6/10
Today I am grateful for pierogis and vodka with Lisa and Kevin.

6/9
Today I am grateful for: -breakfast with Kevin and Kasey in Chicago yesterday morning; -dinner and ice cream with evangelists and local devs in Minneapolis last night

6/8
Today I am grateful to all those who said kind things to me when I was having a bad day.

6/7
Today I am grateful to be invited to speak again at the Chicago Coder Conference this year.

6/6
Today I am grateful to spend a couple days with J. Tower this weekend.




Our new Fiscal Year begins in a couple weeks, so I compiled a list of community developer events that I expect will take place in the next 12 months.

Please let me know if I am missing an important event in the region, if a date has been confirmed, or if you notice any errors in this list.

Event Location Dates URL
Codestock Knoxville, TN July 15-16 http://www.codestock.org/
Iowa Code Camp Coralville, IA July 23 http://iowacodecamp.com/
Cincinnati Day of Agile Westchester, OH July 29 http://dayofagile.org/ 
PyOhio Columbus, OH July 30-31 http://pyohio.org/
M3Conf Columbus, OH Aug 5 http://www.m3conf.com/
Tulsa Tech Fest Tulsa, OK Aug 5 http://techfests.com/Tulsa/2016/default.aspx
That Conference Wisconsin Dells, WI Aug 8-10 https://www.thatconference.com/
MidwestJS Minneapolis, MN Aug 10-12 http://midwestjs.com/
Music City Code Nashville, TN Aug 18-20 http://www.musiccitycode.com/
CloudDevelop Columbus, OH Aug 26 http://clouddevelop.org/
DogFood Con Columbus, OH Oct 5-6 http://dogfoodcon.com/
Ohio LinuxFest Columbus, OH Oct 7-8 https://ohiolinux.org/ 
Technology Hub Appleton, WI Oct 13 http://www.technologyhubconference.com/
DevSpace Huntsville, AL Oct 14-15 https://www.devspaceconf.com/
DevUp Conference St. Louis, MO Oct 20-22 http://devupconf.com/
Midwest Game Dev Expo Columbus, OH Oct 28-30 https://www.thegdex.com/
MKE DOT NET Milwaukee, WI Oct 29 http://www.centare.com/mke-dot-net/ 
Milwaukee Code Camp Milwaukee, WI Oct or Nov http://milwaukeecodecamp.com/
Chippewa Valley Code Camp Eau Claire, WI Oct 22 http://chippewavalleycodecamp.com/index.html
Detroit Dev Day Detroit, MI Nov? http://detroitdevday.org/
SharePoint Fest Chicago Chicago, IL Dec 6-9 http://www.sharepointfest.com/Chicago/
CodeMash Sandusky, OH Jan 10-13 http://www.codemash.org/
Northeast Wisconsin Code Camp Appleton, WI March? http://newcodecamp.com/
GR Dev Day Grand Rapids, MI March? http://grdevday.org/
Chicago Code Camp Chicago, IL April? http://chicagocodecamp.com/
Twin Cities Code Camp Minneapolis, MN April? http://www.twincitiescodecamp.com/#/home
Nebraska Code Camp Lincoln, NE May? http://nebraskacode.com/
PHPTek St. Louis, MO May? https://tek.phparch.com/
Chicago Coder Conference Chicago, IL June? http://chicagocoderconference.com/
Open Source North Minneapolis, MN June? http://opensourcenorth.com/
KCDC Kansas City, MO June? http://www.kcdc.info/

I was in high school the first time someone asked me to name my favourite band. and I had to think about it for a while before I decided it was Steely Dan. They set themselves apart from others making good music because I enjoyed all of their songs and because they played a variety of music and because their style of combining jazz arrangements over pop melodies was so different from what other artists of the last 1970s were doing. Walter Becker and Donald Fagen established themselves as one of the great songwriting pairs in pop music history and always surrounded themselves with top-notch studio musicians.

Decades later, Steely Dan remains one of my favourites; but, remarkably, I've never seen them perform live. That changed last night when I caught their performance at the FirstMerit Bank Pavilion in Chicago. They did not disappoint.

Steve Winwood warmed up - another artist I've always enjoyed, but never saw perform live. Winwood had a successful solo career in the 1980s and he performed the popular "Higher Love" from this era; but most of the performance was taken from his earlier bands, such as Traffic and Blind Faith. He closed with a rocking performance of "Gimme Some Lovin’", a song he wrote and recorded for the Spencer Davis Group in 1966 at the age of 18. 

Steely Dan hit the stage on a muggy night as the sun set and a breeze thankfully blew off nearby Lake Michigan. Steely Dan's core remains singer/keyboardist Donald Fagen and guitarist Walter Becker.

Fagen was the leader on stage, introducing most songs and singing lead. Becker is a great songwriter, but had little stage presence (although he did sing lead on "Daddy Don't Live In That New York City No More". But these limitations are easily ignored when one surrounds oneself with an excellent set of musicians.

And Becker and Fagen brought with them an excellent band which they referred to as "The Steely Dan Orchestra". The two highlights of this orchestra were drummer Keith Carlock and lead guitarist Jon Herington, both of whom have traveled with Becker and Fagen for over a decade.

The 3 female backing vocalist provided depth to most songs and sang lead on "Dirty Work", a song originally sung by David Palmer before Fagen took over all lead vocals.

I loved the live arrangements of their songs. Most did not stray far from the excellent studio arrangements that made Steely Dan famous in the first place, but they toyed with some songs, including a slow jam version of "Josie".

Seeing Steely Dan after all these decades of listening to their music was like meeting an old friend after a long absence - Familiar yet somehow new.

I fell in love with them at My Old School and now they had me reeling in my years.

WP_20160611_21_58_14_Pro WP_20160611_22_03_18_Pro




May 2016 Gratitudes

Comments [0]

6/5
Today I am grateful for
-the number of people who traveled far to attend Open Day yesterday.
-Chicago style pizza on the Gold Coast last night with friends and colleagues.

6/4
Today I am grateful for dinner last night in Downers Grove, IL with a bunch of MVPs.

6/3
Today I am grateful for Japanese BBQ with my team last night.

6/2
Today I am grateful for all the online references, articles, lessons, videos, and tutorials that make learning new technologies much more accessible.

6/1
Today I am grateful for dinner at a Swedish restaurant last night.

5/31
Today I am grateful for my camera, which helps me preserve and share memories.

5/30
Today I am grateful to all those who gave their lives in the service of our country.

5/29
Today I am grateful for an excellent week in Romania.

5/28
Today I am grateful for wine tasting with friends at a castle in Jidvei, Romania

5/27
Today I am grateful for another excellent #ITCAMP16.

5/25
Today I am grateful for my first visit to Bucharest.

5/23
Today I am grateful to arrive safely in Romania.

5/22
Today I am grateful for:
-seeing Nonnie's new house
-breakfast with Debora, David, Sue, and Gary this morning in Forest Park.

5/21
Today I am grateful for a walk around Andersonville last night.

5/20
Today I am grateful for:
-Lunch at Superdawg in Norwood Park
-An afternoon walk along Lake Michigan

5/19
Today I am grateful for a chance to play with a HoloLens yesterday.

5/18
Today I am grateful for pierogis with Christina last night.

5/17
Today I am grateful that my son began his internship yesterday.

5/16
Today I am grateful to see Gary Numan in concert last night.

5/15
Today I am grateful for a hot latte to start the morning.

5/14
Today I am grateful for a vibrant startup community in Chicago.

5/13
Today I am grateful that the skies here have cleared up, giving us a brilliant sunny day.

5/12
Today I am grateful for a day spent writing code.

5/10
Today I am grateful for lunch yesterday with Nick and Tim.

5/9
Today I am grateful:
-to be able to spend most of yesterday with my mother
-to my brother Doug and sister-in-law Sherree housing me for the weekend
-for a rare chance to spend time my brother Dan, who lives in a different hemisphere.
-Mother's Day dinner with family

5/8
Today I am grateful to be back in Michigan with my brothers and other family members.

5/7
Today I am grateful for the ability to binge-watch an entire season of my favourite TV shows.

5/6
Today I am grateful for every person who ever came up to me after a presentation to tell me they enjoyed it and learned something.

5/5
Today I am grateful for Tacos and margaritas at the Taco Joint last night.

5/4
Today I am grateful for a fresh latte, without leaving my kitchen.

5/3
Today I am grateful for an excellent steak dinner with Kevin last night.

5/2
Today I am grateful for lunch yesterday with James.


On April 7 in Arlington Heights, IL, Michael Blumenthal and the PSC Group organized a day-long event, titled “Azure and the Modern Data Center”. The event featured a single track of speakers presenting on topics related to managing Azure from an IT Infrastructure perspective.

My colleague Brian Lewis delivered the keynote at this event and I gave a presentation on Virtualization Containers. Other topics included Compute & Storage Infrastructure, Networking Infrastructure, and Disaster Recovery.

The event was recorded and the videos are now available on Channel 9.

The complete agenda for the day is here:

Welcome Michael Blumenthal
Keynote: Why the Cloud will Change Your Life Brian Lewis
Azure Network Infrastructure Michael Blumenthal
Designing Azure Compute and Storage Infrastructure Bill Lee
Virtualization Containers David Giard
Device Showcase Scott Sheehy & Linda Baez
Deployment with ARM templates and GIT Geremy Reiner
Hybrid IT Management Rishi Bhatia
ASR recovery for protection and migration from on-premises Dan Rey
Designing Identity solutions with AAD Brice McDowell
Closing Remarks and Raffle Michael Blumenthal

image


Recently I interviewed Sally Buberman and Ignacio Lopez, who turned an Imagine Cup project into a successful startup. Wormhole uses gamification to make online learning more engaging. Watch the interview below or at: Startup Stories: An Interview with Sally Buberman and Ignacio Lopez from Wormhole



Mihai Tataran stood next before a group of technologist at the Jidvei winery and castle in Cetatea de Balta, Transylvania. IT Camp had ended the day before and the conference organizers took the speakers to the winery for a tour, a lunch, and a wine tasting. Mihai laughed and translated into English the tour guides jokes comparing wine with a beautiful woman. The group was tired from the activities surrounding the conference, but energized by the fresh air and the sunshine.

The speakers (including me) had come to Transylvania to speak at the 6th annual IT Camp in Cluj-Napoca. Cluj-Napoca is arguably the tech center of Transylvania - the region of northern Romania which has established itself in recent years as a growing technology hub.

IT Camp has grown from a small Microsoft-focused developer event into a 2-day, 6-track, multi-platform event with many presentations covering topics outside of software development, such as business skills and DevOps. This was my third visit to IT Camp in as many years.

The conference featured 3 keynote presentations - all on Day 1:

Cluj Mayor Emil Boc opened the conference by talking about the emergence of the tech industry and the advantage of the universities in his city.

Jayson Street described some things he has done wrong in his career as a security analyst and the lessons he learned from those incidents.

Laurent Ellerbach showed off his IoT-enabled garden that does everything from analyze the soil to automatically turn on sprinklers to take photos on demand.

IT Camp features an impressive list of speakers from at least 9 different countries - mostly from Europe.

I had a chance to see a few sessions presented by others, including Raffaele Rialdi's "Introduction to .NET Core", Mihai Coroș's "Building Your First SPA with Aurelia and ASP.NET MVC 6", and Radu Vunvulea's "Azure microservices in practice".

I delivered 2 sessions at IT Camp: "Open Source Technologies in Microsoft Azure" and "Adding Image and Voice Intelligence to your apps with Microsoft Cognitive Services".

The Open Source Azure session was well-received by the 30 or so attendees. This was a variation on a talk I've done in the past titled "Microsoft Azure Without Microsoft". In it, I highlight many of the open source technologies that are available in Microsoft Azure (e.g., Linux Virtual Machines and PHP web applications) and with which Microsoft Azure can work (e.g., REST services consumed by Java or Ruby).

I was much more happy with the Cognitive Services presentation. The audience filled a room with a capacity of over 100 persons and were impressed by this technology that exposes models built with machine learning to any application that can call a web service.  A line of attendees came to the stage afterward to ask questions.

I also had an opportunity to meet with the Technical Evangelists on the DX Romania team - both in Bucharest before the conference and during IT Camp.

Few conferences treat their speakers as well as IT Camp. Perks of speaking here, included:

  • A room at the Beautiful Grand Hotel Italia, overlooking the city of Cluj-Napoca
  • A buffet breakfast every morning and gourmet dinners every night
  • Evenings spent talking and drinking with other speakers and the conference organizers
  • A field trip the day after the conference. This year, a bus took us to the winery and castle in Jidvei.

I'm writing this recap from an airport lounge in Munich, waiting for a flight to take me home to Chicago. I'm exhausted from a lack of sleep this past week, but I'm happy I had the opportunity to take part in IT Camp and to reconnect with so many people that I only see once a year.


Walking through the Old City in Bucharest in a pouring rain looking for a restaurant among the winding streets, it was hard to remember that I came here for a vacation. But I did.

For the third year in a row, I was invited to speak at IT Camp in Cluj-Napoca, Romania. When speaking in Europe, I always make an effort to take a little extra time and see something new; so I  arrived  Monday evening, although the conference did not start until Thursday.After my ticket to Cluj was booked, I looked around for a place to visit for 2 days and I settled on Bucharest. This was my third trip to Romania, but the first time I set foot in its capital city or the region of Wallachia.

As with all overseas trips, this one began with a flight - or rather with 3 flights. I counted 23 hours between the time I left my apartment to the time I arrived - exhausted - at the Bucharest hotel. Despite the long travel time, it was not a bad trip.

It was late Monday night when I arrived in Bucharest, but the JW Marriott upgraded my room and gave me access to the members' lounge, so I relaxed a bit before bed and slept through my alarm the following morning. It was noon by the time, I ventured out on the streets.

I stopped for about an hour at the Microsoft office in Bucharest and met Radu Stefan - a local Technical Evangelist with whom I had been corresponding. He recommended the City Tour Bus, which takes one past many of the city's cultural and historic landmarks, providing recorded narration as it passes each landmark.

A recommendation from Twitter encouraged me to eat at Caru cu Bere in the Old Town section of Bucharest. The waiter recommended the "House Beer", which was so good I drank 2 (a rare thing for me). I didn't realize until after the waiter brought it, that I had ordered dinner "for 2". It was a good thing I skipped lunch.

Caru cu Bere is located in the Old City - a pedestrian area with cobblestone streets and many old building. I spent a lot of time walking through this section of town - in part because of a desire to explore and in part because it was difficult to find the restaurant. A steady rain fell on me while I walked, attempting unsuccessfully to dampen my spirits.

On Wednesday, I hired a tour guide and driver for the day, who took me around Bucharest. The city has a rich, multicultural history. In the early part of the 20th century, after Romania gained independence, Bucharest was known as the Paris of the East for its beautiful architecture and rich cultural attractions. But the Communists who gained control following World War II had little interest in the Bucharest of the past. Dictator Nicolae Ceaușescu destroyed hundreds of blocks of historic neighborhood to create the enormous and lavish Parliament Building.   Ceaușescu was deposed and executed before this building (the second largest administrative building in the world) was completed.

Highlights of my guided tour were:
-A walk through part of the Parliament Building
-The Village Museum - an outdoor area consisting of old homes from many parts of Romania
-The Romanian Patriarchal Cathedral on Dealul Mitropoliei

Wednesday evening, I boarded a plane for Cluj-Napoca for the IT Camp. I only spent 2 days in Bucharest, but I saw a lot of the city and I learned a lot of its history. It was definitely a worthwhile excursion. No amount of rain could dampen that.


Here is an interview I conducted recently with Victor Cintron of DimDrop – a startup that uses location-based services to improve communication. They are deploying a number of open source technologies to Microsoft Azure.

Startup Stories: An Interview with Victor Cintron, CEO of DimDrop



Last month, I had the privilege of attending the AWS Summit in Chicago. It was a great experience for me because, although I do a lot of work with cloud computing, I have very little experience with the Amazon Web Services (AWS) platform.

The most interesting session I attended was about a service called "Aurora" (Amazon tends to give all their services catchy names). This is a relational database that looks and acts almost exactly like MySQL but runs much faster. The official product page brags that Aurora is a "MySQL-compatible relational database with 5X performance", however the session I attended claimed that they found cases in which Aurora was 63 times faster than MySQL. The presenters didn't share details of those cases, but even if results are only a fraction of that speed, it's still an impressive performance improvement.

Because Aurora is MySQL-compliant, you should be able to plug it into any application and use it just like MySQL. The SQL syntax is identical and the management tools will be familiar to anyone used to managing MySQL.

Of course, the fact that Aurora is hosted on a cloud platform like AWS gives it the advantage of high availability and flexible scaling that cloud computing offers.

Since most of my cloud computing experience is with Microsoft Azure, I tend to use Azure as a reference point for the services I saw at this summit. I was drawn to Aurora in part because I'm not aware of the same offering in Microsoft Azure.

MySQL as a service is available on Azure, but it's offered and supported by ClearDb - a third party.  If you want better performance or scalability on Azure than that offered by ClearDb, you will need to either switch to a different database or create a Virtual Machine and install MySQL on that, in which case you would be using Infrastructure as a Service, instead of Software as a Service.

In many cases, this is a non-issue. If you are building a new application, you have the flexibility to choose your preferred database technology. MySQL and SQL server have very similar languages; and, although I won't get into a debate here as to which is "better", it would be difficult to argue that SQL server is significantly less reliable or enterprise-ready than MySQL.

But there are times when you don't have a choice of database technologies. For example, if you have a large legacy application that you want to migrate to Azure, it may be a daunting task to migrate every stored procedure and SQL statement to use T-SQL.  Or if you are using a framework that is specifically built on top of MySQL, it makes sense to use that database, rather than re-writing the entire data access layer. Luckily, some frameworks have alternative data access layers. For example, Project Nami is a data access layer for WordPress that uses SQL Server as a data store, rather than MySQL.

Although the various cloud computing companies follow one another and are likely to build a service when they see traction on their competitor's platform, I find it interesting to see these gaps in offerings.


Here is a recent conversation I had with Sean Goltz and Addison Cameron-Huff of Global-Regulation, a company that assists researchers who are searching for international law documents. They are deploying a variety of open source technologies on Microsoft Azure.

Watch this interview below or follow this link to the interview.


The Newtonsoft.Json library contains a number of tools for working with JSON from within your .NET application.

New ASP.NET applications created in Visual Studio already contain a reference to the Newtonsoft.Json library. But if you want to add the library to a different project type or if you want to update the version installed by default with an ASP.NET application, you can right-click your project in the Visual Studio Solution Explorer and select "Manage NuGet Package..." and search for Newtonsoft.Json. Select the "Newtonsoft.Json" package (Fig 1) and click either "Install" or "Update".

Newtonsoft is very good at serializing .NET objects into JSON objects.

One feature that I find useful is its ability to rename attributes in my classes. For example, if I have a class named "SocialSecurityNumber" in my C# class and the client consuming my JSON object expects that same property to be named "ssn", I can make this transformation declaratively by adding the JsonProperty attribute to the class property, as shown in Listing 1.

[JsonProperty("ssn")]
public string SocialSecurityNumber { get; set; } 

By convention, C# developers tend to name public properties with mixed case (capitalize the first letter of each word); while JavaScript and JSON developers tend to name properties using Camel casing (capitalize the first letter of each word, except the first word). In the past, I used the JsonProperty attribute to accomplish this, renaming every variable that would be serialized to JSON, as in the following example:

[JsonProperty("firstName")]
public string FirstName { get; set; }
 
[JsonProperty("lastName")]
public string LastName { get; set; }

For projects with many objects and many properties, this can be a tedious task. Fortunately, I recently learned a shortcut.

ASP.NET contains a Formatters class that controls how items are formatted and Newtonsoft.Json can tap into this. The following code, when run at the start of your application, converts all properties to Camel-Case as you transform them to JSON.

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

I added this code to the Register method of the WebApiConfig class in my ASP.NET MVC project, so that it is run when the application starts up, before any serialization is done.

Another useful setting is to add carriage returns and line feeds to the JSON that is created. This has the disadvantage of making your JSON slightly larger; but it makes it much easier for human beings to read, which can be very useful during debugging. This is accomplished with the following line:

settings.Formatting = Formatting.Indented; 

The full listing in the Register() method is shown below:

var formatters = GlobalConfiguration.Configuration.Formatters;
var jsonFormatter = formatters.JsonFormatter;
var settings = jsonFormatter.SerializerSettings;
settings.Formatting = Formatting.Indented;
settings.ContractResolver = new CamelCasePropertyNamesContractResolver(); 

Using the tools in the Newtonsoft.Json library, we can easily adhere to the conventional naming conventions of whatever platform in which our data is used.


Gary Numan was everything I did not expect.

GaryNuman (5) He came to Chicago for 3 nights  at Metro night club in Wrigleyville. Each night he promised to perform a different album from early in his career -  "Replicas" on Sunday; "The Pleasure Principle" Monday and "Telekon" on Tuesday. I chose to attend Sunday because his 1979 album "Replicas" has always been my favourite of his. This was an album I embraced in high school a year before the rest of America learned of Gary Numan with the release of "The Pleasure Principle" and its wildly popular "Cars".

For me, Replicas was always the definitive Gary Numan album. Its layers of electronic melodies and its lyrics about a dystopian future spoke to the adolescent me and the album still holds up decades later.

GaryNuman (2) Numan performed every song from the "Replicas" album and I was impressed by his enthusiasm for songs that he released 3 decades ago.

I don't recall ever attending a concert in which I knew in advance the songs the artist would play. But he surprised us - first by mixing the order of the original album and (more significantly) updating the arrangements.

The electronic music that made him famous is still impressive. "Down in the Park" and "I Nearly Married a Human" featured impressive keyboards and unusual sounds. But, he transformed "Me! I Disconnect From You" from a hypnotic synth-pop tune into a rock song that any post-punk garage band would be proud of. The guitar bass drums came to the fore on a number of his songs, making them more rocking and less ethereal.

Replicas I expected a stiff, robotic, stoic Gary Numan - similar to the mannequin pose on the Replicas album cover. Instead, the audience was treated to an energetic performer dancing to his songs and bringing a renewed passion to his old music.

The only downside was the venue. The fact that Metro only accepts cash was a disappointing surprise, but its General Admission format made it difficult for most attendees to see the stage. There are a limited number of tables one can reserve at more than double the GA price and I'm debating doing this when Echo & the Bunnymen play there in the Fall.

GaryNuman (3) But I found a bit of floor space to enjoy the show and enjoy it I did - from the music to the strobe lights. Thanks to Numan's energy this concert exceeded my expectations.



In an earlier article, I described how to call the Cognitive Services API from JavaScript. The key parts of the code (using the jQuery library) is shown below:

var subscriptionKey = "cd529ca0a97f48b8a1f3bc36ecd73600";
var imageUrl = $("#imageUrlTextbox").val();
var webSvcUrl = "https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=true&returnFaceAttributes=age,gender,smile,facialHair,headPose,glasses";
$.ajax({
    type: "POST",
    url: webSvcUrl,
    headers: { "Ocp-Apim-Subscription-Key": subscriptionKey },
    contentType: "application/json",
    data: '{ "Url": "' + imageUrl + '" }'
}).done(function (data) {
        // ... 
        // Code to run when web service returns data...
        // ...
        }); 

Do you spot the problem with this code?

Although it works very well from a functional point of view, it has a security flaw” As with all Cognitive Services APIs, the Face API requires you to pass a key in the header of your HTTP request. Because there is no easy way to hide this key, it is easy for a hacker to steal your key. Using your key, they can make calls and charge them to your account - either using up your quota of free calls or (worse) charging your credit card for their calls.

One way to hide the key is to make the call to Cognitive Services from a custom web service. This web service can be a simple pass-through, but it allows you to hide the key on the server, where it is much more difficult for a hacker to find it.

We can use Web API to create this custom web service. With Web API, is a simple matter to store the Subscription Key in a secure configuration file and retrieve it at run time. The relevant code goes in an ApiController class as shown below.

// POST: api/Face
public IEnumerable Post([FromBody]string imageUrl)
{
    return GetFaceData(imageUrl);
} 
 
public static IEnumerable GetFaceData(string imageUrl)
{
    var webSvcUrl = "https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=true&returnFaceAttributes=age,gender,smile,facialHair,headPose,glasses";
    string subscriptionKey = ConfigurationManager.AppSettings["SubscriptionKey"];
    if (subscriptionKey == null)
    {
        throw new ConfigurationErrorsException("Web Service is missing Subscription Key");
    }
    WebRequest Request = WebRequest.Create(webSvcUrl);
    Request.Method = "POST";
    Request.ContentType = "application / json";
    Request.Headers.Add("Ocp-Apim-Subscription-Key", subscriptionKey);
    using (var streamWriter = new StreamWriter(Request.GetRequestStream()))
    {
        string json = "{"
        + "\"url\": \"" + imageUrl + "\""
        + "}"; 
 
        streamWriter.Write(json);
        streamWriter.Flush();
        streamWriter.Close(); 
 
        var httpResponse = (HttpWebResponse)Request.GetResponse(); 
 
        string result = "";
        using (var streamReader = new StreamReader(httpResponse.GetResponseStream()))
        {
            result = streamReader.ReadToEnd();
        }
        httpResponse.Close(); 
 
        List faces = JsonConvert.DeserializeObject>(result);
        return faces;
    }
} 

Of course, we could also use the .NET library to abstract the call to the Face API, but I wanted to keep this code as close to the original JavaScript code as possible.  This method returns a List of Face objects. The Face object maps to the JSON data returned by the Face API. You can see this class below.

public class Face
{
    public string FaceId { get; set; }
    public FaceRectangle FaceRectangle { get; set; }
    public FaceLandmarks FaceLandmarks { get; set; }
    public FaceAttributes FaceAttributes { get; set; }
}

Now, we can modify our JavaScript code to call our custom API, instead of calling Face API directly, and we can eliminate the need to pass the key from the client-side JavaScript, as shown below:

var imageUrl = $("#imageUrlTextbox").val();
webSvcUrl = "api/face";
$.ajax({
    type: "POST",
    url: webSvcUrl,
    data: JSON.stringify(imageUrl),
    contentType: "application/json;charset=utf-8"
}).done(function (data) { 
// ... 
// Code to run when web service returns data...
// ...
}); 

In this listing, we have removed the Subscription-Key from the Header and we have changed the Web Service URL. This is JavaScript is calling a web service in its own domain, so it is trusted. The default Cross-Site scripting settings of most web servers will keep JavaScript outside this domain from accessing our custom web service.

This pattern works with any of the Cognitive Services APIs. In fact, it works with any API that requires the client to pass a secure key. We can abstract away the direct call to that API and hide the key on the server, making our code more secure.

Code

  • You can find the full code of the sample described above here.
  • You can find the code for the “unprotected” sample here.

Microsoft Cognitive Services (MCS) allows you to tap into the power of Machine Learning and perform sophisticated analysis of photographs, simply by calling a web service.

The Face API in MCS returns an array of all the faces found in a photo, along with information about each face, such as the location of the eyes, nose, and mouth; the age and gender of the person, and information about eyeglasses and facial hair.

You can sign up to use MCS for free at https://www.microsoft.com/cognitive-services/. Information specific to the Face API can be found at https://www.microsoft.com/cognitive-services/en-us/face-api. (fig 1)

FaceAPI02-SubscriptionKey 
Fig. 1

To use the Face API, click the [Get Started for Free] button. You will see a list of subscription keys. Scroll down to "Face" section and click "Copy" next to one of the Face Subscription keys to save it to your clipboard or click "Show" to reveal the key.

FaceAPI01-APIpage 
Fig. 2

To call the Face API, send an HTTP POST request to https://api.projectoxford.ai/face/v1.0/detect

You may add optional querystring parameters to the above URL:

returnFaceID: If set to "true", the web service will return a GUID representing the face, so that you can make repeated inquiries about this face.

returnFaceLandmarks: If set to "true", the web service will return a "faceLandmarks" object containing a list of points identifying where location of the edges of the eyes, eyebrows, nose, and mouth.

returnFaceAttributes: A comma-delimited list of face attributes the web service should return. Allowable attributes are
age: an age number in years.
gender, smile, facialHair, headPose, and glasses.

The service will always return a rectangle identifying the outline of the face. Adding more properties to return will, of course, slow down both the computation and the download of the data.

You must pass the subscription key (described above) in the header of your HTTP request as in the following example:

Ocp-Apim-Subscription-Key:52b24a988a179f13a25aac4713aec800 

The photo itself will be in the body of the POST request. In the content-type header parameter, you can specify how you plan to send the photo to the server. If you plan to send a link to the URL of a photo, set the content-type to "application/json"; if you plan to send the photo as binary data, set the content-type to "application/octet-stream".

The body of the request contains the image. If you selected "application/json" as the content type, send the URL in the following JSON format:

{ "Url": "/themes/Giard/images/logo.png"}

If successful, the web service will return (formatted as JSON) an array of "face" objects - one for each face detected in the photo. Each object will contain the top, left, height, and width values to define a rectangle outlining that face. If you declared that you want more data (e.g., FaceID, Face Landmanrks, and Face Attributes), that data will also be returned in each face object.

Below is an example of JavaScript / jQuery code to call this API.

var subscriptionKey = "Copy your Subscription key here"; 
 
var imageUrl = "/themes/Giard/images/logo.png";
 
var webSvcUrl = "https://api.projectoxford.ai/face/v1.0/detect?returnFaceId=true&returnFaceLandmarks=true&returnFaceAttributes=age,gender,smile,facialHair,headPose,glasses";
 
var outputDiv = $("#OutputDiv");
outputDiv.text("Thinking..."); 
 
$.ajax({
    type: "POST",
    url: webSvcUrl,
    headers: { "Ocp-Apim-Subscription-Key": subscriptionKey },
    contentType: "application/json",
    data: '{ "Url": "' + imageUrl + '" }'
}).done(function (data) { 
 
    if (data.length > 0) {
        var firstFace = data[0];
        var faceId = firstFace.faceId;
        var faceRectange = firstFace.faceRectangle;
        var faceWidth = faceRectange.width;
        var faceHeight = faceRectange.height;
        var faceLeft = faceRectange.left;
        var faceTop = faceRectange.top; 
 
        var faceLandmarks = firstFace.faceLandmarks;
        var faceAttributes = firstFace.faceAttributes; 
 
        var leftPupil = faceLandmarks.pupilLeft;
        var rightPupil = faceLandmarks.pupilRight;
        var mouth = faceLandmarks.mouthLeft;
        var nose = faceLandmarks.noseLeftAlarOutTip;
        var mouthTop = faceLandmarks.upperLipTop;
        var mouthBottom = faceLandmarks.underLipBottom;
        leftEyeWidth = faceLandmarks.eyebrowLeftInner.x - faceLandmarks.eyebrowLeftOuter.x;
        rightEyeWidth = faceLandmarks.eyebrowRightOuter.x - faceLandmarks.eyebrowRightInner.x;
        mouthWidth = faceLandmarks.mouthRight.x - faceLandmarks.mouthLeft.x; 
 
        var mouthLeft = faceLandmarks.mouthLeft;
        var mouthRight = faceLandmarks.mouthRight;
        var mouthTop = faceLandmarks.upperLipTop;
        var mouthBottom = faceLandmarks.underLipBottom; 
 
        var outputText = "";
        outputText += "Face ID: " + faceId + "
"
;
        outputText += "Top: " + faceTop + "
"
;
        outputText += "Left: " + faceLeft + "
"
;
        outputText += "Width: " + faceWidth + "
"
;
        outputText += "Height: " + faceHeight + "
"
;
        outputText += "Right Pupil: " + rightPupil.x + ", " + rightPupil.y + "
"
;
        outputText += "Left Pupil: " + leftPupil.x + ", " + leftPupil.y + "
"
;
        outputText += "Mouth: 
"
;
        outputText += " -Left: " + mouthLeft.x + ", " + mouthLeft.y + "
"
;
        outputText += " -Right: " + mouthRight.x + ", " + mouthRight.y + "
"
;
        outputText += " -Top: " + mouthTop.x + ", " + mouthTop.y + "
"
;
        outputText += " -Bottom: " + mouthBottom.x + ", " + mouthBottom.y + "
"
;
        outputText += "Attributes:" + "
"
;
        outputText += "age: " + faceAttributes.age + "
"
;
        outputText += "gender: " + faceAttributes.gender + "
"
;
        outputText += "smile: " + (faceAttributes.smile || "n/a") + "
"
;
        outputText += "glasses: " + faceAttributes.glasses + "
"
;
        outputDiv.html(outputText); 
 
    }
    else {
        outputDiv.text("No faces detected."); 
 
    } 
 
}).fail(function (err) {
    $("#OutputDiv").text("ERROR!" + err.responseText);
}); 
 
service call is performed by the following line: 
 
$.ajax({
    type: "POST",
    url: webSvcUrl,
    headers: { "Ocp-Apim-Subscription-Key": subscriptionKey },
    contentType: "application/json",
    data: '{ "Url": "' + imageUrl + '" }' 
 

This request is Asynchronous, so the "done" function is called when it returns successfully.

}).done(function (data) { 

The function tied to the "done" event parses through the returned JSON and displays it on the screen.

If an error occurs, we output a simple error message to the user in the "fail" function.

}).fail(function (err) {
          $("#OutputDiv").text("ERROR!" + err.responseText);
  }); 

The rest of the code above simply grabs the first face in the JSON array and drills down into properties of that face, displaying those properties in a DIV on the page.

For example, in the attached site.css stylesheet, I’ve defined 2 classes - .Rectangle and .FaceLabel - that initially hide objects on the page via the display: none style. These classes also set the position to “absolute” allowing us to position them exactly where we want within a container. The z-order is incresed, so that these items will appear on top of the face in the picture.  The relevant CSS is shown below:

#Rectangle
{
    opacity: 0.3;
    z-index: 10;
    position: absolute;
    display: none;
  }
 
.FaceLabel{
    position: absolute;
    z-index: 20;
    display: none;
    font-size: 8px;
    padding: 0px;
    margin: 0px;
    background-color: white;
    color: black;
    padding: 1px;
  }

Our page contains object with these classes to identify parts of the face identified. Initially, they will be invisible until we determine where to place them via the information returned by the Face API.

<div id="PhotoDiv">
    <img id="ImageToAnalyze" src="images/CartoonFace.png">
    <div class="FaceLabel" id="LeftEyeDiv">LEFTdiv>
    <div class="FaceLabel" id="RightEyeDiv">RIGHTdiv>
    <div class="FaceLabel" id="NoseDiv">NOSEdiv>
    <div class="FaceLabel" id="MouthDiv">MOUTHdiv>
    <img src="images/Rectangle.png" id="Rectangle">
div>

When the call to the Face API web service returns successfully, we drill down into the returned JSON to find out the outline of the face and the location of the eyes, nose, and mouth. Then, we make these objects visible (set the display style to “block”)  and place them above the corresponding facial feature (set the “top” and “left” styles). In the case of the Rectangle image, we also resize it to cover the face detected. The rectangle’s “opacity” style is 0.3, making it translucent enough to see the face behind it. Here is the JavaScript to accomplish this:

$("#Rectangle").css("top", faceTop);
$("#Rectangle").css("left", faceLeft);
$("#Rectangle").css("height", faceHeight);
$("#Rectangle").css("width", faceHeight);
$("#Rectangle").css("display", "block");
$("#LeftEyeDiv").css("top", leftPupil.y);
$("#LeftEyeDiv").css("left", leftPupil.x);
$("#LeftEyeDiv").css("display", "block");
$("#RightEyeDiv").css("top", rightPupil.y);
$("#RightEyeDiv").css("left", rightPupil.x);
$("#RightEyeDiv").css("display", "block");
$("#NoseDiv").css("top", nose.y);
$("#NoseDiv").css("left", noseHorizontalCenter);
$("#NoseDiv").css("display", "block");
$("#MouthDiv").css("top", mouthVerticalCenter);
$("#MouthDiv").css("left", mouthTop.x);
$("#MouthDiv").css("display", "block");

Below is the output of the web page analyzing a photo of my face:

FaceApi03-WebPage

As you can see, calling the Cognitive Services Face API, is a simple matter of making a call to a web service and reading the JSON data returned by that service.

You can find this code in my GitHub repository.


Microsoft Cognitive Services is a set of APIs built on Machine Learning and exposed as REST Web Services. The Speech API offers a way to listen to speech and convert it into text.

GCast 16: Cognitive Services - Speech to Text



Yesterday, I posted a code sample of the simplest web server I could create using node.js. After reading my post, Tugberk Ugurlut pointed me to http-server and his blog post on http-server.

Install http-server globally

Installing http-server is simple with the following command:

install http-server -g

The “-g” switch installs this library locally. I tried it without that switch, but it did not work. However, the advantage of installing it globally is that it will work in any new folder you create on your computer.

Create Web Files to Render

You can change to a folder on your local machine and create some web pages, JavaScript files, and CSS files, such as the 2 sample pages below:

index.html

<html>
<body>
    <h1>Indexh1>
    <div>
        Welcome to my site!
    div>
body>
html>

about.html

<html>
<body>
    <h1>Abouth1>
    <div>
        This is a site!
    div>
body>
html>

Start Web Server

Then, start a web server with the following command:
http-server
 
The server will notify you on what port it is running (8080 by default)

Test it Out

Now you can open a browser and navigate to a page, as shown below:

http-server-about

Notice that you don’t need to type the “.html” or “.htm” extension. The server is smart enough to know the page you are looking for.

It is also smart enough to assume a page with a name like “index.html”, “home.htm”, or “default.htm” is a a default page and render this page when none is specified, as shown below:

http-server-index

This is a very simple way to quickly install, configure, and start a lightweight web server on your local PC for testing or creating static pages.


Often I want to set up a simple web server to render pages that consist only of client-side code, such as HTML, CSS, and JavaScript. In the past, I've created such pages using Visual Studio, but VS contains more functionality than I need in this case and that functionality can slow me down.

I found a lightweight web server solution in node.js, which is quick to install, quick to start up, and (relatively) simple to use. As a bonus, it will run on multiple operating systems.

Here are the steps I use to create a web server.

  1. Install node
  2. Create and open a folder for your pages
  3. npm Init to create the package.json file that node requires
  4. Create a "views" folder for your pages and add any pages to it
  5. Install express and ejs
  6. Create a main script
  7. Create HTML pages
  8. Start the web server
  9. Try it out

1. Install node

You can download node from https://nodejs.org/en/download/. Select your operating system and run the installer. It is a small download and a quick install.

2. Create and open a folder for your pages.

In Windows, I use the command prompt for this. I create my projects in either the c:\development folder (if I plan to keep them) or the c:\test folder (if they are scratch projects for learning)

So, for a scratch project, I would use the following commands to create a folder named "nodetest1":
cd c:\test

md nodetest1
cd nodetest1 

3. npm Init to create the package.json file that node requires

Node requires a file named package.json with important information about the project. A quick way to create this is with the command "npm Init". It will prompt you for information required by package.json, even providing default values for some of these settings. Press ENTER at a prompt to accept the default in parentheses or override the default by typing in a new setting. Below is an example of me walking through this command, accepting mostly defaults

npm init

This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install --save` afterwards to install a package and
save it as a dependency in the package.json file.  See the session below for reference.

Press ^C at any time to quit.
name: (nodetest1)
version: (1.0.0)
description: best app evar
entry point: (index.js)
test command:
git repository:
keywords:
author: David
license: (ISC)
About to write to C:\test\nodetesting\nodetest1\package.json:
{
  "name": "nodetest1",
  "version": "1.0.0",
  "description": "best app evar",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "David",
  "license": "ISC"
}
Is this ok? (yes) 

As you can see the file you create is echoed to the screen before you confirm its creation.

4. Create a "views" folder for your pages and add any pages to it

The "md" command works for this in the command prompt

md views 

5. Install express and ejs

Express and ejs are packages required for a simple web server. You can use the npm install command to install them. Add the "--save" switch to this command to update the dependencies in your package.json file. The following 2 commands install express and ejs packages, respectively.

npm install --save express
npm install --save ejs 

Check out the package.json and verify that these packages now appear in the dependencies section, as shown in the example below:

"dependencies": {
  "ejs": "^2.4.1",
  "express": "^4.13.4"
} 

6. Create a main script.

Below is the simplest script I could create that serves up any page in the "views" folder and sets a default page. In the example above, I named it "index.js". You can name it whatever you want, but you should set the "main" attribute in package.json to the name of your file. I have commented each line to explain what it does.

// This script uses the express library
var express = require('express');
var app = express(); 
 
// Tell node where to find the view pages
app.set('views', __dirname + '/views'); 
 
// Tell node to use the ejs library to handle the view
app.set('view engine', 'ejs');
app.use(express.static('views'));
app.engine('html', require('ejs').renderFile); 
 
// Set a default page (Optional, but goood to have)
app.get('/', function (req, res) {
    res.render('index.html')
}); 
 
// Start the web server
var server = app.listen(3000, function () {
    console.log("Express is running on port 3000");
}); 

In package.json, you specified a main JavaScript file. (In the example above, I used the default "index.js". Open package.json to see what you set.) This is the script that will run when you run node.

7. Create HTML pages

In the view folder, create some HTML pages. The script above specified "index.html", so we will need to create this one. Create any other page you like and name them with the ".htm" or ".html" extension. Here are 2 simple examples:

Index.html

<html>
    <body>
        <h1>Welcome!h1>
        <div>
            This is the INDEX page
        div>
    body>
html> 

about.html

<html>
    <body>
        <h1>About Ush1>
        <div>
            We think therefore we are!
        div>
    body>
html> 

 

8. Start the web server

To start your web server, simply type "node" followed by the name of your main script.  This will launch node and tell you the server is running on port 3000.

9. Try it out

Open a browser and type "http://localhost:3000/" in the address bar. You should see the default page (index.html) displayed. Here is the sample page rendered:

SimpleNodeWebServer1

Type "http://localhost:3000/about.html" to see the "about" sample page described above. If you used my example, you will see the following:
SimpleNodeWebServer2

At the command prompt, press CTRL+C at any time to stop the server, making these pages unavailable.

You can view this sample code at https://github.com/DavidGiard/simplenodewebserver.


Microsoft Cognitive Services is a set of APIs based on Machine Learning and exposed as REST web services. The Emotion API analyzes pictures of faces and determines the emotion shown in each face.

GCast 15: Cognitive Services - Emotion API



April 2016 Gratitudes

Comments [0]

5/1
Today I am grateful for a chance to be part of the Chicago Code Camp keynote yesterday.

4/30
Today I am grateful for:
-My first experience at a FIRST Robotics competition.
-An upgraded flight home last night.

4/29
Today I am grateful for an upgraded hotel room and my first taste of Peruvian food.

4/28
Today I am grateful:
-for dinner last night with Nick, Kathy, and Rick.
-that I arrived safely in St. Louis, despite a rocky start to my trip.
-to Nick for driving me to and from the airport last night.

4/27
Today I am grateful for a hot sauna at the end of a long day.

4/26
Today I am grateful for post-meetup drinks last night with a bunch of JavaScript developers I just met.

4/25
Today I am grateful for breakfast on my balcony in my pajamas.

4/24
Today I am grateful to spend time with Nick and Adriana in Chicago this weekend.

4/23
Today I am grateful for:
-Lunch in the South Loop with Scott yesterday
-Dinner in ChinaTown with Nick and Adriana last night

4/22
Today I am grateful for the variety of people I meet every day.

4/21
Today I am grateful for this view.
ChicagoSkyline (1)
ChicagoSkyline (2)
ChicagoSkyline (3)
ChicagoSkyline (4)

4/20
Today I am grateful to attend the AWS Summit yesterday with Brian and Kevin.

4/19
Today I am grateful that I got my car back with a repaired fender.

4/18
Today I am grateful to sit out on my balcony last night sipping a cocktail and enjoying a warm breeze.

4/17
Today I am grateful for a drink and some beer cheese soup last night with Katie, Justin, and Shira.

4/16
Today I am grateful for:
-Lunch at Wildberry with a bunch of folks from the dev community
-Dinner at a Columbian steakhouse in Lakeview.

4/15
Today I am grateful to see Johnny Clegg in concert last night, after 30+ years as a fan.

4/14
Today I am grateful for lunch with Nonnie yesterday.

4/13
Today I am grateful to get together with my team yesterday, which doesn't happen often enough.

4/12
Today I am grateful that all these family photos are now hanging on the walls of my new apartment.

4/11
Today I am grateful that my taxes are filed.

4/10
Today I am grateful for:
-The opportunity to deliver the keynote presentation at the Tech In 2016 conference yesterday.
-A front-row ticket to see Marshall Crenshaw last night.

4/9
Today I am grateful I was able to track down all my missing tax forms yesterday.

4/8
Today I am grateful for my new cuff links - the first I've received in years!

4/7
Today I am grateful for the power of ibuprofen.

4/6
Today I am grateful for dinner last night with Shelly and her family.

4/5
Today I am grateful to Brian for helping me prepare my upcoming presentation on Virtualization Containers.

4/4
Today I am grateful that I've been able to make it to the gym almost every day for the past 3 months.


Microsoft Cognitive Services uses Machine Learning to recognize text within pictures and exposes this functionality via a RESTful Web Service.

GCast 14: Cognitive Services - Thumbnail Generation


Startup CTOs on Azure

Comments [0]

The Bloody Crown of Conan is the second volume in Del Rey's 3-volume set of the complete Conan stories by Robert Howard. While volume 1: The Coming of Conan the Cimmerian included mostly short stories, this book contains 3 longer works: The People of the Black Circle; The Hour of the Dragon; A Witch Shall Be Born.

BloodyCrownOfConan The Hour of the Dragon is a full novel that takes Conan across many countries of the Hyborian world. It is set in a time when Conan has risen to be king of Aquilonia. Conan's enemies resurrect a dead spirit to enchant the king and steal his throne. Conan's quest to regain the crown leads him across much of the known world, where he fights numerous bottles and raises an army to retake Aquilonia. The action and the epic sweep of this story make it one of Howard's best and enhances this collection.

The other 2 novellas, while not as long or involved as The Hour of the Dragon are more complex than most of Howard's short stories.  By this point in his career, Howard seems to have hit his stride. The action flows freely, if violently, and we can enjoy the adventures of Conan who uses his nearly superhuman strength and skills to overcome nearly impossible odds.

The collection ends with a few uninteresting first drafts of Howard's unpublished Conan stories, followed by a fascinating essay analyzing the themes of the Conan series and the evolution of the character.

For escapism and adventure, it is difficult to beat these stories.


clip_image001

MadHacks is an annual weekend hackathon hosted at the University of Wisconsin in Madison, WI. The organizers decided to move the hackathon from the spring to the fall, which left a gap of nearly 18 months between events. To maintain interest, they decided to host a smaller, 1-day hackathon on April 16. The event was billed as MadHacks Spring Fever.

85 students formed teams and submitted 18 projects.

clip_image003
MadHacks organizers

I served as a mentor and a judge at this hackathon.

I also delivered a 1-hour presentation on Microsoft Cognitive Services.

clip_image005
Presentation on Microsoft Cognitive Services

4 judges evaluated all the submitted projects and chose the top 3. The quality of the projects made this difficult and we had to ask several of the teams to show their project again in order to make a selection.

clip_image007
The judges

Many of the projects were Microsoft branded, such as Xbox games, Azure books, and Microsoft sleeping bags.

The winning projects were:

  1. UniTravel: A mobile application that mapped a route to a destination and calculated not only the time and distance, but also the estimated cost using various transportation options.
  2. Chemical Reactor: A web app that visualized atomic motion and formed new molecules if atoms collided with a force that exceeded the enthalpy required to bond.
  3. Cellular Automata Plant: A web app that visualizes the growth of plant cells over time in a given environment.

 

clip_image009
The UniTravel team
clip_image011
The Chemical Reactor team

The event was organized by University of Wisconsin Microsoft Student Partner Katie Anderson.

The projects created were particularly impressive, given that they were all created in 12 hours or less.

A much larger hackathon is planned at UW-Madison in the fall semester.


Microsoft Cognitive Services uses Machine Learning to recognize text within pictures and exposes this functionality via a RESTful Web Service.

Cognitive Services - Optical Character Recognition


<< Older Posts | Newer Posts >>