tag:blogger.com,1999:blog-91321482727456684592024-03-16T05:55:43.748-07:00Fire + Ice: David Pallmann's Technology BlogDavid Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.comBlogger334125tag:blogger.com,1999:blog-9132148272745668459.post-15911987050104682172020-05-03T15:16:00.002-07:002020-05-06T08:27:36.260-07:00Review: TP-Link AC2600 Range Extender 650 Wifi ExtenderThis is my review of the TP-Link AC2600 Range Extender 650 Wifi Extender.<br />
<br />
<h3>
Spotty Connectivity was Cramping my WFH Style</h3>
<h3>
</h3>
<h2>
</h2>
I recently decided I needed to improve my work-from-home Internet situation. I work for a big tech company (Amazon) and fast, reliable connectivity is something I need to have every day. With multiple family members spending a lot of time streaming and
conferencing, we needed more bandwidth. Most important of all, I needed to resolve the poor
connectivity from my home office to the family room where our fiber
modem is. On some days I would lose connectivity every few minutes
during business hours, which is particularly maddening during a video meeting.<br />
<br />
<h3>
</h3>
To combat the bandwidth problems my wife Becky got on the phone with our
Internet provider Frontier and worked wonders. She not only secured the
maximum bandwidth available (for only $5/month more!) but also scored an
equipment upgrade for the modem. A speed check on fast.com was showing 80 Mbps near the router but I was getting only 10-15 Mbps in my home office. That went up a bit after the bandwidth upgrade but was still a far cry from what it should be. To reach my home office I would need a wifi extender, but which one? I read up a bit on wifi extenders and ordered the TP-Link AC2600 Range Extender 650 from Amazon for $108.<br />
<br />
<h3>
Enter the TP-Link RE650</h3>
I received the RE650 4 days after ordering it and rushed to unpack it and set it
up. I had the notion this would be a pair of devices with an Ethernet
cable, but it's actually just a single unit that you plug into an outlet
and no cables are needed. There are two flip-up flat antennae on either
side.<br />
<h3>
</h3>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinOzknIrF3S_OFpbtjeyNp7fT9QaJpV0Mw-cmfq5QHzN8NcXN0pjHp-9c0hjmhv0dKJOfqDtdkPJjePIbHbgcKSjNWI6tiPOlsCuxC6Pd9BPMm0PD2ZCHLW8u97FWXFVkTEzOiXDpcD9I/s1600/tplink-re650-outlet.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="702" data-original-width="333" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinOzknIrF3S_OFpbtjeyNp7fT9QaJpV0Mw-cmfq5QHzN8NcXN0pjHp-9c0hjmhv0dKJOfqDtdkPJjePIbHbgcKSjNWI6tiPOlsCuxC6Pd9BPMm0PD2ZCHLW8u97FWXFVkTEzOiXDpcD9I/s320/tplink-re650-outlet.png" width="151" /></a></div>
<br />
<div style="text-align: center;">
<i>RE650</i></div>
<br />
My first impression of the RE650 was that it strongly reminded me of The PKE Meter in the 1984 movie Ghostbusters! After prancing around the house pretending I was Egon for a few minutes, I returned to the serious business of setting up our new wifi extender.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaVHIaRof7Zn54elFE8wyh8eMQ0RQlGpAiaM3Yzu9IX8qE4KAwlxsKZlMuPFxC8TCdkWYQwjnX4iK9y9NegGfJbEnFe5JKC9yeUP1TfeSjHjAU4hiW4g8f3anc1kH5E0Ku2aBZ7ktEr48/s1600/pke-meter-egon.jpg" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="359" data-original-width="486" height="236" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaVHIaRof7Zn54elFE8wyh8eMQ0RQlGpAiaM3Yzu9IX8qE4KAwlxsKZlMuPFxC8TCdkWYQwjnX4iK9y9NegGfJbEnFe5JKC9yeUP1TfeSjHjAU4hiW4g8f3anc1kH5E0Ku2aBZ7ktEr48/s320/pke-meter-egon.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Wifi Extender or Specter Detector? You Decide</i></div>
<br />
<h3>
Setup </h3>
The RE650 comes with an easy setup that is <a href="https://static.tp-link.com/2019/201905/20190523/7106508265_RE650(EU)_QIG_V1.pdf">nicely documented</a> and there are several ways to configure it: with a phone app, by pressing the WPS button available on some routers, or using your computer. I chose the latter. You initially plug in the unit near your router and wait for the power light to appear. A new wifi network appears that you can connect to for a web-based configuration. The configuration experience is very simple with just a few pages.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrF_pnjjQaETvma3ILtrap1Ns7ixFlurI6Ycn-Qh6xPV7n6-lVwukAnwe4wS9Xdl2DSEgQNBQQYFMuPPOKBv5_Z53cLEBV8MgCGicS9S1Jpq5_B_nzQmBNuNItGGRme6Bz5pzlPFRp7PQ/s1600/re650-config.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1079" data-original-width="773" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrF_pnjjQaETvma3ILtrap1Ns7ixFlurI6Ycn-Qh6xPV7n6-lVwukAnwe4wS9Xdl2DSEgQNBQQYFMuPPOKBv5_Z53cLEBV8MgCGicS9S1Jpq5_B_nzQmBNuNItGGRme6Bz5pzlPFRp7PQ/s400/re650-config.png" width="286" /></a></div>
<br />
The quick setup lists your detected wifi networks, from which I was able to select my router's 2.4GHz and 5GHz networks and provide their passwords. You then name your new wifi extender networks. Be careful here, the setup program will default to the same names as your router's networks and I found that a little confusing. You almost certainly want new names to distinguish your wifi extender networks from the original networks.<br />
<br />
I expected to be able to set new passwords for the extended wifi networks but apparently that's not an option and you keep using your original network passwords; perhaps that's intentional for security. Once you have the configuration done, you connect to the new wifi extender networks and confirm setup is complete.<br />
<br />
Despite the overall good quick setup design, it did take me 3 attempts to configure the
RE650 and I started over twice with a factory reset (you use a pin for that).<br />
<br />
<h3>
Finding the Optimal Location</h3>
With the RE650 configured, you then unplug it and find a home for it about halfway between the router and the dead zone you want to extend coverage to. That means reviewing where your outlets are and trying to find your best option.<br />
<br />
Although I didn't use it for setup, I did install the phone app afterward which is handy. It includes a Location Assistant tool for checking signal strength. I had three places to choose from, found the best one, and that was that.<br />
<br />
A fast.com speed test from my home office (on the 5G wifi extender network) now shows 70-80 Mbps, an amazing improvement from the 10-15 Mbps I was seeing a week ago. Best of all, I don't have spotty connectivity anymore. Depending on what you're used to you may not consider 80mbps all that speedy—
some of my co-workers have ten times that!—
but I live in a rural area and have limited options. I'm fortunate to be on fiber. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj95mJKGDADNDUBSfAgXZ-nVqqClaO6_IOLfV_ovX5RPw1vpmz2FGKCeWQikly9bWFXjkNvedvdii-oHvwGP_c7hc5HbaQHb1XsLZRpwrMck7nfuxJ4FZQGOuL96jiB-vvAsLajp6b-BIQ/s1600/before-after.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="537" data-original-width="1524" height="140" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj95mJKGDADNDUBSfAgXZ-nVqqClaO6_IOLfV_ovX5RPw1vpmz2FGKCeWQikly9bWFXjkNvedvdii-oHvwGP_c7hc5HbaQHb1XsLZRpwrMck7nfuxJ4FZQGOuL96jiB-vvAsLajp6b-BIQ/s400/before-after.jpg" width="400" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Before and After: a huge improvement</i> </div>
<br />
<h3>
Day 1: Life is Good </h3>
My first day on the new setup was fantastic. I stayed connected and enjoyed much higher speed than I'd ever had from my home office. If only things stayed that way...<br />
<br />
<h3>
Day 2: Connectivity, Interrupted</h3>
On Day 2 that all changed. I had 4 hours of video conferences and they were terrible: garbled video/audio and dropped connections. Connectivity was constantly dropping. I couldn't understand how this could be since the prior day had been so perfect.<br />
<br />
I researched what others were saying about the RE650, specifically around connectivity interruptions. A number of people had experienced the same things, and many of them ended up returning the range extended; had I made a mistake? I kept researching. There was advice to change the channel and channel width on the main router. I'd never really worked with routers to that level but I learned how to access my router and view/edit its settings. For the 5GHz network, channel was set to Automatic. Perhaps there was interference from a neighbor? I reviewed the ports available in setup and chose the highest port at random, 165. Then I reconnected to the wife extended to see how things were. I watched Twitch for an hour to see if there would be any video interruptions. I stayed connected, which was reassuring, but I also saw bandwidth was lower: a fast.com speed test showed I was now in the 30-40 range. I'd lost half my speed.<br />
<br />
More research. <i>Channel width</i> lets you increase throughput. My router admin UI said the channel width was 20, but I'd heard routers could do 40 or even 80 in 5GHz. I didn't see a way to <i>set </i>width, however. Finally I tried changing to a different channel, 36, and the UI now showed a width of 80. I reconnected to my extended wifi network and ran fast.com.... 100mbps! the highest I had seen yet from my home office. But, how was connectivity? I watched video on Twitch for 90 minutes and didn't have any connection loss. Promising, but the real test would be videoconferencing at work the next day.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGzMum6CPPEOntbqQr56-6wac_8pju00_rbRs8e7EPygmzRAvIWwv5MJ492K6CkYPUQtjjkfhMi4-78p5K4KcReUF-b7wO4gBGmvoJTGt77rBdiQ7xh7L4f5AQlanrT_4E3lj6_lshKU/s1600/100mpbs.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="661" data-original-width="758" height="279" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirGzMum6CPPEOntbqQr56-6wac_8pju00_rbRs8e7EPygmzRAvIWwv5MJ492K6CkYPUQtjjkfhMi4-78p5K4KcReUF-b7wO4gBGmvoJTGt77rBdiQ7xh7L4f5AQlanrT_4E3lj6_lshKU/s320/100mpbs.png" width="320" /></a></div>
<br />
In summary, the RE650 is a nicely-designed, easy to install wifi extender that works well. If you need to extend your wifi to a dead zone or improve spotty connectivity, it's a good choice.<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-32239865232605863952020-05-02T10:39:00.000-07:002020-05-02T10:39:17.938-07:00Bad Charting Part 4: Following ConventionsThis is Part 4 in <a href="https://davidpallmann.blogspot.com/2020/02/bad-charting-part-1-charts-vs.html">a series</a> on avoiding the pitfalls of bad charting. In this final post of the series we'll look at the importance of following conventions in charts, including use of color and the use of 3D in charts.<br />
<br />
<h2>
Conventions</h2>
<br />
Conventions. Without them, useful communication is impossible: humans couldn't converse, publish, collaborate, or have discourse (civil or otherwise) without conventions. And so it is with charts: fail to follow conventions, and you'll be sending the wrong message. If you're digesting a chart prepared by someone else, be on the lookout for flouting conventions: it's one of the ways a chart can be rigged to send a contrary message to the story the data tells. In Part 1, we mentioned how makers of infographics often don't feel constrained to "follow the rules" in their charts. Violating conventions is one of the chief offenses.<br />
<br />
<h3>
Directional Flow</h3>
The flow of things on your chart, including arrows, should conform to the culture of your audience. For example, the following are deeply ingrained in Western culture, to the point where few people even bother to think about them consciously: they're just understood.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKfFbaWjm-tX49WAyvOLIqvlCfmabQSpadAzqN-lWW-CQiP-KktnUBmAccKFp_1e1wvSaS9WWkGofAJMW6jZCnhlnA3ZteUeGJSK3omSzD4jb5zZqVoM3llf9l332rRIt6wRnTpiyd-UI/s1600/directions-western-culture.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1600" height="184" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKfFbaWjm-tX49WAyvOLIqvlCfmabQSpadAzqN-lWW-CQiP-KktnUBmAccKFp_1e1wvSaS9WWkGofAJMW6jZCnhlnA3ZteUeGJSK3omSzD4jb5zZqVoM3llf9l332rRIt6wRnTpiyd-UI/s320/directions-western-culture.png" width="320" /></a></div>
<br />
Time moves left to right, always. Going up means more, gain, or north; down means less, loss, or south. Fail to follow these conventions, and people will struggle to understand your visuals. Targeting a different culture than yours? Do your research and find out what they consider normal.<br />
<br />
Here's the most egregious example I know of ignoring conventions. What does this chart make you conclude about the effect of Florida's "Stand Your Ground" law? Gun deaths appear to drop rapidly after 2005.<br />
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD12hSKPw9s3uCrEgoH6q7HDJu4tdyQJ3IezkktLnUlJ-2KRGtVDBY1TVzTD3pQHvMzu-YXt3PJCuQgZV5sVn9NyeLjppN2LtXnfsXl5FK2je2ucSA5LDcqoMaPytwax7Yzm-KM2snrew/s1600/gun-deaths-florida.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="572" data-original-width="457" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiD12hSKPw9s3uCrEgoH6q7HDJu4tdyQJ3IezkktLnUlJ-2KRGtVDBY1TVzTD3pQHvMzu-YXt3PJCuQgZV5sVn9NyeLjppN2LtXnfsXl5FK2je2ucSA5LDcqoMaPytwax7Yzm-KM2snrew/s400/gun-deaths-florida.png" width="318" /> </a></div>
<div style="text-align: center;">
source: <a href="https://www.livescience.com/45083-misleading-gun-death-chart.html">Misleading Gun-Death Chart Draws Fire</a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Now think about what we covered previously about the importance of accurate chart axes, and take a look at the Y axis tick markings: they're upside down! This chart is effectively inverted, because it fails to follow the convention that <i>up means more</i>. <br />
<br />
<h3>
On a Map, Darker Map Shades Mean More</h3>
Consider a map that is conveying data, such as which US states make the most revenue. The convention is that darker shades mean more (greater density or higher amounts).<br />
<br />
In the map chart below, darker blue shades were used for lower export profits and lighter green for higher. It's the opposite from most maps of this kind. This doesn't make the chart evil, but it is flouting a convention. If the shading scale was reversed, readers would get what the map is trying to convey more readily. Every time you go against a convention, you up the chance someone will get the wrong message.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXk4wC4CE6dJLSd0T9l0pSeIFqjeXST33AcYKfwjzttqwfx6-yCsEC00-Odo_IbJPfTuX2og-2pQnaWCcvpxUeCf404DowtXBR_yqRpMPLW20DkxYfTI5rqn3PWCLwm0ouF0Z8kYRzIIU/s1600/map-density.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1200" data-original-width="1200" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXk4wC4CE6dJLSd0T9l0pSeIFqjeXST33AcYKfwjzttqwfx6-yCsEC00-Odo_IbJPfTuX2og-2pQnaWCcvpxUeCf404DowtXBR_yqRpMPLW20DkxYfTI5rqn3PWCLwm0ouF0Z8kYRzIIU/s320/map-density.png" width="320" /></a></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="https://www.alec.org/article/exports-drive-economic-growth-in-the-states/">Exports Drive Economic Growth in the States</a></span></div>
<h2>
Use of Color</h2>
<br />
If you're just trying to select two colors for showing last month's
expenses vs. this month's expenses, color choice might not seem very
important, but it can be. It helps to understand how your audience perceives color so you can use it to support the story your chart is telling. We'll talk about
some of the meanings attached to colors by different groups. First though you should understand that it's a mistake to rely solely on
color to communicate something: a substantial number of people are
colorblind (and many don't even know it). Always accompany color with
other visual cues. Here's how a colored chart might appear to a colorblind person:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbEauI0O52FsFi4Oa0hXT_fPivBOmcfKgPxl5eKd74AntKctzi3HUPex1GBBsyKw82-0d5LYqKx38xys9TO4KkScYs5GYt-xMbZy4y-LS7fIdgh5lNhvzap0Vtms9VnL4Ho0h0-tcpnMw/s1600/color-blind-chart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="384" data-original-width="960" height="160" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbEauI0O52FsFi4Oa0hXT_fPivBOmcfKgPxl5eKd74AntKctzi3HUPex1GBBsyKw82-0d5LYqKx38xys9TO4KkScYs5GYt-xMbZy4y-LS7fIdgh5lNhvzap0Vtms9VnL4Ho0h0-tcpnMw/s400/color-blind-chart.png" width="400" /></a></div>
<br />
<div style="text-align: center;">
<span style="font-size: x-small;">Source: <a href="https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts#toc-14">Chart Do's and Dont's</a></span></div>
<br />
Color might appear to be one of those worldwide or east/west cultural
matters, as in "Western culture associates red with danger"—and it is,
to some degree. Then again, red is often used to communicate other
things like excitement or Communism to that same audience. <br />
<br />
Like most things, going extreme in color will make your chart worse, not better. Avoid too many colors or strong saturated hues: it's the color graphics equivalent of shouting. If you practice restraint in your general color palette, then you can highlight something really effectively with a stronger color.In the two charts below, is the color chart on the left easier or harder
to perceive than the grayscale version to the right? I find
the color chart loud and ugly with colors that distract rather than help. The grayscale chart is effective without the color.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc-f_cKKvai76girRkRLMhledJKoK8N82s2Zq7M9K4-gu26g0v8tQmuUBahoDgyWPxYTMRKqm6ZCWS_l2tM8M9QaLphbjs0B0R6_fKCL_qu_l4VlnXUY5Tm3hUWmAAHLnSy7PjS4ZA5fo/s1600/chart-gray.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="367" data-original-width="1000" height="145" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgc-f_cKKvai76girRkRLMhledJKoK8N82s2Zq7M9K4-gu26g0v8tQmuUBahoDgyWPxYTMRKqm6ZCWS_l2tM8M9QaLphbjs0B0R6_fKCL_qu_l4VlnXUY5Tm3hUWmAAHLnSy7PjS4ZA5fo/s400/chart-gray.png" width="400" /></a></div>
<br />
Different groups attach different meanings to color, known as Color Biases. Speaking broadly, western culture audience will attach any of these associations to colors:<br />
<ul>
<li>Blue: trust, security, peace, coolness</li>
<li>Green: nature, freshness, luck, environment, wealth, inexperience, jealousy</li>
<li>Orange: warmth, harvest, light, heat</li>
<li>Purple: power, royalty, ambition, independence</li>
<li>Red: warmth, excitement, passion, love, danger</li>
<li>Yellow: joy, value, sunlight, caution, cowardice</li>
</ul>
<br />
We can't stop there however. Many industries also have color biases, and failing to know that could really upset how chart colors will hit your audience.You might be inclined to use green for good things and red for bad, but to someone in health care green means infected and red means healthy! It's worth getting to know your audience, and one easy way to do that is to examine how charts in their industry are commonly colored and labelled.<br />
<ul>
<li>In Finance: blue is reliable/subdued, green is profitable, yellow is highlighted/important, red is unprofitable</li>
<li>In Health Care: blue is dead, green is infected, yellow is jaundiced, red is healthy</li>
<li>To Control Engineers, blue means cold/water, green is safe, yellow is caution, red is danger</li>
</ul>
<h2>
3D</h2>
There's only one rule for using 3D in your charts and it's very simple: don't do it, ever. Why, you ask? Making that bar chart or pie chart into 3D adds a nice touch, you might argue. Let's see. Look at the two pie charts below. Who sold the most in Q1? And who sold the most in Q2? When I asked this question the last time I presented on charting, many people said Paul (blue) sold the most in Q1 and Bryan (orange) sold the most in Q2. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQhUIJxuRLQtzdjNm0dD7ccB2DMJkuBbgbemvzCFUUUB8jTxabfOVaEsLy8E4MqAb1KmBqOl5TnAw3QYoZDCzukaKl-ga3IsH2MVAM0fexaCHfBhHLl9wIzRgoPXgAHW1EkP6w7TkNdsg/s1600/3d-pie.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="430" data-original-width="1170" height="117" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQhUIJxuRLQtzdjNm0dD7ccB2DMJkuBbgbemvzCFUUUB8jTxabfOVaEsLy8E4MqAb1KmBqOl5TnAw3QYoZDCzukaKl-ga3IsH2MVAM0fexaCHfBhHLl9wIzRgoPXgAHW1EkP6w7TkNdsg/s320/3d-pie.png" width="320" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
<span style="font-size: x-small;">source: <a href="https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts">Chart Do's and Don'ts </a></span></div>
<br />
In fact, these are two pie charts <u>of the same data</u> (below), simply with a different rotation. Paul and Bryan have exactly the same sales. The 3D effects break the visual contract that normally gives a pie chart its power: your eye and brain interpreting the relative proportions of the visual elements. That's completely demolished by a 3D pie chart. There's no greater evil in the charting world.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisdaHIQolQzk9u5X97KmayZ0ml-Hs9uo3t72twiXaqL00re8uOhKKjq0l-b1fRGvfAkUDtAK-OoxIekkvc_6gJMm0LriErIj5bsKGbBnXCSFPh1k4QznIYn7lLntyf4bwP_OuNU71457E/s1600/3d-pie-data.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="326" data-original-width="848" height="123" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEisdaHIQolQzk9u5X97KmayZ0ml-Hs9uo3t72twiXaqL00re8uOhKKjq0l-b1fRGvfAkUDtAK-OoxIekkvc_6gJMm0LriErIj5bsKGbBnXCSFPh1k4QznIYn7lLntyf4bwP_OuNU71457E/s320/3d-pie-data.png" width="320" /></a></div>
<br />
<br />
In the 3D column chart below, your first impulse is to see the green 1997 value as way smaller than the red 1995 value. You can intellectually understand there's perspective in the graphic, but a reader's first take on the chart is still going to be misleading. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDmdgE7tCmguQu9KHXW4FxWqYGZ-V1-mIGU937IoFg_LZwXIOVCkYv16YXk1mZNP14M6FtPvLjnCZJ4OCUn8FqK7LXa3skVW-A2WQykCBRXrfvTJJu1VwmRKUMdkKPd4PlJCN0wOa66Rg/s1600/3d-columb.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="391" data-original-width="659" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjDmdgE7tCmguQu9KHXW4FxWqYGZ-V1-mIGU937IoFg_LZwXIOVCkYv16YXk1mZNP14M6FtPvLjnCZJ4OCUn8FqK7LXa3skVW-A2WQykCBRXrfvTJJu1VwmRKUMdkKPd4PlJCN0wOa66Rg/s320/3d-columb.png" width="320" /></a></div>
<div style="text-align: center;">
<i>3D column chart</i></div>
<br />
There's simply nothing to be gained by making your charts 3D. Promise me you won't do it.<br />
<br />
<h2>
Resources</h2>
This series was inspired by the first resource I came across about deceptive charting, <a href="https://www.amazon.com/How-Charts-Gerald-Everett-Jones-ebook/dp/B07J5J91CV/ref=sr_1_1?dchild=1&keywords=how+to+lie+with+charts&qid=1588431110&sr=8-1">How to Lie with Charts</a> by Gerald Everett Jones. Now in its fourth edition, Gerald has kept his book current with new material on topics like fake news and social media disinformation.<br />
<br />
Well, that's it for this series. I hope you now feel well-equipped to detect misleading charts when you encounter them, and to avoid being misleading in the charts you create.<br />
David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-23624812846294302962020-03-08T10:41:00.001-07:002020-05-02T10:40:46.423-07:00Bad Charting Part 3: Axis Abuse<div class="post-header">
</div>
This is Part 3 <a href="https://davidpallmann.blogspot.com/2020/02/bad-charting-part-1-charts-vs.html">in a series</a>
on avoiding the pitfalls of bad charting. Today we'll discuss how axis abuse can make a chart deceptive.<br />
<br />
<h2>
Axis Abuse: What Is It?</h2>
<i>Axis abuse</i> happens when your chart's axes (such as the X-axis or Y-axes for a bar chart) don't follow standard conventions. Those conventions include starting your axis at 0, using a proper aspect ratio, and using an expected axis range. Axis abuse is unbelievably common, and that's because it's one of the easiest and most effective ways to distort how a chart is understood.<br />
<br />
<h3>
Axes Should Start at Zero</h3>
When charts show amounts with a visual element (such as bar, column, line, area, and pie charts), there's an implicit assumption that we are being shown <b>the whole thing</b>. When it turns out we're only seeing part of the picture, we're being deceived. The way we're all taught to understand charts with axes is that the bottom left corner is zero. When a chart fails to uphold that, we get the wrong idea about what's being shown. Let's look at some examples.<br />
<br />
<h4>
Example 1: Emissions</h4>
<div class="separator" style="clear: both; text-align: left;">
Look at the chart below. Taking in what the visuals portray, how do you feel about Emission A vs. Emission B? At first glance, Emission B seems about five times worse than Emission A.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu0z_2MwiTzOsZQxDeukP1cSraxlNEs8zhon7KnxL4AIBivxG2BONPS8EgI5Y5pZGXRFeuKhzANhmWlM-fSRFOR3f7uCxaaecgFnlHvfjKIDauNs7828urwuTAs7tCuWoBDhT_1VR4u8c/s1600/axis_emissions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="325" data-original-width="516" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu0z_2MwiTzOsZQxDeukP1cSraxlNEs8zhon7KnxL4AIBivxG2BONPS8EgI5Y5pZGXRFeuKhzANhmWlM-fSRFOR3f7uCxaaecgFnlHvfjKIDauNs7828urwuTAs7tCuWoBDhT_1VR4u8c/s400/axis_emissions.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
The above chart has a flaw: the Y axis starts at 30, not 0, which paints a deceptive picture. Below is the same data, this time with a correct zero baseline. It tells a very different story, doesn't it? Now we see the truth: Emissions B is more like 1.5 times Emissions A.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE44SaIP-JfUAH1yjpgdLUwK6iQkcNOoSSCZIsY-NpwHFrhewJwoZpkDi57suLzWMKLlKxFAvxcc2r9uWdTGxIdinpP79mgeNayBeTwtaXUe4vjWyl3-GTIygLijtJIoKa9wMfsnIcGW4/s1600/axis_emissions2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="325" data-original-width="516" height="251" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgE44SaIP-JfUAH1yjpgdLUwK6iQkcNOoSSCZIsY-NpwHFrhewJwoZpkDi57suLzWMKLlKxFAvxcc2r9uWdTGxIdinpP79mgeNayBeTwtaXUe4vjWyl3-GTIygLijtJIoKa9wMfsnIcGW4/s400/axis_emissions2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<h4>
Example 2: London Times</h4>
Here's an example of a misleading chart in the London Times. The chart—and the whole premise of the article—is about how the Times is outselling the competition. The chart visuals communicate that the Times has more than twice the circulation of the Daily Telegraph. Now look at the Y axis: the chart axis begins at 420,000! If it started at zero, the difference between the Times (485K) and the Daily Telegraph (446K) would be hardly noticeable, a non-story.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjShijeY4FATPI0oRqULj9ORZeKsEhpyd4ruMfRE-IIOYyY9E_lNgjbRzGh-VhS78eUdoF8BPl6Gq5rolQbvXkwa_l40j-wn1KNMpKg9IfWzCUeqVFWRuhgSWSeoWklkkoGFHmnxOsJhFY/s1600/axis_times.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="428" data-original-width="1055" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjShijeY4FATPI0oRqULj9ORZeKsEhpyd4ruMfRE-IIOYyY9E_lNgjbRzGh-VhS78eUdoF8BPl6Gq5rolQbvXkwa_l40j-wn1KNMpKg9IfWzCUeqVFWRuhgSWSeoWklkkoGFHmnxOsJhFY/s400/axis_times.png" width="400" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
T<i>he Times Has A Massive Lead in Circulation ..or Does It? </i><span style="font-size: x-small;"><br />source: <span style="color: black; font-family: "calibri light";">https://www.statisticshowto.datasciencecentral.com/misleading-graphs/</span></span></div>
<h4 class="separator" style="clear: both; text-align: center;">
<i> </i></h4>
<br />
It is unbelievably common for axis abuse to happen in newspapers and magazines. These are organizations that should certainly know better. Be on your guard!<br />
<br />
<h4>
Example 3: Television Sports Chart</h4>
Television news networks and sports networks are just as guilty as print media with axis abuse. Look at the screenshot below from a sports program, where R.A. Dickey's Knuckleball Velocity is made to look like it's half of what it used to be. With an honest baseline of zero the drop from 77.3MPH to 75.3MPH would be barely noticeable.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrAJP6ofd7oWMxWG7-GXvZQODd4UsJ2IKu_h6_kYjDYazODRZ0cplmrHgFxVafJk5sTNDRaPd5zVvsZ7g158qqwK5aYw5ZUOFM61AF18j3ht14O5oIunUqzI1mNY7RnCa4wjE22fzOcsY/s1600/axis_sports.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="637" data-original-width="1192" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrAJP6ofd7oWMxWG7-GXvZQODd4UsJ2IKu_h6_kYjDYazODRZ0cplmrHgFxVafJk5sTNDRaPd5zVvsZ7g158qqwK5aYw5ZUOFM61AF18j3ht14O5oIunUqzI1mNY7RnCa4wjE22fzOcsY/s400/axis_sports.png" width="400" /></a></div>
<div style="text-align: center;">
<i>R. A. Dickey's Knuckleball Isn't What It Used To Be...?</i></div>
<br />
<h4>
Example 4: Average Male Height Increase Over the Years</h4>
The chart below is supposed to show how average male height (aged 21) has increased from the 1870s to the 1970s. It looks pretty astonishing; the visuals convey that men have doubled in height over a century! Once again, we have a dishonest baseline that starts at 155cm instead of 0cm.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp5tubaKKIav2ra21_aKpnn5Ioon_DcDrT8SmlTKvVRZZDlcRybopphpcoHE2eqBVD4Ah4yGFm1K4bWHKK4Cd4NxZqawtWs4oTvhK8u4dsvoKfyoYotHsXy5Y5eo9bUFoh2bg6RFMBbC4/s1600/axis_height.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="440" data-original-width="664" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp5tubaKKIav2ra21_aKpnn5Ioon_DcDrT8SmlTKvVRZZDlcRybopphpcoHE2eqBVD4Ah4yGFm1K4bWHKK4Cd4NxZqawtWs4oTvhK8u4dsvoKfyoYotHsXy5Y5eo9bUFoh2bg6RFMBbC4/s400/axis_height.png" width="400" /></a></div>
<div style="text-align: center;">
<i>My, How You've Grown!</i></div>
<h4 style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 0pt; text-align: center; unicode-bidi: embed; word-break: normal;">
<span style="font-size: x-small;">source: <span style="color: black; font-family: "calibri light";">https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts</span></span></h4>
<div style="text-align: center;">
<i></i></div>
<br />
<h4>
Example 5: Server Load</h4>
Which server load chart below gives you more concern? By now you realize these two charts are driven by the exact same data. The only difference is that the first chart's Y axis starts at 80 while the second starts at 0.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_EdKimHuDjUI8IIwo4egcW-NDPRaN5jHIjaNn-6-Ob3JWl8lyIaMkxci6DK4SJpY9gi8C7b3DkYajuecFbMC3aPXB6WNF04r_sm3Irxe_0cb1y1fN1bHMAN3Zp46nL9bJcmck5CYf2tA/s1600/axis_load1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="300" data-original-width="535" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_EdKimHuDjUI8IIwo4egcW-NDPRaN5jHIjaNn-6-Ob3JWl8lyIaMkxci6DK4SJpY9gi8C7b3DkYajuecFbMC3aPXB6WNF04r_sm3Irxe_0cb1y1fN1bHMAN3Zp46nL9bJcmck5CYf2tA/s400/axis_load1.png" width="400" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNQMz7NiGYVluI-4P-16RdOG040-VF_p2PYqkP5NKsU8iOSrYU5NL4soXA11HaDJhG5XA3DsmyJa6HHKZkJmoRx7pSriQL4R2Xmj40Us_DqtnThP3E7aobPuZV_UYER-uUVRNfEtgCHdc/s1600/axis_load2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="300" data-original-width="535" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNQMz7NiGYVluI-4P-16RdOG040-VF_p2PYqkP5NKsU8iOSrYU5NL4soXA11HaDJhG5XA3DsmyJa6HHKZkJmoRx7pSriQL4R2Xmj40Us_DqtnThP3E7aobPuZV_UYER-uUVRNfEtgCHdc/s400/axis_load2.png" width="400" /></a></div>
<div style="text-align: center;">
<i>Which Load Chart Concerns You More?</i>
<br />
<div style="direction: ltr; margin-bottom: 0pt; margin-left: 0in; margin-top: 0pt; text-align: center; unicode-bidi: embed; word-break: normal;">
<span style="font-size: x-small;"><span style="color: black; font-family: "calibri light";">source: https://grafana.com/blog/2019/06/10/how-not-to-fail-at-visualization/</span></span></div>
</div>
<br />
<h4>
Example 6: Microsoft Edge Performance</h4>
One last example to illustrate how common and audacious this practice is. In the gauge charts below, Microsoft is crowing how Microsoft Edge outperformed Chrome and Firefox in a particular benchmark. While the claim is true, these charts are highly misleading. When you consider that Edge (blue gauge) scored 31,786 while Chrome (green) scored 29,619 and Firefox (red) scored 26,876 it's quite clear these gauges do not start at zero. Even worse than the prior examples, they're not even labelled.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYbvHy7eheRJBGBMxFFp9qIRtyVwiV_d_AGrolfGITA7iMK8jMJxENMccgXehOhk3E1ygVYSfBIEQkDzzeo47HWJy3z58p4v7S_1B0Es-VhWWO98PPvf97P6i9FbCpY_VHG5xoJenlMDo/s1600/axis_edge.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="446" data-original-width="975" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYbvHy7eheRJBGBMxFFp9qIRtyVwiV_d_AGrolfGITA7iMK8jMJxENMccgXehOhk3E1ygVYSfBIEQkDzzeo47HWJy3z58p4v7S_1B0Es-VhWWO98PPvf97P6i9FbCpY_VHG5xoJenlMDo/s320/axis_edge.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Misleading Browser Charts</i></div>
<br />
If we plotted the benchmark data honestly, it would look like this on a column chart:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm4npmyQKqPSrFBt524WV42dj3D4gV6p-MfptVhf8oisvBoq6590jRXRElqLRCoG8rVcLyREKyLylDHUsHRD-K-KrimRvo24Kt5OKQS0vDQLYTRzfQ0R2lPp52R8wJEyNSJqRf5BgiHLk/s1600/axis_edge2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="360" data-original-width="708" height="202" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgm4npmyQKqPSrFBt524WV42dj3D4gV6p-MfptVhf8oisvBoq6590jRXRElqLRCoG8rVcLyREKyLylDHUsHRD-K-KrimRvo24Kt5OKQS0vDQLYTRzfQ0R2lPp52R8wJEyNSJqRf5BgiHLk/s400/axis_edge2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<i>A more Honest Comparison</i> </div>
<br />
<h3>
If You Must Show A Partial Axis... </h3>
On occasion you may feel you have a valid reason to truncate an axis. If you feel
strongly compelled to not show a complete axis, there are responsible
ways to depict that. The chart below makes it clear that the bars are
truncated.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8AxDbiZLozMPEKAFYwloCsH7iAX49xlErleZV0qZ_eF1lFV57CbYAZUzOMT6QV8b_ICEoiS5qsGcNsNJYMbU9A_Jl1004Nw5BycBf-mM8kF3hark6iqzG3eKiz_GoYBLq8sqkP9kQQwk/s1600/axis_gap.png" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="475" data-original-width="708" height="214" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg8AxDbiZLozMPEKAFYwloCsH7iAX49xlErleZV0qZ_eF1lFV57CbYAZUzOMT6QV8b_ICEoiS5qsGcNsNJYMbU9A_Jl1004Nw5BycBf-mM8kF3hark6iqzG3eKiz_GoYBLq8sqkP9kQQwk/s320/axis_gap.png" width="320" /></a></div>
<div style="text-align: center;">
<i>A Responsible Way to Show a Partial Axis</i></div>
<br />
<h3>
Chart with Integrity </h3>
All sorts of excuses are made for not starting with a zero baseline.
There's not enough space. We want to focus in on the interesting part of
the chart. People sit too far from the TV to make out the detail. None
of these excuses justify the deception, and it <u>is</u> deception, whether
intentional or not. You form a conclusion from the visuals long before
(or if) you digest the numbers on the chart. <br />
<br />
The widespread practice of deceptive charting does not make it okay. Beware this lack of integrity when you view charts, and don't go down this road with your own charts. Always value honesty and accuracy over getting attention.<br />
<br />
<h2>
Don't Deceive With Ranges</h2>
Charts can also be deceptive when the amount of data selected is altered to favor a preferred story. Look at the two stock charts below from Yahoo. Which stock would you rather own, the one in red that's descending or the one in green that's on the way up?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggIULTCIUjzr-523_zbHN9aLyILqcfi1U_MlNkEiR_5XfOBRrfJJ_UrYOGFc27rS05Zh8mN98eBtk1Cb-7K1hHLUOTHM9BYC5_NXSsYR8jTIWbCQ_vRz6H9DwUvcK5tReqjH9XqgSJCw0/s1600/interval_stock1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="308" data-original-width="538" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggIULTCIUjzr-523_zbHN9aLyILqcfi1U_MlNkEiR_5XfOBRrfJJ_UrYOGFc27rS05Zh8mN98eBtk1Cb-7K1hHLUOTHM9BYC5_NXSsYR8jTIWbCQ_vRz6H9DwUvcK5tReqjH9XqgSJCw0/s400/interval_stock1.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRxbQ7m2eIzuLgskNxQFzeJUSdxADnQeMEpQ9tgvJFCRRK0cpEl1MDTBxtY4BnJAHf_LJ-s4Rd1DoAFNmEfEmgCLykdHVDWUohdP5pHqNlnalcEWnFKTFagR2fLJ89DPmIOGnBaSZLa0A/s1600/interval_stock2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="309" data-original-width="538" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRxbQ7m2eIzuLgskNxQFzeJUSdxADnQeMEpQ9tgvJFCRRK0cpEl1MDTBxtY4BnJAHf_LJ-s4Rd1DoAFNmEfEmgCLykdHVDWUohdP5pHqNlnalcEWnFKTFagR2fLJ89DPmIOGnBaSZLa0A/s400/interval_stock2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div style="text-align: center;">
<i>Which Stock Would You Rather Own?</i></div>
<br />
<br />
In point of fact, these are both AMZN stock charts take <u>at the same time</u>. The only difference is that the first chart was a 1 Day range of data while the second showed a 1 Year of data.<br />
<br />
Never pull the wool over your audience's eyes by selecting an unexpected data range, and never leave out important information like what the interval is. There's a reason public companies have to abide by strict rules and report data over careful intervals like quarters.<br />
<br />
<h2>
Don't Omit Intervals </h2>
Another way a chart can be deceptive is when you don't have (or don't include) all of the data intervals. The creator of the chart below didn't have data for 2003 or 2004, so it's not on the chart. But that's deceptive, because it makes it look like the data is trending differently than it really is.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-hNpYqPtahhyRWI9pfZyGLeEL_Uba_Yx6hc1YADbSAoXkc9E1FfI2ZjKzw2yPuywoqP646cc6pXaQnRWJkQevS5wk5qPSbD7BX5M0iXz7bDVLJX649EJivl2v198FH5uBpuoe3_iJqL0/s1600/interval1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="372" data-original-width="524" height="283" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-hNpYqPtahhyRWI9pfZyGLeEL_Uba_Yx6hc1YADbSAoXkc9E1FfI2ZjKzw2yPuywoqP646cc6pXaQnRWJkQevS5wk5qPSbD7BX5M0iXz7bDVLJX649EJivl2v198FH5uBpuoe3_iJqL0/s400/interval1.png" width="400" /></a></div>
<br />
<br />
The chart below is better because it makes it clear that some of the data is missing. The viewer is less likely to draw an incorrect conclusion about trends.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZzc6WmwurUDUZzckSbIAsi1Q0AKQBp-83shvPDJUq1NZ0UgBX92BhO6-C5uKkeY7T5XpM0J9f8GU1a81n1FruOue82hcwywQV5mOli717t_hL6sizuwQ2lz4-SO3jsS-0YZMcbwXdSFE/s1600/interval2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="372" data-original-width="524" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZzc6WmwurUDUZzckSbIAsi1Q0AKQBp-83shvPDJUq1NZ0UgBX92BhO6-C5uKkeY7T5XpM0J9f8GU1a81n1FruOue82hcwywQV5mOli717t_hL6sizuwQ2lz4-SO3jsS-0YZMcbwXdSFE/s320/interval2.png" width="320" /></a></div>
<br />
<h2>
Use Proper Aspect Ratios </h2>
Yet another built-in assumption we have when we view charts is that they follow a 45-degree slope. When they don't, we can be fooled into seeing an attractive or scary rate change. Look at the charts below, which show the same data but with varying aspect ratios. They certainly convey different emotions, don't they?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnFaZitRfYvJwCcR-YbaPooQC8zADhm7glxcR3WP9gutx0FxoKOrQL8s6Esx2Cto8L1Vqp-R6T9cC_8iJ13c868gwA665GtKyOz3nQbbuiCOju7Y9fCZMKSmviamgqfmRYs1ZNQ_sniY8/s1600/aspect-ratio.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="478" data-original-width="714" height="266" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnFaZitRfYvJwCcR-YbaPooQC8zADhm7glxcR3WP9gutx0FxoKOrQL8s6Esx2Cto8L1Vqp-R6T9cC_8iJ13c868gwA665GtKyOz3nQbbuiCOju7Y9fCZMKSmviamgqfmRYs1ZNQ_sniY8/s400/aspect-ratio.png" width="400" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Aspect Ratio Changes the Message</i></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts</span></div>
<br />
<h2>
Conclusion</h2>
One of the easiest ways to change the message of a chart is by toying with its axes. Axes that don't start at zero mislead because we are seeing only part of amounts in the visuals. Unexpected ranges also mislead because we are seeing less or more of the data than we expect. Improper aspect ratios and missing intervals can deceive us about trends.<br />
<br />
Chart makers have a great deal of power. There's a visual contact between chart maker and chart viewer, and as a responsible chart maker you need to be aware of that contract and uphold it.<br />
<br />
In <a href="https://davidpallmann.blogspot.com/2020/05/bad-charting-part-4-following.html">Part 4</a>, we'll look at conventions, color, and the use of 3D in charts.<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-31372898027589088752020-02-28T07:09:00.004-08:002020-03-08T10:41:42.533-07:00Bad Charting Part 2: Use the Right Chart TypeThis is Part 2 <a href="https://davidpallmann.blogspot.com/2020/02/bad-charting-part-1-charts-vs.html">in a series</a> on avoiding the pitfalls of bad charting.Today we'll discuss the importance of using the right chart type for what you want to show, and what happens when you get that wrong.<br />
<br />
<h2>
Wrong Chart Type Examples </h2>
Before we get <i>how</i> to choose the right chart type, let's see some examples where using the wrong chart type killed the chart's effectiveness. These examples come from the European Environment Agency's <a href="https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts">Chart Do's and Don'ts</a> site. <br />
<br />
<h3>
Households by Type</h3>
Below we see a stacked column chart depicting households by type. Each column totals 100% but is subdivided to break down percentage of various household types. Before going further, do any particular trends jump out at you from this chart?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZC7zzNM-dfxYwm_wR8JWHM7KT2pFwT98nZCmprP8aSsTasPmZvJeUS7-lyVWFFW3lUOwN8UXKwL-qxYXwBC1W-aqYPs6OiceGJXFStlbX1MGElfy5Y4lCt5sFjnXUfkv4pcvGjqEDjRk/s1600/stacked-column-chart-wrong-chart-type.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="310" data-original-width="450" height="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZC7zzNM-dfxYwm_wR8JWHM7KT2pFwT98nZCmprP8aSsTasPmZvJeUS7-lyVWFFW3lUOwN8UXKwL-qxYXwBC1W-aqYPs6OiceGJXFStlbX1MGElfy5Y4lCt5sFjnXUfkv4pcvGjqEDjRk/s320/stacked-column-chart-wrong-chart-type.png" width="320" /></a></div>
<div style="text-align: center;">
<i>The Stacked Column Chart is the wrong choice for this data</i><span style="font-size: x-small;">source: <a href="https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts">Chart Do's and Don'ts</a></span></div>
<br />
Now consider the same data below plotted in a line chart. There's a dramatic difference, and now it's easy to see a nosedive in the <i>Married Couples with Children</i> category. In the earlier chart, this was all but unnoticeable. As this chartmaker did, you might make this the chief message of your chart and highlight it. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKzYqmZ-KfiXyJpmruk0uWvW5KUIqMY60HaDvlXZRv_aSbV2A7it46jW3f2qYhz5hmH9cvfs0KutkpXfL1ei3pml1OosvED3pm3cdfWiyk3sag6pIN7W1BdCr8yps2Lc8QA9-KQqfHk44/s1600/line-chart-right-chart-type.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="624" data-original-width="860" height="232" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgKzYqmZ-KfiXyJpmruk0uWvW5KUIqMY60HaDvlXZRv_aSbV2A7it46jW3f2qYhz5hmH9cvfs0KutkpXfL1ei3pml1OosvED3pm3cdfWiyk3sag6pIN7W1BdCr8yps2Lc8QA9-KQqfHk44/s320/line-chart-right-chart-type.png" width="320" /></a></div>
<br />
<div style="text-align: center;">
<i>A Line Chart is a better choice for this data</i></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts">Chart Do's and Don'ts</a></span><br />
<br /></div>
<h3>
Specialization in Nordic Labor Markets</h3>
In this example, a bubble chart was plotted over a map to show specialization in high-tech manufacturing and/or R&D in Nordic labor markets in 2005 (that's a mouthful). While the use of the map might be useful to someone very familiar with the local geography, the map obscures rather than helps. It's not the simplest way to show the winners and losers.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikaS1txq1Adf7u3w17titQOf1TggQs8wA3Vz76fINLDoF9PbI-dEjx9t30ozwkLzWaUa8RZGi9eGNfOqxAdJFEHkbtidnN7AB21rcIaBc7YBdAbf6VrI26YfBuc6YuuRDmiT5jmfYDhzM/s1600/bubble-map-wrong-chart-type.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="510" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikaS1txq1Adf7u3w17titQOf1TggQs8wA3Vz76fINLDoF9PbI-dEjx9t30ozwkLzWaUa8RZGi9eGNfOqxAdJFEHkbtidnN7AB21rcIaBc7YBdAbf6VrI26YfBuc6YuuRDmiT5jmfYDhzM/s320/bubble-map-wrong-chart-type.png" width="226" /></a></div>
<div style="text-align: center;">
<i>The Map hinders rather than helps this chart</i></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts">Chart Do's and Don'ts</a></span><i> </i></div>
<br />
The simple bar chart below is a lot easier to digest.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinQhBin6QJGurKN7A1nD3I-i1IEvaxp_AP_Y0JnZnrlKFJWrvJRacq-LcEvUs08uZg3fM-_O1jdzgzdhlmrk_W7QxGd30LNKT95MI7MJGo3Bayi_7kLjeNjS46FAU8hh-VBT-qQlqWLY4/s1600/bar-chart-right-type.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="378" data-original-width="600" height="201" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinQhBin6QJGurKN7A1nD3I-i1IEvaxp_AP_Y0JnZnrlKFJWrvJRacq-LcEvUs08uZg3fM-_O1jdzgzdhlmrk_W7QxGd30LNKT95MI7MJGo3Bayi_7kLjeNjS46FAU8hh-VBT-qQlqWLY4/s320/bar-chart-right-type.png" width="320" /></a></div>
<br />
<div style="text-align: center;">
<i>A Bar Chart is a better choice for this purpose</i></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="https://www.eea.europa.eu/data-and-maps/daviz/learn-more/chart-dos-and-donts">Chart Do's and Don'ts</a></span></div>
<br />
<br />
These examples show how important it is to use an appropriate chart type.<br />
<br />
<h2>
What is it You Want to Show?</h2>
Choosing the right chart type depends on your <u>objective</u>. <b>Why </b>do you want to visualize this data? Do you want to compare something? Show what something is composed of? Show distribution? Show a relationship? Answering this first question will reduce your chart choices from many to a handful.<br />
<br />
Once you know your objective, you'll still have several chart types available. You can settle on the right chart type by also considering the number of variables you need to show, whether there are few or many data points, and whether you'll be showing values over time.<br />
<br />
A guide such as the <a href="https://extremepresentation.typepad.com/blog/2006/09/choosing_a_good.html">Chart Chooser diagram</a> by Dr. Andrew Abela can be helpful. Keep in mind that this is not a definitive list. New chart types arise from time to time and some chart types wax and wane in popularity over time. For example, right now the pie chart has fallen into disfavor in some circles. You might want to prune your options to the chart types your organization is comfortable with. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHVX4VJFPjqbCD7H7wozHO-6V0d5oB5RZvIb0Im4x2GuBnS_SCX6V1UAsBF_3fQU66XWgFTuF2FMuXxMvzYBx-RyJHzvb90Tyn5BCToBr0vMfGKhVbKK1tiAE1Qm87wg3UWDmheWcu-BQ/s1600/chart-chooser.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1050" data-original-width="1395" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHVX4VJFPjqbCD7H7wozHO-6V0d5oB5RZvIb0Im4x2GuBnS_SCX6V1UAsBF_3fQU66XWgFTuF2FMuXxMvzYBx-RyJHzvb90Tyn5BCToBr0vMfGKhVbKK1tiAE1Qm87wg3UWDmheWcu-BQ/s320/chart-chooser.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Chart Chooser</i></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
Let's look at these 4 big categories of data visualization and see what makes them tick.<br />
<br />
<h2>
Comparison</h2>
In a comparison you have multiple items to compare or multiple datasets to compare. If you need to show exact values, consider a table in place of a chart.<br />
<br />
When you have just a few categories a column chart is a good choice. For example, showing responses to a survey question or comparing sales for the last two years. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2BOoVemKxPoa1Qy4vR5tglqIhGz7k0mYSAd8PaH0v43qKDa-hmkEKInXe6pGef9lSOeh6kD_mV6mh04yuhCOH8-AjfwwvNqVSiM_X8QipgJ3wu7h4a5GI6IGxi7lcemke3tK2vkJQH3E/s1600/column-chart-governor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="481" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2BOoVemKxPoa1Qy4vR5tglqIhGz7k0mYSAd8PaH0v43qKDa-hmkEKInXe6pGef9lSOeh6kD_mV6mh04yuhCOH8-AjfwwvNqVSiM_X8QipgJ3wu7h4a5GI6IGxi7lcemke3tK2vkJQH3E/s320/column-chart-governor.png" width="320" /></a></div>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS6MT1XaaS-ZN-CorY3eumF9WStnGtr6yK2ZxjPvqti5Zko0LJ4DfemG9fzMvUBTxR4e5HursI6vBYzxarhX-dWbYTcOdTd_46MSibYTfTiPtbWo9Vc4hkT3CVfrBdU_tqLwr7_Owitq4/s1600/column-chart-sales-2-years.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="481" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS6MT1XaaS-ZN-CorY3eumF9WStnGtr6yK2ZxjPvqti5Zko0LJ4DfemG9fzMvUBTxR4e5HursI6vBYzxarhX-dWbYTcOdTd_46MSibYTfTiPtbWo9Vc4hkT3CVfrBdU_tqLwr7_Owitq4/s320/column-chart-sales-2-years.png" width="320" /></a></div>
<div style="text-align: center;">
<i> Column Chart</i></div>
<br />
When you have many categories or long names, a horizontal bar chart will work better.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjewpqCo43uOgYvhG5uvfkTD_uDlYtCYq4nid3l-EXHvQrEIhtOHIGdojO0R8_qokThgFlgCERfQLD28sCHngkbqf4ukqsDBP3IbVibLEROOQGnaMQ_DiIImkXHlvXzshhBZ60tM6sdUwk/s1600/bar-chart-governor.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="480" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjewpqCo43uOgYvhG5uvfkTD_uDlYtCYq4nid3l-EXHvQrEIhtOHIGdojO0R8_qokThgFlgCERfQLD28sCHngkbqf4ukqsDBP3IbVibLEROOQGnaMQ_DiIImkXHlvXzshhBZ60tM6sdUwk/s320/bar-chart-governor.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Bar Chart</i></div>
<br />
When you have multiple data series per category, a <a href="https://vizzlo.com/create/grouped-bar-chart">grouped column chart</a> (also known as a <i>grouped bar chart</i> or a <i>clustered bar graph</i>) may work best. For example, imagine you want to break out responses to a survey question not only by the response given but also by age range. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_wGnOMsO5OF5f3MBRdclGhQzrU5nqcTwfRGsUvHs9jS6c535F6PiT_n0mryQtkriFWpc0rtN4ReekLRddFh6m6QZR-pucorlgbMChZ_Ld7jHNFvG3hvpSlLp5DvHmrjxAbLY0ztuKw7Y/s1600/clustered-bar-voting-age.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="481" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_wGnOMsO5OF5f3MBRdclGhQzrU5nqcTwfRGsUvHs9jS6c535F6PiT_n0mryQtkriFWpc0rtN4ReekLRddFh6m6QZR-pucorlgbMChZ_Ld7jHNFvG3hvpSlLp5DvHmrjxAbLY0ztuKw7Y/s320/clustered-bar-voting-age.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Grouped Column Chart</i></div>
<br />
To show trends over time for continuous data,
use a line chart. For example, illustrating how various categories of
expenses are trending over time.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtgB-Ca1qugYkYbd7u2vQ9FosqXr3cDvMmDpKQ60DrLPNR4dCwVe-fMHuBgjGCk8HQvMcVYNObhxmKIAF0xa-kt8kpfpk4wGcg_3LRHavGQKu1DoAG9sXMhdEhdcLuPkNoXXJ7avYzlOc/s1600/line-chart-expenses.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="453" data-original-width="489" height="296" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtgB-Ca1qugYkYbd7u2vQ9FosqXr3cDvMmDpKQ60DrLPNR4dCwVe-fMHuBgjGCk8HQvMcVYNObhxmKIAF0xa-kt8kpfpk4wGcg_3LRHavGQKu1DoAG9sXMhdEhdcLuPkNoXXJ7avYzlOc/s320/line-chart-expenses.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Line Chart</i></div>
<br />
<h2>
Composition</h2>
In composition you are revealing what makes up a data set.<br />
<br />
To show the composition of something with simple proportions, a pie chart is ideal. They are one of the most widely-understood chart types. Nevertheless there is currently <a href="https://www.richardhollins.com/blog/why-pie-charts-suck/">a backlash against pie charts</a> by some so you should carefully consider whether they are a good choice for your audience. You can help the pie chart's reputation by using them properly, that is to show percentages that add up to 100%.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUW6RYJcUqixrUTQeAcqyvJGFTsZ2cuYZfpdrLqY82Zn4OlJ75TFUE-kSqIE2AQ-YQQ_nsqALTPRHL2X_TduU7444nmB_kYnRokj7_rP5vyaGZblIfmrmZmeFGa5n7txRZ6tV4dfnFeGM/s1600/pie-chart-customer-sat.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="481" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUW6RYJcUqixrUTQeAcqyvJGFTsZ2cuYZfpdrLqY82Zn4OlJ75TFUE-kSqIE2AQ-YQQ_nsqALTPRHL2X_TduU7444nmB_kYnRokj7_rP5vyaGZblIfmrmZmeFGa5n7txRZ6tV4dfnFeGM/s320/pie-chart-customer-sat.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Pie Chart</i></div>
<br />
A donut chart is nothing more than a pie chart with a hole in the center. Any place you can use a pie chart a donut chart would be equally appropriate. One thing a donut chart can do that a pie chart can't do is show multiple data series by arranging multiple concentric rings around each other.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9ot5bqUkl2YEO1gxv6sEdWpT6j1hiN8QzcyQwciLb-dmwMdPNcHPGpa9OSOuTxYUcp5W9HupzBAUM4PzT7II1R64hyphenhyphenrEwBzLUqM1VTY52rIdpIdfhOdNuQy7LC2jd5obC7cMbrsZFnr0/s1600/donut-customer-sat.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="481" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9ot5bqUkl2YEO1gxv6sEdWpT6j1hiN8QzcyQwciLb-dmwMdPNcHPGpa9OSOuTxYUcp5W9HupzBAUM4PzT7II1R64hyphenhyphenrEwBzLUqM1VTY52rIdpIdfhOdNuQy7LC2jd5obC7cMbrsZFnr0/s320/donut-customer-sat.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCOIGfIdzgHuyUkkZhJVUNXANov0zA_zONjbW5GKHjVw3EVcW2pAwkvFhQpNBD2GsmWssVX9TzKtuD5nvveWajt3NNIC1XJB_3ZAFhjLF_fTOwdgG0YOI3thDiol0ke2WA1qCm80njKpo/s1600/donut-customer-sat.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="481" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCOIGfIdzgHuyUkkZhJVUNXANov0zA_zONjbW5GKHjVw3EVcW2pAwkvFhQpNBD2GsmWssVX9TzKtuD5nvveWajt3NNIC1XJB_3ZAFhjLF_fTOwdgG0YOI3thDiol0ke2WA1qCm80njKpo/s320/donut-customer-sat.png" width="320" /></a></div>
<div style="text-align: center;">
<i> Donut Chart</i></div>
<br />
When you want to show trends over time combined with part-to-whole composition, you can use an area chart. Area charts have some similarities to line charts but use filled areas below the line. The categories are stacked upon each other instead of all being plotted from the baseline. In Area charts the individual trends are harder to make out. Here's an area chart showing subscription sales over the course of a year, with substrata for students, adults, businesses, and non-profits. We might gain some insights into how school schedules or holidays affect sales.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7cqN3Qv1gPeqhBLJo_mX_UyzTsD3hG4jbum9adAtZcAYAv98DQIMxwDQlfe0Crx-NfTjWichzXPFu14PUCZgSuOPTYYacWU2AdLLsgD5DD1QotI7loikvM0PtSHEPJZGOB6HoJ4A0Bks/s1600/area-subscriptions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="481" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7cqN3Qv1gPeqhBLJo_mX_UyzTsD3hG4jbum9adAtZcAYAv98DQIMxwDQlfe0Crx-NfTjWichzXPFu14PUCZgSuOPTYYacWU2AdLLsgD5DD1QotI7loikvM0PtSHEPJZGOB6HoJ4A0Bks/s320/area-subscriptions.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Area Charts</i></div>
<br />
To show the composition of data across different categories, consider a stacked column chart. In the first chart below, sales revenue of various product categories are decomposed by season. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgERHXvt7acZ9zPXkE-zbTdFWJS0WFaf1H-3-UukBp1FDQbrNBxLiNIHrjAnpGxYTD3nCSH8nsdWrgLdq6rANYu-Vp_7TnWpE7n1QC7MptE5oqdWgw2fVgVoQ8I0WXumBfcuft21o8vY1s/s1600/stacked-column-apparel-revenue.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="480" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgERHXvt7acZ9zPXkE-zbTdFWJS0WFaf1H-3-UukBp1FDQbrNBxLiNIHrjAnpGxYTD3nCSH8nsdWrgLdq6rANYu-Vp_7TnWpE7n1QC7MptE5oqdWgw2fVgVoQ8I0WXumBfcuft21o8vY1s/s320/stacked-column-apparel-revenue.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Stacked Column Chart</i> </div>
<br />
When you want to focus on the composition of the data, you can use a stacked column chart and show percentage in the Y-axis. This is sometimes called a Stacked Percent Chart and all columns will be the same height (100%). In the chart below, reusing the same data from the earlier example, apparel revenue percentage is shown, again broken down by season.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgSrsaY7ji2xpcF7mZOl4h2QimL934MpO3mc0kdFZtaujqTJ1oPymRxB-pWnKFr7AliwXIdq1B01_iA1jM2fzggE3hie9rvtruqn9YJSas87Yz1UI9WcGyzGjzqgklN__mpxKVVxGjDAw/s1600/stacked-column-apparel.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="289" data-original-width="480" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgSrsaY7ji2xpcF7mZOl4h2QimL934MpO3mc0kdFZtaujqTJ1oPymRxB-pWnKFr7AliwXIdq1B01_iA1jM2fzggE3hie9rvtruqn9YJSas87Yz1UI9WcGyzGjzqgklN__mpxKVVxGjDAw/s320/stacked-column-apparel.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Stacked Percent Chart</i></div>
<h2>
Relationships</h2>
When you want to show how one variable is related to one or more other variables, consider a scatter plot chart or a bubble chart. Both can all be useful for showing suspected connections between the data. <br />
<br />
A scatter plot chart is used to analyze the relationship between two variables (one on each axis). The pattern of intersecting points can highlight a possible relationship. The chart below suggests a relationship between the amount of sugar people eat and their likelihood of tooth decay.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8kRzn4gtqonNKXxue8MJ_IhM2W7debUpihZXEN0Fkbp6-KzUkyQ_FQAok9QjTZqextM9FAxl2coFtjdG4x4KWuhqLklOhIZANPDacPks6WonGR8f5zqP_TYVcuEr9XwKLqRWj688gz6I/s1600/scatter-plot-chart-relationship-sugar-tooth-decay.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="544" data-original-width="420" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh8kRzn4gtqonNKXxue8MJ_IhM2W7debUpihZXEN0Fkbp6-KzUkyQ_FQAok9QjTZqextM9FAxl2coFtjdG4x4KWuhqLklOhIZANPDacPks6WonGR8f5zqP_TYVcuEr9XwKLqRWj688gz6I/s320/scatter-plot-chart-relationship-sugar-tooth-decay.png" width="247" /></a></div>
<div style="text-align: center;">
<i>Scatter Plot Chart </i><br />
<span style="font-size: x-small;">source: <a href="https://www.pewresearch.org/fact-tank/2015/09/16/the-art-and-science-of-the-scatterplot/">FactTank</a></span></div>
<br />
A bubble chart is much like a scatter plot chart except it can show a third variable, in the size of each bubble (its area, not its diameter). The bubble chart below shows car sales, with price in the Y-axis, units sold in the X-axis, and revenue in in the bubble. We can tell type B generates the most revenue both by the size of the bubble and its placement.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRPWxjnvS9fIPoYILanXEurriH5Wuizr9qZk6AOd3epMQlCZM55JDMT056jr9wFs8l3XcfgChEhLwXwXhadtlgt70ZGFomxW3mdFmkVbnM6lVX5AJ_yhwdSUJOKTI2wojCj58-YASd3Fc/s1600/bubble-chart-car-sales.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="542" data-original-width="1071" height="161" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRPWxjnvS9fIPoYILanXEurriH5Wuizr9qZk6AOd3epMQlCZM55JDMT056jr9wFs8l3XcfgChEhLwXwXhadtlgt70ZGFomxW3mdFmkVbnM6lVX5AJ_yhwdSUJOKTI2wojCj58-YASd3Fc/s320/bubble-chart-car-sales.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Bubble Chart</i></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="https://infogram.com/blog/bubble-charts-101/">Infogram.com</a></span></div>
<br />
While the above charts are well-suited for relationship visualization, it's also possible to show relationships using more common chart types like line, column, and bar charts.<br />
<br />
<h2>
Distribution</h2>
Distribution charts show how variables are distributed over time, which can help identify trends and outliers.<br />
<br />
Use a scatter plot can show the distribution of two variables. The scatter plot chart below shows Old Faithful geyser eruptions. It shows there are short-wait eruptions and long-wait eruptions.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbNOjImrYSDbwvtuy7mvLf7p7blGAQEKnPArkKFu7VDKb4ddZF6gNEhnQouWxEpHC3lbpcGu83KhpYaDDRi2FOw1vfsDCns1twjA0pDg6kGU6YKcJXmpGpk732cHE7vHHzr4QeSZg-ycw/s1600/scatter-distribution-old-faitfhul-eruptions.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="400" data-original-width="401" height="319" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbNOjImrYSDbwvtuy7mvLf7p7blGAQEKnPArkKFu7VDKb4ddZF6gNEhnQouWxEpHC3lbpcGu83KhpYaDDRi2FOw1vfsDCns1twjA0pDg6kGU6YKcJXmpGpk732cHE7vHHzr4QeSZg-ycw/s320/scatter-distribution-old-faitfhul-eruptions.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Scatter Plat showing Distribution</i></div>
<div style="text-align: center;">
source: <a href="https://en.wikipedia.org/wiki/Scatter_plot">Wikipedia</a><i><br /></i></div>
<br />
A histogram is another way to show distribution of continuous data. Histograms superficially resemble column charts but the columns have no spacing and indicate frequency, not specific values. The X-axis shows interval ranges and the Y-axis shows number of times values occurred. The histogram below shows the majority of customers wait between 35-50 seconds.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0BabZvJHAx2aHE4D-zYWdlDh6VmMWOdvNz6krHYCwLaPP5STFJDTQDdmFb3qNGdWEzDO8VnnlWfu0cy5UzUANHgbxvl8_pdev3iIAnYDlLtHL8ewiWGZ542yETdAwGzN2GJTPGMIyxk/s1600/histogram-customer-wait-time.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="487" data-original-width="1024" height="152" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEin0BabZvJHAx2aHE4D-zYWdlDh6VmMWOdvNz6krHYCwLaPP5STFJDTQDdmFb3qNGdWEzDO8VnnlWfu0cy5UzUANHgbxvl8_pdev3iIAnYDlLtHL8ewiWGZ542yETdAwGzN2GJTPGMIyxk/s320/histogram-customer-wait-time.png" width="320" /></a></div>
<br />
<div style="text-align: center;">
<i>Histogram showing Customer Wait Time</i></div>
<div style="text-align: center;">
source: <i> </i><a href="https://corporatefinanceinstitute.com/resources/excel/study/histogram/">corporatefinanceinstitute.com</a><i><br /></i></div>
<br />
<h2>
Progress Toward Goals</h2>
The bullet graph, a 21st century chart, is a nice compact way to show progress toward a goal. These can be vertical or horizontal, and combine the idea of a thermometer chart with red/yellow/green ranges.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicxg0oE_KfpuuRDbrjCLVjQsn5rrmPo0w728AOj0W1K6MlITIseGXo718x2Wn_OC33S4UDIPEU9DXCs7HN296MFMARXO7GJZYdewQB8wOdlmIeHD8NUqj6wt-ZieUGy7GefTGEq2fUvAg/s1600/bullet-graph1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="151" data-original-width="766" height="78" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEicxg0oE_KfpuuRDbrjCLVjQsn5rrmPo0w728AOj0W1K6MlITIseGXo718x2Wn_OC33S4UDIPEU9DXCs7HN296MFMARXO7GJZYdewQB8wOdlmIeHD8NUqj6wt-ZieUGy7GefTGEq2fUvAg/s400/bullet-graph1.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq1nhCTHqFZJhTijBx0kMVl3dKu0102H3IR4XArqGZ949r1cXKQ3J1unOQ0N4Z2QNYgBEFOOs6gGk6FrvzUfUYWZDVmtNK1wrYACAVLyq_oeS3iCm9kcelwnuEAU0HQSop9GlagR2AGuw/s1600/bullet-graph2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="384" data-original-width="315" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq1nhCTHqFZJhTijBx0kMVl3dKu0102H3IR4XArqGZ949r1cXKQ3J1unOQ0N4Z2QNYgBEFOOs6gGk6FrvzUfUYWZDVmtNK1wrYACAVLyq_oeS3iCm9kcelwnuEAU0HQSop9GlagR2AGuw/s400/bullet-graph2.png" width="327" /></a></div>
<br />
<h2>
Many Variables</h2>
Radar Charts, also called Spider Charts, are useful when you have many variables. They let you plot a dozen or more variables and derive a shape from them. Comparing shapes then shows similarity.<br />
<br />
In the chart below, attributes of the Overwatch League are plotted (blue shape). On top of that, attributes of the Twitch community are plotted (orange shape). The chart shows similarities in the two shapes, which helps make the case that Twitch is a good streaming home for the Overwatch League.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2eObHMdwpl_JgbHbfyl2_d3yEE_EHs3EQ-5951EvpuyimGUQ-nX3qwxhnJGf8yRZ8rTHQ5Ae5qTKmte1qEg8e6VPDHxQAS50xkcgrGBjkQdYK1wkLYL8limAG64J5YwfK4QLAlUAipSI/s1600/radar-ovewatch-twitch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="660" data-original-width="743" height="355" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi2eObHMdwpl_JgbHbfyl2_d3yEE_EHs3EQ-5951EvpuyimGUQ-nX3qwxhnJGf8yRZ8rTHQ5Ae5qTKmte1qEg8e6VPDHxQAS50xkcgrGBjkQdYK1wkLYL8limAG64J5YwfK4QLAlUAipSI/s400/radar-ovewatch-twitch.png" width="400" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
Radar Chart</div>
<h4 class="separator" style="clear: both; text-align: center;">
source: <a href="http://www.esportsgroup.net/2017/12/overwatch-esports-needs-twitch/">the eSports Group</a></h4>
<br />
Years back when I worked at Microsoft, we would use radar charts in developer usability studies. We would chart shapes for the developers we tested and compare them to what our APIs provided. <br />
<br />
<h2>
Summary</h2>
There are many kinds of charts because there are many purposes for visualizing data. We've reviewed some examples of how the wrong chart type obscures rather than clarifies. We learned how to choose the right chart type for your objective and reviewed some of the more common chart types.<br />
<br />
In <a href="http://davidpallmann.blogspot.com/2020/03/bar-charting-part-3-axis-abuse.html">Part 3</a>, we'll look at how Axis Abuse can make your charts misleading.<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-67570485134171477102020-02-15T12:27:00.002-08:002020-05-22T14:14:56.155-07:00Bad Charting Part 1: Charts vs. InfographicsIn this post I'll share tips on responsible charting and how to avoid common pitfalls that can result in misleading business graphics. We'll do that by looking at examples of poor charts and pointing out the principles that were violated. In this first post, we'll make the distinction between charts and infographics.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxagYhC1Tiu0Kx9T1UiO4HZNOsRxbmDdmClAKEySJaO_S-7p6QfUbpbS49zPGOdoTPiQ-bfzBqrv4yZiQTQoJXoA3CqxZY7GsmvjAKQ1X8Y4rSoo6yOS7dXdINQPWOUKThBEo4y_Us2aM/s1600/why-charts-mislead.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1021" data-original-width="1600" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgxagYhC1Tiu0Kx9T1UiO4HZNOsRxbmDdmClAKEySJaO_S-7p6QfUbpbS49zPGOdoTPiQ-bfzBqrv4yZiQTQoJXoA3CqxZY7GsmvjAKQ1X8Y4rSoo6yOS7dXdINQPWOUKThBEo4y_Us2aM/s400/why-charts-mislead.png" width="400" /> </a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>A Bad Chart about Why Charts are Bad </i></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
<h2>
Charts: They're All Around Us </h2>
Charts are all around us. Many of us rely on them and create them in our work. Dashboards abound in business and billions of dollars are spent annually on business intelligence products. Charts are a regular output of stock markets, scientists, researchers, statisticians, and governments. They're all over social media, web sites, and television. Charts are part of life. <br />
<br />
Just as publishing came to the masses via word processing, desktop publishing, and blogging the same thing is happening with charting. Charts can now be created in just a few clicks from office productivity software, charting apps, and cloud services. Marketing campaigns frequently leverage infographics in their messaging.<br />
<br />
There are good charts, bad charts, and pretender charts. We live in a time where honest communication is in short supply. There's a lot of deliberate misinformation online and charts are often a vehicle for delivering it. An even larger problem is charts that are unintentionally misleading. That comes from people who don't know the fundamentals of good charting, don't understand their source data well, or just copy-and-paste from somewhere else. These days, charts are created for the most trivial subjects or to express humor in social media posts. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZthEVPXE5UP_ufuN88LLRoT4B-BGL0YZZWQsEG63rkUALyKheKOqtBHw5qa5GpKDMBvP_WTiJdkuQHY8ed96SeRHdg0b3qR1bWWPFVlj5TRRkaLdEPBAiv4nfxluhsXmbx4TQhreg6oM/s1600/teen-pregnancy-drops_afte_20.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="735" data-original-width="1600" height="146" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZthEVPXE5UP_ufuN88LLRoT4B-BGL0YZZWQsEG63rkUALyKheKOqtBHw5qa5GpKDMBvP_WTiJdkuQHY8ed96SeRHdg0b3qR1bWWPFVlj5TRRkaLdEPBAiv4nfxluhsXmbx4TQhreg6oM/s320/teen-pregnancy-drops_afte_20.png" width="320" /></a></div>
<div style="text-align: center;">
<i>I wonder why that would be...</i></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: https://imgur.com/uCbnAaf</span></div>
<br />
<br />
<h2>
Just What is a Chart Anyway? </h2>
Before we go any further we should define what a chart (or graph) is.<br />
<br />
A chart is
a <b>data visualization</b>. That is, a graphical representation of some
numerical data. It's not possible to create a good chart from poor data,
so starting with data you understand is critical. You have a duty to select appropriate and complete source data. You have a duty to portray that data responsibly. You have a duty to provide reference to the source data.<br />
<br />
A chart is also a
type of <b>content</b>, which means you will make decisions that affect how the
chart is perceived by viewers. Your chart tells a story or carries a message, even if you don't intend it to. Be aware that some readers will take your content at face value.<br />
<br />
A chart is also <b>data reduction</b>, which
obligates you to reduce the data in a responsible way. Your viewer should understand how the data was arrived at.<br />
<br />
Finally, a chart is a <b>picture</b>. We all know a picture is worth 1,000 words. Your visual choices imply underlying information. The emotion your chart triggers in your viewer is strong than any figures on the page or text.<br />
<br />
Charting, then, is a great responsibility. You are communicating about data that matters greatly to somebody. It needs to be truthful and clear if you want to maintain a reputation for trustworthiness. As we shall see, not everyone takes these responsibilities seriously.<br />
<br />
<h2>
Charts are not Infographics</h2>
One of the reasons we have rampant problems with charts is the confusion between a business chart and an infographic. An <a href="https://venngage.com/blog/what-is-an-infographic/" target="_blank">infographic</a> is "a collection of imagery, charts, and minimal text that gives an easy-to-understand overview of a topic." Infographics often contain charts, and they simply aren't created with the same rigor that business charts are. Let's look at a chart from an infographic:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizoiB_BI37DeAnNTeYBq0phxoXyggNew5axpE3z4a-WRYL42tNE_AewLh97P465LVXIi4MPXo1OE_ScZrIWtaxMBrfoRuDP9uzzUGCSTey7TFMkhf_CCOY5-bGwgi_9lPRmvcoIGDYLdE/s1600/infographic-chart-fastfood.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="685" data-original-width="1290" height="210" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizoiB_BI37DeAnNTeYBq0phxoXyggNew5axpE3z4a-WRYL42tNE_AewLh97P465LVXIi4MPXo1OE_ScZrIWtaxMBrfoRuDP9uzzUGCSTey7TFMkhf_CCOY5-bGwgi_9lPRmvcoIGDYLdE/s400/infographic-chart-fastfood.png" width="400" /></a></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="http://www.princeton.edu/%7Eina/infographics/starbucks.html" target="_blank">Princeton University</a></span></div>
<br />
The above chart is so bad it made Business Insider's list of the <a href="https://www.businessinsider.com/the-27-worst-charts-of-all-time-2013-6" target="_blank">Worst Charts of All Time</a>. We can note some deficiencies in this chart:<br />
<ol>
<li>It has no title, but we can intuit we are being shown sales revenue for fast food restaurants. </li>
<li>The Y axis isn't labelled, but we can intuit billions of dollars from the chart value labels. </li>
<li>Columns are replaced with corporate logos, and that's a problem. Look at Burger King ($11.3B in sales) vs. McDonald's ($41B). Is the McD logo 4 times the BK logo? No, it's more like 12 times the area. The "clever" use of logos is a bad idea because it breaks the visual contract with the chart reader.</li>
<li>The data set isn't identified. This clearly isn't all restaurants but we aren't told the criteria for the ones that are included. </li>
<li>The time frame isn't identified either. Which year's sales revenue are we being shown?</li>
<li>The chart values are an apples and oranges comparison, because the country of Afghanistan is included in the mix.</li>
</ol>
Below you can see our chart is part of a <a href="https://www.princeton.edu/~ina/infographics/starbucks.html" target="_blank">larger infographic </a>from Princeton University. Now we can see the chart's purpose in support of a message about how Starbucks and McDonald's are global hubs that connect some of the earth's wealthiest and poorest countries. The deficiencies we noted would likely be explained away by the designer as justified in getting the message out in a compelling way. That's the problem with infographics: they're a marketing tool, not a business communication tool. They each have their place but you don't want to confuse them.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" data-original-height="720" data-original-width="1122" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgNWF-LMR-33JmRZzvXh37hXCLvjDqD4vJaGxH1vNr8mRMeO7aTpCFTLkbmPSdQL_Aa2JkngjgXujDoBo36Lgy7yHqxzX8kLz6cRHBlUkGmtUiZNBV8ES8CbClR6cx_LLMTtNNsURz4F_o/s400/infographic-fastfood.png" width="400" /></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="http://www.princeton.edu/%7Eina/infographics/starbucks.html" target="_blank">Princeton University</a></span></div>
<br />
Here's another infographic below, this one showing the mobile games market volume by language. Note the sizes of the bubbles. Chinese is $15B and English is $8B, but the Chinese bubble is not 2 times the area of the English bubble, it's closer to 4 because both height and width were multiplied by the 2. We saw this same error earlier with the use of logos and here it is again. The makers of infographics are usually far more concerned with getting your attention than accuracy.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSKhDvvUU09L40qCvZvV4BOqsFF-h32lmB0I_QcVAPv61M8wcchXon9J1bXiEchQoYVgM8ECAqpCJNe8Fw98dHvOv9DlwmZ4y2-v5Yyt0zfHOGzTyoa4bkpmyu-qBjd1tkXPS93103wew/s1600/mobile-games-language.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1058" height="270" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjSKhDvvUU09L40qCvZvV4BOqsFF-h32lmB0I_QcVAPv61M8wcchXon9J1bXiEchQoYVgM8ECAqpCJNe8Fw98dHvOv9DlwmZ4y2-v5Yyt0zfHOGzTyoa4bkpmyu-qBjd1tkXPS93103wew/s400/mobile-games-language.png" width="400" /></a></div>
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="https://allcorrectgames.com/insights/mobile-game-market-index/">allcorrectgames.com</a></span> </div>
<br />
Here are some of the important differences between a business chart and an infographic:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiTZYJgAoUSAnVg6QGJZ3EUaol8hz065zFYbTQ0jEY5BpMKBVodIakR-4oIgU92Y6M3t2XexDXhSlp9hw3KqDVoYLwOT389Hkop8V8wJCIl_WiLLxkwrCpTpmIlJT2DiR2gCfRhLBtkUc/s1600/info-buschart.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="324" data-original-width="798" height="129" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiiTZYJgAoUSAnVg6QGJZ3EUaol8hz065zFYbTQ0jEY5BpMKBVodIakR-4oIgU92Y6M3t2XexDXhSlp9hw3KqDVoYLwOT389Hkop8V8wJCIl_WiLLxkwrCpTpmIlJT2DiR2gCfRhLBtkUc/s320/info-buschart.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<br />
An infographic is often designed to push a message and includes data that supports the message. A business chart has a message too, but there's a difference. In your business chart, you had some reason to show the data you did in the way you did. There may well be an important revelation you want to communicate but the viewer may discover additional insights from the data being visualized. The business chart doesn't force a conclusion, it says "look at this. look what's happening here."<br />
<br />
Don't make the mistake of using an infographic when you should have a business chart. In an infographic, the excitement comes from the design and messaging. In a business chart, the excitement comes from the data.<br />
<br />
<h2>
Everyone Says So</h2>
Why are infographics so popular? Well, one reason commonly given is shown (fittingly) by the infographics below: the human brain processes images 60,000 times faster than text!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5OCbbFNtVf0ngeomsIKHDfCdcUdJqo0JCYC9LvoKu0VTR0dtLcalde14ttbTu_MCyaYkyOONtKSyegBZbuCsLJeJxb77DiNe2BKIm7IIbVkutjZ07TMYqOPqOvIqWKt9Vs0Hz5ZftQC8/s1600/infographic-60K-1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="245" data-original-width="376" height="208" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5OCbbFNtVf0ngeomsIKHDfCdcUdJqo0JCYC9LvoKu0VTR0dtLcalde14ttbTu_MCyaYkyOONtKSyegBZbuCsLJeJxb77DiNe2BKIm7IIbVkutjZ07TMYqOPqOvIqWKt9Vs0Hz5ZftQC8/s320/infographic-60K-1.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLm7fOTQcWQhRxJgsdR8SUUhs7DAWhIM8V9Yy9QWgaoCvx7k35S1TRNcvp-6pRyl5crRONy7a2VIKX1NAJCQFcllGUqmoCNFt5CQxYS-jfMDQUwkBxB3n9OmOaTAbJ20ahn87gbD8qey8/s1600/infographic-60K-2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="313" data-original-width="521" height="192" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLm7fOTQcWQhRxJgsdR8SUUhs7DAWhIM8V9Yy9QWgaoCvx7k35S1TRNcvp-6pRyl5crRONy7a2VIKX1NAJCQFcllGUqmoCNFt5CQxYS-jfMDQUwkBxB3n9OmOaTAbJ20ahn87gbD8qey8/s320/infographic-60K-2.png" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWHTg1dMkU079hNY2nheDXi2a8KwXA2zpVjX9qDO0bdrn_UWlsvbPyGT0otKlYPDId2fFRPvPHQl2WPcrWpZfYHN_gKgG52rYjrUJk9aAeaTTDuCgsSf7D-kGTIRoNhyRvIjfvWqmuXNE/s1600/infographic-60K-3.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="398" data-original-width="500" height="254" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWHTg1dMkU079hNY2nheDXi2a8KwXA2zpVjX9qDO0bdrn_UWlsvbPyGT0otKlYPDId2fFRPvPHQl2WPcrWpZfYHN_gKgG52rYjrUJk9aAeaTTDuCgsSf7D-kGTIRoNhyRvIjfvWqmuXNE/s320/infographic-60K-3.png" width="320" /></a></div>
<br />
You'll find thousands of infographics and designer/marketing web sites promoting this fact. Now that you've learned this fun fact, you can forget it, because <a href="https://policyviz.com/2015/09/17/the-60000-fallacy/"><b>it's not true</b></a>!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKzaRnORvSjgucdTC2sRMeto-Gb5Sd5VTzv5Ehz95rl3iWZHbGbCY87cWz7Qy1PqBy_Q_4npCxWWdp_QpULCC403giI779SvgDKB1qeqr0BknfJP_dxZgtZcpbNz0hYcfc5Lln3oNUohc/s1600/infographic-60K-false.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="375" data-original-width="583" height="205" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKzaRnORvSjgucdTC2sRMeto-Gb5Sd5VTzv5Ehz95rl3iWZHbGbCY87cWz7Qy1PqBy_Q_4npCxWWdp_QpULCC403giI779SvgDKB1qeqr0BknfJP_dxZgtZcpbNz0hYcfc5Lln3oNUohc/s320/infographic-60K-false.png" width="320" /></a></div>
<br />
<div style="text-align: center;">
<span style="font-size: x-small;">source: <a href="https://visme.co/blog/common-myths-visual-brain/">visme.co</a></span></div>
<br />
This is a big, big problem today. People see something interesting, especially something that supports the story they want to promote, and they pass it on without a second thought. Using or passing on unverified information has no place in business or in your charts.<br />
<br />
<h2>
When is a Chart Warranted?</h2>
Before you embark on creating a chart, ask yourself whether you have a good reason for having one. If the only reason for your chart is to have something pretty, I suggest you reconsider. Charts do make sense in your documents and presentations when any of the following are true:<br />
<ul>
<li>The chart will help your audience <b>understand</b> the data better .</li>
<li>When the <b>shape</b> of the data contains your message.</li>
<li>When you want to <b>highlight</b> or <b>reveal</b> something that would not be evident from a table of figures or wall of text.</li>
<li>When the chart <b>accompanies </b>and <b>augments </b>a narrative or data set (not replaces it).</li>
</ul>
A chart should never be a replacement for its source data. Either include that original data or provide a link to it.<br />
<br />
<h2>
Characteristics of a Good Chart </h2>
A good chart will have these characteristics:<br />
<ol>
<li>Accurately show facts.</li>
<li>Grab the reader's attention.</li>
<li>Show trends or changes.</li>
<li>Be clear and easy to read.</li>
<li>Have a title and axis labels.</li>
<li>Identify units for values.</li>
<li>Use colors to show differences but not rely solely on color.</li>
<li>Use white space around graphic elements and text for readability. </li>
<li>Follow established conventions.</li>
</ol>
In <a href="https://davidpallmann.blogspot.com/2020/02/bad-charting-part-2-use-right-chart-type.html">Part 2</a>, we'll look at how to choose the right chart type and what happens when you get it wrong.<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com2tag:blogger.com,1999:blog-9132148272745668459.post-10950637196819906092020-01-12T14:19:00.000-08:002020-01-13T17:31:15.574-08:00Chicken Sandwich ShowdownThis is my comparison of the Chick-Fil-A Chicken Sandwich vs. Popeyes Chicken Sandwich; what historians are sure to call the defining question of our times.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfRA4NgIFj1-w20g7V0jWzSZ5quzyECIttu1kzLoIX7VModqhzmTYsF7PY5eVJa2WtZFUipWixL6HyHb-pHuJxiE2kLFq52qdjXKXA7LUJ8OTk6m1Bo43Uy_aekQBXz7P_uJpe9UP-vKM/s1600/bags.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="847" data-original-width="1129" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfRA4NgIFj1-w20g7V0jWzSZ5quzyECIttu1kzLoIX7VModqhzmTYsF7PY5eVJa2WtZFUipWixL6HyHb-pHuJxiE2kLFq52qdjXKXA7LUJ8OTk6m1Bo43Uy_aekQBXz7P_uJpe9UP-vKM/s320/bags.jpg" width="320" /></a></div>
<h2>
The Uproar </h2>
Unless you're been fast asleep in the hen house, you're no doubt aware that 2019 had quite the <a href="https://www.washingtonpost.com/graphics/2019/voraciously/chicken-sandwich/" target="_blank">brouhaha over Chicken Sandwiches</a>. I consider myself above such nonsense. Thus, I did not go near a Chick-Fil-A nor a Popeyes Chicken during the ensuing <a href="https://www.businessinsider.com/popeyes-chick-fil-a-chicken-sandwich-feud-hits-twitter-2019-8" target="_blank">Twitter Feud</a>, <a href="https://www.businessinsider.com/popeyes-workers-describe-chicken-sandwich-demand-chaos-2019-8" target="_blank">massive crowds</a>, <a href="https://abc30.com/society/woman-wrecks-car-to-get-popeyes-chicken-sandwich/5682664/" target="_blank">car wrecks</a>, <a href="https://www.businessinsider.com/popeyes-chicken-sandwich-return-linked-to-violent-incidents-list-2019-11" target="_blank">stabbings</a> and other violence. In addition to all that, it's clear from social media that some people hold rabidly-strong opinions about favoring one establishment over the other because of their misguided political leanings. Sigh. This is not the way to get along, America.<br />
<br />
I said I consider myself above such nonsense, but I am curious. I have a detached-observer-technologist's interest in watching social media turn humanity into lemmings, driven by FOMO of whatever minor phenomenon becomes viral. Truly the majority of the US population can no longer be considered sane nor polite. Nevertheless, now that things have calmed down slightly, I thought I would try each sandwich and make a non-agenda-driven attempt to determine which was the better sandwich.<br />
<br />
<h2>
Prior Chicken Sandwich Experience </h2>
The Popeyes sandwich is the newcomer that sparked the Chicken Sandwich Wars, but it's not quite accurate that Chick-Fil-A <i>invented </i>the
chicken sandwich as some claim. I know this because I have been eating
chicken sandwiches since the 70's. In my teens and early twenties, my brother
and I tended to hang out a lot at the local Burger King. One of my
favorite things to get there was the BK Chicken Sandwich: an oblong
processed chicken patty on a bun with mayonnaise. This sandwich was
always a gamble because the amount of mayo applied by the fast food
worker was the defining factor in whether the sandwich was a success.
Today we set our sights a lot higher: both of the modern contenders for the Chicken Sandwich throne are
superior in every way.<br />
<br />
In more modern times, I continue to love chicken sandwiches, but I don't usually buy them from fast food restaurants. My wife makes amazing <a href="https://goodcookbecky.wordpress.com/2010/03/05/cajun-chicken-club-sandwiches/" target="_blank">Cajun Chicken Club Sandwiches</a> and my family loves them. It's not possible that some fast food offering will ever unseat them from being my favorite.<br />
<br />
Prior to this showdown I'd never had the Chick-Fil-A chicken sandwich nor the Popeyes chicken sandwich, but I have had other food from both places. My family likes Chick-Fil-A a lot, and I'm partial to their nuggets, sauces, and excellent Mac and Cheese. I did try the <u>spicy </u>chicken sandwich a few years back and found it too hot for my liking.<br />
<br />
I started frequenting Popeyes when I did consulting in Washington D.C. for a year. I'm partial to Popeyes for their boneless buffalo wings, sauces, and excellent Cajun fries. The town I live in now has a local Chick-Fil-A and Popeyes Chicken, fittingly across the street from each other.<br />
<br />
Do I enter this judging with a bias? I do love Cajun food, and that may give me a slight inclination toward Popeyes. I'm doing my best to be unbiased. As a manager I have had to take training at work on Unconscious Bias and I am counting on that to help me in this taste test.<br />
<br />
<h2>
Purchasing a Chicken Sandwich at Chick-Fil-A</h2>
At 4:28pm on a Saturday, I pull into the Chick-Fil-A drive-thru. This was built recently and is new and clean. The drive-thru has a dual lane, and in prior visits when things have been really busy Chick-Fil-A staff are out working the cars with tablets. Right now is less busy though. There are half a dozen cars ahead of me in the drive-thru.<br />
<br />
When asked for my order, I am greeted by a friendly voice. I ask for a Chicken Sandwich. "Regular or Deluxe?" I am asked. I automatically say Deluxe but later wonder if that makes the comparison unfair. I am then asked if I want any sauces. I'm not sure if the sandwich comes with a sauce or not so I ask for some Chick-Fil-A sauce. I also order a large Mac and Cheese because it's really good.<br />
<br />
I receive my food at 4:40pm. Elapsed time in the drive-thru: 12 minutes. I was charged $4.99 for the sandwich. On to Popeyes!<br />
<br />
<h2>
Purchasing a Chicken Sandwich at Popeyes</h2>
I pull into the Popeyes single-lane drive-thru at 4:45pm and there are no cars ahead of me. <br />
<br />
As Popeyes' sandwich is the newcomer, and is a hit, they
understandably are working to capitalize on it. A poster on the outside
of the building proclaims "I'm Back", referring to the sandwich being <a href="https://www.washingtonpost.com/news/voraciously/wp/2019/08/28/everybody-panic-popeyes-has-run-out-of-the-sandwich/" target="_blank">sold out for weeks</a> after its pilot introduction.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4fOQjz6sv9j0xZnPFibwtDPA0kn-uERPdxP2L-i7Qn6ThJ5VJI0cgpwwQfC81ikQY9oMtaOjpVND6QCS4jJKVqg-12_-YHnUTc_BSYA8lYoSeHMnq3Ldft_xxBVdcJTSZ5NbsbFoK9oA/s1600/im_back.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="847" data-original-width="635" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4fOQjz6sv9j0xZnPFibwtDPA0kn-uERPdxP2L-i7Qn6ThJ5VJI0cgpwwQfC81ikQY9oMtaOjpVND6QCS4jJKVqg-12_-YHnUTc_BSYA8lYoSeHMnq3Ldft_xxBVdcJTSZ5NbsbFoK9oA/s320/im_back.jpg" width="239" /></a></div>
<br />
When asked for my order, I am greeted by a friendly voice. I ask for a Chicken Sandwich. I also order Cajun fries because they're really good. At the payment window, I am asked if I want a sauce. Unsure if the sandwich comes with a sauce, I ask for Mardigras Mustard sauce.<br />
<br />
I receive my food at 4:50p. Elapsed time in the drive-thru: 5 minutes. I was charged a combined amount for the sandwich plus fries, but looking online the sandwich alone is $3.99.<br />
<br />
I head home to taste both sandwiches. On the drive home, it smells really good in the car.<br />
<br />
<h2>
Taste Test: Chick-Fil-A Deluxe Chicken Sandwich</h2>
It is now 5:00pm, 20 minutes after getting my sandwich. The Chick-Fil-A bag is perfect and unwrinkled. Inside, the Chick-Fil-A sandwich comes in a container box. I like this kind of packaging because it provides a place for fries, if you're having fries.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWOqXaN3iiYpyMNk9jGMpq9RxlMFBnxM07nMjntQd2LfEJTeL26IKKmtr5eJryl50TUT80CTirQ0jJspQuKnz5Hgj0ZhrrnD3yZQhRBcE7vtEOWeBgZOihVkmu2yj2hHX_KbeTUBvq2ew/s1600/chick_box.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="847" data-original-width="635" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWOqXaN3iiYpyMNk9jGMpq9RxlMFBnxM07nMjntQd2LfEJTeL26IKKmtr5eJryl50TUT80CTirQ0jJspQuKnz5Hgj0ZhrrnD3yZQhRBcE7vtEOWeBgZOihVkmu2yj2hHX_KbeTUBvq2ew/s320/chick_box.jpg" width="239" /></a></div>
<br />
Opening the lid reveals the sandwich which has an appealing look. Fast food often fails to come close to the pictures used in ads and posters, but this looks attractive. I again wonder if I've done the comparison a disservice by ordering the Deluxe version of the sandwich, which adds cheese, lettuce, and tomato.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc1nd7BBJCgMpJqtYi5ieyIq_4eujk83ONmO0aODjNTunaj2DSM3486LtBDZm6OP0IpeN4kG0VnBlUObG5LYKXhHOm7cCqLAya0DXB0oIDSBiC5bZlmyYov65uG63PMHdJBYLxEWY2kN4/s1600/chick_sandwich.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="847" data-original-width="635" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjc1nd7BBJCgMpJqtYi5ieyIq_4eujk83ONmO0aODjNTunaj2DSM3486LtBDZm6OP0IpeN4kG0VnBlUObG5LYKXhHOm7cCqLAya0DXB0oIDSBiC5bZlmyYov65uG63PMHdJBYLxEWY2kN4/s320/chick_sandwich.jpg" width="239" /></a></div>
<br />
A few bites in, I'm enjoying the sandwich but have realized it doesn't come with a sauce. I spread some Chick-Fil-A sauce on the bun and continue on. I could in fact have asked for any of a dozen sauces; sauces at Chick-Fil-A are free (ahem) unlike Popeyes which is a miser about giving you any extra sauces.<br />
<br />
The bun is just what I want: soft, but not so soft that it gets squished and doesn't survive the length of the meal. I find the chicken moist and delicious. I love the thin crunchy breading on the outside.<br />
<br />
I finish my sandwich and think, "that was a very good chicken sandwich."<br />
<br />
<h2>
Taste Test: Popeyes Chicken Sandwich</h2>
The Popeyes bag is in sad shape. Although I've come to appreciate the <i>food</i> at Popeyes Chicken, the restaurant itself always seems run-down and the bag exemplifies the feeling. It's in stark contrast to the tight ship that is Chick-Fil-A. But on to the sandwich. The sandwich is in a foil bag that loudly proclaims "love that chicken (sandwich)."<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSpHiru5P_kxxm26vtd1uuWR8hHSwxdvDcMFw07qLvrWmOMp4XZjkXCmZvlyzcNWLPp9efgvg_5wy2_BB0733nCYALWKY3yXm8SnrVCuQHuxviK1YilwkbWEtoeKZBalAZch0xYHgL3EA/s1600/popeyes_bag.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="847" data-original-width="635" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSpHiru5P_kxxm26vtd1uuWR8hHSwxdvDcMFw07qLvrWmOMp4XZjkXCmZvlyzcNWLPp9efgvg_5wy2_BB0733nCYALWKY3yXm8SnrVCuQHuxviK1YilwkbWEtoeKZBalAZch0xYHgL3EA/s320/popeyes_bag.jpg" width="239" /></a></div>
<br />
Opening the foil bag reveals the sandwich which looks a little different than I am expecting. After a few bites, I realize I am holding the sandwich upside down and I correct matters. That is why the picture below shows a half-eaten sandwich. Even so, the sandwich looks a lot less like advertisement pictures than the Chick-Fil-A sandwich did. In fact, it looks like the sandwich was dropped and stepped on. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj09KgLCtIKQiKxdj-JS1GgB34qwnVonNmMyk9Lbu1ZDIl3d_yomWXEZByoerG91g0kHTDeigqYQ93Ja62rE4I8lVjtK1EpLeheJCbo4803aU-ldHLEIOJ8xz8fQGuMRnFjjWBKNKty-Z0/s1600/popeyes_sandwich_half.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="847" data-original-width="635" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiR798OkCOgxSOAXO5LHlfX78M6SF_JtQu6xOwYlbMJbdXISsLFtOdrFNGRWVBOGqKt2b1bLRmUeXolLlG8CObW_HG1qjhNCfmD9TqEN7EoERDy-rJ6ke7nfFJ_upa71_Ndk6EPHzTJcYM/s320/popeyes_sandwich.jpg" width="239" /> <img border="0" data-original-height="847" data-original-width="635" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj09KgLCtIKQiKxdj-JS1GgB34qwnVonNmMyk9Lbu1ZDIl3d_yomWXEZByoerG91g0kHTDeigqYQ93Ja62rE4I8lVjtK1EpLeheJCbo4803aU-ldHLEIOJ8xz8fQGuMRnFjjWBKNKty-Z0/s320/popeyes_sandwich_half.jpg" width="239" /></a></div>
<br />
While the sandwich had a kind of squished appearance out of the bag, the sandwich is good and I am enjoying it. It comes with a mayo so I am not needing to add a sauce. But that's okay, the Mardigras Mustard sauce will be delicious with my Cajun fries later on. Did I mention that Popeyes is a miser when it comes to sauces?<br />
<br />
The brioche bun is delightful and survives the meal. I like the chicken, which is juicy, but I expected the Cajun flavor to be more prominent. It is very different from the Chick-Fil-A
chicken: the buttermilk batter is reminiscent of what
you would find on fried chicken. The biggest thing I notice about the chicken, though, is how much of it there is. There is definitely more chicken on the Popeyes sandwich. This is not to say that the Chick-Fil-A sandwich didn't have enough chicken.<br />
<br />
I finish my sandwich and think, "that was a very good chicken sandwich."<br />
<br />
<h2>
Which One Wins?</h2>
It's at this point that I'm expected to declare a winner, but as I finish the second sandwich I am at a loss to pick a favorite. They were both good, but nothing pushes me toward one over the other. Which one would I like to have again? At the moment, neither! I have just finished a double meal and I am full. Really, it's too close to call. If I was marooned on a desert island and you told me I could have either sandwich, I would close my eyes and say "Surprise me."<br />
<br />
Conclusions:<br />
<br />
1. Both places offer an excellent chicken sandwich.<br />
2. My wife's Cajun Chicken Sandwiches remain #1 in my heart.<br />
3. If it's a Sunday, go to Popeyes. Chick-Fil-A is closed.<br />
4. If you're going to <i>photograph</i> the food, I'd go with Chick-Fil-A.<br />
5. If a lower price or more food for the price is your main concern, Popeyes has the edge.<br />
6. If you're a lover of sauces, go Chick-Fil-A.<br />
7. These are just chicken sandwiches, not reasons for a new Civil War or acts of felony violence. <br />
<br />
There you have it. You really can't go wrong with either sandwich, and there are now enough sandwiches for everybody... so your chances of getting one without violence and name calling are excellent. All you militant Chicken-Twitter people can just chill. Can't we all get along?<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-86220280361877981882020-01-11T14:33:00.000-08:002020-01-11T14:39:09.045-08:00Review: Moto Z4This is my review of the <a href="https://www.motorola.com/us/products/moto-z-gen-4-unlocked" target="_blank">Moto Z4 phone</a> from Motorola. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTfyeO3S8hNbLGujW_XYuphWkqnPo-ZGbVzkmcIJ_nhhfFEmfu-CZ4OQqVialX5GyMSrFdL1VoxluUE2cZQvrsz0YVfLonr2O3dUB0V-UWZrVO7IKxSxEiLL6BVhBhHKES-iHV1BwXxXM/s1600/moto-z4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1280" data-original-width="960" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhTfyeO3S8hNbLGujW_XYuphWkqnPo-ZGbVzkmcIJ_nhhfFEmfu-CZ4OQqVialX5GyMSrFdL1VoxluUE2cZQvrsz0YVfLonr2O3dUB0V-UWZrVO7IKxSxEiLL6BVhBhHKES-iHV1BwXxXM/s320/moto-z4.jpg" width="240" /></a></div>
<br />
<h2>
Buying Decision</h2>
About 3 months ago when my <a href="https://davidpallmann.blogspot.com/search?q=pixel" target="_blank">2016 original Pixel XL phone</a> starting losing its battery life, I initially compensated by bringing my phone charger to work. After a few weeks, though, even that wasn't sufficient to keep my phone charged all day and I knew it was time to replace it.<br />
<br />
Whenever you have to replace a phone, the first thing that goes through your mind is how good or bad the experience with your last phone was. I had pretty mixed feelings about the Pixel: while it had worked fine for the last three years, it was a pricey phone at $1000—made all the worse when <a href="https://davidpallmann.blogspot.com/2017/03/google-pixel-xl-phone-review-part-2.html" target="_blank">Google botched my fulfillment</a>, charging me full-out for the phone even though I had arranged Financing.<br />
<br />
<h3>
Price </h3>
Price was going to be a key factor. Although I have always purchased top-of-the-line premium phones for myself, nowadays I'm on a campaign to reduce my living costs without heavily compromising lifestyle. I vowed to find a phone I could live with that cost no more than $500.<br />
<br />
Like most tech professionals, I use my phone frequently and it's essential to have one you can count on. There are some very low cost phones out there, but I wasn't quite ready
to move from top-of-the-line to the bottom and was hoping to find an
affordable mid-range phone. I also wanted a new phone: while we've bought refurbished or last-year's-model phones for our children at times, an Android phone tends to only get updates for a few years, not perpetually.<br />
<br />
<h3>
Display Size</h3>
In addition to my cost objective, I had two others: display size and bloatware-free-Android. My older eyes need a larger-size phone I can see clearly, which is why my last phone was a Pixel XL. Of course, larger-size phones cost more which comes up against the lower-cost objective.<br />
<br />
<h3>
Stock Android </h3>
Avoiding Android bloatware is difficult, as any phone obtained through a carrier is sure to have altered and non-removable vendor apps including Contacts; so no carrier-sold phone for me. Even with an unlocked phone, many vendors may customize Android far more than you'd like: would you rather use Google Assistant or Samsung's Bixby? Although Samsung is the dominant phone manufacturer for Android with a ton of models for every budget, their non-stock Android is a deal-breaker. The two best phone brands for stock Android are Google (of course) and Motorola.<br />
<br />
<h3>
Design</h3>
Perhaps one final objective has to do with recent trends in phones that give me pause: the display notch and the camera bump. I don't have direct experience with either because I've avoided them. Taking away part of the display for a camera offends my design sensibilities, yet so many phones are doing it now. What if that notch hides a critical part of an app? Even it it doesn't, it seems to me it would be a constant irritant. The camera bump equally offends me: it suggests my phone won't lie flat which I'd hate. <br />
<br />
Given my other objectives, I suspected I might have to give in on the notch or the bump. I decided to have an open mind and to handle any prospective phone in-person at a Best Buy before making a decision.<br />
<br />
<h3>
Pixel 3a XL vs. Moto Z4</h3>
With these parameters established, I soon narrowed the field to two
possibilities: the Google Pixel 3a XL or the Motorola Moto Z4, both
costing just under $500 for an unlocked phone.<br />
<br />
The Pixel
3a XL is nearly half the price of the Pixel 3 XL, but what are you
giving up? Both have the same award-winning rear camera, memory, design,
and Android version. The 3a has a polycarbonite unibody instead of
glass-and-metal, so it feels like a cheaper phone. It also has a lesser processor and
a lesser front camera.<br />
<br />
The Moto Z4 seemed to have a lot of what I was looking for. Thinking back, one of the best phones I ever owned was a <a href="https://davidpallmann.blogspot.com/search?q=moto+x" target="_blank">Moto X</a>, with an attractive design and stock Android. When Google bought Motorola, I was jubilant about the future; but after extracting what they wanted from the company and selling it off to Lenovo, I was less so. Still, perhaps another look was warranted. The Moto Z4 reviews mostly agreed the Z4 was a decent mid-range phone with the features I care about; but most of them also recommended passing on this phone because the Z4 didn't offer anything especially new or exciting. The Z4 has a lesser camera than the Pixel, but would likely give me an acceptable overall experience.<br />
<br />
The Moto Z4 also supports Moto Mods, which are accessories that clip on as second backs to the phone. There are mods for 360 camera, video projection, photo printing, and longer battery life. But, most reviews describe Moto Mods as an idea that didn't catch on.<br />
<br />
If you research the Moto Z4, some of the review headlines will certainly give you pause: <a href="https://www.cnet.com/reviews/motorola-moto-z4-updated-review/" target="_blank">The cheapest 5G phone you can buy but shouldn't;</a> <a href="https://www.droid-life.com/2019/06/10/moto-z4-review-its-time-to-move-on/" target="_blank">It’s Time to Move On</a>; <a href="https://www.androidpolice.com/2019/06/19/moto-z4-review/" target="_blank">The Moto Z4 is tragically boring and behind the times</a>. For my criteria, however, the Moto Z4 topped the list and it's what I picked.<br />
<br />
<h2>
Experience</h2>
I bought my black Moto Z4 from Best Buy and it came with the 360 camera Moto Mod included. I added a <a href="https://www.amazon.com/gp/product/B07SVHQKF1/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&psc=1" target="_blank">Metalllic Slate case from Tudia</a>. I haven't really done anything with the Moto Mods, but I'm very happy with the phone.<br />
<br />
Now that I'm a few months in I have no regrets about the Moto Z4: it does everything I want in a phone. I haven't minded the camera notch after all. The battery lasts a really long time and is typically at 80% when I get home from work. It looks and feels great and is a pleasure to use. This is a phone I recommend.<br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-11873629281713422502019-07-14T14:40:00.001-07:002019-07-19T14:43:17.585-07:00Scrum is a Methodology, not a Buffet<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<i style="mso-bidi-font-style: normal;"><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Q. What’s something everybody does, but nobody does the
same? A. Scrum!</span></i></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">In today's post we'll debate this
question: Is it important to fully adopt Scrum as a software methodology, or is
it sufficient to just use the parts that seem useful?</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoRQfyJNOJfjkJPUb3zhR-V6VBbROcqZYgvHCm96xnsnZKvlb6TG-UOpBHd_bOg4OiGsXM3ECHV5Va9BhBKQFQBzX4kWBaMRiX2CLeDM6FDo4MrhsmMY-NblGOwd6_Z-GypPO0ycE3iU4/s1600/buffet-food.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="345" data-original-width="615" height="223" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoRQfyJNOJfjkJPUb3zhR-V6VBbROcqZYgvHCm96xnsnZKvlb6TG-UOpBHd_bOg4OiGsXM3ECHV5Va9BhBKQFQBzX4kWBaMRiX2CLeDM6FDo4MrhsmMY-NblGOwd6_Z-GypPO0ycE3iU4/s400/buffet-food.jpg" width="400" /></a></div>
</div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">I’ve wanted to write something on
this subject for years now, but I’ve hesitated given how explosively charged
Internet debates on software methodologies can be. Let me state at the onset
that I am neither a Scrum Worshipper nor a Scrum Hater: I wrote quality
software before Agile existed and now I write quality software using Scrum. I
value what we have gained with Agile methodologies, but I also bemoan what
they've cost us.</span><br />
<br />
<h2>
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="font-family: "arial" , "helvetica" , sans-serif;"><span style="font-size: large;">ScrumBut: We Do Scrum, But Not All Of It </span></span></span></h2>
</div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Without question, Agile Scrum has taken over as the software methodology of choice, just as Github has taken over as the software repository of choice. Scrum's pervasiveness ought to mean that when a developer who knows Scrum joins a software organization using Scrum they can hit the ground running. In my experience that's hardly ever true, and one of the common reasons is the lack of consistency in how teams apply Scrum. </span><br />
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><br /></span>
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Over the last 12 years I've
consulted with and worked with lots of teams that practice Agile
Scrum. That includes 5 years as a national consulting practice manager, so I've
had exposure to a great many customer projects beyond the ones I contribute to
personally. When the customer controlled the process, the majority of those teams didn't really follow Scrum, they
practiced <b>ScrumBut</b>: as in <i>"We do Scrum, but not all of it</i>."
Do some online research and you'll find plenty of others reporting the same; ScrumBut
is a <a href="https://www.scrum.org/resources/what-scrumbut" target="_blank">well-recognized phenomenon</a>. </span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Here are some of the things I’ve personally
seen teams drop from their practice of “Scrum”:</span></div>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We do Scrum, but we don’t do sprint reviews</span></li>
</ul>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We do Scrum, but we don’t do sprint planning meetings</span></li>
</ul>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We do Scrum, but we don’t do the daily stand-up meetings</span></li>
</ul>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We do Scrum, but we don’t have a product owner</span></li>
</ul>
<ul>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We do Scrum, but we don’t have a scrum master</span></li>
</ul>
<ul>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We do Scrum, but we don’t have a product backlog</span></li>
</ul>
<ul>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We do Scrum, but the product owner assigns work to team
members</span></li>
</ul>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Some of you reading this are Scrum
champions who only work with teams that rigorously enforce Scrum and are shaking your heads. Perhaps it’s
your job to see that Scrum is followed well. That’s great, but I assure you such teams are the minority. Understanding why and whether it's always a negative is important.</span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Why does ScrumBut happen? After all,
Scrum is a <i style="mso-bidi-font-style: normal;">lightweight </i>methodology.
It doesn’t ask much. It only has a few roles, artifacts, and ceremonies. I’ve
identified four reasons:</span></div>
<ol>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Human nature. If you’ve ever
listened to a debate over a political issue or a point of religion, you’re well
aware that even people <i style="mso-bidi-font-style: normal;">who share common
values</i> can disagree endlessly on the finer points. Not everyone is going to
weigh things the same way.</span></li>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Software is a vast realm. There are
many kinds of software and many kinds of developer, with a wide range of
skills, maturity, and experience. Developing a web site is way different from
creating a video platform or working on an operating system. Expecting one methodology
to work equally well across that spectrum is rather optimistic.</span></li>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Agile itself is partly to blame
because its underlying message is often misinterpreted as “you don’t have to do
everything”. It seems the effect of Agile trimming away practices deemed to be
of secondary importance may have encouraged people to just keep doing away with
things.</span></li>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Distrust. Older generations are more
likely to place implicit trust in a system and give it a chance, but the
younger generation is less persuaded. </span></li>
</ol>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Let's consider the case for doing
full scrum (following the methodology) and the case for doing only some of it
(buffet-style) with an honest attempt to be open-minded about the question. </span><br />
<br /></div>
<h2>
<span style="font-size: large;">All or Nothing: The Case for Full Scrum</span></h2>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">I'll fully admit my own inclination
is to use full Scrum. The line of reasoning here
is that Scrum is a <i>methodology</i>: that is, a system whose various
elements are designed to support and complement each other. When you don't
apply all of the parts, you're removing legs from the chair that holds you up.
Dismantling parts of a system undermines the system. Will it still work? Maybe, but not as well as when it's complete.</span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Imagine you have a friend with an
alcohol problem and you bring them to an AA meeting. Here’s what you would <u>not</u>
hear: <i style="mso-bidi-font-style: normal;">“We have a very successful 12-step
program; which steps do you feel are right for you?”</i> Of course that
wouldn’t happen: the program is only effective if it’s taken as a whole, with
all steps being done in the intended order. We recognize that it’s a system. There’s
a second point to be made here: the person with the alcohol problem is not an
expert on how to recover and is hardly in a position to design their own
treatment. In the same way, a software methodology should be viewed as a system
to be adhered to.</span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">It needs to be acknowledged that
even among those who do full scrum there are differences between how it is
practiced. Some organizations overdo Scrum, becoming what is sometimes referred
to as a <i>Church of Agile</i>. We should always keep in mind that the team
does not serve the methodology: rather, <i>the methodology serves the team</i>.
Like anything else popular in the computer world, Scrum is also subject to the
hype cycle which accessorizes the methodology with inflated services,
certifications, self-important titles, expensive software packages, condescending
attitudes, and a sometimes crazy obsession with points and charts. In <a href="https://martinfowler.com/articles/agile-aus-2018.html" target="_blank">The State of Agile Software in 2018</a>, Martin Fowler calls this the Agile Industrial Complex and calls for its dissolution.</span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"> Full Scrum
can be over the top if it is obsessed over and becomes the objective rather
than the means. </span></span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">If doing full Scrum is critical to
project success, there ought to be some clear evidence that full Scrum tends to
work and partial Scrum tends to fail. While I’ve encountered plenty of Scrum
champions <i style="mso-bidi-font-style: normal;">with that opinion </i>based on
their own experiences, I’ve yet to discover objective results that conclusively
support this conviction. For all the personal examples you or I could cite,
that’s not statistically meaningful. If I reflect on my own experiences, yes
I’ve seen software projects fail where oftentimes a lack of discipline
(including a poor understanding of Scrum) is an ingredient; on the other hand,
I’ve seen projects succeed where ScrumBut was applied. </span><br />
<br /></div>
<h2>
<span style="font-size: large;">Why Is It Useful? The Case for ScrumBut</span></h2>
<span style="font-size: large;">
</span>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Partial Scrum is far more common than Full Scrum by every measure I can make. I’ve noticed ScrumBut teams fall into two distinct
categories: those who don’t know any better, and those who consciously choose
partial Scrum. I’ll call them the Naive Scrumbutters and the Intentional
Scrumbutters.</span></div>
<br />
<h3>
<span style="font-size: large;">Naive Scrumbutters</span></h3>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">The Naive Scrumbutters are those who
don’t know any better. A great many teams and organizations will proudly tell
you they are practicing Scrum, and in their minds they are. Sadly, they suffer
from a superficial understanding of Scrum. <i>We're holding a daily Scrum
meeting, therefore we're doing Scrum</i>. </span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Scrum naivete is rampant. I’ve seen
these kinds of activities go on regularly which indicate a poor command of
Scrum principles:</span></div>
<ul>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Sprint planning is where the executive tells the team what
they will work on that sprint</span></li>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">The sprint has started but the stories aren’t ready yet</span></li>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">The product owner decides in advance who will work on what</span></li>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We have to get all of this work done this sprint because
that’s the deadline</span></li>
<li><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Software written this sprint isn’t tested until a later sprint</span><span style="font-family: "symbol"; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"> </span></span></span></li>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We can’t wait for the end of sprint, we need to release
software sooner</span></li>
</ul>
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Naive ScrumBut occurs particularly
often when a high-ranking person in the organization with a shallow knowledge
of Scrum sets the ground rules; no one is willing to challenge them. It also
results when roles are oversimplified or combined or omitted. Scrum works best when
everyone involved understands how it is supposed to work, and much of its value
is lost when the product owner or scrum master lack the understanding or
willingness to perform their role properly. </span></span><br />
<br />
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Naive Scrumbutters are the ones
likely to have many project problems. They’ve removed too many of Scrum’s
underpinnings, and they don’t even know it.</span><br />
<br />
<h3>
Intentional Scrumbutters</h3>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">The other group, Intentional
Scrumbutters, knows full well what Scrum entails, but have decided to leave out
some of its precepts. This approach views Scrum more as a list of potentially
useful practices rather than as a system whose parts reinforce each other. They
treat Scrum like a buffet, taking only the items they like. Reasons given by
organizations for skipping some elements of Scrum include the following:</span></div>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Someone in control of the process
thinks they know better. </span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><i style="mso-bidi-font-style: normal;"><br />I’ve seen [what we do here] work time and
time again. Trust me.</i></span></li>
</ul>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Someone in control of the process
doesn’t see value in some of its elements.</span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><i style="mso-bidi-font-style: normal;"><br />Our roadmap for the rest of the year is
already defined. We don’t need a Product Owner.</i></span></li>
</ul>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Team members don’t see value in some
of its elements.</span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><i style="mso-bidi-font-style: normal;"><br />Why is a sprint review meeting useful? I
don’t think it’s a good use of my time.</i></span></li>
</ul>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">There are difficulties carrying out
some of the elements.</span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><i style="mso-bidi-font-style: normal;"><br />Everyone here has freedom of schedule,
and some of the team live in other states or countries. There’s no way to realistically
schedule a daily stand-up meeting.</i></span></li>
</ul>
<ul>
<li><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="mso-list: Ignore;"><span style="font: 7.0pt "Times New Roman";"></span></span></span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Skepticism</span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><i style="mso-bidi-font-style: normal;"><br />There’s no point in having a sprint
retrospective, because nothing is ever going to change around here.</i></span></li>
</ul>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">“Why is this useful?” is a question
I am often asked by younger developers when I ask them to start doing Scrum
ceremonies they are not used to—even about Sprint Planning and Sprint Review
meetings. Well, that’s always a fair question to ask, but it reveals something
about the person doing the asking; clearly they do not put trust in the system
they’re being asked to follow. Perhaps they will after they’ve seen it work.</span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">While many Intentional Scrumbutters
are clearly making questionable decisions when they tinker with Scrum, it’s not always the
case. I’ve seen Silicon Valley tech companies practice ScrumBut with
spectacularly successful results, consistently producing quality software over
and over. However, I believe these are the exceptions rather than the rule. </span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;"><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">These companies have very experienced engineering
leadership and capable and committed developers across the board</span>, and
I suspect the omissions from Scrum are compensated for by other
engineering practices.<span style="font-family: "times new roman" , serif; font-size: 12.0pt;"> This article is worth a
read: <a href="http://www.cleverpm.com/2017/06/08/why-scrumbut-shouldnt-be-a-bad-word/" target="_blank">Why Scrumbut Shouldn't Be a Bad Word</a>.</span></span></div>
<br />
<h2>
<span style="font-size: large;">SlimScrum: An Alternative to ScrumBut</span></h2>
<span style="font-size: large;">
</span>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">As we’ve seen, ScrumBut happens a
lot. For a variety of reasons, some of them valid, organizations sometimes
jettison elements of Scrum. This results in ScrumBut, which is dangerous
because now the system is incomplete.</span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">What can you do if you are part of
such an organization and would like to practice full Scrum? Depending on your
position and situation, you may or may not have the standing to make changes. If
you can’t authorize outright changes, there is an alternative to ScrumBut which
I call SlimScrum.</span></div>
<br />
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">SlimScrum means you find a way to include
all the roles, artifacts, and ceremonies of Scrum—but are willing to be
flexible in <u>how</u> they are implemented. To my thinking, having all the
elements of Scrum (even if reinterpreted somewhat) is far preferable to leaving
some of them out altogether. Let's consider a few examples.</span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">If it’s truly impractical to get
everyone together for that short daily stand-up meeting, consider using Slack
or an equivalent enterprise social network. In fact, I find it so useful for
team members to list <i style="mso-bidi-font-style: normal;">what they worked on
yesterday / plan to work on today / blocks</i> on Slack that I like to have it
even when teams do have a daily stand-up meeting. </span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">If long meeting times are given as a
reason to not do full Scrum, consider how long sprint planning and sprint
review meetings really need to be. Do you need a 4-hour sprint retrospective
meeting if no one thinks anything needs to be discussed? I am not suggesting
arbitrarily shortening these meetings, but I think there is room to adjust them
based on how your team engages and whether anything useful is being
accomplished.</span></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<br /></div>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Missing Scrum roles is perhaps the
toughest omission to deal with. How do you make up for not having a product
owner? If you’re unable to fix that problem in the organization but your
immediate team is onboard with trying to solve it, have someone in sprint
planning and sprint review meetings <i style="mso-bidi-font-style: normal;">assume
the role</i> of product owner. Using a proxy can work if that person can reach
out to stakeholders between meetings to stay informed. It’s not ideal, but it’s
better than being directionless. You can do the same with the scrum master role.</span><br />
<br />
<h2>
<span style="font-size: large;">In Conclusion</span></h2>
<span style="font-size: large;">
</span>
<div class="MsoNormal" style="line-height: normal; mso-margin-bottom-alt: auto; mso-margin-top-alt: auto;">
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">Scrum consistency is a widespread
problem: you run into ScrumBut all over the place. </span><span style="font-family: "times new roman" , serif; font-size: 12.0pt;">We’ve identified some of the
reasons for it, and looked at both the naive and intentional Scrumbutters. Naive Scrumbutters need to be educated about what Scrum actually is. Intentional Scrumbutters are advised to consider what they might be missing. Even if tinkering with Scrum works for you, it still puts a barrier in place for new hires trained in Scrum which is inefficient.</span><br />
<br />
<span style="font-family: "times new roman" , serif; font-size: 12.0pt;">I
urge teams to treat Scrum (or any methodology) as a system to be followed
completely, not a buffet where you only take what you like. You’ll get a lot
more out of the system if you give it a chance to work for you.</span></div>
<!--[if gte mso 9]><xml>
<o:OfficeDocumentSettings>
<o:AllowPNG/>
</o:OfficeDocumentSettings>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:WordDocument>
<w:View>Normal</w:View>
<w:Zoom>0</w:Zoom>
<w:TrackMoves/>
<w:TrackFormatting/>
<w:PunctuationKerning/>
<w:ValidateAgainstSchemas/>
<w:SaveIfXMLInvalid>false</w:SaveIfXMLInvalid>
<w:IgnoreMixedContent>false</w:IgnoreMixedContent>
<w:AlwaysShowPlaceholderText>false</w:AlwaysShowPlaceholderText>
<w:DoNotPromoteQF/>
<w:LidThemeOther>EN-US</w:LidThemeOther>
<w:LidThemeAsian>X-NONE</w:LidThemeAsian>
<w:LidThemeComplexScript>X-NONE</w:LidThemeComplexScript>
<w:Compatibility>
<w:BreakWrappedTables/>
<w:SnapToGridInCell/>
<w:WrapTextWithPunct/>
<w:UseAsianBreakRules/>
<w:DontGrowAutofit/>
<w:SplitPgBreakAndParaMark/>
<w:EnableOpenTypeKerning/>
<w:DontFlipMirrorIndents/>
<w:OverrideTableStyleHps/>
</w:Compatibility>
<m:mathPr>
<m:mathFont m:val="Cambria Math"/>
<m:brkBin m:val="before"/>
<m:brkBinSub m:val="--"/>
<m:smallFrac m:val="off"/>
<m:dispDef/>
<m:lMargin m:val="0"/>
<m:rMargin m:val="0"/>
<m:defJc m:val="centerGroup"/>
<m:wrapIndent m:val="1440"/>
<m:intLim m:val="subSup"/>
<m:naryLim m:val="undOvr"/>
</m:mathPr></w:WordDocument>
</xml><![endif]--><!--[if gte mso 9]><xml>
<w:LatentStyles DefLockedState="false" DefUnhideWhenUsed="false"
DefSemiHidden="false" DefQFormat="false" DefPriority="99"
LatentStyleCount="375">
<w:LsdException Locked="false" Priority="0" QFormat="true" Name="Normal"/>
<w:LsdException Locked="false" Priority="9" QFormat="true" Name="heading 1"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 2"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 3"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 4"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 5"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 6"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 7"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 8"/>
<w:LsdException Locked="false" Priority="9" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="heading 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index 9"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 1"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 2"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 3"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 4"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 5"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 6"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 7"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 8"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" Name="toc 9"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Normal Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="footnote text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="annotation text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="header"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="footer"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="index heading"/>
<w:LsdException Locked="false" Priority="35" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="caption"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="table of figures"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="envelope address"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="envelope return"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="footnote reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="annotation reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="line number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="page number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="endnote reference"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="endnote text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="table of authorities"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="macro"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="toa heading"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Bullet 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Number 5"/>
<w:LsdException Locked="false" Priority="10" QFormat="true" Name="Title"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Closing"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Signature"/>
<w:LsdException Locked="false" Priority="1" SemiHidden="true"
UnhideWhenUsed="true" Name="Default Paragraph Font"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="List Continue 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Message Header"/>
<w:LsdException Locked="false" Priority="11" QFormat="true" Name="Subtitle"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Salutation"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Date"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text First Indent"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text First Indent 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Note Heading"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text Indent 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Body Text Indent 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Block Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Hyperlink"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="FollowedHyperlink"/>
<w:LsdException Locked="false" Priority="22" QFormat="true" Name="Strong"/>
<w:LsdException Locked="false" Priority="20" QFormat="true" Name="Emphasis"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Document Map"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Plain Text"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="E-mail Signature"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Top of Form"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Bottom of Form"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Normal (Web)"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Acronym"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Address"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Cite"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Code"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Definition"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Keyboard"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Preformatted"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Sample"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Typewriter"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="HTML Variable"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Normal Table"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="annotation subject"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="No List"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Outline List 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Outline List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Outline List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Simple 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Simple 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Simple 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Classic 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Colorful 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Colorful 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Colorful 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Columns 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Grid 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 4"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 5"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 7"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table List 8"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table 3D effects 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table 3D effects 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table 3D effects 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Contemporary"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Elegant"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Professional"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Subtle 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Subtle 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Web 1"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Web 2"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Web 3"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Balloon Text"/>
<w:LsdException Locked="false" Priority="39" Name="Table Grid"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Table Theme"/>
<w:LsdException Locked="false" SemiHidden="true" Name="Placeholder Text"/>
<w:LsdException Locked="false" Priority="1" QFormat="true" Name="No Spacing"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading"/>
<w:LsdException Locked="false" Priority="61" Name="Light List"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 1"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 1"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 1"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 1"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 1"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 1"/>
<w:LsdException Locked="false" SemiHidden="true" Name="Revision"/>
<w:LsdException Locked="false" Priority="34" QFormat="true"
Name="List Paragraph"/>
<w:LsdException Locked="false" Priority="29" QFormat="true" Name="Quote"/>
<w:LsdException Locked="false" Priority="30" QFormat="true"
Name="Intense Quote"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 1"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 1"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 1"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 1"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 1"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 1"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 1"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 1"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 2"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 2"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 2"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 2"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 2"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 2"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 2"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 2"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 2"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 2"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 2"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 2"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 2"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 2"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 3"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 3"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 3"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 3"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 3"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 3"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 3"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 3"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 3"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 3"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 3"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 3"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 3"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 3"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 4"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 4"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 4"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 4"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 4"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 4"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 4"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 4"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 4"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 4"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 4"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 4"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 4"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 4"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 5"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 5"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 5"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 5"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 5"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 5"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 5"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 5"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 5"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 5"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 5"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 5"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 5"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 5"/>
<w:LsdException Locked="false" Priority="60" Name="Light Shading Accent 6"/>
<w:LsdException Locked="false" Priority="61" Name="Light List Accent 6"/>
<w:LsdException Locked="false" Priority="62" Name="Light Grid Accent 6"/>
<w:LsdException Locked="false" Priority="63" Name="Medium Shading 1 Accent 6"/>
<w:LsdException Locked="false" Priority="64" Name="Medium Shading 2 Accent 6"/>
<w:LsdException Locked="false" Priority="65" Name="Medium List 1 Accent 6"/>
<w:LsdException Locked="false" Priority="66" Name="Medium List 2 Accent 6"/>
<w:LsdException Locked="false" Priority="67" Name="Medium Grid 1 Accent 6"/>
<w:LsdException Locked="false" Priority="68" Name="Medium Grid 2 Accent 6"/>
<w:LsdException Locked="false" Priority="69" Name="Medium Grid 3 Accent 6"/>
<w:LsdException Locked="false" Priority="70" Name="Dark List Accent 6"/>
<w:LsdException Locked="false" Priority="71" Name="Colorful Shading Accent 6"/>
<w:LsdException Locked="false" Priority="72" Name="Colorful List Accent 6"/>
<w:LsdException Locked="false" Priority="73" Name="Colorful Grid Accent 6"/>
<w:LsdException Locked="false" Priority="19" QFormat="true"
Name="Subtle Emphasis"/>
<w:LsdException Locked="false" Priority="21" QFormat="true"
Name="Intense Emphasis"/>
<w:LsdException Locked="false" Priority="31" QFormat="true"
Name="Subtle Reference"/>
<w:LsdException Locked="false" Priority="32" QFormat="true"
Name="Intense Reference"/>
<w:LsdException Locked="false" Priority="33" QFormat="true" Name="Book Title"/>
<w:LsdException Locked="false" Priority="37" SemiHidden="true"
UnhideWhenUsed="true" Name="Bibliography"/>
<w:LsdException Locked="false" Priority="39" SemiHidden="true"
UnhideWhenUsed="true" QFormat="true" Name="TOC Heading"/>
<w:LsdException Locked="false" Priority="41" Name="Plain Table 1"/>
<w:LsdException Locked="false" Priority="42" Name="Plain Table 2"/>
<w:LsdException Locked="false" Priority="43" Name="Plain Table 3"/>
<w:LsdException Locked="false" Priority="44" Name="Plain Table 4"/>
<w:LsdException Locked="false" Priority="45" Name="Plain Table 5"/>
<w:LsdException Locked="false" Priority="40" Name="Grid Table Light"/>
<w:LsdException Locked="false" Priority="46" Name="Grid Table 1 Light"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark"/>
<w:LsdException Locked="false" Priority="51" Name="Grid Table 6 Colorful"/>
<w:LsdException Locked="false" Priority="52" Name="Grid Table 7 Colorful"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 1"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 1"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 1"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 1"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 1"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 2"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 2"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 2"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 2"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 2"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 3"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 3"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 3"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 3"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 3"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 4"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 4"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 4"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 4"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 4"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 5"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 5"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 5"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 5"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 5"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="46"
Name="Grid Table 1 Light Accent 6"/>
<w:LsdException Locked="false" Priority="47" Name="Grid Table 2 Accent 6"/>
<w:LsdException Locked="false" Priority="48" Name="Grid Table 3 Accent 6"/>
<w:LsdException Locked="false" Priority="49" Name="Grid Table 4 Accent 6"/>
<w:LsdException Locked="false" Priority="50" Name="Grid Table 5 Dark Accent 6"/>
<w:LsdException Locked="false" Priority="51"
Name="Grid Table 6 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="52"
Name="Grid Table 7 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="46" Name="List Table 1 Light"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark"/>
<w:LsdException Locked="false" Priority="51" Name="List Table 6 Colorful"/>
<w:LsdException Locked="false" Priority="52" Name="List Table 7 Colorful"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 1"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 1"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 1"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 1"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 1"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 1"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 2"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 2"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 2"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 2"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 2"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 2"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 3"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 3"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 3"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 3"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 3"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 3"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 4"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 4"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 4"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 4"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 4"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 4"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 5"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 5"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 5"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 5"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 5"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 5"/>
<w:LsdException Locked="false" Priority="46"
Name="List Table 1 Light Accent 6"/>
<w:LsdException Locked="false" Priority="47" Name="List Table 2 Accent 6"/>
<w:LsdException Locked="false" Priority="48" Name="List Table 3 Accent 6"/>
<w:LsdException Locked="false" Priority="49" Name="List Table 4 Accent 6"/>
<w:LsdException Locked="false" Priority="50" Name="List Table 5 Dark Accent 6"/>
<w:LsdException Locked="false" Priority="51"
Name="List Table 6 Colorful Accent 6"/>
<w:LsdException Locked="false" Priority="52"
Name="List Table 7 Colorful Accent 6"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Mention"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Smart Hyperlink"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Hashtag"/>
<w:LsdException Locked="false" SemiHidden="true" UnhideWhenUsed="true"
Name="Unresolved Mention"/>
</w:LatentStyles>
</xml><![endif]--><!--[if gte mso 10]>
<style>
/* Style Definitions */
table.MsoNormalTable
{mso-style-name:"Table Normal";
mso-tstyle-rowband-size:0;
mso-tstyle-colband-size:0;
mso-style-noshow:yes;
mso-style-priority:99;
mso-style-parent:"";
mso-padding-alt:0in 5.4pt 0in 5.4pt;
mso-para-margin-top:0in;
mso-para-margin-right:0in;
mso-para-margin-bottom:8.0pt;
mso-para-margin-left:0in;
line-height:107%;
mso-pagination:widow-orphan;
font-size:11.0pt;
font-family:"Calibri",sans-serif;
mso-ascii-font-family:Calibri;
mso-ascii-theme-font:minor-latin;
mso-hansi-font-family:Calibri;
mso-hansi-theme-font:minor-latin;
mso-bidi-font-family:"Times New Roman";
mso-bidi-theme-font:minor-bidi;}
</style>
<![endif]--></div>
David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-32261106068272970532019-06-22T13:24:00.000-07:002019-06-23T09:58:05.471-07:00Open Your Eyes to Technology Blindness in Your Decision Making<br />
If you make or recommend technology decisions, you've probably seen your share of good and bad ones with both expected and unexpected outcomes. Technology decisions are tough, and one of the reasons is a kind of blindness we have about technology. In this post we'll examine some different types of <i>technology blindness</i> and what you can do to prevent them from steering you in a wrong direction.<br />
<br />
<h2>
Solving the Wrong Problem</h2>
<h2>
</h2>
<br />
<i>"If I had an hour to solve a problem I'd spend 55 minutes thinking about the problem and 5 minutes thinking about solutions." ―Albert Einstein</i><br />
<br />
Asking the wrong question can derail the decision-making process from day one. Imagine you work in auto sound systems and are asked to make the speakers louder. If you take the request at face value and start working on making your speakers louder, you could well be solving the wrong problem. Instead, you should probe into what the real problem is by inquiring what the impetus was for the request. If you investigate, you might discover the real issue is that the car has poor soundproofing (nothing to do with speaker volume). Or perhaps someone is hard of hearing and the solution to their problem is a hearing aid, not louder speakers. It's critical to understand the actual root problem and not be swayed by someone's suggested solution.<br />
<br />
The <a href="https://en.wikipedia.org/wiki/XY_problem" target="_blank">XY problem</a> is a well-known phenomenon where someone asks "How
can I use X to solve Y?" when they should have been asking "How do I solve Y?" The emphasis on a proposed solution throws all the attention in the wrong place (X), the root problem doesn't get studied, and other potential solutions never get considered (quite possibly including the best solution). You want to understand the real problem at hand and not have a decision colored by an initial suggestion.<br />
<br />
The XY problem is something we're all probably guilty of, but once aware we can stop it from continuing. The XY problem is particularly difficult to contend with if it comes from a high-ranking person in your organization that no one is willing to challenge. Sadly, you may at times run into the XY problem not out of ignorance but deliberately, because someone stands to gain something if decision X is made.<br />
<br />
If you suspect an XY problem, approach it constructively by asking the right questions to get your group to understand what the real decision question is. From there, you can consider multiple solutions in addition to the one that was originally advanced.<br />
<br />
Be sure you're asking the right question, and steer clear of the XY problem.<br />
<br />
<h2>
The Bright Shiny Object</h2>
<br />
<i>"It is a mistake to suppose that any technological innovation has a
one-sided effect. Every technology is both a burden and a blessing; not
either-or, but this-and-that." —Neil Postman </i><br />
<br />
A <i>bright shiny object </i>is anything we're enthralled with. Whether as children or adults, when human beings are fascinated with something they look through rose-colored glasses. Whenever we're shown new technology with some obvious benefits, we tend to focus on the positive and not think very much about negatives. The history of technology is full of examples of things we've rushed to embrace, only to later discover they also come with consequences, sometimes disturbing ones.<br />
<br />
The automobile provided many benefits, including freedom to travel; the ability to work and shop beyond walking distance; and they were fun and cool. When automobiles started to be widely embraced in the 1920s, the public was focused very much on those benefits. There were secondary benefits, too: mass producing the automobile led to jobs and manufacturing innovations like the assembly line. Despite all these benefits, there were also consequences but they went unrealized for a long time. The automobile also polluted; led to traffic jams and highway deaths; and dissolved the traditional practice of multi-generational families living close together.<br />
<br />
Television's huge popularity has given us a multitude of ever-increasing programming for decades, some of it quite good. However, it too has negative repercussions. It's been a huge contributor to obesity; has been shown to have negative behavioral effects on children; and also can't be trusted to be truthful. In the book <a href="https://www.amazon.com/dp/B0023ZLLH6/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1" target="_blank">Amusing Ourselves To Death</a>, author Neil Postman explores what television has done to public discourse and our ability to think and debate critically. Television's nature means entertainment and ratings are king; any other considerations such as truthfulness and accuracy of content are subservient to those top considerations.<br />
<br />
Today we hear a lot about "fake news", usually associated with social
media. When social media started getting traction, people were focused
on benefits such as being able to stay in touch with friends and family
far away; and re-connecting with people from your past. Other
benefits followed: a relative could see pictures or video of that
birthday or graduation they were unable to be there for; and we can now
check lots of reviews before we decide to purchase something or go
somewhere. Among all the good, we're only now becoming aware of the downside: social media lets people spin what they share; encourages addictive behavior
through dopamine-rewarded interactions; distracts drivers (sometimes fatally); and channels our attention on
things that go viral. <u>Of course</u> there is fake news on social media: the fundamental nature of these platforms promote this behavior, whether intended or not.<br />
<br />
The good and bad effects of examples like these are obvious in hindsight but much harder to realize at the time you are confronted with a new technology. That's why it's so important to be on the lookout for them. When you consider any new technology or product you should evaluate it as fully as you can. Not having the full picture means you may have missed a significant negative or not accounted for its true cost.<br />
<br />
Recognize that every technology is a double-edged sword that comes with consequences as well as benefits. Identify them so you are making an informed decision. If a technology is so new there isn't much known about its consequences, ask yourself if you're really willing to risk those unknowns. If your company culture encourages you to take risks or make big bets and you're looking to use a new or unproven technology, you should at least anticipate that there may be unintended consequences and have a fallback plan.<br />
<br />
Get the full picture on any technology, product, or platform you're considering. Make an eyes-open decision that takes into account consequences as well as benefits.<br />
<br />
<h2>
Success Blindness</h2>
<i> </i><br />
<i>"If you can’t measure it, you can’t improve it." ―Peter Drucker</i><br />
<br />
So, you've made a decision. Was it a successful one? You'd think the answer to that would be fairly obvious once some time has gone by, but you'd be surprised how often a decision's effects are less than clear. On more than one occasion I've watched leaders paint a decision as successful when there is no basis for that claim, and it's a sad form of self-deception. On top of that, some people just won't admit to failure and will lie about the state of things to their superiors.<br />
<br />
Don't be deceived and don't be dishonest: know exactly where you stand and have the courage to honestly evaluate the success or failure of your decisions.<br />
<br />
Success blindness is almost guaranteed if you haven't devised a way
to <u>measure </u>the success of your decision. Without measurement, it's too easy to find something
positive in the state of affairs and attribute it your decision without
knowing if there's any correlation. Be aware that it's rather
self-serving to come up with a success measurement <i>after</i> the decision has been put into effect, so be sure to address measurement early on.<br />
<br />
If you want to get better at decision making, technical or otherwise, you need to get in the habit of measuring the success of your decisions. You made that decision in order to bring about a positive result, right? Then there should be a way to measure that result. If you're unsure how to measure the effects of your decision, you can learn how to measure well. I recommend <a href="https://www.amazon.com/How-Measure-Anything-Intangibles-Business/dp/1118539273/ref=pd_lpo_sbs_14_t_0?_encoding=UTF8&psc=1&refRID=SEDDA3GQHYQG8WTF8WGV" target="_blank">How to Measure Anything: Finding the Intangibles in Business</a> by Douglas Hubbard.<br />
<br />
<h2>
Overcoming Technology Decision Blindness</h2>
<br />
Solving the Wrong Problem, Bright Shiny Object Syndrome, and Success Blindness are common afflictions that plague technology decision making. Technology blindness is something we are all susceptible to; overcoming it requires acknowledging it. Start with yourself by taking a hard look in the mirror.
Seek to uncover your own blind areas and decision biases. Then influence others to do the same.<br />
<br />
Constructively ask the right questions in meetings and documents to focus on the real problems you need to understand and shed light on blind spots as you consider solutions. With awareness, you and your colleagues can make more successful decisions with confidence. With measurement, you can get better and better at it.David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-16655153598491808192019-06-15T12:02:00.000-07:002019-06-16T07:24:40.745-07:00Using Mind Maps for Brainstorming and Idea RefinementMind Mapping is a very effective technique for getting teams to brainstorm and refine their ideas. I'd like to share where I learned the technique and how I use it today.<br />
<br />
<h2>
My Introduction to Mind Mapping</h2>
<br />
The year was 2005, and at the time I worked for Microsoft on the product team that was developing "Indigo", later to be known as Windows Communication Foundation. We were a large team of 400, and I'd been invited to attend a meeting called by Oliver Sharp, our General Manager who led the overall team.<br />
<br />
What followed was a fascinating meeting where I observed how to get people to brainstorm and refine their ideas quickly and effectively. It's too long ago for me to remember the exact details (nor would it be appropriate for me to share them), but I'll recount the basic way it proceeded with some generalized content.<br />
<br />
We were slated to release WCF later that year, and Oliver wanted a program
defined to focus on fostering customer adoption of the new technology.
At this meeting we needed to take the raw notion of a "Customer Adoption
Program" and turn it into something tangible. I and several dozen others had been invited to this meeting.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr3BvWqLg9Xt7dt78oR3lqI035VlSca_8B7XJXhRrD7AsVzCJ6LdfRnMSSOimIHIxC0NqK25ZJkJbinucYjCJNXpR_-UrztuEhJ2gcx8SsLiXgqkZM50AintZGsobtBsFRu9-Zr1QkpLg/s1600/CAP_01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="859" data-original-width="1600" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhr3BvWqLg9Xt7dt78oR3lqI035VlSca_8B7XJXhRrD7AsVzCJ6LdfRnMSSOimIHIxC0NqK25ZJkJbinucYjCJNXpR_-UrztuEhJ2gcx8SsLiXgqkZM50AintZGsobtBsFRu9-Zr1QkpLg/s400/CAP_01.png" width="400" /></a></div>
<br />
Oliver shared his screen, which appeared to show a virtual whiteboard. At the center was "Customer Adoption Program". And then he simply asked everyone to chime in. He wanted to hear ideas about what that should include. As things were suggested, he rapidly incorporated them into what I learned was a Mind Map diagram. If someone suggested the need for samples, a spoke went out labeled Samples. If someone else mentioned the need to support migration, a Migration spoke went up. Most suggestions, unless there was group dissent, went on the board initially. Some remained, while others were later removed or combined with something else.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXdh6tMIl0Kpyh-0M9zBMpeXSzOS8Rqum5NMh_qtp1Vxi3ImLYA0kuU9CmPV71wdykIuNjMOZGO2r54eZDohVqmkkq1LYFCnnEtB0gwMUSzh7Ji4jXRYW_c2xE5A_DgfedF2gvmvjZPhY/s1600/CAP_02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="859" data-original-width="1600" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXdh6tMIl0Kpyh-0M9zBMpeXSzOS8Rqum5NMh_qtp1Vxi3ImLYA0kuU9CmPV71wdykIuNjMOZGO2r54eZDohVqmkkq1LYFCnnEtB0gwMUSzh7Ji4jXRYW_c2xE5A_DgfedF2gvmvjZPhY/s400/CAP_02.png" width="400" /></a></div>
<br />
It wasn't just adding spokes. Some spokes, upon being identified, led to offshoot ideas. As ideas were articulated, he asked refinement questions: was this idea
right or wrong? what would it entail? Were we considering alternatives? His skillful questioning forced us to think things through and round out our ideas.<br />
<br />
As more things were suggested, it was necessary to revise the
diagram. After Announcements and Blogging were on the board, we realized
these were both types of Customer Communication; so the diagram changed. The Mind Mapping
software he was using (<a href="https://www.mindjet.com/en-mind-mapping-nb6/?campaignID=7011M000000GEaI&gclid=Cj0KCQjwrpLoBRD_ARIsAJd0BIXOjSTusHGq7Mg44WOKnWV59FxciU3ZUBCERmpvZugJkXp8Vp_nOhQaAix_EALw_wcB" target="_blank">MindJet MindManager</a>,
I think) made these kinds of reorganizations and moving of whole
branches around quick and easy. This allowed the mind map to keep up with the pace
of discussion without being onerous.<br />
<br />
As more spokes were added, conceptual grouping continued. Convention Sessions and Code Camps were events, so they were incorporated into an Events category; and once the category was up there, other types of events came to mind such as training sessions at local field offices. Samples, documentation, and migration guidance became Resources. Whenever a concept had to be inserted or branches had to be moved around, the Mind Map software made this effortless. Ideas were being shouted out left and right and concepts were forming and being refined quickly. Some items were dropped. Some were combined. Some morphed into their own category with sub-items.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuFaECA4vdlAsq5vEvPgmDXLCirv0UY2NWbZ9QxI8OIabU42PRIk2yTJwpxn2FwoPDRYJTiWfeEKwaW1Y1GydiHEbpm9xxrDctjh0pXR4ereU9JTPGehmigi4sop-utFETlC34zPeuGz0/s1600/CAP_03.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="859" data-original-width="1600" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjuFaECA4vdlAsq5vEvPgmDXLCirv0UY2NWbZ9QxI8OIabU42PRIk2yTJwpxn2FwoPDRYJTiWfeEKwaW1Y1GydiHEbpm9xxrDctjh0pXR4ereU9JTPGehmigi4sop-utFETlC34zPeuGz0/s400/CAP_03.png" width="400" /></a></div>
<br />
It really was a marvel to behold how seemingly random ideas were herded and coaxed into a cohesive plan, because a skillful leader let the ideas flow from his team while in command of a powerful tool for organizing thought. When it comes to planning and ideation, I've tried to operate in exactly the same way ever since. Thanks Oliver!<br />
<br />
<h2>
How I Use Mind Mapping Today</h2>
Mind mapping is powerful, but don't get the idea it's something I do every day or every week. Although I do sometimes use mind maps to organize my own thoughts ("What questions might I get at this upcoming meeting?"), mind mapping really shines in a group setting. It's a technique I regularly employ when I need to need to lead a team through product design or annual planning or making a decision.<br />
<br />
A mind map is not the end product in itself but rather a means to an end. You should think of it a device for organizing your thoughts and developing them. For example, I might employ mind mapping in annual planning but my actual deliverable might be a document or spreadsheet, not a mind map. <br />
<br />
If you consider how a creative meeting would go without mind maps, you'll have to capture ideas in a document or on a whiteboard. That's far more limiting when it comes to developing ideas, and tends to make people hesitate to share ideas if they're not fully confident about them. In a mind map exercise, people are encouraged to share ideas and put them up there even if they're only half-baked at first. As the group considers and refines these ideas, the right things will happen to them and the half-baked ideas will become fully-baked. I suppose one could use post-it notes for this kind of exercise, but given there are very affordable software tools for this purpose I recommend using them.<br />
<br />
<h2>
Mind Mapping Tools</h2>
Today, there are many more choices for mind map software. I recently joined a new organization with a new team, and I took a fresh look at available tools. If you Google "mind map software" these days, you'll find there are <a href="https://zapier.com/blog/best-mind-mapping-software/" target="_blank">many to choose from</a> in addition to originals like <a href="https://www.mindjet.com/en-mind-mapping-b6/?campaignID=7011M000000GEWu&gclid=CjwKCAjw0ZfoBRB4EiwASUMdYcpP8UO-FIsrwvyKBuY3JregNz1ETJxTDBEQTPFaf6Cr3nc1UAydkBoC9a8QAvD_BwE" target="_blank">MindManager</a>. There are two basic categories: mind map add-ons and templates for general diagramming products; and software specifically designed for mind maps and other conceptual diagrams.<br />
<br />
The first category (adds-ons and templates) is tempting because you can leverage a tool you already know well, such as Visio, MS Office, Google Docs, LucidChart or Draw.io. However, I've found this approach is too burdensome when you're trying to keep up with a brainstorming session. There tend to be too many clicks needed to add items and connections; and very limited support for inserting nodes and moving around whole branches to another area of the diagram. For example, I've been a PowerPoint user for decades, but I wouldn't try to use it for a mind map session: it would just be too cumbersome to insert new concept nodes and move things around. You really need something that can capture what's happening at the speed of a creative exercise which might include pivoting all your groupings and connections after a moment of epiphany. You also want to avoid a tool that will distract you from being a participant yourself. Personally, I think you're far better off with something designed to facilitate this kind of dynamic activity.<br />
<br />
The second category (software designed for conceptual diagramming) is the better option and also has many choices. You of course should take advantage of free trials to evaluate some of them and decide which features you value the most. You may care most about unlimited canvas size, while someone else may care most about what kind of files can be attached to a diagram. Cost and license models vary: some of these tools are one-time purchases; others are subscription-based or even free. Some require an Internet connection, others don't.<br />
<br />
For myself, I ended up settling on <a href="https://coggle.it/" target="_blank">Coggle</a> this year. Coggle is nominally free, but if you want privacy of your diagrams you're well-advised to pay the $5/month (or $50/year) for a subscription; that's not much for what is turning out to be a very usable tool. For this low price, you can invite others in your organization to co-edit your diagrams without having to purchase any additional subscriptions.<br />
<br />
Here's an example of a mind map in Coggle, one that shows how a spell check feature for a (fictional) web site might be analyzed to get consensus on the best design. Things I value about Coggle include it's attention to usability, it's support for collaborative co-editing of your diagram with others, and that it doesn't overwhelm you with too many choices. <br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq7VO4VrmfnQL4zMj3gpcjzp3ZkR6ghkwCdW4rhy-zgahhbi_8r-ScQV7EsUv_VWE4Ulovu-7HtBUN2yWwsUb7BNFHo_1oB2pZxkmBE57IBw-KD0vnIutEWWJza32HmhQh9mE4SphIqgQ/s1600/COG_01.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjq7VO4VrmfnQL4zMj3gpcjzp3ZkR6ghkwCdW4rhy-zgahhbi_8r-ScQV7EsUv_VWE4Ulovu-7HtBUN2yWwsUb7BNFHo_1oB2pZxkmBE57IBw-KD0vnIutEWWJza32HmhQh9mE4SphIqgQ/s400/COG_01.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Coggle: Mind Map to Get to Consensus on a Site Feature Design Decision</i></div>
<br />
Here's another example in Coggle, a personal one. I was discussing vacation ideas with my teenage son this morning, and here's our initial mind map. This map will no doubt change considerably when I add my wife and daughters to the conversation. Since some destinations appeal on more than one category (Hawaii rates on both Scenic and Fun Activities, Las Vegas rates on both Food and Fun Activities), this might require me to cross-link some items to multiple categories, but that could get messy. Or perhaps graduate to a different visualization or use a spreadsheet, the mind map having done its job to identify important categories and potential candidates. It's best to use tools like this where they shine, and to not force fit them into applications they aren't right for.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaP5IGbTLgPQZp_3ZUG7tuZkIWTNZu7ulx8q1EezSwJbECCdhU_EAMLQ_WTfioF0yywEo3GhY3xanZnHVhzMS-DpVEu7NGd0URgtsxfhw32gD8pbywi-nqTGrLbPiFe7bG0g2WTnu6eE0/s1600/COG_02.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaP5IGbTLgPQZp_3ZUG7tuZkIWTNZu7ulx8q1EezSwJbECCdhU_EAMLQ_WTfioF0yywEo3GhY3xanZnHVhzMS-DpVEu7NGd0URgtsxfhw32gD8pbywi-nqTGrLbPiFe7bG0g2WTnu6eE0/s400/COG_02.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<i>Coggle: Where to Go on Vacation?</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
</div>
In conclusion, mind mapping is a technique and toolset you ought to become acquainted with if you're ever in the position of hosting a brainstorming discussion. Compared to taking notes or just using a whiteboard, mind mapping both invites more ideas and equips you to refine those winning ideas and find consensus. The resulting clarity will be eye-opening.<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-23051507186725675172019-05-10T12:20:00.000-07:002019-05-16T07:14:42.293-07:00Using Gamification to Motivate Development TeamsIn this post I'll share some gamification techniques I've used to motivate software developers and improve team performance. For those not familiar with the term, <a href="https://en.wikipedia.org/wiki/Gamification#Technology_design" target="_blank">gamification</a> means using some elements of games in a non-game setting, such as developing any kind of software. It's all about adding some fun elements to the work that engage the team to rally around some activity and excel at it.<br />
<br />
If you doubt that games are a big deal these days, just consider the statistics. According to <a href="https://filmora.wondershare.com/infographic/video-game-trends-and-stats.html" target="_blank">Filmora</a>, Over $115 billion was spent on gaming in 2018. While gaming is often associated with the young, 63% of gamers are 21-50 and 15% are 51-65. 46% of gamers are women. Some people earn their living by streaming their video game play, called esports. Last year, for the first time the Winter Olympics included an esports event, and some expect esports to become a medal event by 2024.<br />
<br />
<h2>
Why Gamification in Software Development?</h2>
Gamification techniques can, in theory, be employed anywhere there's a human endeavor—but it certainly helps if what you're doing already contains elements that lend themselves to gaming. Software development happens to be a great fit.<br />
<br />
Gamification is all about motivation, and fun is a huge motivator. In software, like anything else, there are tasks that are naturally fun and other tasks that aren't so much fun. For example, most developers like working on features but dislike bug fixing. Features are fun, bugs aren't. What gamification can do is lend elements of fun and competition to those tasks that aren't already fun.<br />
<br />
Managing a team of software developers can be like herding cats at times when what you need is everyone pulling in the same direction and pulling their weight. A good development manager is concerned with both team delivery as well as the care and feeding of team members. He or she will want to see their team reach a point of low friction and high performance, which requires working well together. It's in this area, team dynamics, that a software manager can employee gamification techniques to promote and improve cohesive team behavior. Some of these techniques are subtle but they can make a difference.<br />
<br />
Software development is certainly a race to the finish, and I know of no better illustration than the classic 1959 film Ben Hur starring Charlton Heston. If you're familiar with the film, you might recall the scene where Judah Ben Hur first meets the Sheik and his four white horses, to whom he is very much devoted. Ben Hur observes the team racing and casually observes that the horses each have varying strengths, and the team would function better if certain changes were made such as moving a different horse to the inside of the track. The sheik is impressed with Ben Hur's prowess in team dynamics and pleads with him, "Can you make my four run as one?" Ben Hur agrees to work with the team, which goes on to see great victory.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxggxUjfvKvaCNOMFIuoXAmHmHxY3GiZ68Bl5hXofAdkgnsmvNaYn4-IB8c_c-4pCOFH6yDHk76eUjeYobmIa99wOTumUuarDt2iR3zaH2Koha3F6iGT0XpqK-uvIPi6aFmnPjx_3-5U/s1600/benhur_team.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="353" data-original-width="948" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEglxggxUjfvKvaCNOMFIuoXAmHmHxY3GiZ68Bl5hXofAdkgnsmvNaYn4-IB8c_c-4pCOFH6yDHk76eUjeYobmIa99wOTumUuarDt2iR3zaH2Koha3F6iGT0XpqK-uvIPi6aFmnPjx_3-5U/s400/benhur_team.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>In Ben Hur, "four run as one"</i></div>
<br />
And so, a software project can be treated as a race; and an optimization task can be treated like a strategy game; and a difficult bug can be treated like a puzzle. There are many opportunites to apply gamification in software development. Let's look at a few examples.<br />
<br />
<h2>
Using Dashboards for Fun and Effective Metrics</h2>
Dashboards are fertile ground for gamification. Since many games display scores or stats, you can visualize software development metrics in the same way. Take bug counts, for example. You can show active open bug counts prominently. Even better, you can color-code them based on count, priority, severity, or whatever you choose to emphasize.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5n-22qwo9_8dXmpnx6xuD1aOnN5M6PoMYOj2M1KuFtpBbdWXPFBY50fYRBo5cedMkY5_Ts3_lAi_IXEUi4ZHbh65Qs4fq0vcVrHqetWialLwJBO-XJUUzsg3YWc3ejiyByM0dNSfY_vc/s1600/dash_bug_counts.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="133" data-original-width="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5n-22qwo9_8dXmpnx6xuD1aOnN5M6PoMYOj2M1KuFtpBbdWXPFBY50fYRBo5cedMkY5_Ts3_lAi_IXEUi4ZHbh65Qs4fq0vcVrHqetWialLwJBO-XJUUzsg3YWc3ejiyByM0dNSfY_vc/s1600/dash_bug_counts.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Showing Bug Counts wth Color Coding</i></div>
<br />
In addition to raw bug counts I've found it useful to track how a team is trending on bugs, using the count <i>new bugs found</i> <i>this week</i> against the count of <i>bugs closed this week</i>. It's the ratio I'm interested in: if more bugs were found than were fixed, we're drowning (trending in a poor direction). If we're fixing more bugs than are being found, we're trending positively and our situation is improving. And if we're about even on these counts, we're just treading water but aren't really making progess. You can visualize these valuable statistics easily on a dashboard.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib7sDxQsXg3rUaF9X-aFhf1X3L_XTWsD4QbtP6zP9iHwsRbGCBUtIF_0Md-8BCJjxxxURx13my1osI29SI874mqdNS5hwhK86HA1mQUveEiddUwsok8wek23sHyUXiCNfQzMlXIKxtnvM/s1600/dash_bug_trends.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="133" data-original-width="279" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib7sDxQsXg3rUaF9X-aFhf1X3L_XTWsD4QbtP6zP9iHwsRbGCBUtIF_0Md-8BCJjxxxURx13my1osI29SI874mqdNS5hwhK86HA1mQUveEiddUwsok8wek23sHyUXiCNfQzMlXIKxtnvM/s1600/dash_bug_trends.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Bug Trend Count</i></div>
<div style="text-align: center;">
<br /></div>
If your dashboard allows it, the bug trend ratio could also be shown visually in other ways, like a seesaw or the artificial horizon found an airplane cockpits. The idea is to convey the team's direction dramatically (but not over-dramatically; everything can't be an emergency). And of course you can look at trends over time in charts and reports; here though we're thinkng about simple at-a-glance visuals the team can see every day about the current work. Whatever you choose to show, strive for clear measurements and a simple presentation: everyone should have a common understanding of what they're looking at and what they can do change the situation.<br />
<br />
Putting scores and stats in front of the team is more than an attempt to make metrics fun and playful: it provides a feedback loop by which the team gets regularly reinforced about how effective or ineffective their efforts are. One of the most important things to learn about software teams is <i>never mistake motion for progress</i>. Useful visuals can help everyone on the team see that.<br />
<br />
<h2>
Making it Personal: Leaderboards</h2>
Another valuable gamification technique that also leverages dashboards is the use of <i>leaderboards</i>. I once worked with a team that was doing well on assigned feature work but dragged their heels on bug resolution; the bug backlog was larger than anyone liked and we weren't making sufficient progress against it, despite my weekly exhortations. It's somewhat natural for developers to prefer feature work to bug fixing, as the former is fun and the latter isn't. As a manager, I needed to ensure my team was fixing an appropriate number of bugs each week.<br />
<br />
After some analysis of bug fixing activity, it was clear that we had a mixed bag in terms of developer focus on bugs. A few individuals were in fact addressing an acceptable number of bugs each week. Others did some bug fixes but not nearly the quota I'd established. And there were a handful who fixed no bugs at all. Even though a few were doing their part and more on bug fixes, the overall bug fix counts were far short of our goals. What was needed was a way to motivate every developer to do their part.<br />
<br />
I hit upon the idea of showing bugs fixed each week, by developer, in the form of a leaderboard. Now it was crystal clear to the entire team at our meetings how many bugs each developer had fixed that week, ranked top to bottom by most bugs resolved. Something happens to you when you see your name displayed on a leaderboard like this: nobody wants to be on the bottom of the list, and the more ambitious will compete to be first on the list.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJF7yluRf6JKxJhAFNnV2FBD9hBAZ0IVv_SMjqFE1-38EfJr1PZeFicqMTailVkG8n40ObQxYe_XnF3PYGg7Q6Rg1qCTeIegScoEqWNuAYatrLd55PIxns05Zez3_cRoGcC3YG0olbWfE/s1600/dash_dev_bug_fixes.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="428" data-original-width="256" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgJF7yluRf6JKxJhAFNnV2FBD9hBAZ0IVv_SMjqFE1-38EfJr1PZeFicqMTailVkG8n40ObQxYe_XnF3PYGg7Q6Rg1qCTeIegScoEqWNuAYatrLd55PIxns05Zez3_cRoGcC3YG0olbWfE/s400/dash_dev_bug_fixes.png" width="238" /></a></div>
<div style="text-align: center;">
<i>Bug Fix Leaderboard</i></div>
<br />
Showing the bug fix leaderboard every day made a dramatic difference in bug activity and nearly all developers showed improved frequency right away. Like a sporting event, there were those clustered regularly near the top, middle, or back of the pack. When a dev, determined to break ahead, fixed a record number of bugs and rose on the leaderboard, that fact was pointed out and celebrated. Leaderboards probably aren't a good idea with a really small team but when you have half a dozen or more people they can be quite effective.<br />
<br />
When employing gamification, you do need to be careful about the behavior you're encouraging and think about ways it might be abused. For example, a dev could rack up a large bug fix count by focusing on easy bugs of lower priority rather than top priority issues. Another way a system like this could be abused is the poor bug fix, where a dev appears to have resolved many bugs (looking good on the leaderboard) but in fact most of them end up getting reopened because they weren't fully fixed (or even worse, had side effects causing new bugs to be opened). A better metric would be truly closed bugs where the fix has been verified. You'll want to think through what you're visualizing and make sure it doesn't promote unintended behaviors.<br />
<br />
<h2>
Badges and Microcredentials</h2>
Years back, when I was a practice manager at Neudesic, I needed to train as many of my consultants as possible in a new area: cloud computing. Microsoft had a Virtual Technology Specialist position that partners like Neudesic could participate in, and when one of my consultants qualified I awarded them one of these physical badges. It's not that they actually wore these when going to clients, but these badges of recognition were something they could proudly display in their cubicle, and they incented others to have similar aspirations.<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMS-O9ysVLMLAz8qUM5wn6BqXsZQ-9qAjfC-P66zPVpGTNInn7y9A11WNpZjW1uNHQE6FmFQPCBGVr_yz5Ep456-RtHGeSPY5qV6lbsD7ETgFc2LozcrQYVZT4dfTVpr7NFGxA26loPv4/s1600/neudesic_cloud_shield.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="214" data-original-width="153" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjMS-O9ysVLMLAz8qUM5wn6BqXsZQ-9qAjfC-P66zPVpGTNInn7y9A11WNpZjW1uNHQE6FmFQPCBGVr_yz5Ep456-RtHGeSPY5qV6lbsD7ETgFc2LozcrQYVZT4dfTVpr7NFGxA26loPv4/s400/neudesic_cloud_shield.png" width="285" /></a></div>
Today we have social media, and you can do the same thing digitally. If you use enterprise social media in your organization, and there is support for <a href="https://www.peoplegoal.com/blog/driving-employee-engagement-using-recognition-badges" target="_blank">badges</a>, then you can award badges to team members for good performance. Badges are a form of digital recognition; they're a way of patting someone on the back, figuratively, in full view of your organization. You can have a variety of badges that recognize such things as Excellence, Above the Call of Duty, Innovation, Grace under Pressure, Burning the Candle at Both Ends, Road Warrior, and so on.<br />
<br />
Awarding a badge may seem minor compared to something more substantial like a good performance review or a raise, but they have the important benefit of being immediate and being widely witnessed by others. At my last place of work, I felt really honored when someone in the company awarded me a badge, and I know others felt the same when I awarded them one. It's a simple, easy thing to do; and they work.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEgqR4FDPk903nthl7YS7BW_aepFtUxPt9Jw7KgtRs5k8DcgJuvbArw9I-7h43Kct4jkUVK36m-zuR86TE7LsmtRS4IYn1ticQd1b-jLtVzQWtPwIsipBwXC7_05k4TGfLfBtuVko5sp0/s1600/pulse_badge_profile.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="296" data-original-width="500" height="189" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgEgqR4FDPk903nthl7YS7BW_aepFtUxPt9Jw7KgtRs5k8DcgJuvbArw9I-7h43Kct4jkUVK36m-zuR86TE7LsmtRS4IYn1ticQd1b-jLtVzQWtPwIsipBwXC7_05k4TGfLfBtuVko5sp0/s320/pulse_badge_profile.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinxPUtnjzwawx-TG2Rr9eusoj3D-klEeTUV17BZTgbRe3MAtSPmX2_vjYOu2-EcvkqxgwTd_fQMkelPCAKMs4rBeAE7BbWn_qsnOXzUnDOequjbM5eqWx35nrofT7ZRMx2_4DEwqcs_VA/s1600/badges.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="760" data-original-width="1352" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinxPUtnjzwawx-TG2Rr9eusoj3D-klEeTUV17BZTgbRe3MAtSPmX2_vjYOu2-EcvkqxgwTd_fQMkelPCAKMs4rBeAE7BbWn_qsnOXzUnDOequjbM5eqWx35nrofT7ZRMx2_4DEwqcs_VA/s320/badges.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Badges in Social Media</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
Badges can be used another way besides in-the-moment recognition; they can be used for <a href="https://www.obviouschoice.com.au/what-are-micro-credentials" target="_blank">microcredentials</a>. A microcredential recognizes an achievement or status that a team member has reached. For example, someone who has shown significant innovation could receive the <span style="color: #666666;">Innovator </span>micro-credential. Whether the requirements for that are a single innovation or repeated innovation is something for the team/company to decide.<br />
<br />
Whereas the aforementioned use of badges is mostly a matter of "someone catching you doing something right", microcredentials usually take some effort to attain. A badge is similar to a <i>like</i>, whereas a microcredential is more like <i>unlocking a game achievement</i>. You could use microcredentials for all sorts of things in a software team, for example Build Master, Dev Ops, Certified Expert, Master Debugger, or Published.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzDL3kBPRjY1TnNSFTb_akCgj-Y8QBOHY8jus4tU7N9djLKWShp6rmqfD_YQUQCyQQXpIzZZshYmy10FFW_2HBXk7fgffC0VrHAvqUAk0PrZ23cba6DkNc3szqsgzsIGxTz2T4Tbi6X14/s1600/ibm_microcredentials.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="1024" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzDL3kBPRjY1TnNSFTb_akCgj-Y8QBOHY8jus4tU7N9djLKWShp6rmqfD_YQUQCyQQXpIzZZshYmy10FFW_2HBXk7fgffC0VrHAvqUAk0PrZ23cba6DkNc3szqsgzsIGxTz2T4Tbi6X14/s320/ibm_microcredentials.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Example of Micro-Credentials</i></div>
<br />
With badges and microcredentials, you want to avoid making things too easy: if everyone gets a "participation award", the value of the award is diminished and so is team motivation.<br />
<br />
<h2>
Puzzle Solving</h2>
Puzzle solving is a common task in software development that also lends itself to gamification. Whether it's finding the best approach in your design, optimizing an implementation, or diagnosing a bug, those puzzle-solving tasks become a bit more fun if treated like a game.<br />
<br />
Another favorite film of mine is Apollo 13. There's a scene in that movie where the astronauts are running out of breathable air because three men are trying to survive in a lunar module intended for two people. Engineering is tasked with finding a way to make the square air scrubber cartridges from the command module work in the lunar module which used round cartridges; effectively, <a href="https://history.nasa.gov/SP-350/ch-13-4.html" target="_blank">a square peg had to be made to fit in a round hole</a>. Moreover, the team could only use the items the astronauts had available to them on board.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxmI6s0jIG5K4WjpN8d22b6V5_MT-GBXVIi0_3yR5j_3cMgBactezspGW-JkTZfKOQatkKLXTaOOcn8qQzzQDI7cOog3P-e92g1PRpESd_wlZtdzmd7EEpsbNiUcqswsHiEStCrsM6LMU/s1600/apollo13.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="315" data-original-width="600" height="168" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhxmI6s0jIG5K4WjpN8d22b6V5_MT-GBXVIi0_3yR5j_3cMgBactezspGW-JkTZfKOQatkKLXTaOOcn8qQzzQDI7cOog3P-e92g1PRpESd_wlZtdzmd7EEpsbNiUcqswsHiEStCrsM6LMU/s320/apollo13.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Apollo 13: "The people upstairs handed us this one and we gotta come through."</i></div>
<br />
What I just described was crucial work that if not addressed would have meant the death of three people. But the work can still be formulated as a fun puzzle and I'm sure the engineers took delight in the solution, which involved duct tape, part of a space suit, and cardboard.<br />
<br />
<h2>
Prizes</h2>
For big engineering challenges that are above and beyond normal work requirements, consider prizes. That might take the form of throwing out a challenge across the company and choosing a winner out of the submissions. Doing this allows more people to get involved than assigning the problem to a single team and you get more fresh ideas that way. Innovation just might come from a surprise corner of your organization.<br />
<br />
Offering prizes for solving engineering problems is not new. Charles Lindbergh flew solo from New York to Paris to win the $25,000 Orteig prize in 1927. More recently, the XPrize foundation has been rewarding innovators in private space exploration. Rewards can work just as well on a smaller scale within an organization.<br />
<br />
<h2>
Frequent Demos and Feedback</h2>
I encourage my teams to do frequent show-and-tell. Even if we're doing Agile Scrum, which is supposed to end with a demo at the Sprint Review, I like to see demos regularly—at least once a week. My selfish reason for this as a manager is to have an opportunity to give feedback and provide any needed course control. However there's also a gamification aspect to frequent demos: having developers regularly show off their work is a form of competition.<br />
<br />
I know that I work better and get more done when I am encouraged along the way with constructive feedback. Note that I said constructive feedback, not undeserved praise. Regular demos are a great way to encourage mutual constructive feedback. It's not only enjoyable, it results in better software. Whether demos are an official part of your software methodology or not, I'm a big believer in them.<br />
<br />
If your workplace has any notion of setting aside weekly time for developers to play around on their own projects (the idea behind Google's "20% projects"), that's also a great thing to publicize with demos to the team. It gives recognition, the group feedback is invaluable, and it subtly reinforces competition across the team which raises the bar across the board.<br />
<br />
<h2>
Mundane Tasks</h2>
Every once in a while I find I have to do something that is very, very mundane and repetitive. It might be promoting a bunch of tasks to another sprint, one at a time. It might be that a long list of statements or data elements in a code editor all need to be massaged in some way.<br />
<br />
Sometimes tasks like this lend themselves to automation and sometimes they do not. At times I catch myself and say, Wait! I can write a small program or script and save myself a lot of time. And that's great. But when I can't do that, it's back to the onerous, seemingly never-ending repeated task. I used to just power through such tasks, but more recently I've found ways to make even this kind of work somewhat fun. When I'm in the moment of doing tedious-but-necessary repeated tasks, I can sometimes treat them as a game. What combination of keystrokes or clicks in the editor updates the next statement with the fewest number of interactions? What combinaton of keystrokes is most balanced across the keyboard? Gamification can be applied in many places if you look for it and are sufficiently motivated. It's a form of "Whistle whle you work."<br />
<br />
<h2>
Can Gamification Backfire?</h2>
One potential result of gamification is that your team will <i>play the game</i>. <a href="https://en.wikipedia.org/wiki/Hawthorne_effect" target="_blank">The Hawthorne Effect</a> is a phenomenon in which participants alter their behavior as a result of being observed. That is actually what you intend: you're encouraging your team to engage in order to "win"; the gamification's goal is motivation, engagement, competition, and a change in behavior or performance.<br />
<br />
However, it's also possible participants will try to win in less honorable ways by gaming the system itself. Consider our earlier example of leaderboards for bug fixes, where the most bugs fixed each week gets you to the top of the leaderboard and the bottom is a place of shame. In addition to the potential abuses already mentioned, anyone with project experience knows that one bug can often be logged as multiple bugs and vice-versa. That means these kind of metrics are susceptible to manipulation when there is bias. When setting up gamification, you'll want to think through potential abuses beforehand and take measures to thwart them; no one enjoys a rigged game. In the case of bug tracking, you might lay down some specific rules about how bugs are to be logged, avoiding duplication, and what the criteria is for claiming they are fixed... <i>before</i> you introduce a leaderboard.<br />
<br />
<h2>
Conclusion</h2>
Making work fun leads to happier workers and a better work product. In software development there are multiple opportunities to apply elements of gaming in the course of project work. Today we've examined a few from my own experience.<br />
<br />
If you've never tried gamification, give it a whirl. You might be surprised how effective it is to inject a little fun at work. By the way, there's no need to inform a team you're employing gamification techniques; just start to use them and observe the changes in behavior.<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-8046945116003201352019-05-07T09:43:00.001-07:002019-05-07T10:13:04.625-07:00Romans Ruins Adventure, Part 3: Twitch Minigame<style>
.tr0 { background-color: white; color: black; font-weight: bold; }
.tr1 { background-color: white; }
.tr2 { background-color: aliceblue; }
.syntaxhighlighter {
overflow-y: auto !important;
overflow-x: auto !important;
max-height: 512px;
}
</style>
<script>
if (location.protocol != 'http:')
{
location.href = 'http:' + window.location.href.substring(window.location.protocol.length);
}
</script>In this series of posts I'm sharing my experiences creating an old-style text Adventure game, adapted somewhat for the 21st century. In <a href="http://davidpallmann.blogspot.com/2019/05/roman-ruins-adventure-part-1-nostalgia.html" target="_blank">Part 1</a> I reviewed the history of Adventure games and the game design for my version, Roman Ruins Adventure. In Part 2, I covered an <a href="https://www.amazon.com/dp/B07RLJSS6C/ref=sr_1_1?keywords=roman+ruins&qid=1557184054&s=digital-skills&sr=1-1-catcorr" target="_blank">Alexa Skill</a> implementation of Roman Ruins Adventure. Here in Part 3 I'm covering a Twitch Minigame Extension implementation.<br />
<br />
For those unfamiliar with <a href="https://twitch.tv/" target="_blank">Twitch</a>, it's the world's largest video live streaming platform for the gaming community. Tens of millions of people around the world watch gamers play and chat about it; this is called <i>esports</i>.<br />
<br />
<br />
<h2>
Twitch Extensions: The Basics</h2>
Anyway, back to Twitch Extensions. If you've joined Twitch, you're either a broadcaster or a potential broadcaster, and you have a channel page from which people can access your live stream or videos. You can customize your channel page with additional elements, including Twitch Extensions. One use for Twitch Extensions are mini-games, and that's what I'm building here.<br />
<br />
I'm brand-new to writing Twitch extensions, so this was an exercise in getting familiar with their structure and methodology. There are several kinds of extensions. For our game, we'll be making a <i>panel extension</i>, which will appear below the video player on a broadcaster's channel page.<br />
<br />
To help developers get started, Twitch has <a href="https://dev.twitch.tv/docs/extensions/" target="_blank">assets you can download</a> including a Developer Rig (for locally testing your extension) as well as a Hello World sample. I'm doing this work in Visual Studio Code on Windows, but you can also develop Twitch extensions on MacOS or Linux.<br />
<br />
The Hello World sample has a two-fold structure: there is a front-end portion and a back-end portion. The front-end is just good old HTML, CSS, and JavaScript/TypeScript. That's what's going to render the panel UI. The back-end is a service that can handle POST requests. The Hello World extension simply puts a colored circle on the screen that you can change by clicking. In getting familiar with how extensions work I added to this starter code to make a simple color matching game. Here's what it looks like running in the Twitch Developer Rig:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXc8oFdAWTBQsFsjI7Om5HwBdji04TRaTFduJel4wTme_LrebYlUHW3w6hkVNVd7cubXyMTUOKzig-_uKXSYwBUecBmm8hdsTKmYFGaTZxvbo5lyiXwCvuKtFEOl3ck0pVfbTJa5YAwgU/s1600/rig_ColorMatch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1197" height="256" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXc8oFdAWTBQsFsjI7Om5HwBdji04TRaTFduJel4wTme_LrebYlUHW3w6hkVNVd7cubXyMTUOKzig-_uKXSYwBUecBmm8hdsTKmYFGaTZxvbo5lyiXwCvuKtFEOl3ck0pVfbTJa5YAwgU/s400/rig_ColorMatch.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Testing an Extension in the Twitch Developer Rig</i></div>
<br />
Once an extension is developed, there are <a href="https://dev.twitch.tv/docs/extensions/life-cycle/" target="_blank">other steps to follow</a> before it can become available on Twitch. It proceeds from Local Test to Hosted Test, where the developer can privately try it out on Twitch. It then gets submitted for approval. More on that process later. Armed with confidence from this initial exercise, it was time to make an extension for Roman Ruins Adventure.<br />
<br />
<h2>
Roman Ruins Adventure as an Extension</h2>
With tbe basic gameplay JavaScript code already in place (as described in Parts 1 and 2), this involved three activities:<br />
<br />
1. Injecting the JavaScript game code into the extension project structure.<br />
2. Adapting the user interface for the Twitch environment.<br />
3. Making changes to satisfy the requirments for Twitch Extensions.<br />
<br />
<h3>
Injecting the Game Code</h3>
Adding the JavaScript game code was fairly easy. The place for that in the extension project structure is the front-end code. The front-end code as provided in the Hello World project has a pretty simple structure, with these notable files:<br />
<br />
<ul>
<li>panel.html is the page that renders the extension panel, with a max display are size of 318 x 496 pixels.</li>
<li>viewer.js is supporting code for panel.html.</li>
<li>config.html is a configuration page for configuring the extension, if applicable.</li>
<li>config.js is supporting code for config.html.</li>
<li>helper.js contains helper functions.</li>
</ul>
<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXkRDEgrwpZ5VLmbqVMPrYaB4M7ePJwzQ2Xy3XH7r9EmShdgLeyI-ama2jk5j1tfkBSBOdsNlUap-xH-8zv2eA_MFKQIj3I5WRcunqvfd7x69V6D30Pilw0rsjkOBuqw_QiK2ES-QfAWw/s1600/front-end.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="203" data-original-width="484" height="134" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXkRDEgrwpZ5VLmbqVMPrYaB4M7ePJwzQ2Xy3XH7r9EmShdgLeyI-ama2jk5j1tfkBSBOdsNlUap-xH-8zv2eA_MFKQIj3I5WRcunqvfd7x69V6D30Pilw0rsjkOBuqw_QiK2ES-QfAWw/s320/front-end.png" width="320" /></a></div>
<br />
For my game, I would be adding game play code to viewer.js. I decided to put the game data code into a separate file, gamedata.js, due to its size. I also added jQuery and a tooltip library.<br />
<br />
<h3>
User Interface</h3>
My initial thoughts on a user interface were to keep things simple: after all, this project is about giving new life to old-style textual Adventure games in modern computing interfaces. For the Alexa voice skill described in Part 2, this was a slam dunk (although there was a visual element to consider for some Alexa devices).<br />
<br />
My first implementation had a command bar at bottom for entering commands like LOOK or TAKE BOTTLE, and the rest of the panel was reserved for the game's text narrative. But it looked very plain.<br />
<br />
In prototyping my mini-game as text-only display with text input, I couldn't get away from the feeling that this was going to be a non-starter with much of the Twitch audience. Would a young audience have the patience for entering text commands and reading through narratives, or would it be in everybody's best interest to provide some refinements?<br />
<br />
After playing around with some different ideas, I decided to first off make use of the pictures of Pompeii I'd taken last year, by making the panel background an image of the current room. This certainly added atmosphere and complemented the textual descriptions (a picture is worth 1000 words after all).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLhk1FDCqQN8CngyHNq45vDgbjeD_54vtFh7KCnbPeVDqWMlXPAdYKHExxoOFNqB8BXgO5Pr_RoWhcAVbdB1G-0mtMquGTkKl_2Z9A9Ob8ZXfSnAUcVVyGv6kKQ2wEaaqqzDHHSm0QO-c/s1600/ext-image.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="373" data-original-width="401" height="297" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLhk1FDCqQN8CngyHNq45vDgbjeD_54vtFh7KCnbPeVDqWMlXPAdYKHExxoOFNqB8BXgO5Pr_RoWhcAVbdB1G-0mtMquGTkKl_2Z9A9Ob8ZXfSnAUcVVyGv6kKQ2wEaaqqzDHHSm0QO-c/s320/ext-image.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>With Image Added for Current Room</i></div>
<br />
The second improvement I made is toolbar buttons as an alternative to text commands. The command bar remains, but you can now click toolbar buttons with icons for common commands like LOOK, INVENTORY-TAKE-DROP, and directional movements. As you click these buttons, the command being executed is shown in the command bar. Toolbar buttons result in much faster navigation, which might make all the difference to a player with a short attention span. In addition, the directional toolbar button are enabled/disabled to show in which directions movement is possible. This again can make the game much quicker to figure out and complete, but I think it's an acceptable compromise in usability for the target audience. It is a mini-game after all.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6J3BWtM-IxGdIdjW_sS0aeuHyI3YiXD0LqOzMXkJFpBuj3h2oHSK4S5WrNbqPbb6yae0q-p8m45IdVe1z0E2GcxN2j3xHvKHBRZlcYF_rUA9JAA5JOm4zK1fSPZy3nyKiOJ-B0huJzSQ/s1600/ext-toolbar.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="374" data-original-width="400" height="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6J3BWtM-IxGdIdjW_sS0aeuHyI3YiXD0LqOzMXkJFpBuj3h2oHSK4S5WrNbqPbb6yae0q-p8m45IdVe1z0E2GcxN2j3xHvKHBRZlcYF_rUA9JAA5JOm4zK1fSPZy3nyKiOJ-B0huJzSQ/s320/ext-toolbar.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>With Toolbar Added for Common Commands</i></div>
<div class="separator" style="clear: both; text-align: center;">
<i><br /></i></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiugNwWlhbfudmEZZXyk9OGOPTrxW4kLwqK5-RMY6PF99xYY-yTcU1wK6r5MMbMuuhtCnDxdGMkl1tgcqT3E5fwxx2I7S1wWMaRnid9IX2IGFUURaSf40l4sbWHTom54oWJOhTDVq7fK-E/s1600/ext-inventory.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="372" data-original-width="398" height="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiugNwWlhbfudmEZZXyk9OGOPTrxW4kLwqK5-RMY6PF99xYY-yTcU1wK6r5MMbMuuhtCnDxdGMkl1tgcqT3E5fwxx2I7S1wWMaRnid9IX2IGFUURaSf40l4sbWHTom54oWJOhTDVq7fK-E/s320/ext-inventory.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Inventory-Take-Drop Toolbar Action</i></div>
<br />
The third usability improvement is in the narrative text itself. I've added hyperlinks to prompt the user about common commands they might want to take. That means, for example, coming to the Gladiator Field a player can just click <span style="color: #666666;">a bone</span> in the narrative, instead of typing EXAMINE BONE in the command bar. Likewise, from the Examine Bone text they can click <span style="color: #666666;">take bone</span> instead of typing TAKE BONE in the command bar.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg218wQlPwNVhcFvzvTcOTH57ZApLRTt_KY5irQvTydoTvt8Qq3SuisDIWwqj4UJ7eRNS9ZJX-1_drHc5C4LVc1G5p9jdRvXtJ2UJEc-DIQ5vPLVqcTPLNUN7nXSzdmxSUB-t1_iJhDYXM/s1600/ext-link.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="377" data-original-width="399" height="302" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg218wQlPwNVhcFvzvTcOTH57ZApLRTt_KY5irQvTydoTvt8Qq3SuisDIWwqj4UJ7eRNS9ZJX-1_drHc5C4LVc1G5p9jdRvXtJ2UJEc-DIQ5vPLVqcTPLNUN7nXSzdmxSUB-t1_iJhDYXM/s320/ext-link.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiunZ9156_wwU4XXiCBhSqTmahnwqY3Qqap4qqtJwpdBJpl3Au66tlfjobL7uJXVCLcy5Mwgsiw-vaR6IL-KwSDl10qt-JTrZRStBU6Fss86ZkQY5hVGpWogA2C7Egb6V8i3E1VUbvZK8M/s1600/ext-link2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="374" data-original-width="400" height="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiunZ9156_wwU4XXiCBhSqTmahnwqY3Qqap4qqtJwpdBJpl3Au66tlfjobL7uJXVCLcy5Mwgsiw-vaR6IL-KwSDl10qt-JTrZRStBU6Fss86ZkQY5hVGpWogA2C7Egb6V8i3E1VUbvZK8M/s320/ext-link2.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>With Links in Narrative Text</i></div>
<br />
All of these changes streamline game play, perhaps to the point where the game world needs to be made significantly larger in order to remain engaging. I'll be working on that. For those who feel this foreshortens the traditional Adventure experience, you can always play the Alexa version.<br />
<br />
<h2>
Getting Things Working Locally</h2>
With some UI decisions made and the basic gameplay code added, it wasn't too much work to get this extension working locally. In viewer.js, click events were added to connect UI elements such as the toolbar buttons to game code functions.<br />
<pre class="brush:js">// Initialization - runs immediately after loading
$(function () {
// when we click the cycle button
$('#execute').click(function () {
if(!token) { return twitch.rig.log('Not authorized'); }
execute();
});
$('#command').focus(function() {
$('#command').val('');
});
$('#command').keyup(function(event) {
if (event.which == 13 || event.keyCode == 13) {
execute();
return false;
}
return true;
});
$('#btn-actions').click(function() {
if (gameOver) return;
actions();
});
$('#btn-inventory').click(function() {
if (gameOver) return;
$('#command').val('INVENTORY');
execute();
});
$('#btn-west').click(function() {
if (gameOver) return;
$('#command').val('WEST');
execute();
});
$('#btn-east').click(function() {
if (gameOver) return;
$('#command').val('EAST');
execute();
});
$('#btn-north').click(function() {
if (gameOver) return;
$('#command').val('NORTH');
execute();
});
$('#btn-south').click(function() {
if (gameOver) return;
$('#command').val('SOUTH');
execute();
});
$('#btn-up').click(function() {
if (gameOver) return;
$('#command').val('UP');
execute();
});
$('#btn-down').click(function() {
if (gameOver) return;
$('#command').val('DOWN');
execute();
});
$('#btn-examine').click(function() {
if (gameOver) return;
$('#command').val('LOOK');
execute();
});
$('#btn-help').click(function() {
if (gameOver) return;
$('#command').val('HELP');
execute();
});
newGame();
});
</pre>
A departure from the implementation for Alexa is that the dynamic output being generated is HTML, not text sentences. Sometimes that HTML is just text, but often it has embedded elements such as clickable links (SPAN elements) and line breaks (BR elements).<br />
<br />
Here's a part of the game code that executes the EXAMINE <i>object </i>command. If no recognizable object was referenced, the response is <i>Please identify the object to examine</i>. If we have a known object, objects[object] is the object definition and we can output its <span style="color: #666666;">name </span>property as a title and its <span style="color: #666666;">examine </span>property as a description. A link is then added to TAKE the object (or DROP it, if we're already carrying it). The object's <span style="color: #666666;">carrying </span>flag tells us if we're carrying the object or not.<br />
<pre class="brush:js">// Examine an object.
// Inputs: object : object ID (integer)
// Outputs: command result display to #output
function examine(object) {
if (object===null) {
$('#output').text('Please identify the object to examine.');
return;
}
$('#command').val('EXAMINE ' + objects[object].name.toUpperCase());
var html = '<b>' + objects[object].name + '</b>
' + objects[object].examine + '
';
if (objects[object].carrying)
html += '<span class="link" onclick="drop(' + object.toString() + ')">Drop ' + objects[object].name + '</span>';
else
html += '<span class="link" onclick="take(' + object.toString() + ')">Take ' + objects[object].name + '</span>';
$('#output').html(html);
}
</pre>
<div style="text-align: center;">
<i>examine function</i></div>
<br />
Once I could fully play the game locally and completed general debugging, I was ready for the next step: hosted testing on Twitch.<br />
<br />
<h2>
Hosted Testing</h2>
My first time through the extension process, I struggled a bit uploading the project. You create a zip file and upload it via the Twitch developer console. Each time I tried this the upload failed, but there weren't any details about why it failed. After ruling out any issues with the zipping itself, I eventually realized I wasn't supposed to upload the entire project, only the front-end files. I presume that if you do have a back-end, you must find your own hosting for this, such as an AWS Lambda function.<br />
<br />
Once your files are uploaded, you can tell the developer console to switch your extension from Local Test mode to Hosted Test mode. Now, from your own channel page the extension appears below the video player and you can test it there.<br />
<br />
Since I'd tested fairly extensively with the local Developer Rig, I expected the hosted test to go pretty quickly, but I was in for some surprises. Browsing to my channel on twitch.tv, I activated my panal extension and started playing Roman Ruins Adventure. My game started out okay, but almost immediately it got to a non-working state and would not respond to interactions.<br />
<br />
It turns out there are some requirements extensions need to meet that aren't caught by the Developer Rig. The F12 browser console confirmed there was unhappiness, and most of it was due to Content Security Policy.<br />
<br />
If you aren't familiar with <a href="https://en.wikipedia.org/wiki/Content_Security_Policy" target="_blank">Content Security Policy</a>, it's a standard intended to prevent a variety of attacks including cross-site scripting and clickjacking. It works like this: if the web server includes a Content-Security-Policy header in its responses, then a CSP-compliant client (like your browser) will enforce its regulations. Anything Twitch-hosted will send the Content-Security-Policy header, so any extensions you write for Twitch need to conform.<br />
<br />
Well. I wish the Twitch Developer Rig had alerted me to all of that during local test, but it didn't. Now that I was aware, it was time to refactor the code. One change I had to make was making my JavaScript library references use local files. That was easy enough.<br />
<br />
What else was CSP unhappy with? Primarily, it was the inline <span style="color: #666666;">onclick="function(...)"</span> attributes on the dynamically-generated HTML responses to commands. The biggest challenge here was the dynamic HTML the game functions generated, which often contained embedded links in the form of SPAN elements with <span style="color: #666666;">onclick </span>attributes. Somehow I needed to retain embedded links in my HTML <u>without </u>resorting to <span style="color: #666666;">onclick </span>attributes.<br />
<br />
After thinking about this for a bit, what I settled on was a click handler for #output, the div that holds the entire output for a command. The click handler can be set in the initialization code in viewer.js:<br />
<pre class="brush:js">// Initialization - runs immediately after loading
$(function () {
...
$('#output').click(function(e) {
outputClick(e);
});
newGame();
});
</pre>
The click handler itself, <span style="color: #666666;">outputClick</span>, works as follows. When it responds, it determines the specific element that was clicked: that could be <span style="color: #666666;">#output</span>, but it could also be something within that element, such as a SPAN element. It's the SPAN elements we're interested in, because they represent clickable links. But we're not permitted to use onclick attributes, so how to know what command to associate with a SPAN? What I ended up doing is inventing a custom HTML attribute for my SPANs called <span style="color: #666666;">command</span>. When the click handler determines a SPAN element was clicked, it checks for a <span style="color: #666666;">command </span>attribute, which holds the command it needs to execute.<br />
<pre class="brush:js">// Click handler for the output text, which may contain dynamically embedded links.
// If an item was clicked that contains a command="..." attribute, that command is executed.
function outputClick(e) {
if (e) {
var target = e.target;
if (target) {
var id = target.id;
var command = $(target).attr('command');
if (command) {
if (command==="RESTART") {
newGame();
startGame();
}
else
cmd(command);
}
}
}
}
</pre>
It took a little bit of time to come to this design, but once I did I felt good about it. The code remains simple and understandable, and the extension now works on Twitch in Hosted Test mode. Earlier we looked at some game code, the examine() function. Here's the revised version that is CSP-compliant:<br />
<pre class="brush:js">// Examine an object.
// Inputs: object : object ID (integer)
// Outputs: command result display to #output
function examine(object) {
if (object===null) {
$('#output').text('Please identify the object to examine.');
return;
}
$('#command').val('EXAMINE ' + objects[object].name.toUpperCase());
var html = '<b>' + objects[object].name + '</b>
' + objects[object].examine + '
';
if (objects[object].carrying)
html += '<span class="link" command="DROP ' + objects[object].name + '">Drop ' + objects[object].name + '</span>';
else
html += '<span class="link" command="TAKE ' + objects[object].name + '">Take ' + objects[object].name + '</span>';
$('#output').html(html);
}
</pre>
<div style="text-align: center;">
<i>examine function (revised for CSP)</i></div>
<br />
With these changes uploaded, Roman Ruins Adventure now works in Hosted Test mode. Yippee!<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB1GilJYkcz4TAk_DTnSqfhOM6wDIZp2c8ZsjY94h9wXNLTCREdowPtacBTxn6a1423XMToN_Yc3tuuPx8XfKgwvFaRTbiwXIlKd2n7FTQ4VQzXwAtxyE1acU_fo3Issios6BRqWk-KGg/s1600/ext-hosted.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiB1GilJYkcz4TAk_DTnSqfhOM6wDIZp2c8ZsjY94h9wXNLTCREdowPtacBTxn6a1423XMToN_Yc3tuuPx8XfKgwvFaRTbiwXIlKd2n7FTQ4VQzXwAtxyE1acU_fo3Issios6BRqWk-KGg/s400/ext-hosted.png" width="400" /></a></div>
<div style="text-align: center;">
<i>Extension on Twitch</i></div>
<br />
<h2>
Approval</h2>
All I had to do next was submit Roman Ruins Adventure for approval. There was a form to fill out, screenshots and icons to provide. After a few days' wait, I was approved. Now anyone who is retro-game minded (there are some of us, Retro Gaming is an entire category on Twitch) can partake.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC9Yu5Sc_m3NWWYNGpO6BNjib-7gQJ6ernwJhR1hbQdql5phWIoCXdWzjZMUMHo7tUwgnaUaX6ii1thCl0kaCL4sDOJZvxM89Ff9I2SJFMVjRPlavPF3PFiFvxkBGs16K6KJY_Fk14miQ/s1600/ext-desc.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="791" data-original-width="1600" height="197" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC9Yu5Sc_m3NWWYNGpO6BNjib-7gQJ6ernwJhR1hbQdql5phWIoCXdWzjZMUMHo7tUwgnaUaX6ii1thCl0kaCL4sDOJZvxM89Ff9I2SJFMVjRPlavPF3PFiFvxkBGs16K6KJY_Fk14miQ/s400/ext-desc.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Roman Ruins Adventure Extension Description on Twitch</i></div>
<br />
If you're a Twitch user, feel free to add Roman Ruins Adventure to your channel as a mini-game panel and give it a whirl. I'd be happy to hear your feedback.<br />
<br />
Previous: <a href="http://davidpallmann.blogspot.com/2019/05/roman-ruins-adventure-part-2-alexa-skill.html" target="_blank">Part 2: Alexa Skill</a><br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-72754288524658801152019-05-06T16:37:00.002-07:002019-05-07T09:44:07.988-07:00Roman Ruins Adventure, Part 2: Alexa Skill<style>
.tr0 { background-color: white; color: black; font-weight: bold; }
.tr1 { background-color: white; }
.tr2 { background-color: aliceblue; }
.syntaxhighlighter {
overflow-y: auto !important;
overflow-x: auto !important;
max-height: 512px;
}
</style>
<script>
if (location.protocol != 'http:')
{
location.href = 'http:' + window.location.href.substring(window.location.protocol.length);
}
</script>In this series of posts I'm sharing my experiences creating an old-style text Adventure game, adapted somewhat for the 21st century. In <a href="http://davidpallmann.blogspot.com/2019/05/roman-ruins-adventure-part-1-nostalgia.html" target="_blank">Part 1</a> I reviewed the history of Adventure games and the game design for my version, Roman Ruins Adventure. Here in Part 2 I'm covering an <a href="https://www.amazon.com/dp/B07RLJSS6C/ref=sr_1_1?keywords=roman+ruins&qid=1557184054&s=digital-skills&sr=1-1-catcorr" target="_blank">Alexa Skill </a>implementation of Roman Ruins Adventure.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihwg_L90hw4V1AwLgsd0m0OgJjaHICOA6MuZq_nw9d8r0bOCkFpo9PfnGuS4iayna3MsbXRw4KhOlW3EkQbi8MQuadv59_eZSFcjTJOHrlWdq2ODzzUOohKXgkYxiJy-0mqo9-gRJTZpI/s1600/alexa1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="642" data-original-width="454" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihwg_L90hw4V1AwLgsd0m0OgJjaHICOA6MuZq_nw9d8r0bOCkFpo9PfnGuS4iayna3MsbXRw4KhOlW3EkQbi8MQuadv59_eZSFcjTJOHrlWdq2ODzzUOohKXgkYxiJy-0mqo9-gRJTZpI/s320/alexa1.png" width="226" /></a></div>
<br />
I've already covered the basic game design, game data representation, and game code in JavaScript. Now we'll look at what it takes to implement the game as an Alexa Skill, a voice-driven app. Since classic Adventure games are textual in nature, it's a perfect fit for a voice assistant.<br />
<br />
<h2>
Alexa Skills Project</h2>
Alexa Skills are defined in the <a href="https://developer.amazon.com/alexa/console/ask" target="_blank">Amazon Developer Console</a>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxa2Cks3w8p7XL1IcC2HIJhFlhw76HPRuMUihWaTsuMwnzm2yvxdahRIoCJhwrDE-zuu7kFjSAzK1ve955ohZg0Ka3kqVn9Br1WcJn5PF7ZBdyxzVcAk5TxEvuSfOFmEL_PmIHrAA9XQA/s1600/skills_project.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxa2Cks3w8p7XL1IcC2HIJhFlhw76HPRuMUihWaTsuMwnzm2yvxdahRIoCJhwrDE-zuu7kFjSAzK1ve955ohZg0Ka3kqVn9Br1WcJn5PF7ZBdyxzVcAk5TxEvuSfOFmEL_PmIHrAA9XQA/s400/skills_project.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Alexa Skill Project</i></div>
<br />
Our project has these <a href="https://developer.amazon.com/docs/custom-skills/create-the-interaction-model-for-your-skill.html#about-intents-slots-and-dialogs" target="_blank">intents</a> defined:<br />
<ul>
<li>north, east, west, south, up, down : movement commands</li>
<li>look : examine surroundings</li>
<li>examine <i>object</i> : examine an object</li>
<li>take <i>object</i> : take an object</li>
<li>drop <i>object</i> : drop an object</li>
<li>give <i>object</i> : give an object</li>
<li>help : explain available commands</li>
<li>mission : restate the mission</li>
<li>restart : restart a new game</li>
</ul>
<div>
Each intent includes a set of utterances, which gives us a change to provide a range of possible words and wordings. For utterances that reference an object, such as <span style="color: #666666;">take </span>shown below, the object is defined as a slot named <span style="color: #666666;">object</span>. Elsewhere under slots we defined the possible value for object that might be spoken, such as "bone" or "bottle".</div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-5dBksq7TIRy6ds7wxK2yGYggdUY11bi_7eMC43tEhs9r0cMHt4Lw08cDD7kYE-Rhf-ps2W7eTNKufsk85Z_6sJKu7BBiFp_8TwrsUuXu3VPAID8roJFCBG3uYPhCw6qT_ZXpHORbaRA/s1600/intent_take.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="225" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-5dBksq7TIRy6ds7wxK2yGYggdUY11bi_7eMC43tEhs9r0cMHt4Lw08cDD7kYE-Rhf-ps2W7eTNKufsk85Z_6sJKu7BBiFp_8TwrsUuXu3VPAID8roJFCBG3uYPhCw6qT_ZXpHORbaRA/s400/intent_take.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Take Intent</i></div>
<div class="separator" style="clear: both; text-align: center;">
<i><br /></i></div>
<div class="separator" style="clear: both; text-align: left;">
The Alexa Skill project will recognize intents out of what a user speaks and categorize parts of that speech as objects. The gameplay itself however needs to be in our back end.</div>
<br />
<h2>
Lambda Node Project</h2>
The back end for our skill is a serverless function, an AWS Lambda function. Lambda functions can be written in a variety of languages. We're usinde node.js, because it fits the decision in Part 1 to write the game code in TypeScript/JavaScript.<br />
<br />
<h3>
Variables</h3>
At the top of our code are our variables, in an object named <span style="color: #666666;">session</span>. These include the current command and resulting output; the current room; a game over flag; the number of items being carried; an image URL for the current room; and lastly our arrays of rooms and objects. Those arrays get populated when the game initializes.<br />
<br />
Lambda functions don't inherently preserve state, so we will be passing this object to and from Alexa between invocations in order to preserve our game state.<br />
<pre class="brush:js">var session =
{
command: '',
output: '',
room: 0,
location: null,
gameOver: true,
itemsCarried: 0,
it: null,
imageUrl: image("0.jpg"),
objects: [],
rooms: []
}
</pre>
<h3>
Boilerplate Functions</h3>
In a node.js Lambda function for an Alexa Skill, a number of boilerplate functions are used to interact with Alexa. I'm using ones that came with one of the quickstarts, ColorPicker.<br />
<ul>
<li><span style="color: #666666;">onSessionStart </span>fires when a new session is created. </li>
<li><span style="color: #666666;">onLaunch </span>fires when the skill has been opened.</li>
<li><span style="color: #666666;">Exports.handler</span> routes incoming requests based on type. </li>
<li><span style="color: #666666;">onIntent </span>is called by Exports.handler to process an intent.</li>
</ul>
Let's look at one of those functions, <span style="color: #666666;">onIntent</span>. This dispatches each receieved intent from Alexa to an appropriate handler function.<br />
<pre class="brush:js">/**
* Called when the user specifies an intent for this skill.
*/
function onIntent(intentRequest, session, callback) {
console.log(`onIntent requestId=${intentRequest.requestId}, sessionId=${session.sessionId}`);
const intent = intentRequest.intent;
const intentName = intentRequest.intent.name;
// Dispatch to your skill's intent handlers
if (intentName === 'help') perform("HELP", intent, session, callback);
else if (intentName === 'mission') perform("MISSION", intent, session, callback);
else if (intentName === 'actions') perform("ACTIONS", intent, session, callback);
else if (intentName === 'look') perform("LOOK", intent, session, callback);
else if (intentName === 'examine') performObject("EXAMINE", intent, session, callback);
else if (intentName === 'take') performObject("TAKE", intent, session, callback);
else if (intentName === 'drop') performObject("DROP", intent, session, callback);
else if (intentName === 'use') performObject("USE", intent, session, callback);
else if (intentName === 'inventory') perform("INVENTORY", intent, session, callback);
else if (intentName === 'north') perform("NORTH", intent, session, callback);
else if (intentName === 'east') perform("EAST", intent, session, callback);
else if (intentName === 'west') perform("WEST", intent, session, callback);
else if (intentName === 'south') perform("SOUTH", intent, session, callback);
else if (intentName === 'up') perform("UP", intent, session, callback);
else if (intentName === 'down') perform("DOWN", intent, session, callback);
else if (intentName === 'look') perform("LOOK", intent, session, callback);
else if (intentName === 'repeat') performRepeat(intent, session, callback);
else if (intentName === 'restart') perform("RESTART", intent, session, callback);
else if (intentName === 'AMAZON.HelpIntent') {
getWelcomeResponse(callback);
} else if (intentName === 'AMAZON.StopIntent' || intentName === 'AMAZON.CancelIntent') {
handleSessionEndRequest(callback);
} else {
throw new Error('Invalid intent');
}
}
</pre>
<h2>
Command Functions</h2>
The <span style="color: #666666;">perform </span>function is called for simple commands that don't reference any objects, such as NORTH or LOOK. A command can be determined from the intent name, and is executed with the game function cmd(...).<br />
<pre class="brush:js">// Perform a one-word command - ex: LOOK
function perform(command, intent, alexaSession, callback) {
const repromptText = "Tell me a command, or say HELP for a list of commands.";
let shouldEndSession = false;
let speechOutput = '';
if (alexaSession.attributes)
session = alexaSession.attributes;
speechOutput = cmd(command) + suffix();
callback(session,
buildSpeechletResponse(session.command.toUpperCase(), speechOutput, repromptText, shouldEndSession));
}
</pre>
The <span style="color: #666666;">performObject </span>function is similar, but expects an object to passed along with the intent for commands such as TAKE BOTTLE or EXAMINE BONE. The command is the intent name, a space, and the object name, which is passed as a skill slot value.<br />
<pre class="brush:js">// Perform a command that references an object - ex: EXAMINE BONE
function performObject(command, intent, alexaSession, callback) {
const repromptText = "Tell me a command, or say HELP for a list of commands.";
let shouldEndSession = false;
let speechOutput = '';
if (alexaSession.attributes)
session = alexaSession.attributes;
command += " " + intent.slots.object.value;
speechOutput = cmd(command) + suffix();
callback(session,
buildSpeechletResponse(session.command.toUpperCase(), speechOutput, repromptText, shouldEndSession));
}
</pre>
Both perform and performObject must extract the saved <span style="color: #666666;">session </span>variables from alexaSession.attributes in order to know the game state. Both must pass <span style="color: #666666;">session </span>back to buildSpeechletResponse so that the updated game state is preserved.<br />
<br />
<h3>
buildSpeechletResponse</h3>
The <span style="color: #666666;">buildSpeechetResponse </span>function builds the speech output. Functions like <span style="color: #666666;">perform </span>and <span style="color: #666666;">performObject </span>pass output containing the text we want to speek. buildSpeechletResponse creates the JSON that causes that text to be spoken.<br />
<pre class="brush:js">// --------------- Helpers that build all of the responses -----------------------
function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
var outputSpeech = null;
var cardText = replace(output, '<break time="1s">', '\r\n\r\n');
if (output.indexOf('<') != -1) {
outputSpeech = { // output contains markup (audio, breaks) - output SSML
type: 'SSML',
ssml: '<speak>' + output + '</speak>',
};
}
else {
outputSpeech = { // output is just text
type: 'PlainText',
text: output
};
}
return {
outputSpeech: outputSpeech,
card: {
type: 'Standard',
title: `${title}`,
text: cardText,
content: `SessionSpeechlet - ${output}`,
image: {
"smallImageUrl": session.imageUrl,
"largeImageUrl": session.imageUrl
}
},
reprompt: {
outputSpeech: {
type: 'PlainText',
text: repromptText,
},
},
shouldEndSession,
};
}
</break></pre>
In the case of Alexa devices that can display cards (visuals), output is also created that includes a title of the spoken command, and an image to go with the current room. Those images are my photos of Pompeii, hosted in S3. Here's what the display looks like:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMTw_VGYAHlTN_Mb2B74pEhL0G8pPx4C1mxDtnarET8fuYcIk7jmsyM_Ra6e1E3MHfkwYCV-xolRHx28jHDbcvPil6J_K3NV2SSJ8F1bE79ai82K9r1LPkLTUnh66P8nVr9nB7pzYNQR0/s1600/alexa_card.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="424" data-original-width="721" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMTw_VGYAHlTN_Mb2B74pEhL0G8pPx4C1mxDtnarET8fuYcIk7jmsyM_Ra6e1E3MHfkwYCV-xolRHx28jHDbcvPil6J_K3NV2SSJ8F1bE79ai82K9r1LPkLTUnh66P8nVr9nB7pzYNQR0/s400/alexa_card.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Card Display</i></div>
<br />
And that's it. The rest of the code is game data and game code, which I've described somewhat in Part 1. I'm not going to post the full code just yet since that would give away secrets of the game.<br />
<br />
I've created other Alexa skills, so the skills creation went pretty rapidly. One odd thing I ran into is that Alexa doesn't seem to recognize the term "statue" even though it's in the list of objects I defined for the skill. I had to code around this for now pending further study. Aside from that, I didn't run into any problems. If your skill wants to remain open pending further input, which this game does, you are required to prompt the user with each spoken response. That's why Roman Ruins is constantly asking "What next?" after it tells you something. It wouldn't pass certification otherwise.<br />
<br />
I submitted the <a href="https://www.amazon.com/dp/B07RLJSS6C/ref=sr_1_1?keywords=roman+ruins&qid=1557184054&s=digital-skills&sr=1-1-catcorr" target="_blank">Roman Ruins skill</a> over the weekend and it was approved this morning. Here's how the listing looks on Amazon.com:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEzfYpLhgxv3Je2F_GjOAM3dUOn8Kc3M7e_X4ZCC8fvwGDRjK8Zg0Hoq-XlhpP65cL06Mv8Cdtauk9_mwmhg_hCSe5LGw3MGtx0DdZ7Auic2KlDWR8LN24Mz5NL5aQoir8Iutt-kYQAYA/s1600/ask_listing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="820" data-original-width="1170" height="280" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEzfYpLhgxv3Je2F_GjOAM3dUOn8Kc3M7e_X4ZCC8fvwGDRjK8Zg0Hoq-XlhpP65cL06Mv8Cdtauk9_mwmhg_hCSe5LGw3MGtx0DdZ7Auic2KlDWR8LN24Mz5NL5aQoir8Iutt-kYQAYA/s400/ask_listing.png" width="400" /></a></div>
<br />
<h2>
Playing Roman Ruins Adventure on Alexa</h2>
So, what's it like to play this on Alexa? Below is an excerpt. It works pretty well, but you can always do more to handle a wider range of responses<span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span>and you particularly feel that when you're working on voice applications.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE429Q1a-HXwI9YCXKLeWTBktvvCRbrmaBTNzwel36anwyoA8GdTOh50qLvcgAEYvIijNLm8xYEhq61YmZT4BNPnWE5K1iieGyTV-emqhFowi9ugwm6jTCst5XD8q-wd1_cMMkpBCt0r4/s1600/speech_log_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="800" data-original-width="360" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiE429Q1a-HXwI9YCXKLeWTBktvvCRbrmaBTNzwel36anwyoA8GdTOh50qLvcgAEYvIijNLm8xYEhq61YmZT4BNPnWE5K1iieGyTV-emqhFowi9ugwm6jTCst5XD8q-wd1_cMMkpBCt0r4/s400/speech_log_1.png" width="180" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYbk9b0Z_7O8HXI0yCb6mA9heYzgDnyHJtnbotBLzQjB8qeyTCaUEv3fPu7Ex4IDpF12u9ammkNOdRjUSGyeCmU8l2l7t0Sek6QWdXHiw9G_hQWQ1UA_Kw1DFHXRwCLDRSP-Bw5-lnCEQ/s1600/speech_log_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="760" data-original-width="340" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiYbk9b0Z_7O8HXI0yCb6mA9heYzgDnyHJtnbotBLzQjB8qeyTCaUEv3fPu7Ex4IDpF12u9ammkNOdRjUSGyeCmU8l2l7t0Sek6QWdXHiw9G_hQWQ1UA_Kw1DFHXRwCLDRSP-Bw5-lnCEQ/s400/speech_log_2.png" width="178" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Playing Roman Ruins Adventure on Alexa</i></div>
<br />
Feel free to play! Try "<i>Alexa, open Roman Ruins</i>" and let me know what you think. As I extend and polish the game my goal is to make better and better. Your feedback will help a great deal.<br />
<br />
Previous: <a href="http://davidpallmann.blogspot.com/2019/05/roman-ruins-adventure-part-1-nostalgia.html" target="_blank">Part 1: Nostalgia and Game Design</a><br />
Next: Part 3: <a href="http://davidpallmann.blogspot.com/2019/05/romans-ruins-adventure-part-3-twitch.html" target="_blank">Twitch Minigame</a><br />
<br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-64782829602932713212019-05-06T11:46:00.000-07:002019-05-06T16:42:47.302-07:00Roman Ruins Adventure, Part 1: Nostalgia and Game Design<style>
.tr0 { background-color: white; color: black; font-weight: bold; }
.tr1 { background-color: white; }
.tr2 { background-color: aliceblue; }
.syntaxhighlighter {
overflow-y: auto !important;
overflow-x: auto !important;
max-height: 512px;
}
</style>
<script>
if (location.protocol != 'http:')
{
location.href = 'http:' + window.location.href.substring(window.location.protocol.length);
}
</script>In this series of posts I'll share my experiences creating an old-style text Adventure game, adapted somewhat for the 21st century. Here in Part 1, I'll review the original Adventure and why it was such a ground-breaking development. Then I'll go over the design of my own game, called Roman Ruins adventure.<br />
<br />
In subsequent posts I'll show how this game is implemented for Alexa as a voice skill, and for Twitch as a mini-game extension.<br />
<br />
<h2>
Adventure, the First Interactive Fiction</h2>
<a href="http://davidpallmann.blogspot.com/2019/05/my-gaming-history.html" target="_blank">As I recently blogged</a>, I love games—but mostly retro games. In high school—before personal computers—we were fortunate indeed that Suffolk County owned a <a href="https://en.wikipedia.org/wiki/PDP-10" target="_blank">DEC PDP10</a> timesharing machine and allowed schools in the county to connect to it via teletypewriters over modems. Thus, my first computer experience was this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4Uyr_UIOVJRMPyGfkcjs5b_XVJ6HknsN_rNXsfmsgfhrMB_elvKNdEdKVTnDD9vz6Wc693AuRSZqesXkRoLcZmCbK4VBTV2ue7DFOjBQxpxIZgoaZkt-JpjPf_VdPK7d7ULTb0mBjugM/s1600/asr33_to_pdp10.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="518" data-original-width="1600" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4Uyr_UIOVJRMPyGfkcjs5b_XVJ6HknsN_rNXsfmsgfhrMB_elvKNdEdKVTnDD9vz6Wc693AuRSZqesXkRoLcZmCbK4VBTV2ue7DFOjBQxpxIZgoaZkt-JpjPf_VdPK7d7ULTb0mBjugM/s400/asr33_to_pdp10.png" width="400" /></a></div>
<br />
No screen, just teletype output on a paper roll. We didn't even have lower-case letters. All pouring out at the dismally slow speed of 110 baud. I'm sure this seems extremely limiting to anyone who is not a baby boomer, but as it was my first computing experience I was all over it. I got my foundation in computing basics this way (and it was far superior to college, where they were still having us punch cards!).<br />
<br />
ADVENT, or <a href="https://en.wikipedia.org/wiki/Colossal_Cave_Adventure">Colossal Cave Adventure,</a> was a game that had been developed by Will Crowther and Don Woods for the PDP-10. It had become popular among PDP10 installations and was making the rounds; not on the Internet, but via its predecessor, the ARPANET which had a much more limited audience.<br />
<br />
Adventure was different from other computer-based games of the time: it described a world and you the player had to explore it. You decided what to do, and your actions had consequences. Will Crowther had based his Colossal Cave Adventure on actual cave exploration he had participated in. As this "book" unfolded, you the player made decisions that changed the narrative. That's why this is considered the first example of <a href="https://en.wikipedia.org/wiki/Interactive_fiction" target="_blank">interactive fiction</a>.<br />
<br />
Adventure was one of those "a minute to learn, a lifetime to master" kind of games. You enter text commands, and an English language description told you where you were and what was going on:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">You are standing at the end of a road before a small brick</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">building. Around you is a forest. A small stream flows out</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">of the building and down a gully.</span><br />
<br />
You typed one or two-word commands to Adventure. For example, you could move around with NORTH, EAST, WEST, SOUTH, UP, and DOWN. There were only a handful of commands to learn.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">></span><span style="font-family: "courier new" , "courier" , monospace;"> </span><span style="font-family: "courier new" , "courier" , monospace;"><b>EAST</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">You are inside a building, a well house for a large spring.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">There are some keys on the ground here.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">There is a shiny brass lamp nearby.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">There is tasty food here.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">There is a bottle of water here.</span><br />
<br />
Some "rooms" of the adventure contained objects. You could GET or TAKE an object, which would then come along with you as moved to different rooms. You could likewise DROP an object, leaving it in your current room. You could use INVENTORY to get a list of what you were currently carrying.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">> <b>TAKE LAMP</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">Ok.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">> <b>TAKE FOOD</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">Ok.</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">> <b>INVENTORY</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">You are currently holding the following:</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Brass lantern</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">Tasty food</span><br />
<br />
Some objects were essential: carrying a lamp might allow you to see in a dark place. Some areas of the game were tough to navigate. Adventure is famous for having ten rooms with an identical description. Upon closer examination, each room has a slightly different description and a careful player can make a map to get through the area. Once that's done, navigation is simple. Another technique is to leave an object in each room.<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">You are in a little maze of twisty passages, all alike.</span><br />
<br />
As you played the game, you also discovered puzzles to solve and adversaries to deal with. For example, dwarves are troublesome and can kill you or prevent you from moving past them. A novice player might remember encountering food and be tempted to offer it to the dwarf—only to learn something important about dwarves:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">> <b>GIVE FOOD</b></span><br />
<span style="font-family: "courier new" , "courier" , monospace;">You fool, Dwarves eat only coal! Now you've made him *REALLY* MAD!!</span><br />
<br />
In this manner, by exploring and experimenting, the player learned what was where and what the rules of the road were. There was an artistry in the way places were described: paying attention to descriptions often paid off. Humor and the unexpected were to be found as well.<br />
<br />
The limited computer interfaces available at the time didn't hamper Adventure at all, because all the magic happened in your imagination, just like a book.<br />
<br />
<h3>
Adventure Game Derivatives</h3>
Adventure Games were a big deal in the 1980s. Several companies produced Adventure games commerically. I remember my brother Lee spending a lot of time with the ZORK games from InfoCom.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFoscBoc8GrH5M2UzwLc2flPis1mQX4M_V05T0Cnoi62VrlRLz37qH1tQJbtUQ0C-cB7pbOTJVltt_uwyTX0Fsg8OJr2bOYkgEYCJqrLa1Tcae8dFRprBxL1Qc-euGUPGuC_b7QFYDFEc/s1600/zork-iii-the-dungeon-master_2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="384" data-original-width="560" height="219" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFoscBoc8GrH5M2UzwLc2flPis1mQX4M_V05T0Cnoi62VrlRLz37qH1tQJbtUQ0C-cB7pbOTJVltt_uwyTX0Fsg8OJr2bOYkgEYCJqrLa1Tcae8dFRprBxL1Qc-euGUPGuC_b7QFYDFEc/s320/zork-iii-the-dungeon-master_2.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Zork III: The Dungeon Master</i></div>
<br />
As the years progressed, there was less interest in the textual Adventure games. Home computers and home game consoles were getting powerful and computer interfaces more sophisticated. The focus was on graphics, color, and sound.<br />
<br />
The idea of Adventure Games, though, never stopped being relevant. Many, many games today include similar elements of exploration. For example, the Adventure-style commands are quite apparent in Indiana Jones and the Fate of Atlantis (1992):<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh85q9Rv7XA2PNXOd4cjFFcRSEnACJGhXBe149OdIW1476lFl8P0KYG5jsX8ahZRwzgfWsQtZRcJfm6Za4X8hu91X0gjIxxF0-C22_uCOb3zuDZNJgqUnCcU6Twec3g-wk3rpVdKk0x6z8/s1600/indiana_jones_atlantis.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="960" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh85q9Rv7XA2PNXOd4cjFFcRSEnACJGhXBe149OdIW1476lFl8P0KYG5jsX8ahZRwzgfWsQtZRcJfm6Za4X8hu91X0gjIxxF0-C22_uCOb3zuDZNJgqUnCcU6Twec3g-wk3rpVdKk0x6z8/s320/indiana_jones_atlantis.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Indiana Jones and the Fate of Atlantis</i></div>
<br />
On the original XBOX, I enjoyed Indiana Jones and the Emperor's Tomb (2003). The graphics were sophisticated, the action was controlled with a game controller, and there was a lot of action movement and fighting along the way. But still present were those original ideas from Adventure: a world to explore made up of different rooms; objects to take and use at the appropriate moment; puzzles to solve; and treasure to find.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWxNnlQy-A5qiQSCtstGUgC1XOaIXTO2fh1H77QAAW1jTmgoFAlkjsaG65J7vsZ0Z8-z2KsJqY0j1sTOOxi3HWlqj3DKNSMyBsDemlZsVpEeihVyQYBw8G77W2ggjih0OBhNI12m3HJRE/s1600/908391-indiana-jones-and-the-emperor-s-tomb-windows-screenshot-browsing.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1024" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWxNnlQy-A5qiQSCtstGUgC1XOaIXTO2fh1H77QAAW1jTmgoFAlkjsaG65J7vsZ0Z8-z2KsJqY0j1sTOOxi3HWlqj3DKNSMyBsDemlZsVpEeihVyQYBw8G77W2ggjih0OBhNI12m3HJRE/s320/908391-indiana-jones-and-the-emperor-s-tomb-windows-screenshot-browsing.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Indiana Jones and the Emperor's Tomb</i></div>
<br />
I've never played <a href="https://en.wikipedia.org/wiki/Dungeons_%26_Dragons" target="_blank">Dungeons and Dragons</a> myself, but I'm aware that many games today have combined elements of that as well as Adventure. That often means a painstaking amount of detail goes into every aspect of the game. Take a look at how detailed the inventory is in Elder Scrolls V: Skyrim.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ7WeLjNEqj0c_HIN3mVtFKiVWHTBrf347zzHihMOO-SWs3QRNMow6AXCV9ea5GdBFe6iYbiEu7qvpIan4nTm6Bl5BcBGpe0Lq1OWy7gBJ3nuLWRdqHDbTiWCntoDetOhcs-rkBS4ZJj4/s1600/skyrim.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1000" data-original-width="1600" height="200" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgZ7WeLjNEqj0c_HIN3mVtFKiVWHTBrf347zzHihMOO-SWs3QRNMow6AXCV9ea5GdBFe6iYbiEu7qvpIan4nTm6Bl5BcBGpe0Lq1OWy7gBJ3nuLWRdqHDbTiWCntoDetOhcs-rkBS4ZJj4/s320/skyrim.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Skyrim</i></div>
<div style="text-align: left;">
<i><br /></i></div>
<h3 style="text-align: left;">
Adventure in Modern Times</h3>
Adventure in its original form may be little-known to younger people, but it hasn't been forgotten. There's a documentary on the history of interactive fiction games called <a href="https://www.youtube.com/watch?v=o15itQ_EhRo" target="_blank">Get Lamp</a> on YouTube by Jason Scott.<br />
<br />
You can still play the original adventure today. The AMC Halt and Catch Fire site has an area where you can <a href="https://www.amc.com/shows/halt-and-catch-fire/colossal-cave-adventure/landing" target="_blank">play the original ADVENT</a> on the web.<br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ZtKisB5INVZ-CuAwkMqQmYmoFCR4n3BQtNi86pjox7le-6KOxDqbVUBw6Bi9XEHPPdsGH985mcAtcFrkvQdAYwEpWawT9PjMKzxV0BvzxMdILEY_LfUFddu86xtTjW5C2h_WWP1XsvE/s1600/advent_01_intro.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="554" data-original-width="1011" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8ZtKisB5INVZ-CuAwkMqQmYmoFCR4n3BQtNi86pjox7le-6KOxDqbVUBw6Bi9XEHPPdsGH985mcAtcFrkvQdAYwEpWawT9PjMKzxV0BvzxMdILEY_LfUFddu86xtTjW5C2h_WWP1XsvE/s400/advent_01_intro.png" width="400" /></a></div>
<br />
You can even play ADVENT <a href="https://www.pcgamer.com/you-can-now-play-colossal-cave-adventure-the-first-text-adventure-game-via-sms/" target="_blank">via SMS</a> by texting this number: +1 (669) 238-3683.<br />
<br />
Believe it or not, the original textual game format still has a loyal following. There's even new game development going on, such as 2018's <a href="https://ifdb.tads.org/viewgame?id=yspn49v69hzc8rtb" target="_blank">Alias "The Magpie"</a>. Adventure has left quite a legacy.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAC3Gnk45MrQyGSHIpKM2gPjXX1lwhEYIjTMblvwc2EFJa6SPsaQPtac9kC6lOA5V5-tktbdr0vWA-6ypuLsjLP1rnjQ1Y8Hg84MI-5ghd1HUGMUOnd81a66JoXk8bv6g7UKN74VeFDWo/s1600/magpie_twitch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAC3Gnk45MrQyGSHIpKM2gPjXX1lwhEYIjTMblvwc2EFJa6SPsaQPtac9kC6lOA5V5-tktbdr0vWA-6ypuLsjLP1rnjQ1Y8Hg84MI-5ghd1HUGMUOnd81a66JoXk8bv6g7UKN74VeFDWo/s320/magpie_twitch.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Alias 'The Magpie' being played on Twitch</i></div>
<div style="text-align: center;">
<i><br /></i></div>
<h2>
My Adventure: Roman Ruins</h2>
Given all these fond memories, I decided recently that it was high time I created an Adventure game of my own. I thought to start with something very similar to the original Adventure, then find places where that kind of textual interface made sense in modern times. One idea that occurred to me is the popularity of voice assistants such as Amazon's Alexa: the original Adventure game format fits that mode of communication perfectly. Adventure would also make a nice mini-game, for example a Twitch Extension.<br />
<br />
I gave myself one week in which to design a game, implement it for both <a href="https://www.amazon.com/dp/B07RLJSS6C/ref=sr_1_1?keywords=roman+ruins&qid=1557163245&s=digital-skills&sr=1-1-catcorr" target="_blank">Alexa</a> and Twitch, and submit them for approval (a second reason I'm doing this is to get experience writing Twitch Extensions). Happily both were approved this morning, which is why I'm starting to blog about them. That being said, I'll readily admit a lot more could be done to extend the game and polish the implementation.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2sSGmtIx6Z1YV4daX6PGQtCklvOexONeIy45conZmWHZQ-LCWLqWI_J-lsQQc73FwopqXyqEZTdarZry0itEQRw7V85OVYsFbiY5rMKdiSgWGibItaPm6aZYIF6JNPrEiUXxDox-Kol0/s1600/alexa1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="642" data-original-width="454" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2sSGmtIx6Z1YV4daX6PGQtCklvOexONeIy45conZmWHZQ-LCWLqWI_J-lsQQc73FwopqXyqEZTdarZry0itEQRw7V85OVYsFbiY5rMKdiSgWGibItaPm6aZYIF6JNPrEiUXxDox-Kol0/s320/alexa1.png" width="226" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Roman Ruins on Alexa </i></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTe5S18GcA8s6uUsX4e5Ta5yM-ArMPBH129Vm7utNVPVijSdwSx6JQpDppFNoimn1qhXp_24zrU6Rqxubv268lq03DD8-oUrzl31hFawEXUE9zGRcoa1YgEuiRwcHPRd4C-wALnyLf1fQ/s1600/twitch_1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="418" data-original-width="402" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTe5S18GcA8s6uUsX4e5Ta5yM-ArMPBH129Vm7utNVPVijSdwSx6JQpDppFNoimn1qhXp_24zrU6Rqxubv268lq03DD8-oUrzl31hFawEXUE9zGRcoa1YgEuiRwcHPRd4C-wALnyLf1fQ/s320/twitch_1.png" width="307" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Roman Ruins Adventure mini-game on Twitch</i></div>
<h3>
Game Design</h3>
I decided I would write my game in TypeScript (which transpiles to JavaScript). JavaScript can be run in a huge number of places today, including web browsers and Node.js. But before implementing anything specific I would need to design the game itself.<br />
<br />
The program code of a textual Adventure game doesn't tend to be very large or complex: when these games were first created, available memory was limited. Minimally, for data you need an array of rooms, an array of objects, and a handful of variables to keep track of your current room and the state of game puzzles (obstacles and adversaries). Commands are simple phrases such as NORTH, LOOK, INVENTORY, TAKE LAMP, EXAMINE BOTTLE, or GIVE FOOD.<br />
<br />
Where the real work lies is in the game data. You've got to come up with a world and describe it well with interesting writing. You've got to decide what rooms there are, what directional connections there are between them, and what objects are placed where. You've go to come up with an objective, and there need to be puzzles to solve in order to get to that objective. You've got to craft a narrative that is helpful but not too helpful. Lastly, humor and learning-along-the-way is a hallmark of Adventure games.<br />
<br />
For the setting for my Adventure game, I reflected on a <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" target="_blank">cruise tour of Europe</a> my wife Becky and I took last year for our 25th anniversary. We were particularly impressed with the well-preserved city of <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-7-pompeii.html" target="_blank">Pompeii</a>. I decided I would make my world the ruins of an ancient Roman city, using what we had seen of Pompeii as a model. Plus, I had pictures of Pompeii which might be useful in some game interfaces.<br />
<br />
The first thing I needed was a room map, describing the rooms (places) and how one can move from one room to another. Without giving away too much about the game, below is a partial look at my initial map of ground level. The player would start at the South Gate. By paying attention to descriptions and experimentation, he or she would soon learn they could go north to get to a gladiator's field; then east to reach an amphitheatre; and then north to get to a main road. The main road could potentiall leads to a nunber of interesting areas, such as a Roman house or a temple or a public baths. The player might or might not have noticed a statue to the north of the gladiator field, which might or might not become important later on.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9q0EVDW-DrhsWnpfFvgy7fLsWiU8vIYkeYhHdUVFWA_LZ8F3oUjRC_tETMmkrplEhIueN8pXkLWSQCGRRxhaN2kH3zVlRD2d0-0LLImN_LEqeEw4gt95wTME8BuK1HB5hiYOHkBxRITE/s1600/rooms.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="894" data-original-width="666" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj9q0EVDW-DrhsWnpfFvgy7fLsWiU8vIYkeYhHdUVFWA_LZ8F3oUjRC_tETMmkrplEhIueN8pXkLWSQCGRRxhaN2kH3zVlRD2d0-0LLImN_LEqeEw4gt95wTME8BuK1HB5hiYOHkBxRITE/s320/rooms.png" width="238" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Partial Room Map - Ground Level</i></div>
<br />
Just as Will Crowther used his actual experience exploring caves to guide his world design in Colossal Cave Adventure, I am doing the same by using my visit to Pompeii. The above rooms depict actual places I visited. To be sure, I am not doing a full scale model of the city of Pompeii: it's enormous, and I didn't get to see all of it. Rather, I'm taking the places I did visit and interconnecting them in a similar but simplified way. Using real places allows me to furnish compelling descriptions.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR1B6MR3Si0cZ1xf0WzpC2bVEiKqSXnuDkfkVdBfE-vnAG11lkZgkPh-y8LRRM8_AJ176L4PxkSML5Nt_9dvUQ32FxfR7wXjev_C93zEg_3XQP0c0n7bGvZnemPNwD_xwoD7VsSfbEoJs/s1600/discovery.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="200" data-original-width="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR1B6MR3Si0cZ1xf0WzpC2bVEiKqSXnuDkfkVdBfE-vnAG11lkZgkPh-y8LRRM8_AJ176L4PxkSML5Nt_9dvUQ32FxfR7wXjev_C93zEg_3XQP0c0n7bGvZnemPNwD_xwoD7VsSfbEoJs/s1600/discovery.png" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPKcpF1baEyOZbui7P2ct9vb0yiWTpcAVgllP7hJ-3Sjmu6Z5i16jlmqCHjliuZ9Tb6AaHxe3Wd-8KJDuh52kR4u6_z2TWnY0Wg9VsGvnwognzVxoWRoSEuYuT5tpFlYqVr9C-kX-Xkq4/s1600/1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="320" data-original-width="426" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPKcpF1baEyOZbui7P2ct9vb0yiWTpcAVgllP7hJ-3Sjmu6Z5i16jlmqCHjliuZ9Tb6AaHxe3Wd-8KJDuh52kR4u6_z2TWnY0Wg9VsGvnwognzVxoWRoSEuYuT5tpFlYqVr9C-kX-Xkq4/s320/1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmPqJJcC05ndxwaoLh4IZdZFQJIaa5PMcIHlL-Ff0rQlwoXipQw2EemuWm7f1oCM7wz-VT8GlcAD57ABZ-EvWjxvL65JY2EtORrKPsaoNn1yRL2XEBKxN1RbxXNhbx3pgv5hSsPTfMvHE/s1600/2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="320" data-original-width="426" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmPqJJcC05ndxwaoLh4IZdZFQJIaa5PMcIHlL-Ff0rQlwoXipQw2EemuWm7f1oCM7wz-VT8GlcAD57ABZ-EvWjxvL65JY2EtORrKPsaoNn1yRL2XEBKxN1RbxXNhbx3pgv5hSsPTfMvHE/s320/2.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Pompeii, the Inspiration for </i><i>Roman Ruins</i></div>
<br />
My game would need a mission, some objective. I decided to place three coins somewhere in the city: the player would need to locate a bronze coin, a silver coin, and a gold coin; each progressively harder to locate. Then, the player would need to figure out where to bring each of these coins based on examination and clues they would find along the way.<br />
<br />
<h3>
Game Data</h3>
The JavaScript data storage for my rooms (partial) looks like this. First, there are constants for each room which is useful in specific game play code. Next is the array of rooms itself. Each is a JavaScript object with properties for<br />
<pre class="brush:js">// Room IDs
const SOUTH_GATE = 0; // Nocera Gate (South Gate)
const PALAESTRA = 1; // Gladiator practice field
const AMPHITHEATRE = 2; // Amphitheatre
const DECUMANUS_EAST = 3; // Decumanus Maximus - east
...
// Room detail
session.rooms = [
{ name: "South Gate", // 0 SOUTH_GATE
visited: true,
arrival: null,
look: "You are standing outside an ancient wall. The ground is covered in white ash. To the north is a gate.",
adversary: null,
env: null,
north: PALAESTRA,
east: null,
west: null,
south: null,
up: null,
down: null
},
{ name: "Gladiator Field", // 1 PALAESTRA
visited: false,
arrival: null,
look: "You are standing in a grassy field that appears to have been long-used for sports or fighting. There are ruins to the north, a wall with an entrance to the east, and a wall with a gate to the south.",
adversary: null,
env: null,
north: STATUE_CENTAUR,
east: AMPHITHEATRE,
west: null,
south: SOUTH_GATE,
up: null,
down: null
},
{ name: "Amphitheatre", // 2 AMPHITHEATRE
visited: false,
arrival: null,
look: "You are in a large amphitheatre with stone seating all around. A door leads west. To the north is a road.",
adversary: null,
env: null,
north: DECUMANUS_EAST,
east: null,
west: PALAESTRA,
south: null,
up: null,
down: null
},
{ name: "Decumanus Maximus East", // 3 DECUMANUS_EAST
visited: false,
arrival: null,
look: "You are at the end of a large east-west main road that cuts across the city to the west. There is an entrance to a large building to the south.",
adversary: null,
env: null,
north: null,
east: null,
west: DECUMANUS_CENTER,
south: AMPHITHEATRE,
up: null,
down: null
},
...
</pre>
Some of the essential properties for each room include its <span style="color: #666666;">name</span>, a previously-<span style="color: #666666;">visited</span> flag, special text to add on first <span style="color: #666666;">arrival</span>, a <span style="color: #666666;">look </span>description for the LOOK command, and where the six movement commands lead. There is also an <span style="color: #666666;">adversary </span>variable which tells the game whether some enemy is lurking in the room. Lastly, an <span style="color: #666666;">environment </span>variable tracks whether a room has an interesting environment attribute such as being dark: in a dark room you can't see anything unless you happened to bring a light source with you.<br />
<br />
Object data is handled the same way: there are constants to make it easy to reference a particular object by name in code, and then an array of objects for each game object.<br />
<pre class="brush:js">// Object IDs
const MAX_ITEMS_CARRIED = 5;
const BRONZE_COIN = 0;
const BOTTLE = 1;
const JUG = 2;
const KNIFE = 3;
...
// Object detail
session.objects = [
{ name: "bronze coin", // 0 BRONZE_COIN
room: HOUSE_MENANDER_YARD,
examine: "It is an old coin made of bronze with a horse on its face.",
carrying: false,
disallow: null,
},
{ name: "bottle",
room: HOUSE_MENANDER_ATRIUM,
examine: "It is a bottle of wine.",
carrying: false,
disallow: null,
},
{ name: "jug",
room: SIDEWALK,
examine: "It is an empty pottery jug.",
carrying: false,
disallow: DOG,
disallowDesc: "The dog growls fiercely whenever you approach the jug."
},
...
</pre>
Object properties include the object's <span style="color: #666666;">name</span>, so that you can issue commands like TAKE BRONZE COIN or EXAMINE BOTTLE. There's also the <span style="color: #666666;">room </span>the object is in, an <span style="color: #666666;">examine </span>description for the EXAMINE command, and a <span style="color: #666666;">carrying </span>flag to indicate whether the player is currently carrying it. The <span style="color: #666666;">disallow </span>property, if not null, means the object can't be taken because of an adversary.<br />
<br />
Although most rooms can be navigated to with NORTH, EAST, WEST, SOUTH, etc., some rooms are initially not accessible or even hidden. It takes puzzle solving by acquiring, transporting, and using objects to get to those areas. To invent some game puzzles, I considered non-intuitive paths to some places; natural obstacles; beasts that might not let you pass; and people that might not let you take something you need.<br />
<br />
<h3>
Game Code</h3>
The game code itself is simple. Each of the available commands needs an implementation:<br />
<ul>
<li>INVENTORY simply lists each item in the objects array where the carrying flag is true.</li>
<li>TAKE object checks whether the specified object name exists. If found in the objects array, and in the current room, and not already being carried, the object can be picked up. The carrying flag is set to true and it is now a carried object.</li>
<li>DROP object works just like TAKE, except it can only be applied to an object with the carrying flag set to true. The carrying flag is set to false, and the object's room property is set to the current room.</li>
<li>The EXAMINE object command searches for an item in the objects array matching the specified name. If found, and the object is being carried or is in the current room, its examine property is described. Special code allows the player to sometimes examine other things, such as a statue in the room.</li>
<li>The LOOK command describes your current surroundings. It first displays or speaks rooms[room].description, the general description of the room you're in. It must also tell you if any objects are present. Unless in a dark room without a light source, each item in the object array is described if its room property matches the current room and the carrying flag is false).</li>
<li>The GIVE object or USE object command does something special with an object in order to solve a game puzzle such as defeating an adversary. Special game code checks for specific objects. With a more sophisticated implementation, these things could be represented in the game data itself but I was umm... lazy in these initial implementations.</li>
</ul>
Here's the code that implements directional movement (NORTH, SOUTH, EAST, WEST, UP, DOWN). After identifying a direction command, the room object for the current room's .north, .south, .east, .west, .up, or .down property is passed to the moveTo function. If moveTo is passed a null, movement is impossible. Otherwise, the current room is set to the passed room. If the new room object's visited flag is already true, this is a return to a prior room and a full description is skipped; but the user can always request that with a LOOK command. For interfaces with a visual element, a picture for the current room number is shown (unless it's dark and you have no light source). Other functions are called to also describe what's in the room with you.<br />
<pre class="brush:js"> switch(words[0]) {
...
// Move to a new room
case "NORTH":
case "N":
moveTo(session.rooms[session.room].north);
break;
case "EAST":
case "E":
moveTo(session.rooms[session.room].east);
break;
case "WEST":
case "W":
moveTo(session.rooms[session.room].west);
break;
case "SOUTH":
case "S":
moveTo(session.rooms[session.room].south);
break;
case "UP":
case "U":
moveTo(session.rooms[session.room].up);
break;
case "DOWN":
case "D":
moveTo(session.rooms[session.room].down);
break;
...
function moveTo(newRoom) {
try {
var text = '';
if (newRoom != null) {
session.room = newRoom;
if (session.rooms[session.room].visited) {
text = "You're back at " + session.rooms[session.room].name + ". ";
}
else {
if (session.rooms[session.room].arrival!==null)
text = session.rooms[session.room].arrival + session.rooms[session.room].look + " ";
else
text = session.rooms[session.room].look + " ";
session.rooms[session.room].visited = true;
}
session.location = session.rooms[session.room].name;
session.output = text;
if (isDark())
session.imageUrl = image('dark.jpg');
else
session.imageUrl = image(session.room.toString() + '.jpg');
listObjectsInRoom();
listAdversariesInRoom();
}
else {
session.output = "I can't move that way. ";
}
}
catch(e) {
session.output = "An exception occurred";
console.log("EXCEPTION" + e.toString());
}
}
</pre>
In designing an Adventure game, one must try to anticipate everything a player might try. For a consistent and enjoyable game, logical conclusions should be honored: if a player went NORTH to get from Room A to Room B, then SOUTH from Room B should lead back to Room A. There can be exceptions however: since the places we're describing are not necessarily rectangular, we don't always have to honor the obvious routes. Twisty passages in a maze may lead the player to unexpected places; and there may be the occasional magical secret door that whisks the player to a completely different area of the world.<br />
<br />
A single-level world is not as interesting as a multi-level world. Most of what I'd seen in Pompeii had been single-story buildings. I could surely invent some higher structures, which would allow some UP and DOWN navigation.<br />
<br />
What about a subterranean level? That was a mainstay of Colossal Caves Adventure. Thinking back to our trip to Europe, we had also visited underground catacombs (where early Christians buried their dead), which were networks of many underground rooms. I decided this would make for a good subterranean level in Roman Ruins Adventure, with a handful of places that allow one to travel below ground level and back up. Since the real-world catacombs are mysterious twisty places that are hard to navigate, I would design accordingly. I would also require a light source in order to see anything in these rooms.<br />
<br />
Frustratingly, our visit to the Roman catacombs visit didn't allow picture-taking. I decided this would be the place for my version of "Twisty little passages, all alike." I have a similar (but subtly different) description for each area, with the same cave image; unless it's dark, in which case everything is pitch black. I know some players groan when they encounter these areas but since my game is a homage to the original Adventure I really do have to have one.<br />
<br />
<h2>
Conclusion</h2>
The original Adventure was ground-breaking and has a large legacy of game infuence that continues on to this day. I spent the last week creating my own Adventure game, on a smaller scale. Today we examined some of the game design. It could be a lot bigger: there are only a couple dozen rooms at present. All it will take to expand it is some creative thought and some more game data.<br />
<br />
My week of development targeted creating a basic game, an implementation for Alexa, and an implementation for a Twitch Minigame Extension. I completed all that, but I'll admit there could be a lot more refinement. The game could be expanded with more rooms, more of a narrative to discover, and more game puzzles. The implementations could be more polished and there should be more shared code. I likely will return to all of this and take it further at some point, but I am satisfied with this first week's effort. It was an Adventure!<br />
<br />
In <a href="http://davidpallmann.blogspot.com/2019/05/roman-ruins-adventure-part-2-alexa-skill.html" target="_blank">Part 2</a>, we'll look at my implementaton of Roman Ruins Adventure for Alexa.<br />
<br />
In Part 3, we'll look at my implementation of Roman Ruins Adventure as a Twitch Mini-game.<br />
<br />
Next: <a href="http://davidpallmann.blogspot.com/2019/05/roman-ruins-adventure-part-2-alexa-skill.html" target="_blank">Part 2: Alexa Skill</a><br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-3671033661143952422019-05-02T09:08:00.000-07:002019-05-05T10:50:38.917-07:00My Gaming HistoryI recently joined <a href="https://twitch.tv/" target="_blank">Twitch</a>, a company that is all about gaming and community—so it only seems appropriate to post something about my history with games. While I've never worked on a commercial game, I love games—but mostly <u>retro</u> games.<br />
<br />
<h2>
Board Games</h2>
Growing up there were no game consoles, arcade games, or home computers; but there were board games, and boy did I play a lot of them with my family and friends. First there were the games we played as very young children, like LIFE and Sorry and Trouble. As we grew older, there were the old family favorites: Monopoly and Yahtzee and Scrabble. There were the Parker Brothers classics like Clue and Masterpiece and Risk. There was Rack-O and Stratego.<br />
<br />
In Risk you are out to take over the world. My brother Lee and I played Risk frequently, often roping in a relucant family member to be a third player. I'm afraid we tended to prey on the third player until we were both powerful enough to take each other head on, not a lot of fun for the third player (our mother eventually refused to play with us).<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAEm_QOQIdaqty-9qIz5OHBmXsUdTW7zdES6q0W1rRG62lM6SteyY1LvmB1K1UxJcPPftKYtmMr7Uy9NJ74i-naPLqkocqYvdjJ4KFJqwA1RfWhj9pYxr10KAYGHzr2an4nFEYjkEQVkM/s1600/risk.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="693" data-original-width="1280" height="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAEm_QOQIdaqty-9qIz5OHBmXsUdTW7zdES6q0W1rRG62lM6SteyY1LvmB1K1UxJcPPftKYtmMr7Uy9NJ74i-naPLqkocqYvdjJ4KFJqwA1RfWhj9pYxr10KAYGHzr2an4nFEYjkEQVkM/s320/risk.jpg" width="320" /></a></div>
<br />
Clue was fun because you had to solve a mystery before anyone else did: who did the murder, with what weapon, in what room? Taking notes, analyzing new clues, and guarding your facial expressions were essential.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy-_DhyvRPLck9loAgbCo_4-VbwYXJOR1gxxkus9oHyMSB1qClK-kZeA6phW6DV6UYSIGsXPmji5h09bH03Nrol6RdsQYsHO2oIVjSLNd_1iQS3MUDhhc4l837sStmCMQ0I7QwydxbXaY/s1600/clue.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="865" data-original-width="600" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgy-_DhyvRPLck9loAgbCo_4-VbwYXJOR1gxxkus9oHyMSB1qClK-kZeA6phW6DV6UYSIGsXPmji5h09bH03Nrol6RdsQYsHO2oIVjSLNd_1iQS3MUDhhc4l837sStmCMQ0I7QwydxbXaY/s320/clue.jpg" width="221" /></a></div>
<div style="text-align: center;">
<i>Clue</i></div>
<br />
In addition to strategy games, word games were also special. Scrabble was/is great for vocabulary (and sometimes for bluffing), but you can wait an awful long time for someone to make a move if they have a poor set of letters. Over time we developed the art of pointing nearby objects (such as spoons, mug handles, pens, etc.) in the direction of the player who was taking too long to move until they got the hint.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWKAfpU8zRdBoWdclnpaysBzwtAPHsS6UKQ1CnzRniRGKmSsSkmUl3Bd851G9XZkFQNv-uN3myw8Q2hRUsTwD_8DDZdIogZf1V3JYMjrRoGh3Ji_Hj3FrYch57p1akxLuNdYAe2OfjEEM/s1600/scrabble.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="768" data-original-width="1024" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWKAfpU8zRdBoWdclnpaysBzwtAPHsS6UKQ1CnzRniRGKmSsSkmUl3Bd851G9XZkFQNv-uN3myw8Q2hRUsTwD_8DDZdIogZf1V3JYMjrRoGh3Ji_Hj3FrYch57p1akxLuNdYAe2OfjEEM/s320/scrabble.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Scrabble</i></div>
<br />
Besides Scrabble, we played a lot of Boggle. I was quite good at rapidly finding all the words to be found in a random set of letters.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimBpxCozwv3nyOLaNPkcwyv0W8PlLW5mhxlGyV_pyoNxWOWA89aG4K4J6XWPGMIheRarYpBmplQbIqkPSfuASyVnUAnjcwpWFunTBh2knChOcOWStWiwyAQEsGfaaR12HUyrH7W_9wtfk/s1600/220px-Boggle.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="306" data-original-width="220" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimBpxCozwv3nyOLaNPkcwyv0W8PlLW5mhxlGyV_pyoNxWOWA89aG4K4J6XWPGMIheRarYpBmplQbIqkPSfuASyVnUAnjcwpWFunTBh2knChOcOWStWiwyAQEsGfaaR12HUyrH7W_9wtfk/s1600/220px-Boggle.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Boggle</i></div>
<br />
What about card games? Especially in earlier times, many families avoided official playing cards, not wanting to encourage gambling; but other card games were fine. In particular, Rook is popular in Christian circles<span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span>particularly on my wife's side of the family. A family visit from the in-laws always means we'll be playing Rook.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimvmIM9BNpuwBqVfpjNEX8tg7AVd8S05WH-1UxYanqfA6-uGk4U7VyTeWdHsIdc7nVk17C_8es4KzJNybuiSj7en0qiwbUriq2r7f6sk3vGi4xNgqhys5F0Cnecd7zlR8yt7mFbkOJqBI/s1600/rook1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="476" data-original-width="700" height="217" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimvmIM9BNpuwBqVfpjNEX8tg7AVd8S05WH-1UxYanqfA6-uGk4U7VyTeWdHsIdc7nVk17C_8es4KzJNybuiSj7en0qiwbUriq2r7f6sk3vGi4xNgqhys5F0Cnecd7zlR8yt7mFbkOJqBI/s320/rook1.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Rook</i></div>
<br />
We and our friends played games all the time. I guess we also went to school and worked somewhere along the way, but otherwise we were getting together for games whenever we could.<br />
<br />
In high school I was on the chess club; in between matches we would meet in the library to play chess. By combining several chess sets, we were able to rig a 4-way chess game by adding half chess boards to the outer edges of a chess board, which was arranged omething like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK0IAplt-t-grKZ69tfwRP92jEq93vHPhJoYMpDoyl2hklhbqsy7_0y6FDbM-w4XdNMHmiYva92eakzTIqeKj7cqatM4mfPe8qcCd4BYGRV9Skq6Np1ag4ctTEJZL8tRcjt8JGgNTdEJU/s1600/300px-Four-handed_chess.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="300" data-original-width="300" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiK0IAplt-t-grKZ69tfwRP92jEq93vHPhJoYMpDoyl2hklhbqsy7_0y6FDbM-w4XdNMHmiYva92eakzTIqeKj7cqatM4mfPe8qcCd4BYGRV9Skq6Np1ag4ctTEJZL8tRcjt8JGgNTdEJU/s1600/300px-Four-handed_chess.png" /></a></div>
<br />
<h2>
Early Computer Games</h2>
In High School, on the last day of the 9th grade, I got my first taste of an electronic game. My friend Andrew asked if I had ever been to the Computer Room in the Math Department. A computer? In our school? This was news to me, and I enthusiastically went with him to see Room 214 of Connetquot High School. The room was chattering with noisy <a href="https://en.wikipedia.org/wiki/Teletype_Model_33" target="_blank">teletypewriters</a> churning out text on paper rolls. These teletypes were connected to a <a href="https://en.wikipedia.org/wiki/PDP-10" target="_blank">DEC PDP-10</a> timesharing system the county owned, and we were fortunate indeed to have access as there were no personal computers at the time. It was the first time I had ever seen a computer of any kind, and I was instantly hooked.<br />
<br />
On the walls were stapled listings of programs and program output, including many games. There was a CASINO game, offering games like 21 and slot machines. There was a WUMPUS game where you had to track down and kill an elusive Wumpus creature. LUNAR was a game where you could try to land the Lunar Module on the moon with a limited amount of fuel. In TREK, the user battled Klingons in a space grid. There was an ELIZA game, simulating a psychologist. And, there was ADVENT (Adventure), an Adventure game. Adventure was special: you explored a world, found and carried objects, overcame obstacles and adversaries. Adventure was in fact the very first interactive fiction, and I'll be posting more about it in the future.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi63GzrZ-z2Xci1jQrU7ugYvgyF24uT-S2jRwPijiM1YFNR4IueMZ_REg9NVwQwdNW3s44FPZJSmWW8xmZwC1Oyxeo9i2bG8U5mD3eKHlU8xm8fyDtHVbrY1Q0yhfVyl8aeSSFElwUGcdE/s1600/advent.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="500" data-original-width="668" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi63GzrZ-z2Xci1jQrU7ugYvgyF24uT-S2jRwPijiM1YFNR4IueMZ_REg9NVwQwdNW3s44FPZJSmWW8xmZwC1Oyxeo9i2bG8U5mD3eKHlU8xm8fyDtHVbrY1Q0yhfVyl8aeSSFElwUGcdE/s320/advent.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Adventure</i></div>
<div class="separator" style="clear: both; text-align: center;">
<i><br /></i></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhypCJaYkQUy-8lv47__79EoYlUfeY6oGT_EzRa0vEpO3Gl5P8xLdauNB8bamtIataaPmROJr9lwOa6ZW2h53guk77OSnl3W8VxOa5T4xDxS3a97OGd38R7ZJ_Gv6zZH7M4VbH5OsSPNYg/s1600/wumpus.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="555" data-original-width="940" height="188" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhypCJaYkQUy-8lv47__79EoYlUfeY6oGT_EzRa0vEpO3Gl5P8xLdauNB8bamtIataaPmROJr9lwOa6ZW2h53guk77OSnl3W8VxOa5T4xDxS3a97OGd38R7ZJ_Gv6zZH7M4VbH5OsSPNYg/s320/wumpus.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Hunt the Wumpus</i></div>
<div class="separator" style="clear: both; text-align: center;">
<i><br /></i></div>
<div class="separator" style="clear: both; text-align: left;">
I no longer have any output from it, but I created a game on the PDP10 named CHASE, in which the player was moving around in a grid, being pursued by several adversaries. Each time you moved, the enemies moved closer; but there were barriers you could hide behind and leverage. It was basically the game of Fox and Hounds.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2>
Arcade Video Games</h2>
When video games hit the arcades, I was in my late teens / early twenties, and I spent as much time as I could at the local mall using up my quarters. I mostly played BattleZone, QBert, Tempest, and Marble Madness.<br />
<br />
Battlezone was one of my favorites, with its simple vector-graphics display but very effective strategic gameplay. I hear it was used by the U.S. Army to train tank gunners.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2nrlSV2bRh895CFeYOQUoqRKbp8rZkPisM32iJXy4D8e9FxxOCSuZ5QzJ7xxYMV0uZuwY1HOlePjjX-krxtkp8DNTYxSXhhsELt1s5pFayo02fzgHXhAARhJBznJR12XLiYxl7gDPjIA/s1600/battlezone.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="297" data-original-width="400" height="237" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh2nrlSV2bRh895CFeYOQUoqRKbp8rZkPisM32iJXy4D8e9FxxOCSuZ5QzJ7xxYMV0uZuwY1HOlePjjX-krxtkp8DNTYxSXhhsELt1s5pFayo02fzgHXhAARhJBznJR12XLiYxl7gDPjIA/s320/battlezone.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Battlezone</i></div>
<div style="text-align: center;">
<br /></div>
My all-time favorite arcade game was Marble Madness. I thoroughly admired the Escher-like artwork, the musical score, the zany elements of the game: all artistically combined. Using a trackball to control a marble was genius. I loved it. Alas, Marble Madness only had six levels so although initially successful it was not long lasting.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinj7CZ7-28vclFCQvelb1qeay2icd5qMnGhlDcRpSb_FEah5cDmiqwt_vmI9eC7FsGVMkolLY1r9qBO9sOzxkmmwVtg7n14B8bCU_-yJWCXg7xhJr86ZPoSRnfcW0eEKtXUBFEt9eNSpc/s1600/mm0.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="241" data-original-width="336" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinj7CZ7-28vclFCQvelb1qeay2icd5qMnGhlDcRpSb_FEah5cDmiqwt_vmI9eC7FsGVMkolLY1r9qBO9sOzxkmmwVtg7n14B8bCU_-yJWCXg7xhJr86ZPoSRnfcW0eEKtXUBFEt9eNSpc/s320/mm0.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJE30W-kB4lCpgHNmnlFXqUCDJE7xALD9sz9vqY6estQ4pEgaibtW-LdPIVVBe37CnUEfA-lllQ18XyyqmVNdbtRqEgBGvX0VKPHyhEaFCKABsZXqo5DvCqXu3vBwo_J1vjo0N_doOhHw/s1600/mm1.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="241" data-original-width="336" height="228" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJE30W-kB4lCpgHNmnlFXqUCDJE7xALD9sz9vqY6estQ4pEgaibtW-LdPIVVBe37CnUEfA-lllQ18XyyqmVNdbtRqEgBGvX0VKPHyhEaFCKABsZXqo5DvCqXu3vBwo_J1vjo0N_doOhHw/s320/mm1.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Marble Madness</i><br />
<div style="text-align: left;">
<i><br /></i></div>
<div style="text-align: left;">
I also played a lot of Pac-Man, mostly because that game was everywhere including restaurants and convenience stores. My programmer friend Randy had memorized winning patterns of movement for the first few levels and could play that game like a piano (for this reason, when Ms. Pac Man came out an element of randomness was added).<br />
<br /></div>
</div>
<h2>
Later Computer Games</h2>
A few years later, after home computers had happened, game consoles for the home started becoming available. I had an Atari 2600 and later an Amiga computer. I purchased some of my favorite arcade games such as BattleZone and Marble Madness, but frustratingly these were often not-so-faithful to the original. Marble Madness in particular was hard to adjust to without the original's trackball, which was such a natural way to control a rolling marble.<br />
<br />
In the early 2000s, I remember bringing home Zoo Tycoon for the PC. My daughter Susan loved it, and she kept playing. As a teenager she designed her own extensions for the game and joined an online design community. She met some of her best friends that way: she's currently at the University of Louisville, and got familiar with Kentucky chiefly through a connection she made in that Zoo Tycoon design community. She's visited another friend in Australia several times, another connection from that same community. It surprised me that a game I bought for her as a child (and its community) could have such an ongoing influence in her life.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-WvXc-sZqz6AbVlps5lM9jnJ8rWczXtd1kbjpR3wJHBrCGnnxqhfdJ_ZXKU0mRqQEvIs8x_RrWB8_0eg2-UUpGYviVJHi1_ASYqIIVNATz1QdDsFFgou4R7uEJG1pN3JyRe8ubcZnes/s1600/zoo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="375" data-original-width="500" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjR-WvXc-sZqz6AbVlps5lM9jnJ8rWczXtd1kbjpR3wJHBrCGnnxqhfdJ_ZXKU0mRqQEvIs8x_RrWB8_0eg2-UUpGYviVJHi1_ASYqIIVNATz1QdDsFFgou4R7uEJG1pN3JyRe8ubcZnes/s320/zoo.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Zoo Tycoon</i></div>
<br />
<h2>
XBox and XBox 360</h2>
In 2003 I was working at Microsoft, now with my own family and young children. In an employee knowledge quiz I ended up winning an XBox.<br />
<br />
One of my favorite XBox games was Indiana Jones and the Emperor's Tomb. It was done exceedingly well, and you really felt like Indy when you played. There were great settings, puzzles to solve, treasures to find, and villains to fight. It took me 4 months of weekends to get to the end of the game, somehow also keeping up with my work responsibilities.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilhJX3CCvb266JhrOwDgiiwRkHMMOvLrhNEOa80DqvIMwCHj7gz306ju8jYhQh6uUYRGcLbruFOaEUQGLpLLxFNZ7YlUku-VqUcQeCNn1Wo2k08UHbFb4jTqedQAg84a7KWWj7wxv7BSA/s1600/indy1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEilhJX3CCvb266JhrOwDgiiwRkHMMOvLrhNEOa80DqvIMwCHj7gz306ju8jYhQh6uUYRGcLbruFOaEUQGLpLLxFNZ7YlUku-VqUcQeCNn1Wo2k08UHbFb4jTqedQAg84a7KWWj7wxv7BSA/s320/indy1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtgXX7rDMKjyig3aUDEUuHst1vePG661dlZQnC8nwzK3Vso5VPV1iXr9yDXlD1K4nD1D3gLS-z7m7K-4sSVcFMiRQe9YZVFmHng6ftydYa-B8MK3_PFatOGCO_slb9TX766MAAJoPtf_Y/s1600/indy2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="194" data-original-width="259" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtgXX7rDMKjyig3aUDEUuHst1vePG661dlZQnC8nwzK3Vso5VPV1iXr9yDXlD1K4nD1D3gLS-z7m7K-4sSVcFMiRQe9YZVFmHng6ftydYa-B8MK3_PFatOGCO_slb9TX766MAAJoPtf_Y/s1600/indy2.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Indiana Jones and the Emperor's Tomb</i></div>
<br />
We later upgraded to an XBox 360—only to be highly disappointed that many original XBox games would not work on the 360. I've never understood the XBox team's lack of concern over game compatibility with the prior generation of consoles; it's sad when you can't play your favorite games any more, especially considering the money you've invested in them. When I learned it was going to be the same thing all over again with the XBox One, I decide to stop buying XBox consoles.<br />
<div style="text-align: center;">
<br /></div>
<h2>
Family Favorites</h2>
In addition to my own game interests, it was fascinating to watch the rest of my family's interest in video games. A family favorite on the XBox was Midtown Madness 3, which allowed you to drive like a madman (or madwoman) in either Paris or Washington DC. It was a sad day when our XBox died, and my family still talks about missing Midtown Madness to this day. Alas, it doesn't seem to be available anywhere on modern gaming platforms.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1C_bq8fRaBHQ7WUQAjqqNdfuaq-vOH89znblbd4h5bSCs7pgi031Oe5b_7IGMjLgsWtp94HQw05hKaxLrgjrJHkecqDng-IKVQsx6nPiqaAI7qyTr5V-ael-uETqqNIQoSgoGxWDw2B4/s1600/mm3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="480" data-original-width="640" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1C_bq8fRaBHQ7WUQAjqqNdfuaq-vOH89znblbd4h5bSCs7pgi031Oe5b_7IGMjLgsWtp94HQw05hKaxLrgjrJHkecqDng-IKVQsx6nPiqaAI7qyTr5V-ael-uETqqNIQoSgoGxWDw2B4/s320/mm3.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Midtown Madness 3</i></div>
<div style="text-align: center;">
<br /></div>
I made the mistake of bringing home Viva Piñata one day from the Microsoft Store, and my wife and kids loved it so much I saw nothing of them for the next three weeks ("umm... are we having dinner today?"). In this game, you have to domesticate candy-animals in a strange land. If nothing else, it's certainly colorful.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1vgkLKm6kvXOY2k0AiWfrZzjg4kFqo3TlCpDtKAG6ucoNHnhUO4hyphenhyphenmorHqN1tjxJ3gSKD1ccYm5rHA3PWdeCzrFBviJ6LowTD6ouMjSuJbr5Cyjp9o7GiXdsH5WtOO2sXqSjOgD_MWdo/s1600/viva1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj1vgkLKm6kvXOY2k0AiWfrZzjg4kFqo3TlCpDtKAG6ucoNHnhUO4hyphenhyphenmorHqN1tjxJ3gSKD1ccYm5rHA3PWdeCzrFBviJ6LowTD6ouMjSuJbr5Cyjp9o7GiXdsH5WtOO2sXqSjOgD_MWdo/s320/viva1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqoFsA2LiXpRvmhAMwiRuzuonuHZULHDY5zd6kSIlt0a58GDIYy1y4ftwF2R4Tu_ELC6_HyGQxvo7g9LUDL_WmzDZKYP7JwTEcdBg6YWyuCRBzzNuc_FlLzB078aphTVMeRYumJKOqbN0/s1600/viva2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="177" data-original-width="284" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqoFsA2LiXpRvmhAMwiRuzuonuHZULHDY5zd6kSIlt0a58GDIYy1y4ftwF2R4Tu_ELC6_HyGQxvo7g9LUDL_WmzDZKYP7JwTEcdBg6YWyuCRBzzNuc_FlLzB078aphTVMeRYumJKOqbN0/s1600/viva2.jpg" /></a></div>
<div style="text-align: center;">
<i>Viva Piñata</i></div>
<br />
When the Kinect came out for XBox 360, we could get up off the couch and play interactive games. The Kinect could identify one or two players and respond to location, movement, and hand motions. Kinect Adventures let you do things like river rafting. Kinect Sports let you play many different sports, from bowling to football to volleyball. For a while, Kinect games were all the rage.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1UTtA-eNCVJfSlITpOaSHhx-mcto1WzQGdbKyhRDJzP93oIFqY2TIVz91Ui_yE_ILXfPmYmJsskPfcUNaEmzPzO4VfaYbslA1hjxYbR_-Tn7tdE0OVCGm1erZqLhZDjvK547gthVIPNc/s1600/kinectadventures_1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="242" data-original-width="425" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1UTtA-eNCVJfSlITpOaSHhx-mcto1WzQGdbKyhRDJzP93oIFqY2TIVz91Ui_yE_ILXfPmYmJsskPfcUNaEmzPzO4VfaYbslA1hjxYbR_-Tn7tdE0OVCGm1erZqLhZDjvK547gthVIPNc/s320/kinectadventures_1.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Kinect Adventures</i></div>
<div style="text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUs0ScaR7aYSv00onbfI9FkismATiDM2I2CJvpxTtvHl-uIW4EEUMpRpp57XypzIkv0koj-gMSRudfwJeP7v6iiDSQAJSAi9aSNDhTEsAQYK-4StFvzWURxWFgQlax7v6SmrSQLfpG3a4/s1600/kinect_volleyball.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="562" data-original-width="1000" height="179" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUs0ScaR7aYSv00onbfI9FkismATiDM2I2CJvpxTtvHl-uIW4EEUMpRpp57XypzIkv0koj-gMSRudfwJeP7v6iiDSQAJSAi9aSNDhTEsAQYK-4StFvzWURxWFgQlax7v6SmrSQLfpG3a4/s320/kinect_volleyball.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Kinect Sports</i><br />
<i><br /></i></div>
Traditional board games became available for the 360, and we'd often play those instead of having to set up and put away physical board games. This included Monopoly, Trivial Pursuit, Scrabble, and Yahtzee.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ9sb0cBmQvJJpk8oxxLGsCWfPrqGrkTQl4uRrofkvTcdROsfATbS__aTpmjdDZG7rAWAzwZt3lK0ObH36Tzsy26W3EsytDa9ebKh4vLvNlVOAdpJaOxyzVRHieaNwHR8XSoRT-vHqGfs/s1600/mono360.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="360" data-original-width="640" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ9sb0cBmQvJJpk8oxxLGsCWfPrqGrkTQl4uRrofkvTcdROsfATbS__aTpmjdDZG7rAWAzwZt3lK0ObH36Tzsy26W3EsytDa9ebKh4vLvNlVOAdpJaOxyzVRHieaNwHR8XSoRT-vHqGfs/s320/mono360.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Monopoly on XBox 360</i></div>
<br />
As my kids got older, their taste in games changed. My son liked driving games like Forza Motorsports 3 and Skate 3 (he likes breaking every bone in his body in the "Hall of Meat" mode). My daughter Susan liked Portal 2 and Skyrim. My daughter Debra liked Civilization 6 as well as Skyrim. Skyrim looked a tad dark to me, but I could see the legacy of that original Adventure game in these later games.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSeIiA4v5t-VqeF3qlUhNblecW6w28OyAUVCaSkUr2TzIIid28xa-xzWzsxd3mDy4j5FwyfKLI9lxwHJMCW2QgzjT2opPa-W3oyVkXeWfZCctdZ9RTykqfo4rfOBdyl7_O6jzRf5t7fuw/s1600/portal2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="483" data-original-width="800" height="193" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgSeIiA4v5t-VqeF3qlUhNblecW6w28OyAUVCaSkUr2TzIIid28xa-xzWzsxd3mDy4j5FwyfKLI9lxwHJMCW2QgzjT2opPa-W3oyVkXeWfZCctdZ9RTykqfo4rfOBdyl7_O6jzRf5t7fuw/s320/portal2.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Portal 2</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcqtmONIzggHQllv_pph7QiMOucC42P8BKx5lpaWqOWoDOWW7Tu5hiOTlOTj32fadvE5tEDs57t_DGSPvxbh85ge1Tvai8vr1WUNx3W_pntkWR8ubLSeoW7w6jweOFpMnp1wxlUp25uZc/s1600/606809-the-elder-scrolls-v-skyrim-xbox-360-screenshot-beheading.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="576" data-original-width="1024" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcqtmONIzggHQllv_pph7QiMOucC42P8BKx5lpaWqOWoDOWW7Tu5hiOTlOTj32fadvE5tEDs57t_DGSPvxbh85ge1Tvai8vr1WUNx3W_pntkWR8ubLSeoW7w6jweOFpMnp1wxlUp25uZc/s320/606809-the-elder-scrolls-v-skyrim-xbox-360-screenshot-beheading.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Elder Scrolls V: Skyrim</i></div>
<br />
As the Internet started getting more sophisticated, online games started getting better and better. I remember my young children enjoying Club Penguin, a family-friendly safe place for young ones from Disney.<br />
<br />
Later, Minecraft was a craze. All three of my kids spent lots of time building blocky pixelated creations in Minecraft.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOEMUetAtrExcOdnaCJ7xpREg8wf7PhjhdexmtyRAdJNTwB_q0XxD2dPO87Uurk6Qst9DC1zE62OU7LTlfV9xYjU6pkhXcMDNUDsXBd4SOv_PZYfBfILWcrJxfYf2IzoLy1KPnAxv0_OU/s1600/minecraft.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="720" data-original-width="1280" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgOEMUetAtrExcOdnaCJ7xpREg8wf7PhjhdexmtyRAdJNTwB_q0XxD2dPO87Uurk6Qst9DC1zE62OU7LTlfV9xYjU6pkhXcMDNUDsXBd4SOv_PZYfBfILWcrJxfYf2IzoLy1KPnAxv0_OU/s320/minecraft.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Minecraft</i></div>
<br />
My son became obsessed with airplanes a few years back, and ever since he's spent a lot of his time with flight simulators, particularly X-Plane. He's flown everything from Cessnas to the Space Shuttle. By playing with others, he gets the full experience of flying, talking to air traffic controllers, navigating around other planes, and so on. I'd say these simulators must be pretty good, because when we took him on an actual flight with an instructor for his birthday last year, the instructor was impressed with his knowledge of the cockpit and rules of flight.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_OSeyAVo8iBz-dNAi55W0M7AeA-HVK1gszfaHWz81peNi3tNbDU6hs2fP3RfEjXquPfUJD8nhT4pe5tXeEWuVgDnUWU6g65auzlsZOteXSevYBk5ZfuoimWfzljzZy9dY_61OsnFJy8g/s1600/xplane.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="588" data-original-width="783" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_OSeyAVo8iBz-dNAi55W0M7AeA-HVK1gszfaHWz81peNi3tNbDU6hs2fP3RfEjXquPfUJD8nhT4pe5tXeEWuVgDnUWU6g65auzlsZOteXSevYBk5ZfuoimWfzljzZy9dY_61OsnFJy8g/s320/xplane.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>X-Plane</i></div>
<br />
Today there is Steam, and for this retro gamer that's one way to play some of my favorite games from the past such as the Indiana Jones titles. But I'm still looking for a way to play Midtown Madness and Marble Madness.<br />
<br />
One board game that has recently become a new family favorite is Settlers of Catan, particularly when my daughter Debra is home. She is cold, calculating, and vicious in her gameplay (I've never been prouder!) Catan features heavy strategy and trading elements, and while there's no warfare in the game it reminds me strongly of Risk.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzPGNVKAjfen_XWKYOu-gsxAbNkVQSndyAZIUDleDqOR04TriKOKHJ5MbjKrOtRprp87v_tfT8Bs1rit_NVelxHDQoZJ32t2rJ7RoYeLRIg2dSGUXxD5wZJx-O6xiLOwmvmOi29HZ-D1M/s1600/catan5-1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="320" data-original-width="603" height="169" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjzPGNVKAjfen_XWKYOu-gsxAbNkVQSndyAZIUDleDqOR04TriKOKHJ5MbjKrOtRprp87v_tfT8Bs1rit_NVelxHDQoZJ32t2rJ7RoYeLRIg2dSGUXxD5wZJx-O6xiLOwmvmOi29HZ-D1M/s320/catan5-1.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Catan</i></div>
<h2>
Phone Games</h2>
Like the rest of the world, there's the occasional game craze like Angry Birds or Flappy Bird that everyone gets caught up in fror a while.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkAP4IQBnwzCAte3sdiF4RSPiP849VrDDXCuEHHdJSDPcxaZCaIT9VMlDs7JZMYIBFGdNQQ1eTcis4unctJsxFkE4NDUhdEfOGa77_J-ZvGdI-NpUuH8DTkZbxZjjK9bFI-60iFwfVPI8/s1600/angry.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="183" data-original-width="275" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgkAP4IQBnwzCAte3sdiF4RSPiP849VrDDXCuEHHdJSDPcxaZCaIT9VMlDs7JZMYIBFGdNQQ1eTcis4unctJsxFkE4NDUhdEfOGa77_J-ZvGdI-NpUuH8DTkZbxZjjK9bFI-60iFwfVPI8/s1600/angry.jpg" /></a></div>
<div style="text-align: center;">
Angry Birds</div>
<div style="text-align: center;">
<br /></div>
The phone game my wife and I play the most is Words with Friends: we play it every day with each other. This is something we can do whether we're together or apart.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJcHucDLUrE-ymymOVboVvwZ0ymRT7TcM0NrIVNmwc7kSIFDo7Lv3NH4oKcSkUtvfOJkRb4pFXHNVW4Tt7hc35FWhyphenhyphenVjohhKuE3Smz03mReATF6FC8f6zj0kbn5w90jsCu7afGMTUPems/s1600/words.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="316" data-original-width="221" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJcHucDLUrE-ymymOVboVvwZ0ymRT7TcM0NrIVNmwc7kSIFDo7Lv3NH4oKcSkUtvfOJkRb4pFXHNVW4Tt7hc35FWhyphenhyphenVjohhKuE3Smz03mReATF6FC8f6zj0kbn5w90jsCu7afGMTUPems/s1600/words.png" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Words with Friends</i></div>
<h2>
Conclusion</h2>
One reason I'm a retro gamer is the amount of creativity I saw in the early days. Maybe that was a side effect of the limitations in platforms. Today it seems so many games are First Person Shooters or Driving Games. Many of them are done well, and there's lots of work on world-building, but it still feels to me like there was more creativity and inventiveness in the past. On the other hand, there are lots of modern games I haven't played yet.<br />
<br />
Well, there you have it: a lifetime of game play that is continuing on with the next generation. I'll admit, I've sometimes been so busy at work I've neglected gaming at times. Fortunately, I now work somewhere where gaming is part of work. Let the games begin!<br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-33644275321805959942019-04-24T14:38:00.001-07:002021-08-19T08:57:31.855-07:00Create and Host a Cross-Platform Web Site on ASP.NET Core<style>
.tr0 { background-color: white; color: black; font-weight: bold; }
.tr1 { background-color: white; }
.tr2 { background-color: aliceblue; }
.syntaxhighlighter {
overflow-y: auto !important;
overflow-x: auto !important;
max-height: 512px;
}
</style>
<script>
if (location.protocol != 'http:')
{
location.href = 'http:' + window.location.href.substring(window.location.protocol.length);
}
</script>
This is the second post <a href="http://davidpallmann.blogspot.com/2019/04/create-cross-platform-console-command.html">in a series on .NET Cross-Platform Support</a>. In my <a href="http://davidpallmann.blogspot.com/2019/04/create-cross-platform-console-command.html" target="_blank">first post</a>, I covered how to create, build, and deploy a console command in .NET Core for Windows, Linux, and MacOS. In today's post, I'll cover how to create a web site with ASP.NET Core and deploy it on both Windows and Linux.<br />
<br />
If you're going to follow along, you'll need to install the <a href="https://dotnet.microsoft.com/download" target="_blank">.NET Core SDK</a>. I'm doing my development with .NET Core 2.2 and Visual Studio Code on Windows, but you could just as easily do the same on Linux or MacOS.<br />
<br />
The web site we'll create is a simple one-page site that performs conversions between different units of measurement, such as from miles to kilometers.<br />
<br />
<h2>
Development</h2>
<div>
<br /></div>
<h3>
Creating an ASP.NET MVC Project</h3>
We'll use the <span style="color: #666666;">dotnet new</span> command to create a starter project. I want to use MVC, so we'll request the MVC template.We'll specify the folder and project name <b><span style="color: #666666;">convert</span></b>.<br />
<br />
<b>dotnet new mvc -o convert</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP_F6uiiLzO0r_ijeTLhsujWoMvUCX6IdkTrTFCIgn4IZfHkW9198sPm_SXhCEDKpJQvC688Bb7rOujYbEeDSMKVEvSDMXUuIDd7A1m2YLhAsJuUl476HUdO6yHrYEK_dDR6dDuL7oSzQ/s1600/dotnet-new.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="410" data-original-width="1103" height="147" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhP_F6uiiLzO0r_ijeTLhsujWoMvUCX6IdkTrTFCIgn4IZfHkW9198sPm_SXhCEDKpJQvC688Bb7rOujYbEeDSMKVEvSDMXUuIDd7A1m2YLhAsJuUl476HUdO6yHrYEK_dDR6dDuL7oSzQ/s400/dotnet-new.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<div style="text-align: left;">
<br /></div>
This creates a folder named <span style="color: #666666;">convert</span>. Within that folder are our project files along with subfolders.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYusmhCF1WqcbB79ZiYRqNjqWaii9QAlH8tBeoeBxRPO1HFJ8pfTifXy25g9kgKVSBoptbJ8AtipsxSpEBsna6ibcj1ZWutWAveKwxciJAz9zZbWCzpDCjJ_AhfRm8ZmRLEryAfiOtlnE/s1600/dotnet-new-files.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="397" data-original-width="768" height="206" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYusmhCF1WqcbB79ZiYRqNjqWaii9QAlH8tBeoeBxRPO1HFJ8pfTifXy25g9kgKVSBoptbJ8AtipsxSpEBsna6ibcj1ZWutWAveKwxciJAz9zZbWCzpDCjJ_AhfRm8ZmRLEryAfiOtlnE/s400/dotnet-new-files.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<h3>
Coding the Site</h3>
Fire up Visual Studio Code and use Open Folder to open the <b>convert</b> folder that was just created.<br />
<br />
If you're new to ASP.NET Core, let's take a moment to familiarize ourselves with the project that has been created. Keep in mind this MVC project is only one of many ASP.NET Core project tempaltes<br />
you can use.<br />
<br />
<h4>
Project Structure</h4>
In the convert folder, there is Program.cs and Startup.cs. Program.cs contains function <span style="color: #666666;">Main</span>, which is where execution begins. It creates a WebHost, and references the Startup class.<br />
<br />
<pre class="brush: csharp">using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace convert
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
</pre>
<br />
Startup.cs contains the initialization code for the WebHost. This refactoring of ASP.NET is extremely modular and extensible, and includes a built-in dependency injection system.<br />
<br />
<pre class="brush: csharp">using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace convert
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.Configure<CookiePolicyOptions>(options =>
{
// This lambda determines whether user consent for non-essential cookies is needed for a given request.
options.CheckConsentNeeded = context => true;
options.MinimumSameSitePolicy = SameSiteMode.None;
});
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseExceptionHandler("/Home/Error");
// The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseCookiePolicy();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
}
}
}
</pre>
<br />
Since we're just building a simple demonstration web site, we dont need to make any changes to the code in Program.cs or Startup.cs.<br />
<br />
Within the <b>convert </b>folder, we have Controllers, Models, and Views subfolders. These are all conceptually familiar to anyone familiar with the Model-View-Controller pattern. Controllers contains C# controller classes; Models contains C# model classes; and Views contain Razor pages (which are HTML with embedded C# code and Razor directives).<br />
<br />
There's also a wwwroot folder, which contains static css, image, and JavaScript files.<br />
<br />
<h4>
Project Starting Point</h4>
We can build and run the project to see what we have been given out-of-the-box. In Visual Studio Code, open a new terminal window with Terminal > New Terminal. Run <b><span style="color: #666666;">dotnew build</span></b> to build the prjoect.<br />
<br />
In traditional ASP.NET, launching the site locally from Visual Studio would use IIS or IIS Express to host the web site. In ASP.NET Core, all we need is the <b><span style="color: #666666;">dotnet run</span></b> command. Enter <b><span style="color: #666666;">dotnet run</span></b> in the terminal window to host a web server. Click the displayed HTTP or HTTPS link to open the site in a browser. We can see we get a simple Welcome page.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7-X7P7gxKpklp43Bs9airloq4h5CwPoH_ND4m3J9Ix98ZL2EJrJGOI9QExtRL7f-jVESps-B9J1uwCrp1Jb1rTK7GFuNor0Sp8hHxYWwnzi-5Mvg2yjpdqirML2BF-2cDeTEDB_9u3eo/s1600/dotnet-run-original-terminal.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="859" data-original-width="1600" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj7-X7P7gxKpklp43Bs9airloq4h5CwPoH_ND4m3J9Ix98ZL2EJrJGOI9QExtRL7f-jVESps-B9J1uwCrp1Jb1rTK7GFuNor0Sp8hHxYWwnzi-5Mvg2yjpdqirML2BF-2cDeTEDB_9u3eo/s400/dotnet-run-original-terminal.png" width="400" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWYfxH4-x5u8pyk85dEhDJyn3aUZ0k4vV83xHwu3nt5Js1_7hgJ5TpycNpmBogeE_PsWuLZEFHbeQXZ4UHBHpZm39vC0_YQp7s9hjON_ui7gbBUQdNzt6rNcZsXlfyK0mTgI0Ute21WRg/s1600/dotnet-run-original.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="251" data-original-width="1600" height="62" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWYfxH4-x5u8pyk85dEhDJyn3aUZ0k4vV83xHwu3nt5Js1_7hgJ5TpycNpmBogeE_PsWuLZEFHbeQXZ4UHBHpZm39vC0_YQp7s9hjON_ui7gbBUQdNzt6rNcZsXlfyK0mTgI0Ute21WRg/s400/dotnet-run-original.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<h4>
Code the HTML Page</h4>
We need to change the HTML in the default page, /Views/Home/index.cshml. We add the following code to the page:<br />
<pre class="brush:csharp">@{
ViewData["Title"] = "Home Page";
}
<div class="text-center">
<h1 class="display-4">Unit Converter</h1>
<p>Use this page to convert between common units of measurement</a>.</p>
</div>
<div> </div>
<div>
<input id="source-value" type="number" value="10" style="font-size: 14px" />
<select id="source-unit">
<option value="">-- select source units --</option>
<option value="ft" selected>Feet (ft)</option>
<option value="km" selected>Kilometers (km)</option>
<option value="m">Meters (m)</option>
<option value="mi">Miles (mi)</option>
</select>
<button id="btn-convert" onclick="convert();">Convert</button>
<input id="dest-value" type="number" value="" style="font-size: 14px" readonly=readonly />
<select id="dest-unit">
<option value="">-- select destination units --</option>
<option value="ft" selected>Feet (ft)</option>
<option value="km">Kilometers (km)</option>
<option value="m">Meters (m)</option>
<option value="mi" selected>Miles (mi)</option>
</select>
</div>
<script>
function convert() {
var value = $('#source-value').val();
var sourceUnits = $('#source-unit').val();
var destUnits = $('#dest-unit').val();
$('#dest-value').val('');
if (sourceUnits==='' || destUnits==='') return;
if (sourceUnits===destUnits)
{
$('#dest-value').val(value);
return;
}
console.log(value);
console.log(sourceUnits);
console.log(destUnits);
var url = '/home/Convert?value=' + value + '&source=' + sourceUnits + '&dest=' + destUnits;
$.ajax({
url: url,
method: 'GET',
}).done(function(data) {
$('#dest-value').val(data);
//$( this ).addClass( "done" );
console.log(data);
});
}
</script>
</pre>
We can now build the site with dotnet build and run it with dotnet run so that we can test it.<br />
<br />
<b>dotnet build</b><br />
<b>dotnet run</b><br />
<br />
Now we can enter an amount and select source and destination units. Clicking Convert converts the value.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHWzXzVH24TpVywiH0MfQd52aAgvxVtuvEMEzRrTyjI-d3zN9iWnnVshBJBJ6NdD4OA1nfHOBDG3uVDThCkR8IqdcDFj-2pYINWk-jCp54bfXkhh4r09X9TGOCXUB1iMm6h3-XETAkW9Y/s1600/win-site-test.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="516" data-original-width="1562" height="131" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHWzXzVH24TpVywiH0MfQd52aAgvxVtuvEMEzRrTyjI-d3zN9iWnnVshBJBJ6NdD4OA1nfHOBDG3uVDThCkR8IqdcDFj-2pYINWk-jCp54bfXkhh4r09X9TGOCXUB1iMm6h3-XETAkW9Y/s400/win-site-test.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Our site, while simple, could easily be expanded to support many more conversions over time. For our purposes of testing cross-platform compatibility, this is sufficient and we can move on to seeing things work on Linux.<br />
<br />
<h2>
Publishing to Linux</h2>
We can generate output for linux with the dotnet publish command, specifying the distribution we wish to target. We'll use Ubuntu 18.04, 64-bit (because that's an AMI available for AWS EC2).<br />
<br />
<span style="color: #666666; font-family: "courier new" , "courier" , monospace;"><b>dotnet publish -c Release --self-contained -r ubuntu.18.04-x64</b></span><br />
<br />
To deploy, we'll need to allocate a Linux web server, for which we'll use NGINX. We'll then deploy our convert site, and finally configure NGINX to serve as a reverse proxy to our ASP.NET Core site.<br />
<br />
<b>1. Create EC2 instance</b><br />
<br />
We first create an Ubuntu EC2 instance on AWS. We save the .pem (key) file created with the instance, which will be needed anytime we want to connect to the instance with SSH.<br />
<br />
Configure an inbound rule allowing port 80 in the security group for the EC2 instance.<br />
<br />
As we allocate the EC2 instance, we save the .pem (key) file, which we'll need for subsequent steps.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsfiyVh9KHNVw3rF7T_VVK2sbthrkCTEocmeIbZiY556Hl3ddSZU2OxH1g4GXIEBNmP4dntcuglDxw69jBwvoKIyvjTmzUxzRyPZvcrLM3zANqK44dvFUo4RV01B-tiu_MQq16eqxsq5U/s1600/ec2.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="507" data-original-width="1600" height="126" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhsfiyVh9KHNVw3rF7T_VVK2sbthrkCTEocmeIbZiY556Hl3ddSZU2OxH1g4GXIEBNmP4dntcuglDxw69jBwvoKIyvjTmzUxzRyPZvcrLM3zANqK44dvFUo4RV01B-tiu_MQq16eqxsq5U/s400/ec2.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>2. Connect with SSH</b><br />
<br />
Once the instance is up and running, we connect to it with SSH, specifying our instance URL and the .pem (key) file we created with the instance:<br />
<br />
<span style="color: #666666; font-family: "courier new" , "courier" , monospace;">ssh -i "dp-dev.pem" ubuntu@ec2-my-ip.us-west-2.compute.amazonaws.com</span><br />
<br />
<b>3. Set up web server</b><br />
<br />
To set up a web server, we use the sudo ("SuperUser do") command to allow port 80 on the firewall.<br />
<br />
sudo ufw allow 80/tcp<br />
<br />
Next, we install <b><span style="color: #666666;">nginx</span></b>, a popular web server:<br />
<br />
<span style="color: #666666; font-family: "courier new" , "courier" , monospace;">sudo apt-get install nginx</span><br />
<span style="color: #666666; font-family: "courier new" , "courier" , monospace;">sudo service nginx start</span><br />
<br />
Once installation completes, we are able to confirm that we can access the EC2 instance as a web server:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoq6uefqKqxBd0FCNQWgb7WCjDKYoyntjJJE1iNg5uSsolrgosVl3KxzWhcbd49UBxa3xCLtGj7o6_wle86P5vM3213zs2HIda1Pl8QYB29CGcXHRID89pgB3Ycp_7H9aDzA8gLMCDFB4/s1600/nginx.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="593" data-original-width="913" height="258" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoq6uefqKqxBd0FCNQWgb7WCjDKYoyntjJJE1iNg5uSsolrgosVl3KxzWhcbd49UBxa3xCLtGj7o6_wle86P5vM3213zs2HIda1Pl8QYB29CGcXHRID89pgB3Ycp_7H9aDzA8gLMCDFB4/s400/nginx.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>4. Deploy the .NET Core application</b><br />
<br />
Via SSH, create a convert file under /home/ubuntu. Then use a tool such as WinSCP to copy the files from the Ubuntu publish folder to /home/ubuntu/convert:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU4rJVT2kGv2uY2V-Da8wfrRKCZ5zVR2t-qyBgngKVW0uHqeOwrUpfY3-ZjRCAURk_AqJ_o147XXw_AjAUX14yKGVUXPYdu1KytqVC06VwDgsM1zKdMXXuegtkqwgCYd5GPyDL-LPyL9E/s1600/winscp-copy.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="859" data-original-width="1600" height="213" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjU4rJVT2kGv2uY2V-Da8wfrRKCZ5zVR2t-qyBgngKVW0uHqeOwrUpfY3-ZjRCAURk_AqJ_o147XXw_AjAUX14yKGVUXPYdu1KytqVC06VwDgsM1zKdMXXuegtkqwgCYd5GPyDL-LPyL9E/s400/winscp-copy.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<b>5. Configure nginx to be a Reverse Proxy for Convert.dll</b><br />
<br />
Following the Microsoft instructions <a href="https://docs.microsoft.com/en-us/aspnet/core/host-and-deploy/linux-nginx?view=aspnetcore-2.2">here</a>, we do the following to set up NGINX as a reverse proxy for the NET Core convert site. This simply means NGINX will forward requests to our application.<br />
<br />
a. Stop the nginx site<br />
<br />
<span face=""consolas" , "menlo" , "monaco" , "lucida console" , "liberation mono" , "dejavu sans mono" , "bitstream vera sans mono" , "courier new" , monospace , sans-serif" style="background-color: #fafafa; font-size: 14px; white-space: pre;">sudo service nginx start</span><br />
<br />
b. Change directory to /etc/nginx/sites-available and replace the file <span style="color: #666666;"><b>default </b></span>with the content below (I used Notepad++ and WinSCP for this):<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">cd /etc/nginx/sites-available</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span>
<span style="font-family: "courier new" , "courier" , monospace;">server {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> listen 80;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> server_name example.com *.example.com;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> location / {</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_pass http://localhost:5000;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_http_version 1.1;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_set_header Upgrade $http_upgrade;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_set_header Connection keep-alive;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_set_header Host $host;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_cache_bypass $http_upgrade;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> proxy_set_header X-Forwarded-Proto $scheme;</span><br />
<span style="font-family: "courier new" , "courier" , monospace;"> }</span><br />
<span style="font-family: "courier new" , "courier" , monospace;">}</span><br />
<br />
If you run into permission issues, try uploading your new <b><span style="color: #666666;">default </span></b>file to a path you have write access to, such as where you copied the convert application publish files to. Then, in cd /etc/nginx/sites-available, you can use sudo cp to copy the file:<br />
<br />
<span face=""consolas" , "menlo" , "monaco" , "lucida console" , "liberation mono" , "dejavu sans mono" , "bitstream vera sans mono" , "courier new" , monospace , sans-serif" style="background-color: #fafafa; font-size: 14px; white-space: pre;">cd /etc/nginx/sites-available</span><br />
<span face=""consolas" , "menlo" , "monaco" , "lucida console" , "liberation mono" , "dejavu sans mono" , "bitstream vera sans mono" , "courier new" , monospace , sans-serif" style="background-color: #fafafa; font-size: 14px; white-space: pre;">sudo cp /home/ubunto/convert/default .</span><br />
<br />
c. Start the nginx service<br />
<br />
<span face=""consolas" , "menlo" , "monaco" , "lucida console" , "liberation mono" , "dejavu sans mono" , "bitstream vera sans mono" , "courier new" , monospace , sans-serif" style="background-color: #fafafa; font-size: 14px; white-space: pre;">sudo service nginx start</span><br />
<br />
<b>6. Start the Convert Site</b><br />
<br />
From /home/ubuntu/convert, use the dotnet command to run convert.dll to start the Convert site<br />
<br />
<span face=""consolas" , "menlo" , "monaco" , "lucida console" , "liberation mono" , "dejavu sans mono" , "bitstream vera sans mono" , "courier new" , monospace , sans-serif" style="background-color: #fafafa; font-size: 14px; white-space: pre;">cd /home/ubuntu/convert
</span><span face=""consolas" , "menlo" , "monaco" , "lucida console" , "liberation mono" , "dejavu sans mono" , "bitstream vera sans mono" , "courier new" , monospace , sans-serif" style="background-color: #fafafa; font-size: 14px; white-space: pre;">dotnet convert.dll</span><br />
<span face=""consolas" , "menlo" , "monaco" , "lucida console" , "liberation mono" , "dejavu sans mono" , "bitstream vera sans mono" , "courier new" , monospace , sans-serif" style="background-color: #fafafa; font-size: 14px; white-space: pre;"><br /></span><b>
7. Try to access the site in a browser:</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1zkZJoa6nyxikwZ7XzCbNIZDgfZIbgdqhGEH0OuHRiYOtLrijX4GZP6EvJt7PMJIIXkveHW5xMX1Irx2Y00hnKaH4yaBZ7p8IpStJo-u4MvpTo2GloQrVqdGHR_rPuxIZq3dNdmWWIic/s1600/nginx-convert.png" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="859" data-original-width="1263" height="271" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1zkZJoa6nyxikwZ7XzCbNIZDgfZIbgdqhGEH0OuHRiYOtLrijX4GZP6EvJt7PMJIIXkveHW5xMX1Irx2Y00hnKaH4yaBZ7p8IpStJo-u4MvpTo2GloQrVqdGHR_rPuxIZq3dNdmWWIic/s400/nginx-convert.png" width="400" /></a></div><p>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Our ASP.NET Core Convert site is now running on Ubuntu Linux, with NGINX serving as a reverse proxy. If you've never worked with Linux as a web server before, getting to this step with a .NET web site is a great moment.</p><p><br />
</p><h2>
Conclusion</h2>
In this post I've shared what my first-time experience publishing an ASP.NET Core web site to Linux. There were plenty of unknowns working with an operating system I had little experience with, but with a little persistence I got there. .NET Core is well done, and ASP.NET Core is no exception. It's very empowering to realize how broader your .NET Skills can now reach with .NET Core.<br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-56944298930483689362019-04-24T10:03:00.000-07:002019-04-24T10:10:47.265-07:0025th Anniversary Cruise, Part 7: Pompeii<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">In </span><a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" style="background-color: white; color: #888888; font-family: roboto; font-size: 13.2px;" target="_blank">this series</a><span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"> of posts I'm describing the Mediterranean Cruise my wife Becky and I took in 2018 for our 25th anniversay, Here in Part 7 I'm covering our seventh stop, Pompeii.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<h2>
<span style="background-color: white; font-family: "roboto"; font-size: large;">Pompeii (★★★★)</span></h2>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Pompeii was marvelous. In terms of historical richness and the amount of things to see, Pompeii delivered more than any other stop on our trip. </span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Pompeii was an ancient Roman city near Naples that was buried by lava in the AD 79 eruption of Mount Vesuvius. The result is a highly-preserved ancient city. It's also a complete city: you can walk it's streets, look into houses and public places and restaurants and so on. It's not possible to see it all in one day, but our excellent tour guide Jose took us to many of the highlights and gave us lots of good information throughout the day.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">Pompeii is in pleasant surroundings with picturesque hillsides, trees, and flowers.</span></span><br />
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><br /></span></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH0pqi3F7I6Lsfh8o_-VEwQa1rZ1T_dConrGrUkYiXMhTmua2UDjV0EFW-5diC4sGDpAaSMIBNx8q8idlG3bzzed7XhsF2tTAv60vnXfwsmGIz3w3fyFA8CkqeHdcIZwa3RqOXMPKjgFk/s1600/village.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjH0pqi3F7I6Lsfh8o_-VEwQa1rZ1T_dConrGrUkYiXMhTmua2UDjV0EFW-5diC4sGDpAaSMIBNx8q8idlG3bzzed7XhsF2tTAv60vnXfwsmGIz3w3fyFA8CkqeHdcIZwa3RqOXMPKjgFk/s320/village.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNbsIDCFdXMZ8yjXJH92aMVh4CFkYuPxkiDPIaDmopJtrDXaFod5VXZ0dyKu_qgx2nNuYlaHbNYN8aabs934wLgYv_tcfYCz7fhsOb5q-S_zBA7BLv7T9gWCLXpcvO_LL5lW32ouJru70/s1600/trees.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNbsIDCFdXMZ8yjXJH92aMVh4CFkYuPxkiDPIaDmopJtrDXaFod5VXZ0dyKu_qgx2nNuYlaHbNYN8aabs934wLgYv_tcfYCz7fhsOb5q-S_zBA7BLv7T9gWCLXpcvO_LL5lW32ouJru70/s320/trees.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh090Ekkzs1fy4uL85NVfFdh-KEdA8Re2Zvis0jgYwklTG9UD4-ONGHp8fkOk9LLGVudU47A-ZehmW9DNKGGYMZ5R8A2FOr8gO-WEU51uhjue4cVCO8N7gIJlwJsN7rDTTnlxZfkDm-mBA/s1600/hillside.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh090Ekkzs1fy4uL85NVfFdh-KEdA8Re2Zvis0jgYwklTG9UD4-ONGHp8fkOk9LLGVudU47A-ZehmW9DNKGGYMZ5R8A2FOr8gO-WEU51uhjue4cVCO8N7gIJlwJsN7rDTTnlxZfkDm-mBA/s320/hillside.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXXNFRS5ogc_eWh8uD84R0RCQWO14q7ViuuZvuVA4VLnZSuswgVzLdZUrXB7jSWykneIMI1nr-wxbEs5vYvtl8spwRzsJFFnGSDvZu681aKCe1lSwS5B7OOUHdjpyd05RLInttKRDyk30/s1600/wall.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXXNFRS5ogc_eWh8uD84R0RCQWO14q7ViuuZvuVA4VLnZSuswgVzLdZUrXB7jSWykneIMI1nr-wxbEs5vYvtl8spwRzsJFFnGSDvZu681aKCe1lSwS5B7OOUHdjpyd05RLInttKRDyk30/s320/wall.jpg" width="320" /></a></div>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><br /></span></span>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">Our guide walked us past practice fields for the gladiators and an amphitheatre.</span></span><br />
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><br /></span></span>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1m0KWfOTzTcP7d6WMZKkccYYP63zPouYXrCM7yYJ0IAO5z7bKdtyt8FPDkccbKxnL3sYP4v3OLXrH4j8Cl42Na83rMuAbDnPmhUumzRI4sjj-G-QiVa07FSdBPz7eII2BrR3cxRfx0z8/s1600/columns.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="224" data-original-width="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg1m0KWfOTzTcP7d6WMZKkccYYP63zPouYXrCM7yYJ0IAO5z7bKdtyt8FPDkccbKxnL3sYP4v3OLXrH4j8Cl42Na83rMuAbDnPmhUumzRI4sjj-G-QiVa07FSdBPz7eII2BrR3cxRfx0z8/s1600/columns.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1xYrqaEwRDGY_sYH6-iRzb9j6LPNOVquPRgZq4VQPf3ipTn90ca_F-SYFzuX8MjKNQMZNJI7b2YmZLkyXNKp5pEzSifUNUvT2S7NgTwicseQhZfnv2QkvXKP_k0QJpef1Qy6Pe57JsDU/s1600/amphitheatre.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1xYrqaEwRDGY_sYH6-iRzb9j6LPNOVquPRgZq4VQPf3ipTn90ca_F-SYFzuX8MjKNQMZNJI7b2YmZLkyXNKp5pEzSifUNUvT2S7NgTwicseQhZfnv2QkvXKP_k0QJpef1Qy6Pe57JsDU/s320/amphitheatre.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We then proceeded to walk the streets. The Pompeiians were pretty sophisticated. There were stone blocks to step on so upper-class citizens could avoid walking in garbage. There were shells embedded in the streets to provide reflective illumination at night.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI1kr4Br1-Wk1aP0wN97OdZaGbQNPE-nb4LiTVW9aDWYY29TqinlAnLxYvJcrrA9QqO2hh0UW6Yu3A228vFkIHMwiS6yMJXiHCcqcoq0C3c5shdfKqufOy2X5z055swiQYCIF_s1GjZVo/s1600/avenue.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="969" data-original-width="1292" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgI1kr4Br1-Wk1aP0wN97OdZaGbQNPE-nb4LiTVW9aDWYY29TqinlAnLxYvJcrrA9QqO2hh0UW6Yu3A228vFkIHMwiS6yMJXiHCcqcoq0C3c5shdfKqufOy2X5z055swiQYCIF_s1GjZVo/s320/avenue.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCQ6Lo5K2H3VPuT1sIkXzDUhwghBtHQy6Daunsn0ocULS6dVysyCnUOKY92FvIYOve46Oi_aaOv2qXaoVryD_Y3g9rYlDjAxCjATl3goAnBT8-Gho8ayGmJz5Dweqr2EYiRAs_zWuTyNY/s1600/money-welcome.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="690" data-original-width="920" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhCQ6Lo5K2H3VPuT1sIkXzDUhwghBtHQy6Daunsn0ocULS6dVysyCnUOKY92FvIYOve46Oi_aaOv2qXaoVryD_Y3g9rYlDjAxCjATl3goAnBT8-Gho8ayGmJz5Dweqr2EYiRAs_zWuTyNY/s320/money-welcome.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
"Your Money is Welcome Here"</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Seeing Roman homes was impressive. Some homes had impressive floor tiles. Wall mosaics were common.</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXUydA3NgktrtZO8x1h3Bl8aO_Om9CZPxiUB2u4V1lKeoOriz-uFhNt89E4HXxD5Y8OPct8X33U8ch5y0EulELswIakj9RleWchfRZqN-aNp3ONkbljqMyTF1-dAEsHl_fImJeNxcXnQ/s1600/floor_mosaic.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEghXUydA3NgktrtZO8x1h3Bl8aO_Om9CZPxiUB2u4V1lKeoOriz-uFhNt89E4HXxD5Y8OPct8X33U8ch5y0EulELswIakj9RleWchfRZqN-aNp3ONkbljqMyTF1-dAEsHl_fImJeNxcXnQ/s320/floor_mosaic.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpl_siQmp7D25FvpBcOPJGvM7X0oYOOCHeE00kktkYf5eyFjUBlo6tktVhKwKJTYXK_MezvMsfcgpf2JfBhluHSnJD7i2kUo_C6d5bu5TgIvoa8uqw3BCJcqjB8X1uuhLfGUphh1WotLY/s1600/house.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgpl_siQmp7D25FvpBcOPJGvM7X0oYOOCHeE00kktkYf5eyFjUBlo6tktVhKwKJTYXK_MezvMsfcgpf2JfBhluHSnJD7i2kUo_C6d5bu5TgIvoa8uqw3BCJcqjB8X1uuhLfGUphh1WotLY/s320/house.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Public baths with hot and cold water; and a restaurant kitchen.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYMU1a9gJ7PfjiNn4-t4fBzBI7R0xVbJyGz_4-5we3geHrQkpwwz3tZ7dyTKKFoQfGBFjpwTD-2sxzoL4fwOQ8PVqYEWtDt0OstSYLdhaLISKqhEmcObb2qR_ALoRzA3ObYJeaHAau5yo/s1600/bath.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYMU1a9gJ7PfjiNn4-t4fBzBI7R0xVbJyGz_4-5we3geHrQkpwwz3tZ7dyTKKFoQfGBFjpwTD-2sxzoL4fwOQ8PVqYEWtDt0OstSYLdhaLISKqhEmcObb2qR_ALoRzA3ObYJeaHAau5yo/s320/bath.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6f-p7ltCco6Pkazos6yC4kYVDOyMKMwnRIebIMkMfSdY821_xoqJNk7kpR-fcsIa_fbm07DZZtxVil8XCxhX7T-UXy3vnbgoHJvObIdk8KWirFgbhlj8ztEaxrPIpHjxp0NYx3eo4EEQ/s1600/food_prep.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6f-p7ltCco6Pkazos6yC4kYVDOyMKMwnRIebIMkMfSdY821_xoqJNk7kpR-fcsIa_fbm07DZZtxVil8XCxhX7T-UXy3vnbgoHJvObIdk8KWirFgbhlj8ztEaxrPIpHjxp0NYx3eo4EEQ/s320/food_prep.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We also saw some of the casts made of bodies.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0kaM4pSw-PoaqPdQpcaHXqNtRPL7A19ew_59JSy_plcK_De3nVhpZj2iX2ROw-cnIKc44H6nmhf4-WElQobPu8vhsKcFKKT5SfmXbWhUVB7f6UKlV7RLK19ytQ5p5Sae5DsnViKtuivs/s1600/bodies.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0kaM4pSw-PoaqPdQpcaHXqNtRPL7A19ew_59JSy_plcK_De3nVhpZj2iX2ROw-cnIKc44H6nmhf4-WElQobPu8vhsKcFKKT5SfmXbWhUVB7f6UKlV7RLK19ytQ5p5Sae5DsnViKtuivs/s320/bodies.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Inside this arch you can see Mount Vesuvius.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNnj1mtVc4LP4O62L5Uu3jWtnkat6NglVNCT5lu83wyRd1uar4bKypYnS0mvEjkU31Ai-2CIw8bjbi-g8nKqGgUJKCVQTTmpTnAkQKqywSXpmSEnMKRo0p029eEimzh5QmSgMDGkEeF64/s1600/arch_vesuvius.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="224" data-original-width="299" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNnj1mtVc4LP4O62L5Uu3jWtnkat6NglVNCT5lu83wyRd1uar4bKypYnS0mvEjkU31Ai-2CIw8bjbi-g8nKqGgUJKCVQTTmpTnAkQKqywSXpmSEnMKRo0p029eEimzh5QmSgMDGkEeF64/s1600/arch_vesuvius.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
That's about all we had time for, but despite seeing a lot there's far more to Pompeii. We certainly felt Pompeii didn't disappoint.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Previous: <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversay-cruise-part-6-rome.html">Part 6: Rome</a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-58991648456629642492019-04-24T09:21:00.001-07:002019-04-24T10:03:48.260-07:0025th Anniversay Cruise, Part 6: Rome<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">In </span><a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" style="background-color: white; color: #888888; font-family: roboto; font-size: 13.2px;" target="_blank">this series</a><span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"> of posts I'm describing the Mediterranean Cruise my wife Becky and I took in 2018 for our 25th anniversay, Here in Part 6 I'm covering our sixth stop, Rome.</span><br />
<h2>
<span style="background-color: white; font-family: "roboto"; font-size: large;">Rome (★★★★)</span></h2>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Like Florence, Rome is an ancient city full of wonders. Like Florence, you can't do Rome justice in a day (or even a week). But a day is better than not visiting at all. </span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">I will admit to some trepidation about visiting Rome; on my very first tour of Europe in 1981, I remember the tour guides talking to themselves: one remarked to the other that he would never do a tour in Rome again because of all the pickpocketing. In preparing for this trip, we were regularly warned against pickpocketing in Europe and especially Rome. We came prepared, with money belts and a watchful attitude. Happily there were no incidents here or anywhere else on our trip.</span><br />
<h2>
<span style="background-color: white; font-family: "roboto"; font-size: large;">St. Peter's Basilica</span></h2>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">We're not Catholic, so seeing St. Peter's Basilica wasn't of particular interest to us</span></span><span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span><span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">but if we were going to see the Colosseum, this was part of the tour. It is a very large (holds 60,000) and ornate building, built in 1626. It is filled to the brim with art, gold, and homages to various popes. It been guarded for centuries by the <a href="https://en.wikipedia.org/wiki/Pontifical_Swiss_Guard">Swiss Guard</a>.</span></span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl_ybzPOeyoGFrTKjc8hj76UUPKieQKq8ZTsW8_fRcRWxJB1YNKkZbeYziAJbOKV68ngCZpqmgqSo3MlrC-gBdVYiPbFE4lW_lR97v0hilccen7WkhOctz9-WFlwaohOTJa6GaijQRj9w/s1600/peters_outside.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhl_ybzPOeyoGFrTKjc8hj76UUPKieQKq8ZTsW8_fRcRWxJB1YNKkZbeYziAJbOKV68ngCZpqmgqSo3MlrC-gBdVYiPbFE4lW_lR97v0hilccen7WkhOctz9-WFlwaohOTJa6GaijQRj9w/s320/peters_outside.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOVB3aaMkdlh1OGQEnqWny0wlZpefectJobAwl1zndZWQ9QlKiiGPfvg79_IV92cGXIKl_Duf0LZYwgbsYLRRgSM5PdEaNbYSEeGyG5DgDTnyZYfM8u6E2hFi3pc6OfeiLabzok-e-CBc/s1600/peters_swiss_guard.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="969" data-original-width="1292" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOVB3aaMkdlh1OGQEnqWny0wlZpefectJobAwl1zndZWQ9QlKiiGPfvg79_IV92cGXIKl_Duf0LZYwgbsYLRRgSM5PdEaNbYSEeGyG5DgDTnyZYfM8u6E2hFi3pc6OfeiLabzok-e-CBc/s320/peters_swiss_guard.jpg" width="320" /></a></div>
<i>St. Peter's Basilica and Swiss Guard</i><br />
<h3>
<span style="background-color: white; font-family: "roboto"; font-size: large;">Trevi Fountain</span></h3>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">The Trevi Fountain dates back to ancient Rome and is one of the most famous fountains in the world. It is the terminal point of an aqueduct started in 19 B.C. The fountain underwent an overhaul in 1732 where it became more ornate and baroque. The palace behind the fountation is the Palazzo Poli.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhupvxlcN3IFeHlf97oowye642KzEoVrdKi4bRQO6uBdIYPEoPP548CW_VJoXscn2JBD5dpthoTOscSzO9kNqsrvgdryYXLf_hu0GFki57SCK752VfNc5R0ih3E_BKiS4JPnYpb0PK3Pko/s1600/trevi1jpg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="969" data-original-width="1292" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhupvxlcN3IFeHlf97oowye642KzEoVrdKi4bRQO6uBdIYPEoPP548CW_VJoXscn2JBD5dpthoTOscSzO9kNqsrvgdryYXLf_hu0GFki57SCK752VfNc5R0ih3E_BKiS4JPnYpb0PK3Pko/s320/trevi1jpg.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEoQr7JNxu6PWSB4mku5dE5LV9kQGtZD3smxHucTu_8Aw1QXChttDWOhSR6F1n8fO2zOK3L-R8tyK244UCpWEkxxUdXRmfjJpCboaVzO5MSXHarjnNakm5ngS_Kk6xxA-rkXVVXIc-bSc/s1600/trevi2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjEoQr7JNxu6PWSB4mku5dE5LV9kQGtZD3smxHucTu_8Aw1QXChttDWOhSR6F1n8fO2zOK3L-R8tyK244UCpWEkxxUdXRmfjJpCboaVzO5MSXHarjnNakm5ngS_Kk6xxA-rkXVVXIc-bSc/s320/trevi2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipeczt_BmYvi89iSdAmpPRyHi3dJSouFdvVCNB8_OsHPW316Rm0Lb9HSA7VsMVSKkxzZqDBsbebZVheSwnEwjCqEPO22zfeP4YK7gGyj9JX11TP6MjmPLzLA4RDn4eZ58Asl87iIo2_90/s1600/trevi3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEipeczt_BmYvi89iSdAmpPRyHi3dJSouFdvVCNB8_OsHPW316Rm0Lb9HSA7VsMVSKkxzZqDBsbebZVheSwnEwjCqEPO22zfeP4YK7gGyj9JX11TP6MjmPLzLA4RDn4eZ58Asl87iIo2_90/s320/trevi3.jpg" width="240" /></a></div>
<div style="text-align: center;">
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><i>Trevi Fountain</i></span></div>
<div style="text-align: left;">
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span></div>
<div style="text-align: left;">
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">We enjoyed some gelato while taking in the fountain.</span></div>
<div style="text-align: left;">
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhguyLDNM_3oo7en8eD8HuqUq8kFLJEvqHOwyoVutl-9iH3Sjk-wAztSY9s-RTMuM2YpY70kzapHUMGqYm6jbq4Eniv93iXdeH07Z_W_43dYu_wCQWb3sNW3FiUpX6gHrxwLaPLkwSOgbk/s1600/gelato.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhguyLDNM_3oo7en8eD8HuqUq8kFLJEvqHOwyoVutl-9iH3Sjk-wAztSY9s-RTMuM2YpY70kzapHUMGqYm6jbq4Eniv93iXdeH07Z_W_43dYu_wCQWb3sNW3FiUpX6gHrxwLaPLkwSOgbk/s320/gelato.jpg" width="320" /></a></div>
<div style="text-align: left;">
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXBXNgb7pk3-BORdIAyqIXtYxlf7FgSSYDlHg31_Jx4RcRLV9AotHUpSCyx_005lic6sgw0zH1Nm8xdj9v-AEuk09lyZzmI4Xa2gqSWVFTqNOkcYOdTz6Bdd0Tp409MFzSHU1tdnDIoDE/s1600/gelato2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="969" data-original-width="727" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXBXNgb7pk3-BORdIAyqIXtYxlf7FgSSYDlHg31_Jx4RcRLV9AotHUpSCyx_005lic6sgw0zH1Nm8xdj9v-AEuk09lyZzmI4Xa2gqSWVFTqNOkcYOdTz6Bdd0Tp409MFzSHU1tdnDIoDE/s320/gelato2.jpg" width="240" /></a></div>
<h3>
<span style="background-color: white; font-family: "roboto"; font-size: small;">Roman Lunch</span></h3>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">We had a group lunch at the Albergo Mediterraneo. It included bread, wine, pasta, veal, espresso, and dessert and was very good.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5TUiKG1_8JumR0Mv6HYLrio_ib-utAMceMGruPIa27GqqtWlznIddMlewHmKu_24tRri5XMQJ-UmAPvY4MTZkiNf6epxl7D7gl6dFjNreSnMaRjMDfxbAJMyIbm2_bOCpOw1fOrkr6no/s1600/lunch1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi5TUiKG1_8JumR0Mv6HYLrio_ib-utAMceMGruPIa27GqqtWlznIddMlewHmKu_24tRri5XMQJ-UmAPvY4MTZkiNf6epxl7D7gl6dFjNreSnMaRjMDfxbAJMyIbm2_bOCpOw1fOrkr6no/s320/lunch1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAkXIBNBuB8ny0e4DvsCTzlUBFvXm8J18Q8aCaqs-_8n_fFPWS-EStAkYXJpVoXC8wH4owtEXEgCr4HfAUqPNUAoXy8Ma6l2GSr8rxqwpQvMJFBYBVi-_SvO9Z6rvlXMFExVZwc_PlI4A/s1600/lunch2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAkXIBNBuB8ny0e4DvsCTzlUBFvXm8J18Q8aCaqs-_8n_fFPWS-EStAkYXJpVoXC8wH4owtEXEgCr4HfAUqPNUAoXy8Ma6l2GSr8rxqwpQvMJFBYBVi-_SvO9Z6rvlXMFExVZwc_PlI4A/s320/lunch2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguGb0DVOegEU-XyEU3QszPKHMYqKp4kWoeZd3xdhHvKsIkzCMwkAnPOCCQT2RDkU90fJJvHVKNnaHKt3dNQ6FJtHXW5yTAzrC-s_ze-e9Q38CxTdFNf02gjwjUCvYh7FZSNPR0KpLmRec/s1600/lunch3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguGb0DVOegEU-XyEU3QszPKHMYqKp4kWoeZd3xdhHvKsIkzCMwkAnPOCCQT2RDkU90fJJvHVKNnaHKt3dNQ6FJtHXW5yTAzrC-s_ze-e9Q38CxTdFNf02gjwjUCvYh7FZSNPR0KpLmRec/s320/lunch3.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0mF7X0ce42CUmOGcv_uk6qrk-KE02KbCgls5EX6BDZ2DvaegRsrCvGC8c2_Y-trOB2FXgw7BzRlJZz6N0TY79d9IOroysaOHWX3FDpVR8iA2sighVceya2FVYQjXLcMe5BfibNkCefcU/s1600/lunch4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi0mF7X0ce42CUmOGcv_uk6qrk-KE02KbCgls5EX6BDZ2DvaegRsrCvGC8c2_Y-trOB2FXgw7BzRlJZz6N0TY79d9IOroysaOHWX3FDpVR8iA2sighVceya2FVYQjXLcMe5BfibNkCefcU/s320/lunch4.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_aP_V_616wbxwpRX9-YB5zU_aZRYpx-BPW9M-3MNdfXT9XoFXEUX-F6eHyhxAeK37sfBpvTQWhDEgE1xnGUXSbcOYhHxRbGbmNJNsrR3FucuIwNBldOOkrrpHdWaKnxgXDRvCmldecyc/s1600/lunch5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_aP_V_616wbxwpRX9-YB5zU_aZRYpx-BPW9M-3MNdfXT9XoFXEUX-F6eHyhxAeK37sfBpvTQWhDEgE1xnGUXSbcOYhHxRbGbmNJNsrR3FucuIwNBldOOkrrpHdWaKnxgXDRvCmldecyc/s320/lunch5.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Nr3L-zROWgL-kw0MyKOV44ByoxZqxA1JtbRo_b0MsR3_gWCbwHrurH8RvLhnTFSn7UM_EuqGyWC5JOPV68c2um7Z2xTnF4_lv_NHbEai04WSr0f7NR2M7fO5eOixe2UUnDxiMgciVpc/s1600/lunch6.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3Nr3L-zROWgL-kw0MyKOV44ByoxZqxA1JtbRo_b0MsR3_gWCbwHrurH8RvLhnTFSn7UM_EuqGyWC5JOPV68c2um7Z2xTnF4_lv_NHbEai04WSr0f7NR2M7fO5eOixe2UUnDxiMgciVpc/s320/lunch6.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Lunch in Rome</i></div>
<h2>
<span style="font-size: large;">
Colosseum</span></h2>
Our next stop wa the Colosseum, one of the "must see" sights in Rome. Just past the Arch of Constantine and ruins of the Forum is the colosseum. The Colosseum is the a great oval amphitheatre whose walls are partly gone. According to Wikipedia it's the largest amphitheatre ever built and could hold 50,000-80,000 spectators.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXEr2sKS9oMsg47uCnL7Ww_5KotQtjqfKWGr1vzCTUPwq-ljFCQMeGWXIfRscSjZuXYHc1o_3Ilf_d8gjZVt1RYnK5g29i9PXzTNgu9HulrfQeSg8SaLD_Yb3SxjXTDGNYMf36ADkQ_mA/s1600/forum1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgXEr2sKS9oMsg47uCnL7Ww_5KotQtjqfKWGr1vzCTUPwq-ljFCQMeGWXIfRscSjZuXYHc1o_3Ilf_d8gjZVt1RYnK5g29i9PXzTNgu9HulrfQeSg8SaLD_Yb3SxjXTDGNYMf36ADkQ_mA/s320/forum1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikv_htdaGM7p-xpRKz47zwlcaeZJm6u9GQTm1HSMsKl3HPKZtyo7CFtIfokOPuCGUEr0JpqJDK9y6dvA6XhXXqAne4lFyBSZPdrVAgLh9pFCKQ7f6gZyLQcp9RfFIBqTmvHrPt1H10POw/s1600/gate1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikv_htdaGM7p-xpRKz47zwlcaeZJm6u9GQTm1HSMsKl3HPKZtyo7CFtIfokOPuCGUEr0JpqJDK9y6dvA6XhXXqAne4lFyBSZPdrVAgLh9pFCKQ7f6gZyLQcp9RfFIBqTmvHrPt1H10POw/s320/gate1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm2o0CvedNXVrz1ciOhbYekk9WWR_q-Nsn147vG6a8PfeL2c4-tm-UvX9r374J-UNK3k_H8gyddjTZQqAXwcADU_c0IzCPR7TRcuc92OSZknRTLOztyJ34vnQdEtyEcUTj9WDx2qQNBCc/s1600/col1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjm2o0CvedNXVrz1ciOhbYekk9WWR_q-Nsn147vG6a8PfeL2c4-tm-UvX9r374J-UNK3k_H8gyddjTZQqAXwcADU_c0IzCPR7TRcuc92OSZknRTLOztyJ34vnQdEtyEcUTj9WDx2qQNBCc/s320/col1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfiw8Kbfy-9qgPUjxtDn9BBeOksZl_OedXU62YolInRkqwWhL0Ai1QVVo5BJ_RCPPTXHxeoi-UwEhW5y0ggE-9TUvi9WL-tPskfnhh-oZaKQW47a63GOry8Ib7LLllFpiNSp0aQr_CMzA/s1600/col2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="230" data-original-width="307" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfiw8Kbfy-9qgPUjxtDn9BBeOksZl_OedXU62YolInRkqwWhL0Ai1QVVo5BJ_RCPPTXHxeoi-UwEhW5y0ggE-9TUvi9WL-tPskfnhh-oZaKQW47a63GOry8Ib7LLllFpiNSp0aQr_CMzA/s1600/col2.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLjjrfRpjHKnkGTwMKmpLTEQu0wq4LS3pdsffjmrOpYbEZsSwbXkOKNUOtJixHBXrIVWx4Ybc4Z0PjQ15QCtsLmzOTgZxcYHOjGK6RX-zjNeC2PBg8JIDwkVcQbaxGO7ke4sYpd5-AgNg/s1600/col3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLjjrfRpjHKnkGTwMKmpLTEQu0wq4LS3pdsffjmrOpYbEZsSwbXkOKNUOtJixHBXrIVWx4Ybc4Z0PjQ15QCtsLmzOTgZxcYHOjGK6RX-zjNeC2PBg8JIDwkVcQbaxGO7ke4sYpd5-AgNg/s320/col3.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_90cy0fzgBZ9_Oq6GcIAnZ0TT7VhojaN_-Xi26gvMnIn5Unv818LPMRjgAvwjjyAEVpHOg1vXvU2ebBUWRhBFaEttK-JTCBlPiw9xEgDDJDnRtcass3QSlC9Xt3kn0WaJCHg8MtsjlGA/s1600/col4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_90cy0fzgBZ9_Oq6GcIAnZ0TT7VhojaN_-Xi26gvMnIn5Unv818LPMRjgAvwjjyAEVpHOg1vXvU2ebBUWRhBFaEttK-JTCBlPiw9xEgDDJDnRtcass3QSlC9Xt3kn0WaJCHg8MtsjlGA/s320/col4.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXf5ZaInVWYijg2qtFAxh9X8qWSdUfHzp0LndyBVipePwuRf8DwWqAC6dt60NjDj1fun3EkkECRGQhytoZv-8NJ6TibX2vmuQzsaW1mUR_fypFUC-_DCN_i7_yngHgmkQxgfRXdcJATsM/s1600/col5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXf5ZaInVWYijg2qtFAxh9X8qWSdUfHzp0LndyBVipePwuRf8DwWqAC6dt60NjDj1fun3EkkECRGQhytoZv-8NJ6TibX2vmuQzsaW1mUR_fypFUC-_DCN_i7_yngHgmkQxgfRXdcJATsM/s320/col5.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>The Colosseum</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Our tour guide was talking fast and was hard-to-understand, unfortunately. After a few talks, we were left to explore on our own. Fortunately, I'd seen enough documentaries on the Colosseum to understand something of its design and history.</div>
<h2 style="clear: both; text-align: left;">
<span style="font-size: large;">Catacombs</span></h2>
<div class="separator" style="clear: both; text-align: left;">
We next saw the catacombs, burial places for Christians used from the 2nd to 5th centuries. Unfortunately, photographs were not permitted. The catacombs are labyrinths of subterranean passages with niches for corpses. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihQSiEfsfsiyYBK_mvaldXeKEGec-jEUDiOWLFs-BxvHKsluvHjwt3_fraMRxroZX3fsQWvY_Ux749qDE7cXTr8FCE-CY1D3HoD6vJDUY_5evIXu3p5-KY0mlnoD-9lqbCPrJ8Juvyx2s/s1600/cat.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihQSiEfsfsiyYBK_mvaldXeKEGec-jEUDiOWLFs-BxvHKsluvHjwt3_fraMRxroZX3fsQWvY_Ux749qDE7cXTr8FCE-CY1D3HoD6vJDUY_5evIXu3p5-KY0mlnoD-9lqbCPrJ8Juvyx2s/s320/cat.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">This place kind of gave me the creeps: there are many tight spaces that give rise to claustrophobia; and one could easily get lost here. It was however nice and cool in contrast to what had otherwise been a very hot day.</span><br />
<h2>
<span style="background-color: white; font-family: "roboto"; font-size: large;">Back on the Ship</span></h2>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">After a fascinating but also a very long day, we returned to the Crown Princess and had dinner in the main dining room. I enjoyed a Roast Beef, Yorkshire Pudding, and Gazpacho. I'd never had Gazpacho beore and I loved it. Becky had roast pork.</span></span><br />
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-8WawNJ9PyB300rYgkNt9AtciEIU94cUzARJvWPGn0NBx7R-WGmu0P1FbUCInozy_PqzzT1R369cpT8nIbEmyHGTUCKe-qzPEzeGtz9kljmBHWla5bVtDHwQZU3cFs4aElSGMGZT-26k/s1600/dinner_roastbeef.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-8WawNJ9PyB300rYgkNt9AtciEIU94cUzARJvWPGn0NBx7R-WGmu0P1FbUCInozy_PqzzT1R369cpT8nIbEmyHGTUCKe-qzPEzeGtz9kljmBHWla5bVtDHwQZU3cFs4aElSGMGZT-26k/s320/dinner_roastbeef.jpg" width="320" /></a></div>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhneN1I14iNYuGVzxRmCaeKKLXAzRJl_mQjPlvULI5s9yRqwStZrYm6mmC0aLK_idzpQLczfGoAfzWnFA6MFLaWciyg7AwP1p5e0XM8TobSdUDIeH_BPewdaznddmccRMplwIWNvKa-ltg/s1600/dinner_gazpachojpg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhneN1I14iNYuGVzxRmCaeKKLXAzRJl_mQjPlvULI5s9yRqwStZrYm6mmC0aLK_idzpQLczfGoAfzWnFA6MFLaWciyg7AwP1p5e0XM8TobSdUDIeH_BPewdaznddmccRMplwIWNvKa-ltg/s320/dinner_gazpachojpg.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLqytvMTYmpUA1XezUSe01WWbZROCj2pxl0z-gjhQuiqSVqBVZq7KPpUBbZWXPyH6XlTck-IYuUQyWlNgIIoDnIljRt51Jf2tTmBMa7unK8aSMv2chX0M4PM82ucbvMsaNBXaeu3Z-48E/s1600/dinner_pork.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLqytvMTYmpUA1XezUSe01WWbZROCj2pxl0z-gjhQuiqSVqBVZq7KPpUBbZWXPyH6XlTck-IYuUQyWlNgIIoDnIljRt51Jf2tTmBMa7unK8aSMv2chX0M4PM82ucbvMsaNBXaeu3Z-48E/s320/dinner_pork.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Eating Well in the Main Dining Room</i></div>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><i><br /></i></span></span>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">Previous: <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-5-florence.html">Part 5: Florence</a></span></span><br />
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">Next: <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-7-pompeii.html">Part 7: Pompeii</a></span></span>
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><br /></span></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-79021601866630028882019-04-20T15:34:00.001-07:002019-04-24T09:22:02.660-07:0025th Anniversary Cruise, Part 5: Florence<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">In </span><a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" style="background-color: white; color: #888888; font-family: Roboto; font-size: 13.2px; text-decoration-line: none;" target="_blank">this series</a><span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"> of posts I'm describing the Mediterranean Cruise my wife Becky and I took in 2018 for our 25th anniversay, Here in Part 5 I'm covering our fifth stop, Florence.</span><br />
<h2>
<span style="font-size: large;"><span style="background-color: white; font-family: "roboto";">Florence (</span><span style="font-family: "roboto";">★★★★)</span></span></h2>
<span style="font-family: "roboto";"><span style="font-size: 13.2px;">Florence is famous for being the birthplace of the Renaissance, without which we'd all be leading significantly more mundane lives. Having to see Florence in a single day is a sin, but it's better than not seeing Florence at all. </span></span><br />
<span style="font-family: "roboto";"><span style="font-size: 13.2px;"><br /></span></span>
<span style="font-family: "roboto";"><span style="font-size: 13.2px;">Our first view of Florence after jumping off the tour bus was exciting, and that feeling continued throughout the day. Every corner we turned had something significant to see, whether it was the natural beauty of Tuscany or a work of architecture. </span></span><br />
<span style="font-family: "roboto";"><span style="font-size: 13.2px;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoIOnQRp1UJ6cJAT6abQiTxsm96DwCrssOLlm0kqVWZ0AgROqz8obi3EXhq5_ruB8H0pXsTJM_wt7eTUUGh5zU86AI_VqXDNMFopCZ0fN2rLbdFYR__cWEaFaCbl4MGPVKfg0CBsWeWHc/s1600/waterfront.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="969" data-original-width="1292" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhoIOnQRp1UJ6cJAT6abQiTxsm96DwCrssOLlm0kqVWZ0AgROqz8obi3EXhq5_ruB8H0pXsTJM_wt7eTUUGh5zU86AI_VqXDNMFopCZ0fN2rLbdFYR__cWEaFaCbl4MGPVKfg0CBsWeWHc/s320/waterfront.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiXiy1DL0pdRG5XfaJZPkc1YMipSlaYtepD7ZPqqr7CpiVnpHM4wR8JfzNYFxQFoZXtZCn_-5e-P1kQkhpW-Isc4pYeHhwy-PHOPvPG-sMSupmiwV38vbyg7SGJXjSEOvi5LBs2y6YUVQ/s1600/church.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiXiy1DL0pdRG5XfaJZPkc1YMipSlaYtepD7ZPqqr7CpiVnpHM4wR8JfzNYFxQFoZXtZCn_-5e-P1kQkhpW-Isc4pYeHhwy-PHOPvPG-sMSupmiwV38vbyg7SGJXjSEOvi5LBs2y6YUVQ/s320/church.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFQeCuiYmnJBLZp7Y7Lp7lGFafEkb0D5j9wQykoGuZBAbRNhP00RG1sFTHKPlQTjQSpGH9SMJlyCvVZW8zZYUTeZN7HNbOmK6BS7FmaxPckAOTb8KDOxsUwYKdHKDTnhG0b1vfKD928oI/s1600/alley.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFQeCuiYmnJBLZp7Y7Lp7lGFafEkb0D5j9wQykoGuZBAbRNhP00RG1sFTHKPlQTjQSpGH9SMJlyCvVZW8zZYUTeZN7HNbOmK6BS7FmaxPckAOTb8KDOxsUwYKdHKDTnhG0b1vfKD928oI/s320/alley.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiarrsLgp4CF2AwARwu3mraiUMcnRdlxG4mNMBbTP7kUrJ_oWNm9E9aLDbtda-VSN-T6TxZskT6v1ks9Ctys0fVKAb-WXsAfwGjVuI_JzIbf2IIhkEcXkD7-jloIskFaoFqGceOEp5epDk/s1600/door.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiarrsLgp4CF2AwARwu3mraiUMcnRdlxG4mNMBbTP7kUrJ_oWNm9E9aLDbtda-VSN-T6TxZskT6v1ks9Ctys0fVKAb-WXsAfwGjVuI_JzIbf2IIhkEcXkD7-jloIskFaoFqGceOEp5epDk/s320/door.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Walking through Florence</i></div>
<h2 style="clear: both; text-align: left;">
Uffizi Gallery</h2>
<div class="separator" style="clear: both; text-align: left;">
The Uffizi Gallery is one of the most important art museums in the world. It is crammed full of a massive amount of art. We unfortunately had a short time here, and as our tour guide whisked us from one room to the next I knew that for each masterpiece we were shown there were 100 we had to skip past. It also didn't help that every single person in there was trying to take pictures at the same time. It is nicely arranged so that you can see the progression of art styles over time.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq-zFp99AireQPx3gNOUKegiHCLpF73RuWgBfOH_4a6OipFF0m5SOW6HGKxO_VTjfQ6ogUX5iALtRCei_vTSmzDaboZ6jFTl2Aw4djYApecSlSmSVOhDf-7F4sw8NMKO-boXoFrh_xWhU/s1600/art1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq-zFp99AireQPx3gNOUKegiHCLpF73RuWgBfOH_4a6OipFF0m5SOW6HGKxO_VTjfQ6ogUX5iALtRCei_vTSmzDaboZ6jFTl2Aw4djYApecSlSmSVOhDf-7F4sw8NMKO-boXoFrh_xWhU/s320/art1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzkquXrmZ2DxfFu-qdbRjh_PVh6ENeS9h8r-Pf2aj9zUWwZnE4l8tigpNwV6Oh0b0j-ZttfTB8rNUI16h5RlWiCXB0g07hiqVub3N7giLnyhdx6UDoLre1ugD8WvWXVwnjq-3VBQduqGY/s1600/art2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzkquXrmZ2DxfFu-qdbRjh_PVh6ENeS9h8r-Pf2aj9zUWwZnE4l8tigpNwV6Oh0b0j-ZttfTB8rNUI16h5RlWiCXB0g07hiqVub3N7giLnyhdx6UDoLre1ugD8WvWXVwnjq-3VBQduqGY/s320/art2.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwjFlYoM2uE7yXS10yvhkt-vcHmIKLxwsCysIyXG9xzWn8JG-HHux_CrYCDm5OjDgcOegQIGvKoABtgq8E-9Icb5u2snnSHABIfiS7kcEjnsChnShkNokE1EycGAtOVnhLtE-Nv-h3ckA/s1600/bust.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwjFlYoM2uE7yXS10yvhkt-vcHmIKLxwsCysIyXG9xzWn8JG-HHux_CrYCDm5OjDgcOegQIGvKoABtgq8E-9Icb5u2snnSHABIfiS7kcEjnsChnShkNokE1EycGAtOVnhLtE-Nv-h3ckA/s320/bust.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIlGkNG_61KxPPrduhekPpDPsM3m1SAB7S3QUzmHvK-i3SXUsL30iCMKktU26D7IOKB-gTZoYI4cpcA6xCL_ITHaKW3bldRQXHkFaJ5GYBRjwooy0-n7MVPS3yU7yU132nVZe4Yv-k_T0/s1600/sculpt1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIlGkNG_61KxPPrduhekPpDPsM3m1SAB7S3QUzmHvK-i3SXUsL30iCMKktU26D7IOKB-gTZoYI4cpcA6xCL_ITHaKW3bldRQXHkFaJ5GYBRjwooy0-n7MVPS3yU7yU132nVZe4Yv-k_T0/s320/sculpt1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh__ySD7r0hSxiH5YeP7a1joyHFB1WFFYhVzfrFNiDCo7y3-DayeUvxS9yOmZofVsJogVI4BNgBEXbFlIhsTN3k2z3VbHEOWBnfVrmp4X2CIJYa52pHSdozGEsPlsKFxt5yaeJxdnuNqHM/s1600/lorenzo.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh__ySD7r0hSxiH5YeP7a1joyHFB1WFFYhVzfrFNiDCo7y3-DayeUvxS9yOmZofVsJogVI4BNgBEXbFlIhsTN3k2z3VbHEOWBnfVrmp4X2CIJYa52pHSdozGEsPlsKFxt5yaeJxdnuNqHM/s320/lorenzo.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Statue of Lorenzo the Magnificent, Patron of Renaissance Culture</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
If I ever have the opportunity to return to Florence, I'd want to spend a lot more time here. Even as we were being whisked own corridors, I realized that even the ceiling above our heads were covered in artwork</div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6P4Q9w-aRCYrX647BGq9uMe412GCxtaGjcLatl3eMWNBuQn5LkFqFHuxqVHIipgpoyESq6BEIxlcPAaube_15Isn2opb1YoT8ynb8NXDy70DzlIddFUY5zR90R9FbT5-vOf0hmaP0K6Y/s1600/uffizi-corridor-ceiling.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi6P4Q9w-aRCYrX647BGq9uMe412GCxtaGjcLatl3eMWNBuQn5LkFqFHuxqVHIipgpoyESq6BEIxlcPAaube_15Isn2opb1YoT8ynb8NXDy70DzlIddFUY5zR90R9FbT5-vOf0hmaP0K6Y/s320/uffizi-corridor-ceiling.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRgVPjamU7oN1a3LV51c_-1FJO0ywQIX8CUU7cMSgOEOC-HU7MryUDtOJoyTw40jFjEBwnFKdDy9hn-9BP4C6A4ELMrhv5zaGPaKxCAwR3J9CNtEpBRAbEZ5DdQ6WtRpjxB_Qrd37dJdk/s1600/ceiling.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRgVPjamU7oN1a3LV51c_-1FJO0ywQIX8CUU7cMSgOEOC-HU7MryUDtOJoyTw40jFjEBwnFKdDy9hn-9BP4C6A4ELMrhv5zaGPaKxCAwR3J9CNtEpBRAbEZ5DdQ6WtRpjxB_Qrd37dJdk/s320/ceiling.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Serious Art</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Some of the key works in the Uffizi Gallery are from Botticelli, Da Vinci, Michelangelo, and Rafael. In particular I remember The Birth of Venus by Botticelli.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh54O3otMI7F-j3DNBvhEb4BW69tJXB_RinnR70R6OAQZDxYIz93DYJl-C_tcgbgTRuEAssRQM7KEFaj2pmIf9mQpIijGAMmlBg0gIOC75LlDkJfC-PpxO7m_bToEw4zPjM4QNrw_j5_Ro/s1600/birth_of_venus.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh54O3otMI7F-j3DNBvhEb4BW69tJXB_RinnR70R6OAQZDxYIz93DYJl-C_tcgbgTRuEAssRQM7KEFaj2pmIf9mQpIijGAMmlBg0gIOC75LlDkJfC-PpxO7m_bToEw4zPjM4QNrw_j5_Ro/s320/birth_of_venus.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>The Birth of Venus</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The best city shot of Florence I got was actually looking out the window from one of the floors of the Uffizi gallery: </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhjgt6m2ZJ8-GVvXP2vCmhZlYBLpYIKmDeUgMAfNO14CqrIJsXQ40jfdNC0gifOghpCWbXABLD42JuMWGlcSKzmeCIyGbTArKmep6uySfRVRREtfp15BbSXPACGcI5IAWKp5lKFEdzQMw/s1600/florence_bridges.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhjgt6m2ZJ8-GVvXP2vCmhZlYBLpYIKmDeUgMAfNO14CqrIJsXQ40jfdNC0gifOghpCWbXABLD42JuMWGlcSKzmeCIyGbTArKmep6uySfRVRREtfp15BbSXPACGcI5IAWKp5lKFEdzQMw/s320/florence_bridges.jpg" width="240" /></a></div>
<h2 style="clear: both; text-align: left;">
Piazza della Signoria</h2>
<div class="separator" style="clear: both; text-align: left;">
The Uffizi Gallery is adjacent to the Piazza della Signoria, the historic center of Florence. This was a marvelous place to look about and take in the essence of Florence. We enjoyed espresso there.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiO4UpffP8xen9hSbIcrUHVi612c8PfyJ6tR0AAg0RGKpO6OOfsJozntX7xo1j7o2-RQ3OWD5jk5cLDxBuJWjaHxXwM3kJZJK9eeLsCtKhlgY3JzUUDkWgTTjoPGzKymH89aHJbAYUaK0/s1600/piazza1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhiO4UpffP8xen9hSbIcrUHVi612c8PfyJ6tR0AAg0RGKpO6OOfsJozntX7xo1j7o2-RQ3OWD5jk5cLDxBuJWjaHxXwM3kJZJK9eeLsCtKhlgY3JzUUDkWgTTjoPGzKymH89aHJbAYUaK0/s320/piazza1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivNDktI6hjFiWH5eriGZi5zmECO8arPi0MbMaV8VLCE6CBlC610JU1mRvFMjh5oeymapIXvYx2U5KUmMnb0U-h9fyCa0C-4shkTVAYUdwfFDaPRMn792SUAuHhc4MPagaXD6JrdPdBhAs/s1600/piazza2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivNDktI6hjFiWH5eriGZi5zmECO8arPi0MbMaV8VLCE6CBlC610JU1mRvFMjh5oeymapIXvYx2U5KUmMnb0U-h9fyCa0C-4shkTVAYUdwfFDaPRMn792SUAuHhc4MPagaXD6JrdPdBhAs/s320/piazza2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhahGYfrJ1BNzjSaCSMZXHZGwdtRgU0gBliuq1ph8iqbWrn3KLuL-k_GoHpshl6p8KGGKJzEuXSzULrA-AopaSDsURo2R_u94XQyAXF1puNpXnKzoCmdPyF10DjU_d0JpZdIh9K9bsaN0c/s1600/piazza3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhahGYfrJ1BNzjSaCSMZXHZGwdtRgU0gBliuq1ph8iqbWrn3KLuL-k_GoHpshl6p8KGGKJzEuXSzULrA-AopaSDsURo2R_u94XQyAXF1puNpXnKzoCmdPyF10DjU_d0JpZdIh9K9bsaN0c/s320/piazza3.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwYyW0fc4uM3dRqjdld8OI1pNygkyDYh2kKzgUlsNeR-1KK88Kxj32iBoRniN5U0U1ggNT5U9DeWhivIFORV5hW7Tm4sv-hpQLRlKkPSOQteYxpPUVKOI-BSCFHBKHYYp_0PHITA1u8yQ/s1600/piazza4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhwYyW0fc4uM3dRqjdld8OI1pNygkyDYh2kKzgUlsNeR-1KK88Kxj32iBoRniN5U0U1ggNT5U9DeWhivIFORV5hW7Tm4sv-hpQLRlKkPSOQteYxpPUVKOI-BSCFHBKHYYp_0PHITA1u8yQ/s320/piazza4.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Piazza della Signoria</i></div>
<h2 style="clear: both; text-align: left;">
Lunch</h2>
<div class="separator" style="clear: both; text-align: left;">
Once again a chance to eat Italian food in Italy! Our tour included lunch as a group at Osteria dei Baroncelli, right around the corner from the Uffizi Gallery. The restuarant had an ornate interior, fitting for its location. Lunch included bread, wine, a pasta starter (enthusiastically served family style from the largest serving bowl I have ever seen), veal, salad, and Tiramisu. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrUK5uc4IEaHKPyCefXSOer_-yp4v5xcxbPJfsu_3c9_mdiNPt2oa5nkFajVkusdrGsEM7XHnARQjt2hr_5iEHZ6v38y58c2ZBgtdjrB5IcD-Z4kKIdKSoNp8VGjxXrpH-X66WO-EXC3M/s1600/osteria.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrUK5uc4IEaHKPyCefXSOer_-yp4v5xcxbPJfsu_3c9_mdiNPt2oa5nkFajVkusdrGsEM7XHnARQjt2hr_5iEHZ6v38y58c2ZBgtdjrB5IcD-Z4kKIdKSoNp8VGjxXrpH-X66WO-EXC3M/s320/osteria.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU5wd3pbM6V2nhOYQxLSTGn2A9wCj2OsV2pKNdKxi-K4XcbzzdS5S1RXBjqPG9toCRBhhJECAFqZhmOBJ9tRt1CrP5g3NzMCMe-wmbA4725xtiQzORrhtPDOriZCDLlvQU1wFlDfzRvjI/s1600/lunch1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU5wd3pbM6V2nhOYQxLSTGn2A9wCj2OsV2pKNdKxi-K4XcbzzdS5S1RXBjqPG9toCRBhhJECAFqZhmOBJ9tRt1CrP5g3NzMCMe-wmbA4725xtiQzORrhtPDOriZCDLlvQU1wFlDfzRvjI/s320/lunch1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDVvPJH55xF6vUks7Xrd8YJFZe7HjEmWuGiVAI-2fUynt_hdT59jvOsrll-Y0zSCd5dIEC-iQSHvLhImvBO2IwnNHZbFJUs_IDx9ZIqSWp4FeYnPutGmYKwEW9WKzu7Aw-_-eND3t5lbQ/s1600/lunch2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDVvPJH55xF6vUks7Xrd8YJFZe7HjEmWuGiVAI-2fUynt_hdT59jvOsrll-Y0zSCd5dIEC-iQSHvLhImvBO2IwnNHZbFJUs_IDx9ZIqSWp4FeYnPutGmYKwEW9WKzu7Aw-_-eND3t5lbQ/s320/lunch2.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbNrmA1DN6yTnTVXwSjRLUmeb7dZki0oInKjm8_vmsdNQadENsA4p-1Z8FFsDbQSR6hhDFe-arnieCijVR1E0_VLVRb_cPe3qFt1J3LC2O7M2vCr7qJkktkiaYKBFvgyBZubpTcxK1Iwo/s1600/lunch3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbNrmA1DN6yTnTVXwSjRLUmeb7dZki0oInKjm8_vmsdNQadENsA4p-1Z8FFsDbQSR6hhDFe-arnieCijVR1E0_VLVRb_cPe3qFt1J3LC2O7M2vCr7qJkktkiaYKBFvgyBZubpTcxK1Iwo/s320/lunch3.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikrlX66BQayet0R5N7TC1bpKNxV96ypzVLLDWxdj0prvRUb5KJ7yZaHgMkWgNCI-q_ogv3ws7LmcZv1AUSIKyZG_FKMCLtJs6Lq3-ce7wFT9SrVTpndzb8z_rLo0Y8GJovIwm2cYn6oxc/s1600/lunch4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikrlX66BQayet0R5N7TC1bpKNxV96ypzVLLDWxdj0prvRUb5KJ7yZaHgMkWgNCI-q_ogv3ws7LmcZv1AUSIKyZG_FKMCLtJs6Lq3-ce7wFT9SrVTpndzb8z_rLo0Y8GJovIwm2cYn6oxc/s320/lunch4.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHsxUt3puCPC8xHhHbs7DIJng1M3GDFULAVakG7tGLlrrlg7DlNeEsMeeIaKLxT0-_M3Venpm2LfGEVi3iz9Cmva_86t2m7gxk1-tACZKYQrFpngD53i21-8cCPVhoaMHabSBNcHyjfvs/s1600/lunch5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHsxUt3puCPC8xHhHbs7DIJng1M3GDFULAVakG7tGLlrrlg7DlNeEsMeeIaKLxT0-_M3Venpm2LfGEVi3iz9Cmva_86t2m7gxk1-tACZKYQrFpngD53i21-8cCPVhoaMHabSBNcHyjfvs/s320/lunch5.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>A Delicious Italian Lunch</i></div>
<h2 style="clear: both; text-align: left;">
Walk Across Florence</h2>
<div class="separator" style="clear: both; text-align: left;">
The other art gallery on our itinerary was the Accademia, where Michalangelo's David is housed—but that's quite some distance away. We walked across Florence for what felt like miles; inspiring sights to see, but also hot and tiring.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2PbMe5k7pmEKhrLrSQ9QJLl2agm0-gh1mgLDIXqcbDU6YdTclS5M8EJpJxq1ZXt7EP90SU09ayueotZN5vSLDl6vRbKsuDLDFXx3HNJmNpu-7VWLfjWrvpdlMGT7tuoT-xsvRwQ9sri4/s1600/walk1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj2PbMe5k7pmEKhrLrSQ9QJLl2agm0-gh1mgLDIXqcbDU6YdTclS5M8EJpJxq1ZXt7EP90SU09ayueotZN5vSLDl6vRbKsuDLDFXx3HNJmNpu-7VWLfjWrvpdlMGT7tuoT-xsvRwQ9sri4/s320/walk1.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4IFj1taxOlZjvf-XSaAjyNrpKds5MaCgzcaao-IPNNi9bK62mdyFVHiPDfI0XW0KEp0LeW-t60Ly1TcO-IRh13cxFtJ8wrg4MnaolTnMm-slpdBJnHXx851M7cgx0i4ugd31P1XPvRfw/s1600/walk2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4IFj1taxOlZjvf-XSaAjyNrpKds5MaCgzcaao-IPNNi9bK62mdyFVHiPDfI0XW0KEp0LeW-t60Ly1TcO-IRh13cxFtJ8wrg4MnaolTnMm-slpdBJnHXx851M7cgx0i4ugd31P1XPvRfw/s320/walk2.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>The Long March across Florence</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
On the way, we saw the Duomo from the outside. The dome is a familiar symbol of Florence, but I hadn't realized the dome was part of a much larger structure, a majestic cathedral building.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRoZ110GQ4V79aRU1hNwfVhusZ_xGxETloVOJMCMxPE0KbXm_qQWjTLkjzOaan2fwZu1Gx-adbM9kWzE1NoHti0CkRMNI1w3HSv5QPIbxpDgNscqOUJNlIau7pNrOUvVVuZn4uB4LjboI/s1600/duomo1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRoZ110GQ4V79aRU1hNwfVhusZ_xGxETloVOJMCMxPE0KbXm_qQWjTLkjzOaan2fwZu1Gx-adbM9kWzE1NoHti0CkRMNI1w3HSv5QPIbxpDgNscqOUJNlIau7pNrOUvVVuZn4uB4LjboI/s320/duomo1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheKN6k367x8FX8nmB3veRYGVi3eQm52Jpqk2uO56fR99_r6mXGajtmva8asc0dGUMyRndLvzYQUWJr4Q5K4bsa43Kxr3nD0SXEBkiRjlj_kNd9uZgVlX_BGjWMoZL0tlU27DhSuakG3XY/s1600/duomo2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheKN6k367x8FX8nmB3veRYGVi3eQm52Jpqk2uO56fR99_r6mXGajtmva8asc0dGUMyRndLvzYQUWJr4Q5K4bsa43Kxr3nD0SXEBkiRjlj_kNd9uZgVlX_BGjWMoZL0tlU27DhSuakG3XY/s320/duomo2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ4VbBV5aGBbjDAhugODRxrJB57F8KV2HccHhYjJqrf7KlLv35YriTtTzt1r1rXRFwWkmaPhRjljWcnLcOJI5hKoFBVuFQIUDefMXAaa7hYc6ct4-GEx8hivJ9sa-4PFURQISdbjJD0ag/s1600/duomo3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJ4VbBV5aGBbjDAhugODRxrJB57F8KV2HccHhYjJqrf7KlLv35YriTtTzt1r1rXRFwWkmaPhRjljWcnLcOJI5hKoFBVuFQIUDefMXAaa7hYc6ct4-GEx8hivJ9sa-4PFURQISdbjJD0ag/s320/duomo3.jpg" width="320" /></a></div>
<i>Duomo</i><br />
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We also saw the Florence Baptistery, with bronze doors by Lorenzo Ghiberti containing detailed Old Testament scultures. Michelango called them "The Gates of Paradise."</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSXrTyRam278K-ocCl2ZzG0Q_HJ7O7xPM2V7b2RGOrpVdJ-Vpzcw6P0ecg8KqJVnY7ueIlJCGOt8u4CYL5PMj9yP4xsqw_xOHvGhmQ2yKALmZzmnFU5sSHprslNesBi5w7fu5bDB8KASI/s1600/baptistery.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiSXrTyRam278K-ocCl2ZzG0Q_HJ7O7xPM2V7b2RGOrpVdJ-Vpzcw6P0ecg8KqJVnY7ueIlJCGOt8u4CYL5PMj9yP4xsqw_xOHvGhmQ2yKALmZzmnFU5sSHprslNesBi5w7fu5bDB8KASI/s320/baptistery.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWhChnNqkVAsKTGiEj6suRd8rF4BKeije5pi8cYGAH8lF3kFIiDEdglc_8ZuZv4_eqSDYJmDZPok_8K0SVW4brsndoVcenOhcHSZP-sZKLnfeBnbq98Q57A-Ym6WF4a2LnVZ8w3llsPg8/s1600/gates_of_paradise.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhWhChnNqkVAsKTGiEj6suRd8rF4BKeije5pi8cYGAH8lF3kFIiDEdglc_8ZuZv4_eqSDYJmDZPok_8K0SVW4brsndoVcenOhcHSZP-sZKLnfeBnbq98Q57A-Ym6WF4a2LnVZ8w3llsPg8/s320/gates_of_paradise.jpg" width="240" /></a></div>
<i>The Gates of Paradise</i><br />
<h2 style="clear: both; text-align: left;">
Accademia</h2>
<div class="separator" style="clear: both; text-align: left;">
Finally we made it to the other art gallery, the Accademia. This gallery contains major works from Michelangelo included his statue David. The status was originally in the Piazza della Signoria where a replicate still stands, but the original was moved to the gallery in order to protect it.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRI_xkjc-xhyphenhyphenMzaQwvphKcoFf_cuJLyWKvc-stQIJKGUfPeDtPX_92qe-Vfab9bEQEAuwqSE8SM16KCPyoudhA5BHkqRUyupAzO0fvpxKgFbr8aug6LIPG8Jv5-3NZEY9fFHjmNbvEkA/s1600/acc1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfRI_xkjc-xhyphenhyphenMzaQwvphKcoFf_cuJLyWKvc-stQIJKGUfPeDtPX_92qe-Vfab9bEQEAuwqSE8SM16KCPyoudhA5BHkqRUyupAzO0fvpxKgFbr8aug6LIPG8Jv5-3NZEY9fFHjmNbvEkA/s320/acc1.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvY64PfLGXopwK2wxnz-ynpJfvO0idLXA6ZgN9OCcqBCB76rKACB0ozvQ38ihbcr6NUBgWMGv0rW1YgN2butobqLzM8DMOEif0IZkZo5924-SyXDPKtXZqQFdmZDlQDiERrXk0TVtTcrE/s1600/acc2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvY64PfLGXopwK2wxnz-ynpJfvO0idLXA6ZgN9OCcqBCB76rKACB0ozvQ38ihbcr6NUBgWMGv0rW1YgN2butobqLzM8DMOEif0IZkZo5924-SyXDPKtXZqQFdmZDlQDiERrXk0TVtTcrE/s320/acc2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhB1giQKdRXV9LtujfutmXPMs-QrCdfDZe15oEZqiQUcvWz4ZQtHwJ6O1Hu5xjWAdfZnCXRFWT1TdjJSf-iJ5aTTjzhMFPtLGrFtPCqLFEy-atjWyj5BO2gGPwELYdbchrvExPFom2NQk/s1600/acc3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhB1giQKdRXV9LtujfutmXPMs-QrCdfDZe15oEZqiQUcvWz4ZQtHwJ6O1Hu5xjWAdfZnCXRFWT1TdjJSf-iJ5aTTjzhMFPtLGrFtPCqLFEy-atjWyj5BO2gGPwELYdbchrvExPFom2NQk/s320/acc3.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg45w0NDMz1Y9VbexwBurbqBlCpL1fAgznoNF6MQynG27wtQ-BHkHeCBeVKMtx9vf-E4dZUhDUheDRjufveDeD5xDs44Zc0jYxohJ1tXw6aT3qAKLu3fdYxcDiSSqptg_LRfneG7Kbo9WU/s1600/acc4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg45w0NDMz1Y9VbexwBurbqBlCpL1fAgznoNF6MQynG27wtQ-BHkHeCBeVKMtx9vf-E4dZUhDUheDRjufveDeD5xDs44Zc0jYxohJ1tXw6aT3qAKLu3fdYxcDiSSqptg_LRfneG7Kbo9WU/s320/acc4.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Art by Michelango</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The biggest draw in the gallery is of course the David statue. An awful lot of people were perpetually surrounding the statue, including art students.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmCrvCPFQjfUsiGaf9xrJ-MhyS5I5_bedaBjwIwFfA6-5QgHPyjh5-WeC4DcBumYgOnZPwe42URoXvDwZfUxMzbCb4UFKy2sFcO_dVG_1MiEF9oD5SLCbF2Z0K18Ina0kmtazCFFKL42w/s1600/david1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmCrvCPFQjfUsiGaf9xrJ-MhyS5I5_bedaBjwIwFfA6-5QgHPyjh5-WeC4DcBumYgOnZPwe42URoXvDwZfUxMzbCb4UFKy2sFcO_dVG_1MiEF9oD5SLCbF2Z0K18Ina0kmtazCFFKL42w/s320/david1.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivfLzdzzICPQyaPU1Q2wg6grKKPGGJ8D_s-MfOC66d4LAV251ZM3tXQdNjcUtS1_p6wqnUlxtYxqxHxgLTJhQ46frXzHORimym22n-ZdtoDiTvrU1KsGf-MP7W-jwzpKk-TZwbiGwUytY/s1600/david2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivfLzdzzICPQyaPU1Q2wg6grKKPGGJ8D_s-MfOC66d4LAV251ZM3tXQdNjcUtS1_p6wqnUlxtYxqxHxgLTJhQ46frXzHORimym22n-ZdtoDiTvrU1KsGf-MP7W-jwzpKk-TZwbiGwUytY/s320/david2.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkET7jCww7PU5nwcYmVs35_PtCEv2UAWIbWtDJslK9VvwVuLhurZMlWdiLOsNqyUDizk4aM18vYQT1HKwZg9gZUMzLqkoiRiMG0HefpTcsipnNLM0xdftFemwyviGcquTTQCOC7aUeGho/s1600/david3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjkET7jCww7PU5nwcYmVs35_PtCEv2UAWIbWtDJslK9VvwVuLhurZMlWdiLOsNqyUDizk4aM18vYQT1HKwZg9gZUMzLqkoiRiMG0HefpTcsipnNLM0xdftFemwyviGcquTTQCOC7aUeGho/s320/david3.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>David</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Florence was a wonderful place to visit, and we give it 4 stars. We really wished we had more time there.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Previous: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-4-portofino.html" target="_blank">Part 4: Portofino</a></div>
<div class="separator" style="clear: both; text-align: left;">
Next: <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversay-cruise-part-6-rome.html">Part 6: Rome</a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-6352125299760364332019-04-20T14:04:00.001-07:002019-08-10T12:50:41.969-07:0025th Anniversary Cruise, Part 4: Portofino<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">In </span><a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" style="background-color: white; color: #888888; font-family: Roboto; font-size: 13.2px; text-decoration-line: none;" target="_blank">this series</a><span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"> of posts I'm describing the Mediterranean Cruise my wife Becky and I took in 2018 for our 25th anniversay, Here in Part 4 I'm covering our fourth stop, Genoa--where we took an excusion to Portofino.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">The excusion we <u>really</u> wanted to take is to the Cinque Terre (or "5 lands"), a picturesque collection of towns on the coastline of the Italian Riviera. But that excursion was a long 10 hours, and it would be back-to-back with long hot days ahead in Florence, Rome, and Pompeii. We weren't sure we'd hold up, so we opted for a short half-day excursion to Portofino instead. I'd been to Italy before, but only en-route to somewhere else. This was my first opportunity to really see Italy.</span><br />
<h2>
<span style="background-color: white; font-family: "roboto"; font-size: large;">Portofino (★★★)</span></h2>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Portofino is a small fishing village on the Italian Riviera south of Genoa. I already used the word picturesque, but there's no better word. Portfofino is just a marvelously scenic place. It's not very big, and there's really nothing to do there except walk around and eat at a cafe--but we're really glad we went. Just being in such a beautiful place makes you feel good</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">To get there we took a tour bus to Santa Margharita, itself a lovely place.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEutvGrW0zDza4rpy-qoCISVfcs-_92N_uOhgAu4Wc6CuprD_JkC48tPajrcQQS8_yfW5X60dY19Zs-G_8CkCYwPk4fF6Bn5e-bT9mnmMT_xb-yme7gEt8DdBDy8ae3_nQl13ZiKUPeS8/s1600/santa1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="969" data-original-width="1292" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEutvGrW0zDza4rpy-qoCISVfcs-_92N_uOhgAu4Wc6CuprD_JkC48tPajrcQQS8_yfW5X60dY19Zs-G_8CkCYwPk4fF6Bn5e-bT9mnmMT_xb-yme7gEt8DdBDy8ae3_nQl13ZiKUPeS8/s320/santa1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhECxcklD7FlYwSCBcs2PhUv4gRMKV7TcsE3IKXEUnjORMSyGB6c47cEjXSTIOaokU_ujkAasbuH8QNOGwqwp3oF4rpf9bJRk9-9ANBk7de1QkWpKw9II_1JBF6LEwI99fPhKenvIF93BA/s1600/santa2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhECxcklD7FlYwSCBcs2PhUv4gRMKV7TcsE3IKXEUnjORMSyGB6c47cEjXSTIOaokU_ujkAasbuH8QNOGwqwp3oF4rpf9bJRk9-9ANBk7de1QkWpKw9II_1JBF6LEwI99fPhKenvIF93BA/s320/santa2.jpg" width="320" /></a></div>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Becky was feeling the heat and bought a hat from a local young man who I'm sure charged us 4 times what they were worth. </span><span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">From here we boarded a ferry which took to us to Portofino. Portofino means "Port of the Dolphin", but we didn't see any dolphins.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD1Gu2COOQ3wygfCdS51d-jS5kq8QOO_Ay7ukaRDecB4zZuVJRG8wP9aUxcAtcydtGYol3fBwUOT44QqezU1l1-YXkU42Ck2VEku_saFy9jEHDPoCX3ac7eGfdVBJd8ysu-LwlcC2wyUI/s1600/ferry1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjD1Gu2COOQ3wygfCdS51d-jS5kq8QOO_Ay7ukaRDecB4zZuVJRG8wP9aUxcAtcydtGYol3fBwUOT44QqezU1l1-YXkU42Ck2VEku_saFy9jEHDPoCX3ac7eGfdVBJd8ysu-LwlcC2wyUI/s320/ferry1.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8tm-0h4ZStZuTW4JRlXoTVO_Y5FMut-zrQF9WYH0azoI9kl1QgETgN4k152TADPUGX4oN2U7NEDcIRhfV47yy0RljqrPbr_B0-KVb7yiLvNR95pCs3tKK8YIxPF9DX_0IClJSXgKrNu0/s1600/ferry2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi8tm-0h4ZStZuTW4JRlXoTVO_Y5FMut-zrQF9WYH0azoI9kl1QgETgN4k152TADPUGX4oN2U7NEDcIRhfV47yy0RljqrPbr_B0-KVb7yiLvNR95pCs3tKK8YIxPF9DX_0IClJSXgKrNu0/s320/ferry2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLAaagxz4O1tMoqIhzkL1LUII5p3jfDN5b1Ex4H_EccxLtiJzNYsrllEVKLlzaLPcU0aoG3jQU96bxMtRqMrrG02cVxzQwUsx91NqJmqOCQt2oDhAGSoydcGDv1H3NnM4Vdmx8ZKsX2Tc/s1600/ferry3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLAaagxz4O1tMoqIhzkL1LUII5p3jfDN5b1Ex4H_EccxLtiJzNYsrllEVKLlzaLPcU0aoG3jQU96bxMtRqMrrG02cVxzQwUsx91NqJmqOCQt2oDhAGSoydcGDv1H3NnM4Vdmx8ZKsX2Tc/s320/ferry3.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Riviera on the way to Portofino</i></div>
<br />
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;">As we entered Portofino harbor, the <i>picuresqueness </i>of the place is apparent to all.</span></span><br />
<span style="font-family: "roboto";"><span style="background-color: white; font-size: 13.2px;"><br /></span></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic5pElp68cx_HNFtL3j_Mwqi_a_hTxRWt35tkMnNBRbyOAvopMurjfYXdOB282b13BJAEmE5Dp93-7ZHeghLiwmZR-N4DBLIuANptPI6w5Lj9mb_MpZEBPGhqDjlkwteaAJHxU77PePL8/s1600/porto1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEic5pElp68cx_HNFtL3j_Mwqi_a_hTxRWt35tkMnNBRbyOAvopMurjfYXdOB282b13BJAEmE5Dp93-7ZHeghLiwmZR-N4DBLIuANptPI6w5Lj9mb_MpZEBPGhqDjlkwteaAJHxU77PePL8/s320/porto1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixZ8IvJR2AMKbwddzwBG6v9ULhrOFcrR7SxDah7VhbrxmdSEFKrEGVel5BWm1BUymEcKVfj0hQgIPXSIuUe1l4IWlZYHey1dCRF-oosjMDy_Iw0TtI1Sw6F7RJfjFnPrH9pBi1-W_U-Zo/s1600/porto2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEixZ8IvJR2AMKbwddzwBG6v9ULhrOFcrR7SxDah7VhbrxmdSEFKrEGVel5BWm1BUymEcKVfj0hQgIPXSIuUe1l4IWlZYHey1dCRF-oosjMDy_Iw0TtI1Sw6F7RJfjFnPrH9pBi1-W_U-Zo/s320/porto2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4aIhFZ_wUhJKue-A0n59zyFKKBSg7pFbJGYqzzTSB0vLsYWbZnO5RiO7cH5Yv8ji5f1e-m8IwUOUS5nxalh_kVw2rzVulMrqh0uCn9RJ4ce2UvWs_TXa1BSCC9GAiiG0ygjEySNWQMtw/s1600/porto3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4aIhFZ_wUhJKue-A0n59zyFKKBSg7pFbJGYqzzTSB0vLsYWbZnO5RiO7cH5Yv8ji5f1e-m8IwUOUS5nxalh_kVw2rzVulMrqh0uCn9RJ4ce2UvWs_TXa1BSCC9GAiiG0ygjEySNWQMtw/s320/porto3.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Portofino Harbor</i></div>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">And then there are the yachts. Portofino is a playground for the rich and famous, so you'll see big yachts. Next to even bigger yachts. Next to even bigger yachts. But also many small boats.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcn7i4YUF2x7IcEkIY2jRgYrVZFpDWaG6oEMk6EqnRxro_N8EWitSUFVKp8YulTpV5bevTqcZzzWyX4XHjOL08wttrMy2Sfjed3OMN3zjK4ddr-vgbbQ3Hff_XS3nPaml09Y6VgoaTUlw/s1600/yacht.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhcn7i4YUF2x7IcEkIY2jRgYrVZFpDWaG6oEMk6EqnRxro_N8EWitSUFVKp8YulTpV5bevTqcZzzWyX4XHjOL08wttrMy2Sfjed3OMN3zjK4ddr-vgbbQ3Hff_XS3nPaml09Y6VgoaTUlw/s320/yacht.jpg" width="320" /></a><i><br />Yacht-zee</i></div>
<div class="separator" style="clear: both; text-align: center;">
<i><br /></i></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXwxkQGLVC20h6BdHEdOejt7WuaGxO0fn0asSilyTUYysbSKRd5r4PlNc3I2f5CXAl5MieimiENTSBLLEQwysY8l0ps5QMIaQUV0EWI0BlktXSBc6MpjauNO5WcWKV0l0BTS9Znt0SULA/s1600/wooden-boat.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhXwxkQGLVC20h6BdHEdOejt7WuaGxO0fn0asSilyTUYysbSKRd5r4PlNc3I2f5CXAl5MieimiENTSBLLEQwysY8l0ps5QMIaQUV0EWI0BlktXSBc6MpjauNO5WcWKV0l0BTS9Znt0SULA/s320/wooden-boat.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Small Wooden Boats</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Once in Portofino, you can wander around. There are places that sell souvenirs. There are art galleries, but too expensive for our tasts. And there are restaurants. It's hot. I too buy an overpriced hat.</span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEismBdkyJMf-lMq1c5IL9aAq2es7J1Ir_fCDvRt-u7FBlzqCFxKhFll7jIYKWmJ94ElwtuEwqMByQy9K2QYBgeFel8jQSOinx2NX0Xh6PEbPPVsNY53-h9v30sKUcwo9aD3R2V592HK0kA/s1600/walk1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEismBdkyJMf-lMq1c5IL9aAq2es7J1Ir_fCDvRt-u7FBlzqCFxKhFll7jIYKWmJ94ElwtuEwqMByQy9K2QYBgeFel8jQSOinx2NX0Xh6PEbPPVsNY53-h9v30sKUcwo9aD3R2V592HK0kA/s320/walk1.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZKoP0IMWRjjuu8ao-r5YxLFJAfbSPvAQMLZiCAEo96qMpRBD8Mi2lgxd3Ip0kD7_ZHquxKNtMd1XUj7-a3Oq9VtnrBnT-JBUsC60NwmuFfZlyKghwFdkcHj2UydtHgQ8UiNWCnu-X4ZI/s1600/walk2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZKoP0IMWRjjuu8ao-r5YxLFJAfbSPvAQMLZiCAEo96qMpRBD8Mi2lgxd3Ip0kD7_ZHquxKNtMd1XUj7-a3Oq9VtnrBnT-JBUsC60NwmuFfZlyKghwFdkcHj2UydtHgQ8UiNWCnu-X4ZI/s320/walk2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKIOWUtG72HCeFoNrXPEAWNqyKCMDc2CWEy1AbEJyEQvHqyDV3gPlI_tmzSg8tX6Q554vph8ADw5_q51KdnU4ysTS814ANWqdApQ7GXCK1vTCy7s19fl0A3G79mLjQcir3YkB4vaYmbDQ/s1600/walk3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiKIOWUtG72HCeFoNrXPEAWNqyKCMDc2CWEy1AbEJyEQvHqyDV3gPlI_tmzSg8tX6Q554vph8ADw5_q51KdnU4ysTS814ANWqdApQ7GXCK1vTCy7s19fl0A3G79mLjQcir3YkB4vaYmbDQ/s320/walk3.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOgiaTAALARUuG6YVTRJUoIRhHoLOUvD86QTNQu2z70pO9qM1c85z-n67Q0a23ctevDGpL0H7NwmO6uD74-c_nZ4iuRxD6jUiKa85pVs_Hx535x1pX_vzgDZEfNgYRNcLzaTwVlk08N4Y/s1600/walk4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOgiaTAALARUuG6YVTRJUoIRhHoLOUvD86QTNQu2z70pO9qM1c85z-n67Q0a23ctevDGpL0H7NwmO6uD74-c_nZ4iuRxD6jUiKa85pVs_Hx535x1pX_vzgDZEfNgYRNcLzaTwVlk08N4Y/s320/walk4.jpg" width="320" /></a></div>
<br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">There are some paths that take you higher up for a nice view of the harbor.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSfzm20HlgKbCYCLRk-nkrzRRi6oW4HFS9hvuC2l6W5PYQrTvXhKdFjo5-Vqmg2ZW24uVjs5ZQx_q67oU6wLrUVOtDhOmXaXPuAdZJSsOk4ksvdebJFsVQpwz-_qf_m3Xmbucxuox5xVg/s1600/high1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSfzm20HlgKbCYCLRk-nkrzRRi6oW4HFS9hvuC2l6W5PYQrTvXhKdFjo5-Vqmg2ZW24uVjs5ZQx_q67oU6wLrUVOtDhOmXaXPuAdZJSsOk4ksvdebJFsVQpwz-_qf_m3Xmbucxuox5xVg/s320/high1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXkwD55SG14ZrG33MK7jdelOEP94c9fLw6qenehUqGILNUk8p5MVGtYhNdBpDfgoeex1RDmr2t0dYlNIA7NMkVX9EfHWqpSnmKbbyDYJWj6nUGPJWBG5_5zG3t7k-UJFgiFo4lGuC_E4M/s1600/high2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXkwD55SG14ZrG33MK7jdelOEP94c9fLw6qenehUqGILNUk8p5MVGtYhNdBpDfgoeex1RDmr2t0dYlNIA7NMkVX9EfHWqpSnmKbbyDYJWj6nUGPJWBG5_5zG3t7k-UJFgiFo4lGuC_E4M/s320/high2.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Views from Higher Up</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">It would be unthinkable to visit Italy and not have something Italian to eat. We had pizza at one of the cafes.</span></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH1d0Aktv4qjdup5KU9xcstPyiYi5FKZecgOY7okOu50R7xLKfEb_fliCZp43Qa0SyGPhY701LbPGZ819hMYAK8jGWQf3CtRCbT_bUtoF5IRIrFSrHWzmRoauRriG7zBpGAieBgpAUkpk/s1600/cafe0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiH1d0Aktv4qjdup5KU9xcstPyiYi5FKZecgOY7okOu50R7xLKfEb_fliCZp43Qa0SyGPhY701LbPGZ819hMYAK8jGWQf3CtRCbT_bUtoF5IRIrFSrHWzmRoauRriG7zBpGAieBgpAUkpk/s320/cafe0.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuoOXurvzwIfK5EPVY5PmnKizmZSFtDk4nJ4_gD3jBOslW_V8vvBQtmUJQ9aIxhxgZNIVYSl9997ltb6gcyBdjPDZr3G3Rk9CKRMr-35ggmkMQAPYHWVh291Uc5foberTLPc4GPEDxlEE/s1600/cafe1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhuoOXurvzwIfK5EPVY5PmnKizmZSFtDk4nJ4_gD3jBOslW_V8vvBQtmUJQ9aIxhxgZNIVYSl9997ltb6gcyBdjPDZr3G3Rk9CKRMr-35ggmkMQAPYHWVh291Uc5foberTLPc4GPEDxlEE/s320/cafe1.jpg" width="240" /></a></div>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">We ordered a pizza from the menu that said it came with ham, mushrooms olives, and artichokes. Unlike an America pizza, each ingredient lives in its own section of the pie; I've since learned that Italians value individual ingredients and look down on mixing many different toppings together. Interesting, we had to remove pits from the olives--something we found consistently throughout Europe. Anyway, the pizza was very good.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">We very much liked Portofino and give it a rating of 3 stars. Do understand that it is pricey, but it's supposed to be. We would very much like to see the Cinque Terra some day, but really anywhere you go on the Amalfi Coast is a winner.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br />Prev: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-3.html" target="_blank">Part 3: Marseilles</a> </span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Next: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-5-florence.html" target="_blank">Part 5: Florence</a></span><br />
<br />
<br />
<br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-68539576141780493942019-04-20T13:18:00.001-07:002019-08-10T12:46:58.474-07:0025th Anniversary Cruise, Part 3: Marseilles<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">In </span><a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" style="background-color: white; color: #888888; font-family: Roboto; font-size: 13.2px; text-decoration-line: none;" target="_blank">this series</a><span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"> of posts I'm describing the Mediterranean Cruise my wife Becky and I took in 2018 for our 25th anniversay, Here in Part 3 I'm covering our third stop, Marseilles France.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<h2>
Days at Sea</h2>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">So far we'd had a great time at our point of embarkation, Barcelona. After a day at sea we visited Stop 2, Gibraltar which we also greatly enjoyed. Now after another day at sea we crossed into France to visit Marseilles. This was my first time to France.</span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">Days at sea are a chance to enjoy the ship. </span><span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">One of the nice benefits of a cruise ship is the food. While specialty restraurants and the cafes cost extra, your cruise includes both the main dining room and buffet, both of which are available for breakfast lunch and dinner. </span><br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlLFkFn56lOP4j2flEJpr6bMNNweYnNMRD_FsP5OYEPlqNsphS28fe_XKVA0Pc8w_fGeY7f0pTojw6_SoUBXm7NugiEZcBeJ3wJ7yH262JQn1HbDR-7y5A2V7BPfRaYO1o4pANJ7U1Y0M/s1600/windy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlLFkFn56lOP4j2flEJpr6bMNNweYnNMRD_FsP5OYEPlqNsphS28fe_XKVA0Pc8w_fGeY7f0pTojw6_SoUBXm7NugiEZcBeJ3wJ7yH262JQn1HbDR-7y5A2V7BPfRaYO1o4pANJ7U1Y0M/s320/windy.jpg" width="240" /></a></div>
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;"><br /></span>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik6Ls99sSve_E6EKW4znftTkxuPR5smYKiduA4ZCkh64J3aoQqnZhMGRzofRKqHEYWWn61x29-hV_9WAddnALB0ciuXkJkiyxl1B7g_KqCsy1VEcwixZjBYekC6EbtdrHSHrUIYfdAj3w/s1600/cafe_breakfast.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEik6Ls99sSve_E6EKW4znftTkxuPR5smYKiduA4ZCkh64J3aoQqnZhMGRzofRKqHEYWWn61x29-hV_9WAddnALB0ciuXkJkiyxl1B7g_KqCsy1VEcwixZjBYekC6EbtdrHSHrUIYfdAj3w/s320/cafe_breakfast.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZEcaSfKeCQCoBKUN0mV_str5L-Otp3AhkV8Gtw1dBveCSwbtPTdKxGxUnwW78VLbJgJmv1sEKZezdsj29wY84oeCCsI4WDtRPFX3cGx7xKWCJ0sGhvvcI-Wdhh3geQWUmgHjIIClp7Q4/s1600/buffet.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZEcaSfKeCQCoBKUN0mV_str5L-Otp3AhkV8Gtw1dBveCSwbtPTdKxGxUnwW78VLbJgJmv1sEKZezdsj29wY84oeCCsI4WDtRPFX3cGx7xKWCJ0sGhvvcI-Wdhh3geQWUmgHjIIClp7Q4/s320/buffet.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Life at Sea</i></div>
<br />
<span style="background-color: white; font-family: "roboto"; font-size: 13.2px;">While most days at sea are casual, there are a handful of formal nights. This is a chance to dress and up and perhaps dine at one of the fancier restaurants. We celebrated one evening at the Crown Grill, the ship's steak restaurant, which we really enjoyed.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIY6IvmA98QV51hnlnhZVyzCNTSdv6UyXb_SudntoU2QNuIfP7ZmBatsiXvCTafpl0xKkB1BI6sDaRL2H9wj1_BO4LFH75v7_zpp4-R4WyL8Y96GY0C-HpB9WRpRtaMCojXF65O2-hBrw/s1600/crown-grill.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjIY6IvmA98QV51hnlnhZVyzCNTSdv6UyXb_SudntoU2QNuIfP7ZmBatsiXvCTafpl0xKkB1BI6sDaRL2H9wj1_BO4LFH75v7_zpp4-R4WyL8Y96GY0C-HpB9WRpRtaMCojXF65O2-hBrw/s320/crown-grill.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzZdOcfKjJzDioY6wUltJ6PJubhoHRk5RGVTnblQdIToiClqQupZRQVlRA3IqW97RVPsAJBQD_afZroCJ3WUnd6B4LeWDj-IlaIeaVUlm8hJBem5b__-SoAGtTBe-pT5X5weYVx4VnKTc/s1600/crown-waiter.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhzZdOcfKjJzDioY6wUltJ6PJubhoHRk5RGVTnblQdIToiClqQupZRQVlRA3IqW97RVPsAJBQD_afZroCJ3WUnd6B4LeWDj-IlaIeaVUlm8hJBem5b__-SoAGtTBe-pT5X5weYVx4VnKTc/s320/crown-waiter.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Crown Grill</i></div>
<h2>
Marseilles (★★★)</h2>
Everyone knows of Paris, but Marseilles is also a vitally important French city. It is sometimes called the "secret capital of France". While Paris is the largest French city in terms of population, Marseilles is the largest in terms of area. It is also the oldest city in the country with a history that goes back over 2600 years: Marseilles was settled by ancient Greeks.<br />
<br />
Located on the French Riviera, Marseilles is beautiful. It is full of picuturesque locations and amazing architecture. Even while on the tour bus just driving through the city again and again you would see jaw-dropping sights. Below are a few I quickly grabbed with my camera.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8tnzxEK5V9l5BlNad_HK440yaD6FH1RXhgSfR0a-QiCZ1giq2ig_X1DuP_GzYNp2UmvNghzh5EFoPdx0xJGaQEUbMKBVeloryvaSyyhyjB_nDhqcyVpHWhAo-Aa22ydRhe4rghFYVARU/s1600/church_arch.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8tnzxEK5V9l5BlNad_HK440yaD6FH1RXhgSfR0a-QiCZ1giq2ig_X1DuP_GzYNp2UmvNghzh5EFoPdx0xJGaQEUbMKBVeloryvaSyyhyjB_nDhqcyVpHWhAo-Aa22ydRhe4rghFYVARU/s320/church_arch.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLO03QuP6g_1wrv2INe7UJrdfz76YKdyLb2IHEdMAgoUu8AHptzNG2GffmJXKGH91C19QrTdw1Q-adQM594l43UHoJUXQ7U0xzfRTLl7t_tH9Z02UQGsdw8CL-s8bsh-__jNITFXiqkB0/s1600/arch.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgLO03QuP6g_1wrv2INe7UJrdfz76YKdyLb2IHEdMAgoUu8AHptzNG2GffmJXKGH91C19QrTdw1Q-adQM594l43UHoJUXQ7U0xzfRTLl7t_tH9Z02UQGsdw8CL-s8bsh-__jNITFXiqkB0/s320/arch.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlQwMMgBBZkttZTVBWaUuUH5enTD55wt0DEp0O9bJAngg8TpCxIwSepfOD4LhJVM8lZA41U0I4xe1GBP7Zsawv1Fg9AKwehJ0tgRpAqaZFJ6z4M9MdG1Xd2erqk041uQ6dc-B09byCzNw/s1600/church2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlQwMMgBBZkttZTVBWaUuUH5enTD55wt0DEp0O9bJAngg8TpCxIwSepfOD4LhJVM8lZA41U0I4xe1GBP7Zsawv1Fg9AKwehJ0tgRpAqaZFJ6z4M9MdG1Xd2erqk041uQ6dc-B09byCzNw/s320/church2.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Captured on the Tour Bus</i></div>
<br />
<h3>
Palais Longchamp</h3>
The Palais Longchamp is a palace that was built to celebrate completion of a canal. The palace itself was strikingly beautiful, but I was saddened to see graffiti at the edges. Who would deface something like this?<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrLXfgpqtLX4iGxGlsJe90l-vyuj-DR3fGBw-ZGDVoFpcFxfPGRkXIURB07Rk-YLGZ0prXCexa0b5BSRN491SYxLpSId8o4UUpJahKqVpH6BXj5Tk7ipboCHoWdcjBhZiij9W2PzLDz2w/s1600/palais_longchamp1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrLXfgpqtLX4iGxGlsJe90l-vyuj-DR3fGBw-ZGDVoFpcFxfPGRkXIURB07Rk-YLGZ0prXCexa0b5BSRN491SYxLpSId8o4UUpJahKqVpH6BXj5Tk7ipboCHoWdcjBhZiij9W2PzLDz2w/s320/palais_longchamp1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtj8oAEqdHrVxC5yzPIxj743jtatpadjiqCf4m3Dzzc55_L4eNPaH2_2iXt-v9hWRjvRIzBRyp_aGXFMzhkSjTe9CANjF3i8-A2hmyzIkc4_AjB0Ziuyid9EoyVf5RMK7dm-vvxQOangw/s1600/palais_longchamp2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="1600" height="180" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgtj8oAEqdHrVxC5yzPIxj743jtatpadjiqCf4m3Dzzc55_L4eNPaH2_2iXt-v9hWRjvRIzBRyp_aGXFMzhkSjTe9CANjF3i8-A2hmyzIkc4_AjB0Ziuyid9EoyVf5RMK7dm-vvxQOangw/s320/palais_longchamp2.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Palais Longchamp</i></div>
<h3>
Chateau D'If</h3>
The Chateau D'If (below left) was a fortress that served as an effective deterrent against attack. It later become a prison. It had a number of famous prisoners, including some fictional ones: if you're familiar with <i>The Count of Monte Cristo</i>, this is the setting for Edmond Dantes' incarceration.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrYF1EENB6sK4CCrByzlg-9uUpjH1O2GqwrL8qboP4Qvp1mqeIhU_d1pMSyJxVECX8dASEXkZ4nGNNMnZEJOs1ITdKnf8jzfZK_fedsyDoQu6ONc3N0lmWCBEQDbmqPxnA1a0bUfzbmMM/s1600/chateau_dif.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrYF1EENB6sK4CCrByzlg-9uUpjH1O2GqwrL8qboP4Qvp1mqeIhU_d1pMSyJxVECX8dASEXkZ4nGNNMnZEJOs1ITdKnf8jzfZK_fedsyDoQu6ONc3N0lmWCBEQDbmqPxnA1a0bUfzbmMM/s320/chateau_dif.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4NBfWMBrELt5xgJ0k_GAep2ltKg9baRqjaxIbzlLSuwbsjh3FN_VpkCQry5cBxz5Hx4fNx3ktrta4XA_iEsDyi0_DDKa_v3XlcKiHDcoQx5rq2jgXUFReESWpcgt24lKDbl-EtrOpEk0/s1600/dif_arch.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4NBfWMBrELt5xgJ0k_GAep2ltKg9baRqjaxIbzlLSuwbsjh3FN_VpkCQry5cBxz5Hx4fNx3ktrta4XA_iEsDyi0_DDKa_v3XlcKiHDcoQx5rq2jgXUFReESWpcgt24lKDbl-EtrOpEk0/s320/dif_arch.jpg" width="240" /></a></div>
<div style="text-align: center;">
<i>Chataeu D'If and Arch</i></div>
<br />
At the seaport we were also shown a number of monuments and buildings, not all of which I remember the details about.<br />
<br />
<h3>
Notre-Dame de la Garde</h3>
Notre-Dame de la Garde is a basicila built on Marseille's highest point that has become the city's best-known symbol. It's a long climb up many steps to reach the top, but the view is worth it.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjza5dFzy1XpWj_YLJ9LniPbaD12d0XYQCmjO6uD3IlTYxfLodlhsVmTsC_jDPlKXxBmSeXV5_ijcLUD8JSjW7dP4mZ35ngt6LtBN4sSMyDOAENJeGyNBSRjFugoByaYYFztyhFJSQIiTY/s1600/notre-arch.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjza5dFzy1XpWj_YLJ9LniPbaD12d0XYQCmjO6uD3IlTYxfLodlhsVmTsC_jDPlKXxBmSeXV5_ijcLUD8JSjW7dP4mZ35ngt6LtBN4sSMyDOAENJeGyNBSRjFugoByaYYFztyhFJSQIiTY/s320/notre-arch.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjShR7cENWAnKZjuysyLaZK5QLYARKan2vbxJO5BUgiDza_w9m5s6LUiNNdeRrrSyZXeWgmYgeAVyDwEXF752YK2z5W56YS__5oXJJtidSiHvFiOoeHQminP4YSTRtODVCzy2ElOb6uz9g/s1600/notre-steps.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjShR7cENWAnKZjuysyLaZK5QLYARKan2vbxJO5BUgiDza_w9m5s6LUiNNdeRrrSyZXeWgmYgeAVyDwEXF752YK2z5W56YS__5oXJJtidSiHvFiOoeHQminP4YSTRtODVCzy2ElOb6uz9g/s320/notre-steps.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Notre Dame de la Garde</i></div>
<h3>
Seaport and Crepes</h3>
We were given some free time for lunch at the <i>Port Vieux</i> seaport. We found a cafe that served crepes, and had crepes and Nutella. It was delicious. Becky, who grew up in Austria, is particularly fond of Nutella.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4G0z2EQ-rQuxV_2ganbxX-jWhoaTPYVtI-ANWJJ-jI5IXrsP0Rpd_mNwgTpyYxFfobatK72PXMGgWggyec28vaKAxqPUr5HK_egKoHUV76bFqwXa2zod_BvG1swkl7urMlb3TF6dcXk4/s1600/crepes_nutella1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj4G0z2EQ-rQuxV_2ganbxX-jWhoaTPYVtI-ANWJJ-jI5IXrsP0Rpd_mNwgTpyYxFfobatK72PXMGgWggyec28vaKAxqPUr5HK_egKoHUV76bFqwXa2zod_BvG1swkl7urMlb3TF6dcXk4/s320/crepes_nutella1.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzxau-id3IA6IeBR37itlA_Z13Z_-Tue9dxCzdCVvzcJF-7gY49gHm8Nxw7EyeRmfRF_W9H1xznv4WtJ7N5RbssWsLdUxTKlxRGYMIGIWRx5LiLAFPhL7jPmYiVMQI-trb4SoMX-rJO-E/s1600/crepes_nutella2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzxau-id3IA6IeBR37itlA_Z13Z_-Tue9dxCzdCVvzcJF-7gY49gHm8Nxw7EyeRmfRF_W9H1xznv4WtJ7N5RbssWsLdUxTKlxRGYMIGIWRx5LiLAFPhL7jPmYiVMQI-trb4SoMX-rJO-E/s320/crepes_nutella2.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Crepes and Nutella</i></div>
<br />
Right across the street, was an interesting piece of artwork, the <a href="https://www.thisiscolossal.com/2013/03/the-port-vieux-pavilion-a-mirrored-canopy-constructed-on-a-french-wharf/" target="_blank">Port Vieux Pavilion</a>. It mirrors real life, so that if you looked up you saw the city mirrored. It kind of reminded me of Chicago's Cloud Gate ("the bean").<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirkrtvU33gXLhs9YgFKBfPk4rgf4QpCRiv0D8AsM92KKB77RNXTCc512RChaLRxM1b6zuJcmR9ETtDhtVeKRLfPKLoLaihlTlyYlSAw-4sQ7FLmL98ytUpNVcz5QtScewYZ0TGeToyKwg/s1600/mirror1jpg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirkrtvU33gXLhs9YgFKBfPk4rgf4QpCRiv0D8AsM92KKB77RNXTCc512RChaLRxM1b6zuJcmR9ETtDhtVeKRLfPKLoLaihlTlyYlSAw-4sQ7FLmL98ytUpNVcz5QtScewYZ0TGeToyKwg/s320/mirror1jpg.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhQPDgM4bekDIKPn_I0Do4S6CZ0XzCk_BQ_tgE615UiMITFkvejVwiPTimJV8BDvAWFVMH43jOAJT7NfuYH0-xpsQFlMxZ9dI07HskTq2gKzMr2mgdfbchTUjJHLNjyjybH708opgMUok/s1600/mirror2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhQPDgM4bekDIKPn_I0Do4S6CZ0XzCk_BQ_tgE615UiMITFkvejVwiPTimJV8BDvAWFVMH43jOAJT7NfuYH0-xpsQFlMxZ9dI07HskTq2gKzMr2mgdfbchTUjJHLNjyjybH708opgMUok/s320/mirror2.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>Port Vieux Pavilion</i></div>
<div style="text-align: center;">
<br /></div>
We had an enjoyable time in Marseilles, and know that we only scratched the surface. We give it a rating of 3 stars, but suspect we might raise that with more time.<br />
<br />
Prev: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-2-gibraltar.html" target="_blank">Part 2: Gibraltar</a><br />
Next: Part 4: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-4-portofino.html">Genoa / Portofino</a><br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-3952166603034174032019-04-20T11:42:00.000-07:002019-04-20T13:19:09.438-07:0025th Anniversary Cruise, Part 2: GibraltarIn <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" target="_blank">this series</a> of posts I'm describing the Mediterranean Cruise my wife Becky and I took in 2018 for our 25th anniversay, Here in Part 2 I'm covering our second stop, Gibraltar.<br />
<br />
<h2>
Gibraltar <span style="background-color: white; font-family: "roboto"; font-size: 22px;">(★★★)</span></h2>
After a great time in Barcelona Spain we had boarded our ship the Crown Princess to start our cruise. Our next stop was Gibraltar, a British Territory at the southern tip of Spain. Gibraltar has an interesting history as a British possession with a strategic maritime location: half the world's seaborne trade passes through the strait of Gibraltar. It has been long fought over by nations and at various times has been captured by Granada, Morocco, and Spain. It was ceded to Britain in 1713 by the Treaty of Utrecht.<br />
<br />
And it certainly does feel British. One of our disappointments in selecting our cruise was that England was not included in our itinerary; but visiting Gibraltar kind of made up for that, because it is British through and through, from the red phone booths to double decker buses to the delicious Fish and Chips.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlRnHVd9te7mANu8UCza5wOqIZ2ELZ3FWFY8wDDTmqVsrl0iNXZtAy7m1TUsZSKt1EJT0JwbkR4IgLKRdyK6ZgEWFyb4vGUZeUwU_ur2JsfngVbRwkK4LgBBvj3nPTWI7clL3cWAXifLQ/s1600/phonebooth.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhlRnHVd9te7mANu8UCza5wOqIZ2ELZ3FWFY8wDDTmqVsrl0iNXZtAy7m1TUsZSKt1EJT0JwbkR4IgLKRdyK6ZgEWFyb4vGUZeUwU_ur2JsfngVbRwkK4LgBBvj3nPTWI7clL3cWAXifLQ/s320/phonebooth.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCLhWPeSyU51TtknsEZMNNWIIU-hZFolo77e3dsDlRbrYwlGk_roJyVcAhXSseM92KLQtP3JhL3U-JIP6NcB7Xn4nbW9DcvoVDfRdSHS352JWrXSO_UsybIdBHe3iUZ3GwoL6kTYUwfBY/s1600/dd_bus.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCLhWPeSyU51TtknsEZMNNWIIU-hZFolo77e3dsDlRbrYwlGk_roJyVcAhXSseM92KLQtP3JhL3U-JIP6NcB7Xn4nbW9DcvoVDfRdSHS352JWrXSO_UsybIdBHe3iUZ3GwoL6kTYUwfBY/s320/dd_bus.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Gibraltar is British Through and Through</i></div>
<br />
Since becoming British, Gibraltar has a rich tradition of holding off invasions and there are lots of local reminders of that history such as cannon and memorial statues.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrc0-AiqsnlnCt3DxieQMVyzBi44HcocIESkHHNvtVt2sAAFl-XJMKvI4ARgf6PQR52ueB3MEhEiDCljnGamIhLn0BRroCMOPyyrrhxzltPb4JKt9vEdIebXfFcGZGvwUcoI2ElvFVd8s/s1600/cannon.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrc0-AiqsnlnCt3DxieQMVyzBi44HcocIESkHHNvtVt2sAAFl-XJMKvI4ARgf6PQR52ueB3MEhEiDCljnGamIhLn0BRroCMOPyyrrhxzltPb4JKt9vEdIebXfFcGZGvwUcoI2ElvFVd8s/s320/cannon.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfCYESCTBviG7B7iTa8nKq9ym2NSppV3qU93KG-Tea48l4bJF70vyAxaCfQUKq0L_5qUu6s2lzMiieWSlS9raKUUKozjzgKnd1lsJQyF-yQidW9bfYvyPDBR6hTsqoi-siz9VSj4QUVJA/s1600/status_evacuation.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfCYESCTBviG7B7iTa8nKq9ym2NSppV3qU93KG-Tea48l4bJF70vyAxaCfQUKq0L_5qUu6s2lzMiieWSlS9raKUUKozjzgKnd1lsJQyF-yQidW9bfYvyPDBR6hTsqoi-siz9VSj4QUVJA/s320/status_evacuation.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Reminders of Military History</i></div>
<br />
The big prominent geographic feature of Gibraltar is the Rock of Gibraltar (used as a logo by Prudential Insurance: "Get a piece of the rock"). A cable car ride up to the top is essential for a first-time visitor. From that vantagepoint you can see Europe and Africa at the same time. We enjoyed espresso at the Top of the Rock cafe.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvPnYagA1vEfjPUaMS-Et2QOWywN6iGKd8j3GDGLMbBZpCciPlAlrFnfnZQjq6PmWh7pNR0Ng4It1FNYEcnFpdSTXrxTtaMsMnGSQCaweh1uOYkoSqbR2YqQ7zm0_xXbqzfmRtuXchHPU/s1600/tram.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvPnYagA1vEfjPUaMS-Et2QOWywN6iGKd8j3GDGLMbBZpCciPlAlrFnfnZQjq6PmWh7pNR0Ng4It1FNYEcnFpdSTXrxTtaMsMnGSQCaweh1uOYkoSqbR2YqQ7zm0_xXbqzfmRtuXchHPU/s320/tram.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF5ttO1j6_HyLkGNl-p23AMXHpP01YGhxpidUGKqzdmUbvZVSvb3S57loR-Gi-NJX3ZdSh9vMCFjI3h7q6tP_u8MNwKpP4OKhib8J1culsmim7HpbSbWtOOkRGEfn27tVVl-UvscQtvIo/s1600/rock.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="214" data-original-width="285" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgF5ttO1j6_HyLkGNl-p23AMXHpP01YGhxpidUGKqzdmUbvZVSvb3S57loR-Gi-NJX3ZdSh9vMCFjI3h7q6tP_u8MNwKpP4OKhib8J1culsmim7HpbSbWtOOkRGEfn27tVVl-UvscQtvIo/s1600/rock.jpg" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-MOe67A8q2v184NKjP9ESqoa5fWlQdkpFFttWjy3ZcCheeg8E9sDrlDTJjzE3COwa9lDdz7jMFyzCpUTvmKR3UwSQXio5HsMCUiRFzc5qVy-VLSETvsX4RG7bVeqFZERV-liJGCxjd48/s1600/top_of_the_rock.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-MOe67A8q2v184NKjP9ESqoa5fWlQdkpFFttWjy3ZcCheeg8E9sDrlDTJjzE3COwa9lDdz7jMFyzCpUTvmKR3UwSQXio5HsMCUiRFzc5qVy-VLSETvsX4RG7bVeqFZERV-liJGCxjd48/s320/top_of_the_rock.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>At the Rock of Gibraltar</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
At the Rock of Gibraltar you can also see the "Barbary Apes", which are not apes at all but macaques (monkeys) indiginous to the area. We'd heard these creatures have learned to grab bags and parcels from tourists, so were careful not to have anything tempting with us. There are signs all over warning to be careful around them.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5hf7kqcmn1z-IKibrgpKd6BaVCfXblDbaZP6uzA2gtmNT1-DBdfFG4lIipXvGCvBYbr0H9LyETWAGZW_X873UO1I96EsjDpWY4PgQlHZWQ0Wrs_XeI84esIrw03vaHk-xE-dTfbPpELY/s1600/apes_warning2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5hf7kqcmn1z-IKibrgpKd6BaVCfXblDbaZP6uzA2gtmNT1-DBdfFG4lIipXvGCvBYbr0H9LyETWAGZW_X873UO1I96EsjDpWY4PgQlHZWQ0Wrs_XeI84esIrw03vaHk-xE-dTfbPpELY/s320/apes_warning2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrHbso-MHO1OhYooMpBUC_VuofQBpNQckx9up2C4kJ8cgqg2hxdM9CvcECiGbTGrfglJ5qijbJvRMNK6os9v0mz2ZptowetwBK8JbhQy5rucHQTBmzcnHS7ZNpISq1G6jj0g-7KIPpRW4/s1600/apes_warning.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjrHbso-MHO1OhYooMpBUC_VuofQBpNQckx9up2C4kJ8cgqg2hxdM9CvcECiGbTGrfglJ5qijbJvRMNK6os9v0mz2ZptowetwBK8JbhQy5rucHQTBmzcnHS7ZNpISq1G6jj0g-7KIPpRW4/s320/apes_warning.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcMA8jLypOya5a5OAFJEF_yvF7k2DV6DjwDAdM-ydU9o62vPe52uIntDdR4lK4Oqnf1ORNWe8N3eNBPUveWHMG4x9sJSx2RzzsRaM_sPHu84oXsSJwFnLPWD6aeCgqZnZJO7XQeW9VNjs/s1600/apes1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgcMA8jLypOya5a5OAFJEF_yvF7k2DV6DjwDAdM-ydU9o62vPe52uIntDdR4lK4Oqnf1ORNWe8N3eNBPUveWHMG4x9sJSx2RzzsRaM_sPHu84oXsSJwFnLPWD6aeCgqZnZJO7XQeW9VNjs/s320/apes1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX4jH8yGTnc_i6UUPxxHFdxJb-T_qzPyy7S-8iUhUneP5dtOk9IN7jVHP6W3PARSwFLpUjXfltFSkSiQobjhkrFNjo02cU_og1tpwK6DCY-i5p6T-48Z01IGPIOYdf6VlJGVZvArW3TO0/s1600/apes2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhX4jH8yGTnc_i6UUPxxHFdxJb-T_qzPyy7S-8iUhUneP5dtOk9IN7jVHP6W3PARSwFLpUjXfltFSkSiQobjhkrFNjo02cU_og1tpwK6DCY-i5p6T-48Z01IGPIOYdf6VlJGVZvArW3TO0/s320/apes2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWcY6TkBC0I4CGc7FocI2jy3-7ON-Q0zuUxDYeRAw85021bUxvjradcuVP_nNYm7KewHIES3et0gGgXDNloBdwR9ZWtmYaTckEOru5Nsdk4qZRspaPhohFZaUur8B80fJDGe1rn8WWaj4/s1600/apes3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWcY6TkBC0I4CGc7FocI2jy3-7ON-Q0zuUxDYeRAw85021bUxvjradcuVP_nNYm7KewHIES3et0gGgXDNloBdwR9ZWtmYaTckEOru5Nsdk4qZRspaPhohFZaUur8B80fJDGe1rn8WWaj4/s320/apes3.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Barbary Apes</i></div>
<br />
Gibralatar isn't very large, but it is interesting. After visiting the Rock we took a leisurely walk down Main Street, passing lots of shops and street merchants. I'd promised Becky some jewelry on this trip, and she selected some Tanzanite earrings. We saw some interesting glass blowing demonstrations. We ate lunch at Roy's Fish and Chips, which locals told us was the best in Gibraltar.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmvG9jOc_zgxDvAqUMCsm0WMfY3aH7VvbcdLp7bnURZum58X5xol_SXTvRYvXX3NOLv6DbDN0JrmxB7yUP-CJTiV15ypp7cWAU8dACeChgAHzsy8JegwAz4w-C8UgbsB1ufQMyBo70Gdc/s1600/earrings+-+Copy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmvG9jOc_zgxDvAqUMCsm0WMfY3aH7VvbcdLp7bnURZum58X5xol_SXTvRYvXX3NOLv6DbDN0JrmxB7yUP-CJTiV15ypp7cWAU8dACeChgAHzsy8JegwAz4w-C8UgbsB1ufQMyBo70Gdc/s320/earrings+-+Copy.jpg" width="240" /></a></div>
<span style="text-align: center;"> </span><br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUnwrmF0YwX6-2cwPzMXAze_5POeGBZkq5AmoZpVOU5gssGk9Ej1AhVteDuNZre-hUTsp9EgqSMbVbq0noTRv3NA3VBfgNVWwrRPISMqu2Hqa80Rkexj0LFv5tXN9jko93NiVMwQ2JHBs/s1600/glass+-+Copy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUnwrmF0YwX6-2cwPzMXAze_5POeGBZkq5AmoZpVOU5gssGk9Ej1AhVteDuNZre-hUTsp9EgqSMbVbq0noTRv3NA3VBfgNVWwrRPISMqu2Hqa80Rkexj0LFv5tXN9jko93NiVMwQ2JHBs/s320/glass+-+Copy.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNSaDu10nXK9eLp3-hDj8mJvp6mT4vBDpLYFoaDW6FosOi3x4O81IKcAA7za5rTrKElaJx6bHrJl0jGGbjxH91zkCFWJX0IAMRhm4V2aQIe6lePJoXrcWWGZDgZydsCxAKmwBOZJNxvKk/s1600/glass2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNSaDu10nXK9eLp3-hDj8mJvp6mT4vBDpLYFoaDW6FosOi3x4O81IKcAA7za5rTrKElaJx6bHrJl0jGGbjxH91zkCFWJX0IAMRhm4V2aQIe6lePJoXrcWWGZDgZydsCxAKmwBOZJNxvKk/s320/glass2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVmnsmcNRd4rOwsrEjIxUJ5adM1g9jfG-HL4vwzzvGterTQg0gQp8qkqOzPR8nyOHrtDvT6_fsWJVmMWBz9CueVYiS9myT6JVQW5AJFUY_NY-Yc8rYpRECO9O-Dm6Dy0rK02zPPD-LteQ/s1600/roys1+-+Copy.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVmnsmcNRd4rOwsrEjIxUJ5adM1g9jfG-HL4vwzzvGterTQg0gQp8qkqOzPR8nyOHrtDvT6_fsWJVmMWBz9CueVYiS9myT6JVQW5AJFUY_NY-Yc8rYpRECO9O-Dm6Dy0rK02zPPD-LteQ/s320/roys1+-+Copy.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGSSCAl9SWhp6KNYHuiAl8xjFDLUVyukFij3t6O_psNNJcal5F-OI_kJc610nvum_mGLl4n1DAsJlbAWLCgoezdq81ANJzIti7AExLD_7skrGuf_etRwR0i7hE5zah5q0k5jHo4lY-KZ8/s1600/roys.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="1227" data-original-width="920" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiGSSCAl9SWhp6KNYHuiAl8xjFDLUVyukFij3t6O_psNNJcal5F-OI_kJc610nvum_mGLl4n1DAsJlbAWLCgoezdq81ANJzIti7AExLD_7skrGuf_etRwR0i7hE5zah5q0k5jHo4lY-KZ8/s320/roys.jpg" width="239" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Various Activities On Main Street</i></div>
<br />
We really enjoyed Gibraltar, and give it 3 stars. It's such a unique place, both geographically and historically. It's quaint and fun, and gave us a taste of the UK. If we'd had more time there we would have also explored <a href="https://en.wikipedia.org/wiki/St._Michael%27s_Cave" target="_blank">St. Michael's Cave</a>.<br />
<br />
Previous: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html" target="_blank">Part 1: Barcelona</a><br />
Next: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-3.html" target="_blank">Part 3: Marseilles</a><br />
<br />
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-55582813497166178572019-04-20T10:51:00.004-07:002019-08-10T12:29:56.563-07:0025th Anniversary Cruise Part 1: BarcelonaLast year, my wife Becky and I celebrated our 25th anniversary with a 2-week European cruise. In this post I'll review what we did, share some cruising tips, and point out things we did (or didn't) like about the cruise. Here in Part 1 I'll cover the first leg of our trip, Barcelona.<br />
<br />
<h2>
Cruise Planning</h2>
The cruise we took was on Princess Cruise Lines and is called the 14-Day Mediterranean & Aegean Medley. Why Princess? They had the itinerary we were looking for. I wanted to see some classic art and architecture in cities like Venice, Florence, or Rome; Becky was also keen to visit the Greek Isles. This cruise gave us a route that started in Spain and went to France, Italy, and Greece. Specifically, the cruise would take us to <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-1-barcelona.html">Barcelona</a> (Spain), <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-2-gibraltar.html">Gibraltar</a>, <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-3.html">Marseilles </a>(France), <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-4-portofino.html">Genoa</a> (Italy), <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-5-florence.html">Florence</a>, <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversay-cruise-part-6-rome.html">Rome</a>, <a href="http://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-7-pompeii.html">Pompeii</a>, Kotor (Montenegro), Corfu (Greece), Crete, Mykonos, and Athens.<br />
<br />
We'd cruised before. On our honeymoon in 1993 we took an NCL cruise to the Caribbean. In 2008 for our 15th anniversary we took the family (five of us) to the Hawaiian Islands, also on NCL. Since a 25th anniversary is special, we splurged on this cruise, including flying business class. And we decided to leave the kids at home, hoping our 15-year old son supervised by his 19-year old sister could get by for two weeks without any major incidents (they did).<br />
<br />
Our ship was the <a href="https://www.princess.com/ships-and-experience/ships/kp-crown-princess/" target="_blank">Crown Princess</a>, a 952-ft long vessel which accommodates 3080 guests and 1200 crew. We had a balcony cabin on Aloha deck, strategically chosen not to be near noisy areas of the ship; and on the left side in order to get a good view of the European shoreline for most of the cruise. Princess was the first cruise line to offer private cabin balconies, which has since become a cruise ship standard.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlmYYrv4xfnKEOpJwhU7O-nz2QG94NDWzfh-nly5s35gLVUTdJL91WXMJN7NaS70pCdvFAIE2uG03WfppJQ9Mwv4S_mvKaq9FdIgj9fajIpyGRVz8FBhP7lhgi3RDTNTfSE-738eScUWU/s1600/ship_external.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="969" data-original-width="1292" height="240" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjlmYYrv4xfnKEOpJwhU7O-nz2QG94NDWzfh-nly5s35gLVUTdJL91WXMJN7NaS70pCdvFAIE2uG03WfppJQ9Mwv4S_mvKaq9FdIgj9fajIpyGRVz8FBhP7lhgi3RDTNTfSE-738eScUWU/s320/ship_external.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Crown Princess</i></div>
<br />
If you're going to take a cruise, expect to spend time doing a lot of planning. Once you've settled on your cruise line and itinerary and decided when to go and locked in a reservation, you have to choose a cabin, line up shore excusions, and make air travel arrangements. We scheduled our cruise in June because July or August would have been stiflingly hot in the Mediterranean. If you want to do any sightseeing at the starting or ending point of your cruise, you'll want to add a few days on land. We scheduled ourselves to fly in to Barcelona a day early, and to stay an extra day in Athens at the end. Cruise lines sometimes throw in goodies depending on how early you book. We received full beverage packages just for booking our cruise early, which otherwise would have cost somewhere around $700 per person.<br />
<br />
<h2>
Flight From LAX to Barcelona</h2>
With final assurances that our teenagers would be fine at home—and the many reminder notes I left around the house to feed the dog, take out the trash, etc.—we left from Los Angeles International airport. We flew on a KLM 747 on the upper level. In general you have much better service on international flights than domestic, especially so if you're flying a premium class. Flying in the upper level of a 747 was a fun and unique experience.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrxu_zgIsTvJUbu_S45jcp6JxJkz8oqtAooX3bECkhOe4bR7ojVe_snr38fAII2zN5Iabdela8btk9zlXuGJJi2rpwCXFT3nNjwduDxp_Nu0e7pAKAfYEdmFbAHZcIto4-LmdGDcQ33CA/s1600/klm_747.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhrxu_zgIsTvJUbu_S45jcp6JxJkz8oqtAooX3bECkhOe4bR7ojVe_snr38fAII2zN5Iabdela8btk9zlXuGJJi2rpwCXFT3nNjwduDxp_Nu0e7pAKAfYEdmFbAHZcIto4-LmdGDcQ33CA/s320/klm_747.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhgJXtUgLN4Ct2UVtXkMuyFKYv-OTQF6VWvmXJbQ-wGEO63As0v768bYbel6CEI9Uw7Bo8oxgxM2rQ11p73cjFpuYU108TUawtHq7sssKK4GgWlXCuDCF3M-zJukjiE3EbWIDUwbeBVZg/s1600/klm_bus_second-level.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhgJXtUgLN4Ct2UVtXkMuyFKYv-OTQF6VWvmXJbQ-wGEO63As0v768bYbel6CEI9Uw7Bo8oxgxM2rQ11p73cjFpuYU108TUawtHq7sssKK4GgWlXCuDCF3M-zJukjiE3EbWIDUwbeBVZg/s320/klm_bus_second-level.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The business class on KLM is pretty sweet. Good service by flights attendants, excellent food and drink, a great selection of video entertainment. A flight attendant did accidentally spill a drink on Becky, but she took it in stride and changed her top. For me, this was a nice contrast to the constant economy flights to and from DC that I'd been flying all year for work.</div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6akdVj0j7_wgnhPecNulDEEARnfdUac-pNDTfHNf7v8P7rav80eIkEvcvJtTsxstpL65azU1bkWSzSI_5lwR639UGGWV-0SN4R3u_WX75Jb0OYHCwSjCnlKn27vyGzh4yGFlylFObHUQ/s1600/klm_bus_class.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6akdVj0j7_wgnhPecNulDEEARnfdUac-pNDTfHNf7v8P7rav80eIkEvcvJtTsxstpL65azU1bkWSzSI_5lwR639UGGWV-0SN4R3u_WX75Jb0OYHCwSjCnlKn27vyGzh4yGFlylFObHUQ/s320/klm_bus_class.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOnrMhSaDfb0zeXrBBmiPermbv5wLY4VCTdS7XdIGRe3z2WoAYNf6VkVpRNQGWJZ_nMtNQibdkxS7OKA085tmnmpmYCFVY-oyUVNxP3wnuAm-KIkqoOO5-rVsbe7a5mm2_3YPlU7uuqxI/s1600/klm_bus_smiles.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOnrMhSaDfb0zeXrBBmiPermbv5wLY4VCTdS7XdIGRe3z2WoAYNf6VkVpRNQGWJZ_nMtNQibdkxS7OKA085tmnmpmYCFVY-oyUVNxP3wnuAm-KIkqoOO5-rVsbe7a5mm2_3YPlU7uuqxI/s320/klm_bus_smiles.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_sBv7c0dF9KpRTpFSCBu1nK1Wo8Fmj9ZCY0urSNIOj4NxdNr2Zu1gfcEd4GJzbOd8KJ_K7jbbmyvLdufx1gk8DFHHWxpxOet-8OqMDhih4nkPWvbyBOO7iBwtxwIODOV3mft0hXYpQo8/s1600/klm_bus_dinner.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_sBv7c0dF9KpRTpFSCBu1nK1Wo8Fmj9ZCY0urSNIOj4NxdNr2Zu1gfcEd4GJzbOd8KJ_K7jbbmyvLdufx1gk8DFHHWxpxOet-8OqMDhih4nkPWvbyBOO7iBwtxwIODOV3mft0hXYpQo8/s320/klm_bus_dinner.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Our flight had a stop-over in Amsterdam. Our second leg to Barcalona was delayed, and we spent several hours in the KLM Lounge at Schiphol Aiport. We had planned to spend the afternoon and evening exploring Barcelona before boarding the cruise ship the next day, but now our time was evaporating.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Finally we boarded our second flight—an A320—for the short flight to Barcelona, Spain. Although this was also business class, it wasn't nearly as lavish as the international flight had been. I was particularly surprised to find out that soft drinks aren't free on domestic European flights.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2>
Barcelona (★★★★)</h2>
<div class="separator" style="clear: both; text-align: left;">
We arrived in Barcelona significantly tired, but determined to see something of Barcelona while we had the chance. Barcelona is famous for its architecture by <a href="https://en.wikipedia.org/wiki/Antoni_Gaud%C3%AD" target="_blank">Antoni Gaudi</a>, so we took a taxi to <a href="https://en.wikipedia.org/wiki/Park_G%C3%BCell" target="_blank">Park Güell</a>. Park Güell is a community that Gaudi started in 1900; today is a public park. It is full of interesting and whimsical architecture.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYV0Q28Y7iNhwCQ9ySP8iwMNLcaeuvzqIGc00IV9JfOBL05Yk_9umNlt_HWHC9k92u6kI0tC20YlU47YA6aLxuPZC3g4N0d23_0tkw9AQOpgUh_O9jpOvTSLf-jgxFKMWPDAjxy0jDXOo/s1600/Barcelona_bldg2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgYV0Q28Y7iNhwCQ9ySP8iwMNLcaeuvzqIGc00IV9JfOBL05Yk_9umNlt_HWHC9k92u6kI0tC20YlU47YA6aLxuPZC3g4N0d23_0tkw9AQOpgUh_O9jpOvTSLf-jgxFKMWPDAjxy0jDXOo/s320/Barcelona_bldg2.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7DCwLI4YBqFUf38z5gn8_XOq1WOjZelS2qi7CgAFm27QDRoY94Tni8oWIw2y0TMwH-QVcdbyZ4Z1cQ26oZH-jWiz_ZlFu333alLU8JDuBniA18pYStGUuZcqTJB80qElXPL528hflvpc/s1600/Barcelona_bldg1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh7DCwLI4YBqFUf38z5gn8_XOq1WOjZelS2qi7CgAFm27QDRoY94Tni8oWIw2y0TMwH-QVcdbyZ4Z1cQ26oZH-jWiz_ZlFu333alLU8JDuBniA18pYStGUuZcqTJB80qElXPL528hflvpc/s320/Barcelona_bldg1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5WUgD91XRHuttCpCQ2vx0OIV5Rmjq9aUA_Op9PJikU7XhxNs79IXoR6eE9VH3ODlOQMbrsZXEpDMU_gJwpDRUDmI0YlB1w655VdfWXjgJbz-Vakk2_LioftearrGAVjy1GaGqfm_u7Ms/s1600/Barcelona_iguana.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5WUgD91XRHuttCpCQ2vx0OIV5Rmjq9aUA_Op9PJikU7XhxNs79IXoR6eE9VH3ODlOQMbrsZXEpDMU_gJwpDRUDmI0YlB1w655VdfWXjgJbz-Vakk2_LioftearrGAVjy1GaGqfm_u7Ms/s320/Barcelona_iguana.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxKeNzkanXE7OOb_Nc-ZVYIWTzVB0PSCF4guog_nkRjo_8yJMfN0nFUALoSZHZqZQgF4-o-wzKYqHtYsFyJ2SG5KMqy0RnB1PJjhq-W1yDB4HZgcw8x31HvPJjdvZCHfY-qGvWAFNicdQ/s1600/Barcelona_bldg3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxKeNzkanXE7OOb_Nc-ZVYIWTzVB0PSCF4guog_nkRjo_8yJMfN0nFUALoSZHZqZQgF4-o-wzKYqHtYsFyJ2SG5KMqy0RnB1PJjhq-W1yDB4HZgcw8x31HvPJjdvZCHfY-qGvWAFNicdQ/s320/Barcelona_bldg3.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Park Güell, Barcelona, Spain</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We really were too exhausted to really appreciate what we were seeing, but according out our photos we had a great time! There's a lot of other Gaudi architecture in the city but sadly we didn't have time to see it. On a future visit it would be great to see the <a href="https://en.wikipedia.org/wiki/Sagrada_Fam%C3%ADlia" target="_blank">Familia Sagrada</a> and other Gaudi sites.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
For dinner, we walked a few blocks from our hotel and enjoyed tapas (small plates), which are a big deal in Barcelona. We had all sorts of interesting things to eat: bravas (potatoes with a spicy tomato sauce), croquettes, stuffed cherry peppers, local breads, and Catalan cream, a dessert similar to Creme Brulee. It was delicious. After ordering so many small items, I wondered out loud what the bill might come to. Somehow Becky predicted the amount and when the bill came she was within 1 Euro! </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLYt44wBR3NTrJUzWr-GiTekjN0Y77DdAWh31UegBNgD_ewHMONxNiJ8TIArnK4k7_jzkcenZJkysN8BkcTUZ0ifvMLk1Au1VouNv_94ceJOd526rstybIYOowIVXGW7ZzdE3_R6sDVRQ/s1600/Barcelona_tapas1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLYt44wBR3NTrJUzWr-GiTekjN0Y77DdAWh31UegBNgD_ewHMONxNiJ8TIArnK4k7_jzkcenZJkysN8BkcTUZ0ifvMLk1Au1VouNv_94ceJOd526rstybIYOowIVXGW7ZzdE3_R6sDVRQ/s320/Barcelona_tapas1.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_RgI4C0JxapY1oggfflthcjoVRBT08zKxBQg51L8jFo7GEInkkDjc7ogfJuFxDlsH2CdMCPs2jTAGUWuh-B67wdHmzadIVw9-FxTbL7mic0_N_M1gnivw1id3dYUAa-o8INnUSivArwA/s1600/Barcelona_tapas2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="231" data-original-width="173" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi_RgI4C0JxapY1oggfflthcjoVRBT08zKxBQg51L8jFo7GEInkkDjc7ogfJuFxDlsH2CdMCPs2jTAGUWuh-B67wdHmzadIVw9-FxTbL7mic0_N_M1gnivw1id3dYUAa-o8INnUSivArwA/s1600/Barcelona_tapas2.jpg" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnJHvUKsvMDulCEBIvpwC6VTHTauloRUDc_x5GT9fE-caBlF4OJB-o2WAa7vw5UycE7208CDGcPlSIxGJICYJYg6PDEVVOUrSR0O3r4Vc0SrNiOiHQJf0mJB-xqPOP6_VRa-hSlBKKEFY/s1600/Barcelona_tapas3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjnJHvUKsvMDulCEBIvpwC6VTHTauloRUDc_x5GT9fE-caBlF4OJB-o2WAa7vw5UycE7208CDGcPlSIxGJICYJYg6PDEVVOUrSR0O3r4Vc0SrNiOiHQJf0mJB-xqPOP6_VRa-hSlBKKEFY/s320/Barcelona_tapas3.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjADh8-JB6l9npNEoxT4dwkpSPu0Gct50hVoyNYB0lERDAaNnRbTxxIO_QUJuPQKRWzvadcx_m999_4dj5gcqP_iR2AKM256XQG6xm-j85wdAt_UvRCC0H5ANQUDd4D_Tu_naxCmMieEVI/s1600/Barcelona_tapas4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjADh8-JB6l9npNEoxT4dwkpSPu0Gct50hVoyNYB0lERDAaNnRbTxxIO_QUJuPQKRWzvadcx_m999_4dj5gcqP_iR2AKM256XQG6xm-j85wdAt_UvRCC0H5ANQUDd4D_Tu_naxCmMieEVI/s320/Barcelona_tapas4.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4Fx3QYaIltwVIRCW0yHXw58CwAOBjUUf-ysCkx83jnwKugRBoWkBbt9Sopi0io_lrbaEwk3u9pUfNbYHB_Mdt_KHtLESGfRPYtdGamOLfqWJsxy4gmaHnSB1sqRVypuHzIv3D6NtA_NI/s1600/Barcelona_tapas5.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg4Fx3QYaIltwVIRCW0yHXw58CwAOBjUUf-ysCkx83jnwKugRBoWkBbt9Sopi0io_lrbaEwk3u9pUfNbYHB_Mdt_KHtLESGfRPYtdGamOLfqWJsxy4gmaHnSB1sqRVypuHzIv3D6NtA_NI/s320/Barcelona_tapas5.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Tapas</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The next morning, after an excellent breakfast at the Hotel Hesperia Presidente, we took advantage of a few hours in the morning to explore further. We walked <a href="https://en.wikipedia.org/wiki/La_Rambla,_Barcelona" target="_blank">Las Ramblas</a>, a large pedestrian walkway full of tourists and restaurants and merchants which ends in a statue of Christopher Columbus. You may recall hearing in the news in 2017 there was an incident where terrorists drove a van onto Las Ramblas killing 15 people and injuring 100 others--this is where that happened.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUdl8AY977DGyHx4AV9EAx6fEJHA-6snrzp813nn7-eByDhUawxQVBmNZBcZgoAnceRdFnFatLk2sTr1wc7CSXqp_BJKna7dUAqUQczTJIfWf8uxDjJudpCYgC_91KVu_ig65E41IPzWs/s1600/Barcelona_LasRamblas.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiUdl8AY977DGyHx4AV9EAx6fEJHA-6snrzp813nn7-eByDhUawxQVBmNZBcZgoAnceRdFnFatLk2sTr1wc7CSXqp_BJKna7dUAqUQczTJIfWf8uxDjJudpCYgC_91KVu_ig65E41IPzWs/s320/Barcelona_LasRamblas.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAgYnr08537UbPkkT2OjDvxUhFOvZ94Zu2mYNruImZQsrUI3j3ipSPv_6Kl1IIXjnFRCTFZ5SGWbgYHt3j9WOV4fPf_4VQJ8eBCOLFlsR-QeyMkKm6ohnErG_ttLlA780AQ2B9bwRl1Nc/s1600/Barcelona_LasRamblas2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgAgYnr08537UbPkkT2OjDvxUhFOvZ94Zu2mYNruImZQsrUI3j3ipSPv_6Kl1IIXjnFRCTFZ5SGWbgYHt3j9WOV4fPf_4VQJ8eBCOLFlsR-QeyMkKm6ohnErG_ttLlA780AQ2B9bwRl1Nc/s320/Barcelona_LasRamblas2.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvT9zUD5n0n0PJ9EWAl07EsOjCWb8VxPOUuK9dBzCnRGHs61Z5hnwjJKGFIM3ye27pPfvZ6rQnDGMYEU4axR0QiXaP1bhjLoQR_YfPPjCoKEq2m4gR064kxnuASZnvvIsEmICtXIIZmPQ/s1600/Barcelona_columbus.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhvT9zUD5n0n0PJ9EWAl07EsOjCWb8VxPOUuK9dBzCnRGHs61Z5hnwjJKGFIM3ye27pPfvZ6rQnDGMYEU4axR0QiXaP1bhjLoQR_YfPPjCoKEq2m4gR064kxnuASZnvvIsEmICtXIIZmPQ/s320/Barcelona_columbus.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Las Ramblas</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both;">
Along Last Ramblas, we stopped at the <a href="https://en.wikipedia.org/wiki/La_Boqueria" target="_blank">Boqueria Market</a>, a public market just overflowing with fresh goods. Barcelona is all about <i>jamon </i>(ham) and Manchego cheese. Fun discovery at the market: in the last picture below, see the guy serving espresso at the Notxo Bar? If you watch the Rich Steves Europe episode on Barcelona, the exact same guy is in it.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihW_RlqnwMzWajANcc_sZDmd3rh1LELbkSO0YjD6Qan15kpM2O5_IUWKmEl13Ba0DopS07_LvkomgogrmoA_TaTkfyU-33C6Uhw2nkm667luBpcLrJeq-dIPVF6zil7gLeHbKYSqWJLwE/s1600/Barcelona_market4.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEihW_RlqnwMzWajANcc_sZDmd3rh1LELbkSO0YjD6Qan15kpM2O5_IUWKmEl13Ba0DopS07_LvkomgogrmoA_TaTkfyU-33C6Uhw2nkm667luBpcLrJeq-dIPVF6zil7gLeHbKYSqWJLwE/s320/Barcelona_market4.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0qkUKLq3WkRs8iCTqIsAW5tOk8zBeIV2gxna4TWzuHajyXM4oy4rdZCkzpeVQopBfbTIcVwRguL-ZDpfrLaAowaD3fBtTnkYzwcl9_GLa53L7o7vj2jqDSFfeZyKVs5yNfXs18KQbhyk/s1600/Barcelona_market1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj0qkUKLq3WkRs8iCTqIsAW5tOk8zBeIV2gxna4TWzuHajyXM4oy4rdZCkzpeVQopBfbTIcVwRguL-ZDpfrLaAowaD3fBtTnkYzwcl9_GLa53L7o7vj2jqDSFfeZyKVs5yNfXs18KQbhyk/s320/Barcelona_market1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiffBq5U9yO_rpNzR0nEBFb428TWLzz9W5WSS-iK7C9MSiV1YM2Y5-7DM6o0zMiTKSO9sKlyidvRiMsumd_dFzuhfKMpGLoUJwTu5a8amoo2U23NkrnjzLPSXVijc9nycqPFK0QArcFCDA/s1600/Barcelona_market2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiffBq5U9yO_rpNzR0nEBFb428TWLzz9W5WSS-iK7C9MSiV1YM2Y5-7DM6o0zMiTKSO9sKlyidvRiMsumd_dFzuhfKMpGLoUJwTu5a8amoo2U23NkrnjzLPSXVijc9nycqPFK0QArcFCDA/s320/Barcelona_market2.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjALCRmrbrkaFznS-mFDY1ONnUM8fLx1GpvPK5k_ah3yCaZFmjCq2RRfBrcG0tw3qsZjEhdt3KkZk8GDVUo1WZA6lU57k4xf_4GvQ5bx4k1mx6Jky02NCC_o5VP_MznAmmzfS7K6vJeatk/s1600/Barcelona_market3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjALCRmrbrkaFznS-mFDY1ONnUM8fLx1GpvPK5k_ah3yCaZFmjCq2RRfBrcG0tw3qsZjEhdt3KkZk8GDVUo1WZA6lU57k4xf_4GvQ5bx4k1mx6Jky02NCC_o5VP_MznAmmzfS7K6vJeatk/s320/Barcelona_market3.jpg" width="320" /></a></div>
<div style="text-align: center;">
<i>La Boqueria Market</i></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Barcelona is part of a region called Catalonia. The Catalans have long been seeking independence from Spain, and this is readily apparent by all the red-and-yellow Catalan flags that are all over the place.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirMSI9zMuQmiNWVpYJvVZStz6IGrc4HlpWnbfDeOEuT1aXB0WeSZlVhMv_TLtqsV3-7LX2sR_smLU3kXd27_V5TL5_J6gOtvExrQJ8J57BnMkiYAKjcHyD_gKbrCzeYp_S2ZFOG3cF4LA/s1600/Barcelona_Catalan.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirMSI9zMuQmiNWVpYJvVZStz6IGrc4HlpWnbfDeOEuT1aXB0WeSZlVhMv_TLtqsV3-7LX2sR_smLU3kXd27_V5TL5_J6gOtvExrQJ8J57BnMkiYAKjcHyD_gKbrCzeYp_S2ZFOG3cF4LA/s320/Barcelona_Catalan.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Catalan Flag</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
By mid-morning, it was time to head back to the hotel and get taken over to the cruise ship. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We really enjoyed Barcelona and give it 4 stars. It's a vibrant and friendly city, and a place we'd like to visit again, there's so much more to see here. Plus we're hooked on tapas.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2 style="clear: both; text-align: left;">
Boarding On the Ship</h2>
<div class="separator" style="clear: both; text-align: left;">
By mid-morning we were on a bus with other passengers being ferried to the pier to board the Crown Princess. There was the airport-like security screening, then waiting until our group was called. Once on board, we had to wait an hour or so for our cabin to be ready. We waited that time out looking around the ship, which was beautiful. Crown Princess has a large atrium that serves as the community center of the ship. It's adjacent to cafes and the dining room and there is regular entertainment. We particularly liked a music group named X-Trio that performed regularly throughout our voyage.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU2kR8C7lR_e_3pNwFqBLhVNOlmRgzVD_nf4dPr2-NRDGbSugm2LcKVlQxCYvgqJEWVaLw7GqTNHXkMs6e6hlNNBt8corinbMVLFWuh0mvTTUbELfU1LmTIWWL20k0r2Hd0dfL8Tqjtmk/s1600/cp_atrium1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgU2kR8C7lR_e_3pNwFqBLhVNOlmRgzVD_nf4dPr2-NRDGbSugm2LcKVlQxCYvgqJEWVaLw7GqTNHXkMs6e6hlNNBt8corinbMVLFWuh0mvTTUbELfU1LmTIWWL20k0r2Hd0dfL8Tqjtmk/s320/cp_atrium1.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPzQw3fdRKeNP3qE1S17HbFUtNibI7csJQ7F4xD0k5CsL39m0dImqp5E70_beqFAbl24CNpJcX_agP3miSG9mf5mSqmI6C3nkSHwzZ2Y0gpfk1s2xuUTOgrpMViW32dwfZSkGnnCo61XY/s1600/cp_atrium2.jpg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjPzQw3fdRKeNP3qE1S17HbFUtNibI7csJQ7F4xD0k5CsL39m0dImqp5E70_beqFAbl24CNpJcX_agP3miSG9mf5mSqmI6C3nkSHwzZ2Y0gpfk1s2xuUTOgrpMViW32dwfZSkGnnCo61XY/s320/cp_atrium2.jpg.jpg" width="240" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9zTiWLMVZABTf28v21N8vHaKeZRADq_BQmj2gDwPMg17Iik2LDg8nn_RLsqytpabmhhV6BrJlhXih9oII0gKR_GnJVCNvmzsar786jmkGal3Wgnn2uKEmNW7nbqq2PBVTOD_D-2RPLiI/s1600/cp_atrium3.jpg.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9zTiWLMVZABTf28v21N8vHaKeZRADq_BQmj2gDwPMg17Iik2LDg8nn_RLsqytpabmhhV6BrJlhXih9oII0gKR_GnJVCNvmzsar786jmkGal3Wgnn2uKEmNW7nbqq2PBVTOD_D-2RPLiI/s320/cp_atrium3.jpg.jpg" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Crown Princess Atrium</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Our cabin was what we expected: not overly large, but workable. Having a balcony was nice. One minor disappoinment: on previous cruises there were always towel animals left by the steward; not so on this cruise.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhboTlnSUY4G5Zs4Rux4kAUea9ieBpm2sUfF_vPlTZ55hadi_pzDWC3QrLRpmi8D_FHqHyfo2Gl2f0QX_CILRUNl5RmOMYQhGUTJGDPYR6w-bme7pRmoLoXY7f3g4nekGMAalNKma3Mdb4/s1600/cabin0.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhboTlnSUY4G5Zs4Rux4kAUea9ieBpm2sUfF_vPlTZ55hadi_pzDWC3QrLRpmi8D_FHqHyfo2Gl2f0QX_CILRUNl5RmOMYQhGUTJGDPYR6w-bme7pRmoLoXY7f3g4nekGMAalNKma3Mdb4/s320/cabin0.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu_rMKzOxrZ6gqlCtghMULOfjrlzog9uX1LzHKQfP_qJbE14jrBzJQgPawiMMPDqiT0gdZfCoPmvIEMbBNEP3ea0_LVzLLRFPpHmdLOIM6YKdmwSR_dkgIWoLwxrpMnGwhJTAzk2YhBNc/s1600/cabin1.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu_rMKzOxrZ6gqlCtghMULOfjrlzog9uX1LzHKQfP_qJbE14jrBzJQgPawiMMPDqiT0gdZfCoPmvIEMbBNEP3ea0_LVzLLRFPpHmdLOIM6YKdmwSR_dkgIWoLwxrpMnGwhJTAzk2YhBNc/s320/cabin1.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTJh8wVoVz5gaFzB69dIjo5SiNVDv6qyuQZNaGv6la-rOJOC2zHWuBH0J-lfsril69ghzeYMZA6WPJhn8AHphXlcJhNAxm57auft_L3g413__CYUyngkDofiPBHuAPPJ78iSZcms7M_hw/s1600/cabin2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="921" data-original-width="1227" height="239" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjTJh8wVoVz5gaFzB69dIjo5SiNVDv6qyuQZNaGv6la-rOJOC2zHWuBH0J-lfsril69ghzeYMZA6WPJhn8AHphXlcJhNAxm57auft_L3g413__CYUyngkDofiPBHuAPPJ78iSZcms7M_hw/s320/cabin2.jpg" width="320" /></a></div>
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp2JMXHmv-hKSCmX3o-xe0imFJpBgwwdP3-b_6M9KARiS603eqQGPvMVe3urOcgk0iIWaWmllzL9JdIUNqjv8_tmHUjCNgjvmLgvrtzmG1COdiTuoeHqY3YGvL2o3HKg4nvxVOoIbVd7w/s1600/cabin3.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="920" data-original-width="690" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgp2JMXHmv-hKSCmX3o-xe0imFJpBgwwdP3-b_6M9KARiS603eqQGPvMVe3urOcgk0iIWaWmllzL9JdIUNqjv8_tmHUjCNgjvmLgvrtzmG1COdiTuoeHqY3YGvL2o3HKg4nvxVOoIbVd7w/s320/cabin3.jpg" width="240" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Balcony Stateroom</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Well, that sums up our first leg: flying to Europe, visiting Barcelona, and getting on board our ship. We were only getting started and had another 13 days ahead of us!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Next: <a href="https://davidpallmann.blogspot.com/2019/04/25th-anniversary-cruise-part-2-gibraltar.html" target="_blank">Part 2: Gibraltar</a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<br />
<br />David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com0tag:blogger.com,1999:blog-9132148272745668459.post-91035811161130398052019-04-15T14:50:00.002-07:002019-04-24T14:41:43.339-07:00Create a Cross-Platform Console Command in .NET CoreIn this post, I'm going to show how you can effortlessly create a console command in .NET Core that runs on Windows, Linux, and MacOS. I'll do this step-by-step in detail with the assumption you may be new to .NET Core.<br />
<br />
To those diehard .NET developers who have been resisting .NET Core, let me give you some words of encouragement. You've no doubt been hearing more and more about .NET Core, and perhaps you haven't liked everything you've heard ("Config files are no longer XML?"). At this point, there's no denying that .NET Core has momentum: companies all over are making the switch. If you haven't learned .NET Core yet, you probably should: it's where Microsoft is now investing their development platform efforts, and the world is moving to it. On the plus side, there are some exciting new capabilities such as the cross-platform support we'll be focusing on in this post.<br />
<br />
To illustrate a cross-platform .NET Core console command, we'll create an updated version of a command I wrote about last year named <a href="http://davidpallmann.blogspot.com/2018/08/release-management-and-my-release-tool.html" target="_blank"><b>release</b></a>. The purpose of the <b><span style="color: #666666;">release</span><span style="color: #444444;"> </span></b>command is to create and verify software release manifests in the form of directory files with hashes. Two files with the same content will have the same hash; even a one-character difference between two files will cause them to have wildly different hashes. The release command supports these actions:<br />
<br />
<b>release </b>: displays help<br />
<b>release hash</b> <i>file </i>: displays a hash code for a single file<br />
<b>release create </b><i>manifest-file</i> : creates a manifest file listing files and hash codes<br />
<b>release verify </b><i>manifest-file</i> : reads the manifest file and compares against the file system<br />
<br />
<h2>
Prerequisites</h2>
Our first step is to <a href="https://dotnet.microsoft.com/download" target="_blank">download and install the .NET Core SDK</a>. At the time I'm writing this, the latest stable release of .NET Core is 2.2, so that's what we're using here.<br />
<br />
While optional, I'll also suggest you download <a href="https://code.visualstudio.com/download" target="_blank">Visual Studio Code</a>. You can in fact use any editor / IDE you prefer, including traditional Visual Studio, but if your interest in .NET Core is cross-platform support then it makes sense to also use Visual Studio Code. With it and the .NET Core SDK, not only can you target non-Windows platforms; you can also do the development and building itself on any of those platforms.<br />
<br />
<h2>
Creating a Console Project with the Dotnet Command</h2>
To create our starter console project, we use the <b><span style="color: #666666;">dotnet </span></b>command. In .NET Core, you can do lots of things from the command line, including creating new projects from templates; building them; and running them. On Windows, open a command prompt as an Administrator and set your directory to a folder where you want to be doing .NET Core development.<br />
<br />
To create our console project, use the command dotnew new console -o <i>project-name</i>:<br />
<br />
<b>dotnet new console -o release</b><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-SrtySplXxokZv9Y5tk-RYYJwMe2huh6z20uxx04Y3Jx5146sEkYGXI-fYAqCJLF5MGDXXTg3yqHv26gpIfz35deAu5r81uZHdXeCvQc9jVxGRViij4NvMbgVC5GrJAC8LBjxqAOaQP0/s1600/dotnet-new.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="319" data-original-width="719" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-SrtySplXxokZv9Y5tk-RYYJwMe2huh6z20uxx04Y3Jx5146sEkYGXI-fYAqCJLF5MGDXXTg3yqHv26gpIfz35deAu5r81uZHdXeCvQc9jVxGRViij4NvMbgVC5GrJAC8LBjxqAOaQP0/s400/dotnet-new.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
This generates a small number of files in a release folder. Program.cs is our started code, and release.csproj is our project file.<br />
<br />
<h2>
Create the Project Code</h2>
<h3>
Open the Project in Visual Studio Code</h3>
Next, launch Visual Studio Code and open the folder we just created. If you're new to Visual Studio Code, you'll probably expext to be opening .csproj and .sln files, but it doesn't work that way in Visual Studio Code. Just open the release <u>folder</u> you created in the prior step, and trust that we'll be doing our building and running with the dotnet command.<br />
<br />
<h3>
Write the Console Program Code</h3>
If you examine the generated Program.cs, you'll see it just outputs Hello World! to the console. We need to replace this with our desired code. In my case, we'll paste in the <a href="https://github.com/davidpallmann/release-exe/blob/master/Program.cs" target="_blank">Program.cs source code</a> from my original .NET Framework implementation.<br />
<br />
Our Program.cs in Visual Studio Code now looks like this:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLKcyBwqwhpN-bilF6qBzcrIGaKV1aw5UbfvkHug46AJ3lidZP0xN5sRZtEhS2GUtc5GBpdsqribL_wLROAdnFQhVD8yu6K36-C7OzZQBuboR9NfB5qch4oT02czffSpj5FO4dLWQHWVc/s1600/vscode-program-cs.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="867" data-original-width="1600" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLKcyBwqwhpN-bilF6qBzcrIGaKV1aw5UbfvkHug46AJ3lidZP0xN5sRZtEhS2GUtc5GBpdsqribL_wLROAdnFQhVD8yu6K36-C7OzZQBuboR9NfB5qch4oT02czffSpj5FO4dLWQHWVc/s400/vscode-program-cs.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
We don't really need to do anything else: the original release command consisted of just Program.cs and didn't have any application configuration. We may need to make some changes later on when we test on other operating systems, but for now we can proceed as we are on Windows.<br />
<br />
<h2>
Build and Test the Project</h2>
<h3>
Build the Project</h3>
Now we can build the project, for which we'll again be using the dotnet command. You can issue the build command from the command prompt as we did earlier, but for those new to Visual Studio Code you also have the option of using the integrated Terminal window in the editor. Just select Terminal > New Terminal from the menu, and you have a console window below your code.<br />
<br />
<b>dotnet build </b><br />
<br />
Execute the <b><span style="color: #666666;">dotnet build</span></b> command.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO47hDDwxUr8X8wA8hdsmwGciHH9A5XMehyphenhyphenWuGIFOmlnuLrd-VgaEqoiQnTVHJ5Rn4LPX17b1njt1x0s4o-awQs_SraDQcpAe6leBzf6ZEy8BUsc8G-4MaNc0_FMS2Yks2vIWwCYFU1jo/s1600/vscode-dotnet-build.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="867" data-original-width="1600" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhO47hDDwxUr8X8wA8hdsmwGciHH9A5XMehyphenhyphenWuGIFOmlnuLrd-VgaEqoiQnTVHJ5Rn4LPX17b1njt1x0s4o-awQs_SraDQcpAe6leBzf6ZEy8BUsc8G-4MaNc0_FMS2Yks2vIWwCYFU1jo/s400/vscode-dotnet-build.png" width="400" /></a></div>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
If you examine the release folder, you'll see there is a bin folder that contains a Debug folder that contains a netcoreapp2.2 folder. In /bin/Debug/netcoreapp2.2 we see a release.dll (not a .exe as you might expect), a release.pdb, and several json files.<br />
<br />
The reason we don't see an .exe is that by default a .dll is generated, which you can execute using the <span style="color: #666666;">dotnet </span>command. Don't be worried: t is possible to generate an .exe, and we'll do so shortly.<br />
<br />
<h3>
Run the Project</h3>
Now that we have built our program we can try running it, using the <b><span style="color: #666666;">dotnet run</span></b> command. Once again you can issue this from a command prompt or a Visual Studio Code Terminal window.<br />
<br />
<b>dotnet run</b><br />
<br />
<div class="separator" style="clear: both; text-align: left;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAWKUtga1jWEVFdtYF0r2jSRm6ZANXxgGWbZObPhwkYON4gYTa7LoBepyDS2TZtycmPklgA_AI_Zg-TwaN0nCOA4LSR49GwgHjGbyxANffRp1fZ9q84zkFtrXZ_36j59F_J8E5FLGkyxQ/s1600/vscode-dotnet-run.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="337" data-original-width="1093" height="122" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAWKUtga1jWEVFdtYF0r2jSRm6ZANXxgGWbZObPhwkYON4gYTa7LoBepyDS2TZtycmPklgA_AI_Zg-TwaN0nCOA4LSR49GwgHjGbyxANffRp1fZ9q84zkFtrXZ_36j59F_J8E5FLGkyxQ/s400/vscode-dotnet-run.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Our command appears to run. With no command line parameters, all release does is display help. We haven't done any real work yet but it's encouraging that our .NET Framework code has not needed any changes to work in .NET Core.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Now we can try the various actions available in the release command to test that they work.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We again use the <b><span style="color: #666666;">dotnet run</span></b> command to execute our command, but we can pass the same parameters we would give to release.exe.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet run hash <span style="color: #666666;">file</span></b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The <span style="color: #666666;">hash <i>file</i></span> parameters tell the release command to display the hash code for the specified file. This works fine.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikLeFZHNeZXCDq08wYffotGCcE4AD4mJyA8-5tBudafwDH-ZjHj0ef81x9cZXd1pc0onegP-p1r_mpdBqv42-fSHidgHL0-PJTBDX8jqgTfJAjjVJEMC3RLAlYKkuCn-_lnLU1bCt75h0/s1600/vscode-dotnet-run-hash.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="157" data-original-width="1110" height="56" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEikLeFZHNeZXCDq08wYffotGCcE4AD4mJyA8-5tBudafwDH-ZjHj0ef81x9cZXd1pc0onegP-p1r_mpdBqv42-fSHidgHL0-PJTBDX8jqgTfJAjjVJEMC3RLAlYKkuCn-_lnLU1bCt75h0/s400/vscode-dotnet-run-hash.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet run create 0001.dir</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Next we'll try the <span style="color: #666666;">create <i>manifest-file</i></span> edition of the release command, which creates a release manifest file containing filenames and hash codes.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbwrJeT1KFwwE-g3qOETQCwMqCN27MbaEQGVD1VXE2zpTL4Tm4bK_ENr6eCT7INFdTSfrFmy7rO1SK7vg-rvlVHd2Q9_8tTZxRYZ911oXuORjCWEBA5X9_ShE2FxN50hWgSQPIlQqNeEs/s1600/vscode-dotnet-run-create.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="438" data-original-width="1052" height="165" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbwrJeT1KFwwE-g3qOETQCwMqCN27MbaEQGVD1VXE2zpTL4Tm4bK_ENr6eCT7INFdTSfrFmy7rO1SK7vg-rvlVHd2Q9_8tTZxRYZ911oXuORjCWEBA5X9_ShE2FxN50hWgSQPIlQqNeEs/s400/vscode-dotnet-run-create.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
This again works as expected, generating the following ouput in manifest file 0001.dir:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV2Ri72lIaimB0wav7qtU-_8f7uIW8dE-SKdx4OW8IRqt9WznhgNMHWDNyQCgo_j-Ls-kfUypxozLo5QsM02AE1L-W42qrbxqDRLr8M9Hxan90foXpDbiz2FhW-e4aNBnxvnH1YYjAysk/s1600/vscode-0001-dir.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="433" data-original-width="809" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgV2Ri72lIaimB0wav7qtU-_8f7uIW8dE-SKdx4OW8IRqt9WznhgNMHWDNyQCgo_j-Ls-kfUypxozLo5QsM02AE1L-W42qrbxqDRLr8M9Hxan90foXpDbiz2FhW-e4aNBnxvnH1YYjAysk/s320/vscode-0001-dir.png" width="320" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet verify 0001.dir</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
The last version of the release command we'll test is <b><span style="color: #666666;">verify <i>manifest-file</i></span></b>, which reads a manifest and checks its hash codes against what it sees in the file systems, reporting any differences or missing files.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsVDgsx8dfUJ68QXGZcOad2cKu0pnko1a4auf-Q829_F74ruI0fmKpWw3Tbyb1Sm5vY9pRnsWnqQvdfdCQrP2dIMqhB_LV5VUULHCL684pqCG_qjScgl85mjiIJovrT9FqjKidpyjPD34/s1600/vscode-dotnet-run-verify.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="124" data-original-width="402" height="121" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsVDgsx8dfUJ68QXGZcOad2cKu0pnko1a4auf-Q829_F74ruI0fmKpWw3Tbyb1Sm5vY9pRnsWnqQvdfdCQrP2dIMqhB_LV5VUULHCL684pqCG_qjScgl85mjiIJovrT9FqjKidpyjPD34/s400/vscode-dotnet-run-verify.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Once again, the command is working great. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2 style="clear: both; text-align: left;">
Publishing to Windows</h2>
<div class="separator" style="clear: both; text-align: left;">
At this point, we've rather effortlessly imported our original .NET Framework code for the release command into .NET Core via Visual Studio Code, built it, and tested it. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We would now like to generate an actual .exe so that we can run this command on any Windows system without needing to use the <b><span style="color: #666666;">dotnet run</span></b> command. To do this, we use the <b><span style="color: #666666;">dotnet publish</span></b> command, specifying parameters targeting a particular environment<span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span>in this case, 64-bit Windows 10:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet publish -r win10-x64</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
If we look in our /bin/Debug/netcoreapp2.2 folder, there is now a win10-x64 subfolder which contains our release.exe. If we copy the files in this folder (release.exe, all .dlls, all .json files) to c:\Windows\System32 or better yet to a folder contained in our PATH, we can now run the release command the way it was intended to be used from any Windows command prompt:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVXUXS4vatRzB4wVLnRkzyiIMLZFUsYCXxzpcwwZHl_5Qv1PUwLCdzNPJO7eAAtWTlKzwPevKrjGhIgH3Vr0rAHN_vIzy-5mbqE6Hi7Wr7CrNBZ4U-O4_ssM3vmcYvRgfQASd2K4RLz4w/s1600/vscode-release-exe.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="319" data-original-width="719" height="176" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVXUXS4vatRzB4wVLnRkzyiIMLZFUsYCXxzpcwwZHl_5Qv1PUwLCdzNPJO7eAAtWTlKzwPevKrjGhIgH3Vr0rAHN_vIzy-5mbqE6Hi7Wr7CrNBZ4U-O4_ssM3vmcYvRgfQASd2K4RLz4w/s400/vscode-release-exe.png" width="400" /></a><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVXUXS4vatRzB4wVLnRkzyiIMLZFUsYCXxzpcwwZHl_5Qv1PUwLCdzNPJO7eAAtWTlKzwPevKrjGhIgH3Vr0rAHN_vIzy-5mbqE6Hi7Wr7CrNBZ4U-O4_ssM3vmcYvRgfQASd2K4RLz4w/s1600/vscode-release-exe.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"></a></div>
<div class="separator" style="clear: both;">
What we just did works, but involves a larger number of files than we would like. We can reduce the number of output files by creating a Self-Contained Deployment. We can generate an SCD by specifying the <b>-c Release</b> option to dotnet publish. This generates a smaller number of files in a Release/Win10-x64 folder.</div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
<b>dotnet publish -c Release -r win10-x64</b></div>
<div class="separator" style="clear: both;">
<br /></div>
<div class="separator" style="clear: both;">
Now that we've got our .NET Core console program working in Windows, it's time to publish it to additional platforms.</div>
<div class="separator" style="clear: both;">
<br /></div>
<h2 style="clear: both; text-align: left;">
Publishing to Linux</h2>
<div class="separator" style="clear: both; text-align: left;">
With .NET Core, we can stay right where we are on our Windows machine and generate a Linux release.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
To create a Linux executable, we will again use the <b><span style="color: #666666;"> dotnet publish</span></b> command just as we did a moment ago, but with different parameters. The -r parameter targets the particular Linux distribution and version we have in mind. In this case, I'll target Ubuntu 18 64-bit because that's available for the AWS free tier:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both;">
<b>dotnet publish -c Release --self-contained -r ubuntu.18.04-x64</b></div>
<div>
<br /></div>
<div>
This produces a set of files under bin/Release/netcoreapp2.2\ubuntu.18.04-x64</div>
<div>
<br /></div>
<div>
We can't test this without a Linux instance. I did the following to create an Ubuntu Linux instance on AWS and install .NET Core and my application:</div>
<div>
<br /></div>
<div>
1. Allocate a Linux instance on AWS. In my case, running Ubuntu 18.04,64-bit. Wait for it to initialize.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
2. Connect to the instance from the AWS console via SSH. In my case, I used the <a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/latest.html" target="_blank">PuTTY utility for Windows</a>. Note that connecting from the AWS Console via PuTTY on Windows did not work until I made some permission changes on my .pem key file as per the instructions <a href="https://superuser.com/questions/1309447/how-to-secure-ssh-private-key-on-windows-10" target="_blank">here</a>.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
3. On the Linux instance, in a browser, install the <a href="https://dotnet.microsoft.com/download" target="_blank">Dotnet Core Runtime</a>. I did this by following the instructions <a href="https://dotnet.microsoft.com/download/linux-package-manager/ubuntu18-04/runtime-2.2.0" target="_blank">here</a>. Once completed verify the dotnet command works. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmkzxwzMjEe5pRYIZGcJnXUgxKtAeIFyqVPiHFtwEQ69U3kwMj-jcdp9AvgPC_1DbQB8wZZnzDTIyDoq7tN12t7rd4wGcrQjWXvhuAftEoqAnq0rJLqV1ufyxD68Oy2rxPmrYZty-fhxE/s1600/ubuntu-install-dotnet-runtime.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="810" data-original-width="719" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmkzxwzMjEe5pRYIZGcJnXUgxKtAeIFyqVPiHFtwEQ69U3kwMj-jcdp9AvgPC_1DbQB8wZZnzDTIyDoq7tN12t7rd4wGcrQjWXvhuAftEoqAnq0rJLqV1ufyxD68Oy2rxPmrYZty-fhxE/s400/ubuntu-install-dotnet-runtime.png" width="355" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
4. Copy the files in the publish folder (/bin/Release/netcoreapp2.2/ubuntu.18.04-x64/publish) generated by the dotnet publish command up to the Linux instance. If you're a Linux newbie, you might struggle mightily with transfer commands like SCP and PSCP (I certainly have). I like to use the WinSCP tool for file transfers, as described <a href="https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/putty.html" target="_blank">here</a>.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjztyjtMkBg9sM_vcdd3UKpnD7kWB8YHDyibxvDVydTg_HqvwpXPPyVP4jKCR5OFXDzRwrXqKJdBHB4pbwK8ePxiX9IsU-MTG3swXH5VMRVy1XImJhEj0O9j2PtcusuCdkr9EBSOIaVtYI/s1600/ubuntu-winscp.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="727" data-original-width="1097" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjztyjtMkBg9sM_vcdd3UKpnD7kWB8YHDyibxvDVydTg_HqvwpXPPyVP4jKCR5OFXDzRwrXqKJdBHB4pbwK8ePxiX9IsU-MTG3swXH5VMRVy1XImJhEj0O9j2PtcusuCdkr9EBSOIaVtYI/s400/ubuntu-winscp.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFw3co8nCvdwbGLc2Hi28twCwOPdJWocpiqfc0O7AyiFFstz0znyWgGwl8pgfudHSu9B7CYw1Ay2ARo7wU9qeMRo564iJhmVyikBk95p1NEywNpiO5VbLN2F4PMXztL2QlZXviQLCIfFc/s1600/ubuntu-winscp-after.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="727" data-original-width="1097" height="265" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFw3co8nCvdwbGLc2Hi28twCwOPdJWocpiqfc0O7AyiFFstz0znyWgGwl8pgfudHSu9B7CYw1Ay2ARo7wU9qeMRo564iJhmVyikBk95p1NEywNpiO5VbLN2F4PMXztL2QlZXviQLCIfFc/s400/ubuntu-winscp-after.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
5. On the Linux machine (via SSH or PuTTY), from the folder containing the publish files, you can now run the command with <b>dotnet release.dll. </b>At first glance, things seem to be working well<span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span>but we need to be exhaustive in our testing.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet release.dll</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7_4xi00J4Fk7-EzJ9IbIWXJnGcQ5R5g2dP_kjtgmIAc5xnI_lcMSVI-e-OKKb8PaN5n6v_tqRY28b0x7BVjv4YIBp63K8FbB5qJRT0Ie_7Co-D4TqsO59aXJR81736EMZJ9varAtnhF4/s1600/ubuntu-release.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="304" data-original-width="715" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7_4xi00J4Fk7-EzJ9IbIWXJnGcQ5R5g2dP_kjtgmIAc5xnI_lcMSVI-e-OKKb8PaN5n6v_tqRY28b0x7BVjv4YIBp63K8FbB5qJRT0Ie_7Co-D4TqsO59aXJR81736EMZJ9varAtnhF4/s400/ubuntu-release.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet release.dll hash mscorlib.dll</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXE5EfWv4VVM_58h8sVA2CravKMqDB83GjdcM_5MPDBD20b0kNpIYpKpyBQX5Jbi-6DHxNjJe6LDNrk2xTXS9wOmi1kUuntcMDtaoqDmndENhr2yFh5_lXDi1iydNXb7qa_FSNHMDuhGM/s1600/ubuntu-release-hash.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="304" data-original-width="715" height="170" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjXE5EfWv4VVM_58h8sVA2CravKMqDB83GjdcM_5MPDBD20b0kNpIYpKpyBQX5Jbi-6DHxNjJe6LDNrk2xTXS9wOmi1kUuntcMDtaoqDmndENhr2yFh5_lXDi1iydNXb7qa_FSNHMDuhGM/s400/ubuntu-release-hash.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet release.dll create 0001.dir</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-JbaXS2qggd-teXEDeAkCvd0WarRevZtQYWDrh0nPrO6Lbw8StOlVMa-Nva58Bo_HPKkfwusR5c-ASneu2ScGuFkMW7O_9XhKmPAPMSlHaQAGFTiCdbt5DXES36N6v4T0NWhDYXull2w/s1600/ubuntu-release-create.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="422" data-original-width="715" height="235" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-JbaXS2qggd-teXEDeAkCvd0WarRevZtQYWDrh0nPrO6Lbw8StOlVMa-Nva58Bo_HPKkfwusR5c-ASneu2ScGuFkMW7O_9XhKmPAPMSlHaQAGFTiCdbt5DXES36N6v4T0NWhDYXull2w/s400/ubuntu-release-create.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<b>dotnet release.dll verify 001.dir</b></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Here we ran into trouble: the <span style="color: #666666;">verify </span>operation thought every file in the manifest directory file did not match the local file system. A quick inspection of the code revealed why: it was written for Windows, and presumes that backslashes are used to separate folders in paths.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Well, that's easy enough to correct. We modified our code to support both backslash and forward-slash paths. Here's an example of one of the areas of code that had to be augmented:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-RuPozrULaClI8WIKSgfDkkxsckn5eDxyNLjh46poN6Sb8N7qbZauZxPxjPdds5JtjeLwA-GQblSOGukXKQ8sLXSuBEFJt-0od7RukV2emdEXzXguJk9K0XnIhyphenhyphenZCtRncBw5F-nXsOns/s1600/release-modify.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="867" data-original-width="1600" height="216" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-RuPozrULaClI8WIKSgfDkkxsckn5eDxyNLjh46poN6Sb8N7qbZauZxPxjPdds5JtjeLwA-GQblSOGukXKQ8sLXSuBEFJt-0od7RukV2emdEXzXguJk9K0XnIhyphenhyphenZCtRncBw5F-nXsOns/s400/release-modify.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
With the above change in place, we again test<span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span>on both Windows as well as Linux<span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span>to confirm the release command is now fully working. It is! Below is a a run of the <span style="color: #666666;">verify </span>operation on Ubuntu Linux after posting an updated release where a few of the files have changed. The release command is working just as it supposed to, confirming 193 files checked and 2 files different.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1FFn1_Yh1HHRB85Pf0UTVRfKwr5JYgz5v0VcoVCwn6oaUDQWqk6Mhll4eHHQy3WQXjpgD956FNjaIuTiwEcmWt9coqlulxCV3ByMFsGWIo2uup4DaKa7deuBlNB4qvasMoart3WP8pYI/s1600/release-verify-ubuntu.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="304" data-original-width="705" height="171" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh1FFn1_Yh1HHRB85Pf0UTVRfKwr5JYgz5v0VcoVCwn6oaUDQWqk6Mhll4eHHQy3WQXjpgD956FNjaIuTiwEcmWt9coqlulxCV3ByMFsGWIo2uup4DaKa7deuBlNB4qvasMoart3WP8pYI/s400/release-verify-ubuntu.png" width="400" /></a></div>
<div style="clear: both; text-align: left;">
Our <b style="font-size: medium;">release </b><span style="font-size: small; font-weight: 400;">command now works on Linux!</span></div>
<div style="clear: both; text-align: left;">
<span style="font-size: small; font-weight: 400;"><br /></span></div>
<h2 style="clear: both; text-align: left;">
Publishing to MacOS</h2>
<div class="separator" style="clear: both; text-align: left;">
We can publish to MacOS by specifying an OSX release. To deploy, I'll be borrowing my wife's Macbook Air which is running OSX 10.14; the publish command we need to use therefore is:</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both;">
<b>dotnet publish -c Release -r osx.10.14-x64</b></div>
<div>
<br /></div>
<div>
The steps to deploy our application on MacOS are:</div>
<div>
<br /></div>
<div>
1. Run the above <b><span style="color: #666666;">dotnet publish</span></b> command (adjusted for the version of MacOS you are targeting) to generate a publish folder for MacOS.</div>
<div>
<br /></div>
<div>
2. On the Mac, in a browser, visit <a href="http://dotnet.microsoft.com/download">http://dotnet.microsoft.com/download</a> and download the .NET Core Runtime for MacOS. Open the download to install. Test it works by opening a Terminal window and entering <b><span style="color: #444444;">dotnet</span></b>.</div>
<div>
<br /></div>
<div>
3. Transfer your application files to the Mac. First copy the application files from your Windows PC OSX publish folder (in /bin/Release/netcoreapp2.2/osx.10.14-x64/publish) to a thumbdrive. Then plug the thumbdrive into the Mac. Create a new folder under Applications and copy the publish files there. For my application that folder is Applications/Release.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI0eC8jDHKH49yGsMI4SW_nSb-Z_dun_9L2QFpXWhqpJuER4mZBBb9dnUGuN6QvhnoNn8Hwa7IMqRea0cb2y2ssFCOHezmQrXpapzrmc-In66DZ8wMgDiGIi6MlRKmkX_yJlB8pVvkKZc/s1600/macos_copy_files.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="851" data-original-width="882" height="385" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiI0eC8jDHKH49yGsMI4SW_nSb-Z_dun_9L2QFpXWhqpJuER4mZBBb9dnUGuN6QvhnoNn8Hwa7IMqRea0cb2y2ssFCOHezmQrXpapzrmc-In66DZ8wMgDiGIi6MlRKmkX_yJlB8pVvkKZc/s400/macos_copy_files.png" width="400" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
4. In a Terminal window, CD to the folder from Step 3 where the files were placed. Run the release command with <b>dotnet release.dll </b>followed by any command line arguments.</div>
<div>
<br /></div>
<div>
<b>dotnet release.dll</b></div>
<div>
<br /></div>
<div>
The dotnet release.dll command (with no arguments) simply displays help, and tells us our program is intact and able to execute on MacOS:</div>
<div>
<br /></div>
<div>
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_37jtJNChyphenhypheneom1_q9MGrh4hH0wG4z-L0tDRoNKVO-jrW2aM-EqrKTIZndUK5AdMGM9afnZQHd8gvW9k2FjGnrekK6Rbhkho01Hg8iYYntU16LJacpPXnPBJmWclLw04AgNoYllUh9TN0/s1600/macos_release.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="477" data-original-width="697" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_37jtJNChyphenhypheneom1_q9MGrh4hH0wG4z-L0tDRoNKVO-jrW2aM-EqrKTIZndUK5AdMGM9afnZQHd8gvW9k2FjGnrekK6Rbhkho01Hg8iYYntU16LJacpPXnPBJmWclLw04AgNoYllUh9TN0/s400/macos_release.png" width="400" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>dotnet release.dll create 0001.dir</b></div>
<div>
<br /></div>
<div>
The <b><span style="color: #666666;">create <i>manifest-file</i></span></b> operation hashes files in the current working directory and any subfolders and created a manifest directory file with has codes.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaRFiqFh6Os3atXm-43dW4PHE36mUDGXQhsV6E-E0TtegEkA7WJYPiHvKQ5Sk97PU_cuRDhVEZfKETKyO_IHf4pN6KBQokW6QUDUBvIkGlMk3Q6f8U2Y4qXIbOa77ds2VtDcDcF_9T3vA/s1600/macos_create.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="477" data-original-width="697" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaRFiqFh6Os3atXm-43dW4PHE36mUDGXQhsV6E-E0TtegEkA7WJYPiHvKQ5Sk97PU_cuRDhVEZfKETKyO_IHf4pN6KBQokW6QUDUBvIkGlMk3Q6f8U2Y4qXIbOa77ds2VtDcDcF_9T3vA/s400/macos_create.png" width="400" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>cat 0001dir</b></div>
<div>
<br /></div>
<div>
Here's the manifest file that was created:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKV7tlhXZPboDsoO9eKD97qc3hg9BCfU-igIeNAFfXBA7p7sOQtTX6gZf1fro9oJXtajqFzpnv8KtFonzl2KyAdwOpostXOxkIVItXNAcMLRvftxamrm6NqBlLU77QwjcX6XzMjmbCUJ0/s1600/macos_manifest.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="477" data-original-width="697" height="218" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKV7tlhXZPboDsoO9eKD97qc3hg9BCfU-igIeNAFfXBA7p7sOQtTX6gZf1fro9oJXtajqFzpnv8KtFonzl2KyAdwOpostXOxkIVItXNAcMLRvftxamrm6NqBlLU77QwjcX6XzMjmbCUJ0/s320/macos_manifest.png" width="320" /></a></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<br /></div>
<div>
<b>dotnet release.dll verify 0001.dir</b></div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Finally, here's the <b><span style="color: #666666;">verify <i>manifest-file</i></span></b> operation, which reads the manifest file and verifies it against the file system. </div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfMhcUIXoN6vMGBERowOcAwfrjv73os0HMWydqTMhrEnheJ41I40Yk4qY0iWxiCStPnuLCb5TDhPtzg0hdiOM6oF9KXG3IkA_n7XwXOrSNMQAw3w_CNAmyxvre63NjgIyA5nWv4GoIqxE/s1600/macos_verify.png" imageanchor="1" style="clear: left; float: left; margin-bottom: 1em; margin-right: 1em;"><img border="0" data-original-height="477" data-original-width="697" height="272" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfMhcUIXoN6vMGBERowOcAwfrjv73os0HMWydqTMhrEnheJ41I40Yk4qY0iWxiCStPnuLCb5TDhPtzg0hdiOM6oF9KXG3IkA_n7XwXOrSNMQAw3w_CNAmyxvre63NjgIyA5nWv4GoIqxE/s400/macos_verify.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
Our <b>release </b>command now works on MacOS!</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2 style="clear: both; text-align: left;">
Post-Mortem: Cross-Platform Support for .NET Core</h2>
<div class="separator" style="clear: both; text-align: left;">
In this post, we've shown how .NET Core code can generate output that runs not only on Windows but also on Linux and MacOS. We ported a .NET Framework console program to .NET Core and proved it could run on all three operating systems.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Our initial development was on Windows, but needn't have been. Everything that was done on Windows in this article could just as easily been done on Linux or MacOS using the .NET Core SDK and Visual Studio Code.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
We demonstrated Linux support by targeting Ubuntu Linux with the<b> <span style="color: #666666;">dotnet publish</span></b><span style="color: #666666;"> </span>command. On AWS, I instantiated a Linux server. On the server we ran some terminal commands to install .NET Core Runtme, then copied our files from the Ubuntu publish folder to a folder on the Linux box. Adminittedly, this took several hours: I struggled with setting up ssh and trying to copy files with scp. There were lots of little gotchas, such as having to change permissions on the AWS .pem (key) file. Ultimately, the PuTTY and winscp tools made things easier for this longtime Windows developer. With the Linux-basics learning curve behind me, I'm confident my next time around deploying .NET Core apps to Linux will go much more rapidly.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
As the console program we ported was a release utility that accesses the file system, we did need to make some changes<span style="background-color: #f9f9f9; color: #333333; font-family: "open sans" , "helvetica neue" , "helvetica" , "arial" , sans-serif; font-size: 14px;">—</span>but only because the original code presumed Windows file pathing with backslashes. The modified code is far more useful because it can work across multiple operating systems. It only took about an hour to modify the code and test that the program still worked correctly on each OS.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
To get up and running on the Mac, things went quite quickly. Rather than connecting remotly to an AWS VM, I had the Mac in front of me. I used a browser to download .NET Core Runtime, and a thumbdrive to transfer files using the Finder. In a Terminal window, testing the program on MacOS went smoothly and everything worked the very first time I tried it.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2 style="clear: both; text-align: left;">
Conclusion</h2>
<div class="separator" style="clear: both; text-align: left;">
.NET has certainly come a long way from its debut in 2000. .NET Core does introduce some changes, not all of them pleasant, but the changes are there for good reasons. If you've been dragging your feet on .NET Core, I urge rethinking your position. .NET Core adoption is rampant. Microsoft is producing platforms like .NET Core and tools like Visual Studio Code in order to win over developers regardless of their preferred operating system, and it is working because they are very well done.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Being able to use .NET Core and C# for development yet target other operating systems is huge. Not only are many companies using .NET Core, many of them are using for non-Windows deployments: a clear sign of that, if you peruse job postings, is how many companies are advertising for .NET Core skills targeting deployment to Linux.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Next: <a href="http://davidpallmann.blogspot.com/2019/04/create-and-host-cross-platform-web-site.html">Create and Host a Cross-Platform Web Site on ASP.NET Core</a></div>
David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com1tag:blogger.com,1999:blog-9132148272745668459.post-54291719989949052552019-02-26T07:05:00.006-08:002019-02-26T11:28:33.787-08:00CIA World Factbook on AWS, Part 3: Alexa Voice Interface using Lambda and DynamoDB<style>
.tr0 { background-color: white; color: black; font-weight: bold; }
.tr1 { background-color: white; }
.tr2 { background-color: aliceblue; }
.syntaxhighlighter {
overflow-y: auto !important;
overflow-x: auto !important;
max-height: 512px;
}
</style>
<script>
if (location.protocol != 'http:')
{
location.href = 'http:' + window.location.href.substring(window.location.protocol.length);
}
</script>
In this 3-part series, I'm showing how you can take CIA World Factbook data and use it for your own purposes on Amazon Web Services. Previously in <a href="http://davidpallmann.blogspot.com/2019/02/cia-world-factbook-data-on-aws-part-1.html" target="_blank">Part 1</a> we created the back-end to collect data and store it in DynamoDB and S3 storage, using a Lambda Function to insert document records. In <a href="http://davidpallmann.blogspot.com/2019/02/cia-world-factbook-data-on-aws-part-2.html" target="_blank">Part 2</a> we created a Lambda API for data access and a <a href="http://world-factbook.aws.davidpallmann.com/" target="_blank">web site</a> for browsing, searching, and viewing charts. <span style="text-align: center;">Today in Part 3 we're creating an Alexa Skill so that the world country data can be accessed by voice.</span><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB3hd4DWcgAJ0KylnN1bbsuIfxhCyou5ePYClzyDueih3GA1ORl0uz7WJgQJRsqf1ckKPmSlyEeuaQMViLWrUKU0zV4oMsX1HOilXoaUaIIXPNm6tlbeYdTbKs3sI9fKJ83c-4WDGT1aM/s1600/arch.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="911" data-original-width="1600" height="227" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjB3hd4DWcgAJ0KylnN1bbsuIfxhCyou5ePYClzyDueih3GA1ORl0uz7WJgQJRsqf1ckKPmSlyEeuaQMViLWrUKU0zV4oMsX1HOilXoaUaIIXPNm6tlbeYdTbKs3sI9fKJ83c-4WDGT1aM/s400/arch.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<br /></div>
<h2>
What We're Building</h2>
Unless you've been living under a rock, you know that Amazon's cloud-based voice service is named Alexa and can be accessed from... well, anywhere: devices like the Amazon Echo and Dot; on your TV via Amazon FireStick; in a variety of cars; and many other places. Even if you don't own an Alexa-enabled device, you can get to right now on the web at <a href="https://alexa.amazon.com/">https://alexa.amazon.com</a>; or from your phone using the Alexa app.<br />
<br />
You can access the country data skill with <b>"Alexa, Open World Country Data"</b>.<br />
<br />
We are going to create an Alexa Skill (voice app) named World Country Data, backed by a Lambda Function that responds to spoken inquiries. The Lambda Function will query the DynamoDB database to retrieve country data.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjx3m3G6rPZPtii7Rs8aavkAWQDCEQzQ-BH8wfeStVkYLamij6ujcLIvF3s9qNi5ZWyodIimslZM4RTVCgSldW6y1EkaV7eCqUmIfQztC_1ZlB1mIC8pWFCtcHrOTRfGpG_g8GmEUR8fYs/s1600/dialog_main.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="719" data-original-width="436" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjx3m3G6rPZPtii7Rs8aavkAWQDCEQzQ-BH8wfeStVkYLamij6ujcLIvF3s9qNi5ZWyodIimslZM4RTVCgSldW6y1EkaV7eCqUmIfQztC_1ZlB1mIC8pWFCtcHrOTRfGpG_g8GmEUR8fYs/s400/dialog_main.png" width="242" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>World County Data Dialog</i></div>
<br />
The Alexa skill will be able to respond to inquiries like these:<br />
<br />
<ul>
<li>What is the population of <i>country</i>?</li>
<li>Where is <i>country</i>?</li>
<li>How large is <i>country</i>?</li>
<li>What language is spoken in <i>country</i>?</li>
<li>What are the major cities in <i>country</i>?</li>
<li>What countries border <i>country</i>?</li>
<li>What are the natural resources of <i>country</i>?</li>
<li>What are the agricultural products of <i>country</i>?</li>
<li>What are the industries of <i>country</i>?</li>
<li>Give me an overview of <i>country</i></li>
<li>Brief me on the economy of <i>country</i></li>
<li>How many mobile phones are in <i>country</i>?</li>
</ul>
<div>
In addition, a user can also inquire about how countries compare and rank:</div>
<div>
<ul>
<li>Wha country is the largest?</li>
<li>Which countries have the highest exports?</li>
<li>What countries have the most Internet users?</li>
<li>What country has the lowest population?</li>
</ul>
<div>
We also want the ability to play an audio clip:</div>
<div>
<ul>
<li>Play the national anthem of <i>country</i></li>
</ul>
Here's what happens architecturally: spoken inquires from users to Alexa undergo speech recognition, machine learning, and natural language processing. Alexa recognizes an <i>intent </i>and passes it to our Lambda Function. Factbook skill looks up the required data from the DynamoDB which contains JSON records for each country. The function returns a speech response, which in some cases may reference an audio clip. For Alexa devices with a display, the response also includes a <i>card</i>, which displays has a map or flag image (depending on device size). Audio clips and images are stored in S3.<br />
<ul>
</ul>
</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOsyWNrKN_y33ZGJ0kimw9hJqa-hiXSgzMmJcvnVXWgjgKjG3gsJhG2uFf9-cYgxIe7YlVzh-004ONHK9be8emKHljqrS2yMqNJHrdR2O0Vkn-CNAAzy4lDbIvCEM7iFQsdlu0K1Oi2N8/s1600/arch-skill.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="558" data-original-width="1221" height="182" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiOsyWNrKN_y33ZGJ0kimw9hJqa-hiXSgzMmJcvnVXWgjgKjG3gsJhG2uFf9-cYgxIe7YlVzh-004ONHK9be8emKHljqrS2yMqNJHrdR2O0Vkn-CNAAzy4lDbIvCEM7iFQsdlu0K1Oi2N8/s400/arch-skill.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Achitecture of World Country Data Skill</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
Our project will consist of a Alexa Skill (configuration) and a Lambda Function to go with it (code). We'll start with the Alexa skill. Our starting point for the project was the Color Picker sample in Node.js, which provides basic skeleton code for a skill.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<h2>
Alexa Skill</h2>
</div>
<div>
To avoid potential confusion, I should mention that as I started work on this leg of the project, it came to my attention that there is already an <a href="https://www.amazon.com/Laynr-World-Factbook/dp/B01DMQ0QN4" target="_blank">existing World Factbook skill</a> (not from me). Don't confuse that with my skill which is named <a href="https://www.amazon.com/dp/B07P8S976X/ref=sr_1_1?keywords=world+country+data&qid=1551189825&s=digital-skills&sr=1-1-catcorr" target="_blank">World Country Data</a>. The two skills are pretty different in scope, however.</div>
<div>
<br /></div>
<div>
Alexa Skills are created in the Amazon developer portal, developer.amazon.com, not the AWS console. You'll need to register as a developer. Our skill is named World Country Data.</div>
<div>
<br /></div>
<div>
The first area to set up in the skill project are the <i>intents</i>. An intent is something a user is trying to communicate, such as <i>What's the population of {country}</i> and contains a list of <i>utterances</i>. Intents are easy and not easy at the same time: it's simple enough to enter some utterances for the intent and try it out on Alexa. What's not so easy is thinking through all the possible ways someone might phrase an inquiry.</div>
<div>
<br /></div>
<h3>
Scalar Value Inquiries</h3>
<div>
One category of intents we'll have is inquires about scalar values, such as <i>What's the population of {country}?</i>, that return a single value (in this case, a number). Here's our definition for the <span style="color: #666666;">population </span>intent:<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbdR3fUjfWPkPe64kxJbXyXB5kteahrrc88v4Rpj8hL30eZUqvVSwbLsAk1iKXicpts_71XHC2PF_3avw6z_cGjxOEl9defgWbT6ntPBq3d4Qzf0sR7e6i6kHOoSM0zh7b6R5HIvcd4MI/s1600/intent_population.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="864" data-original-width="1021" height="337" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbdR3fUjfWPkPe64kxJbXyXB5kteahrrc88v4Rpj8hL30eZUqvVSwbLsAk1iKXicpts_71XHC2PF_3avw6z_cGjxOEl9defgWbT6ntPBq3d4Qzf0sR7e6i6kHOoSM0zh7b6R5HIvcd4MI/s400/intent_population.png" width="400" /></a></div>
<div>
<br /></div>
<div>
The embedded value {country} is called a <i>slot</i>, which is a type of placeholder. We want to be able to ask these questions about any country. Further down in the intent, we see that the slot <span style="color: #666666;">country </span>is of type <span style="color: #666666;">country</span>, meaning a custom list of country names we will create.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQbblBZrFfq6JhwR7JJk7Kkwq3oUmlGCxqRT6BsGFdp1bhRrRiOAtaoHJjryOM-heRICvcdwqgoYD0hk7rykc4mIKCcFbelHjyr9aKeElknfGScJFpdrDNKRkv_uU9A4M4sI7N8axI2rs/s1600/intent_population2.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="460" data-original-width="1426" height="128" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQbblBZrFfq6JhwR7JJk7Kkwq3oUmlGCxqRT6BsGFdp1bhRrRiOAtaoHJjryOM-heRICvcdwqgoYD0hk7rykc4mIKCcFbelHjyr9aKeElknfGScJFpdrDNKRkv_uU9A4M4sI7N8axI2rs/s400/intent_population2.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: left;">
There have been a number of places in this project where it's been necessary to list 260 individual countries. Defining the possible slot values for <span style="color: #666666;">country </span>is one of them. My fingers are getting a good work out! Technically speaking, the intents would work without listing every possible country here; however, there's a huge improvement in Alexa's understanding and selecting the right intent when the expected slot values are defined.</div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsGz7jOUS3xjHYQxdv-HD0KNDjsKHhnJwSYB6U-MgNGzaPhPX1mcqzlHT4X5imLWo2B31Keba7TmusaA4CVj0667aT9v323KVc0Sa3P6ZsCxVGFMuScRGIii3_ZhbJsxfHJPbMsmlNgXQ/s1600/slot_country.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="832" data-original-width="1600" height="207" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjsGz7jOUS3xjHYQxdv-HD0KNDjsKHhnJwSYB6U-MgNGzaPhPX1mcqzlHT4X5imLWo2B31Keba7TmusaA4CVj0667aT9v323KVc0Sa3P6ZsCxVGFMuScRGIii3_ZhbJsxfHJPbMsmlNgXQ/s400/slot_country.png" width="400" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Defining country Slot Values</i></div>
<div class="separator" style="clear: both; text-align: left;">
<br /></div>
<div>
The response to this intent will be provided by our Lanbda Function, which we'll get to later in this post. We create similar intents for area, climate, terrain, literacy rate, and the number of phones. This hardly scratches the surface of the available data; we'll come back and do more someday.</div>
<div>
<br /></div>
<h3>
Text Narratives</h3>
<div>
Some fields in the country JSON contain paragraph text. For example, there's <span style="color: #666666;">introduction.background</span>, a background preamble on the country; and <span style="color: #666666;">economy.overview</span>, a brief on a country's economy. Technically, retrieving these items is no different than the scalar values described in the prior section; the experience to the user is quite different, however, as Alexa will read on and on. We handle these kind of inquires in the same way, with intents.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj15VOSU3_U1BDHsIl4x8wvcTCw_7jzXFdzCvJoKG3fplhkFkCbPSAG1g8uAupj0oPK7GaPdHXnEHTf_laGz7J1lxiwhK8-zgqNpwdPvoFCxmfoUqWO_WDRbkwP13crp9dWKXxFkqkrGlE/s1600/dialog_overview.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="663" data-original-width="393" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj15VOSU3_U1BDHsIl4x8wvcTCw_7jzXFdzCvJoKG3fplhkFkCbPSAG1g8uAupj0oPK7GaPdHXnEHTf_laGz7J1lxiwhK8-zgqNpwdPvoFCxmfoUqWO_WDRbkwP13crp9dWKXxFkqkrGlE/s400/dialog_overview.png" width="236" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>Alexa Dialog: Country Overview</i></div>
<h3>
Lists</h3>
<div>
Some of the World Factbook data is in the form of lists (JSON object arrays), such as a country's agricultural products or major urban areas.<br />
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgseodf_QiH0EnCE6Q7J8-59O1u2SgoKloBSsDER5VU9MU3Puwx6Dxl4zCaadJXe3z3dYanyg6xBFJKITZZBKOEAt7nFIgD-6l_8wAgwH53BZC-ynuFKQ7YNlp55j-dlqQ2KZqKu5FLyLs/s1600/dialog_list_major_cities.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="407" data-original-width="510" height="255" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgseodf_QiH0EnCE6Q7J8-59O1u2SgoKloBSsDER5VU9MU3Puwx6Dxl4zCaadJXe3z3dYanyg6xBFJKITZZBKOEAt7nFIgD-6l_8wAgwH53BZC-ynuFKQ7YNlp55j-dlqQ2KZqKu5FLyLs/s320/dialog_list_major_cities.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Alexa Dialog: Major Urban Areas</i></div>
<div>
<br /></div>
<div>
Our intents for lists are not much different than our intents for scalar values: the only slot needed is the country name. However, our Lambda Function will need different code to retrieve list data.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXNuwfcnPtMwouhwUm4ry83Y1PyHmNgSmRz_8NoEMET02mQmzPDW4csw8fZkJ07I3LnUEQPpoehOe2BfxN0DByBjG3FBtkuIRuITz6nSrXqZD-QipFLwYvNjAEtRdaL5IzxDMFTB1_DT0/s1600/intent_list_major_cities.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="663" data-original-width="1490" height="142" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXNuwfcnPtMwouhwUm4ry83Y1PyHmNgSmRz_8NoEMET02mQmzPDW4csw8fZkJ07I3LnUEQPpoehOe2BfxN0DByBjG3FBtkuIRuITz6nSrXqZD-QipFLwYvNjAEtRdaL5IzxDMFTB1_DT0/s320/intent_list_major_cities.png" width="320" /></a></div>
<div style="text-align: center;">
<i>Intent major_cities: Utterances</i></div>
<h3>
Top Countries</h3>
<div>
In addition to asking facts about a particular country, a user might want to know which countries are ranked highest or lowest in various categories like area, population, exports, or inflation. In Part 2 we created Lamba functions and database queries to get this information and render column charts. Today we can use the same queries (such as Top 10 exports) and give a response like this: <i>The countries with the largest area are Russia, Antarctica, and Canada</i>.</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7qZzNlvqMNP-cKRlHuSPaFamfwIPQFYGWGRmof5z2ffSIz3tApzfptcPHbbAWQPSHxEq_Rw6v4lHxGhOS8qeLnkAlF-TLaroTMBz2Qzb9-gLoPuUHjLtXh60WijXfcwrYTEeSN0J1KL4/s1600/dialog_top.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="561" data-original-width="486" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi7qZzNlvqMNP-cKRlHuSPaFamfwIPQFYGWGRmof5z2ffSIz3tApzfptcPHbbAWQPSHxEq_Rw6v4lHxGhOS8qeLnkAlF-TLaroTMBz2Qzb9-gLoPuUHjLtXh60WijXfcwrYTEeSN0J1KL4/s400/dialog_top.png" width="346" /></a></div>
<div style="text-align: center;">
<i>Alexa Dialog: Leading Countries</i></div>
<div>
<br /></div>
<div>
As before, our intents need to consider a variety of utterances that convey the same meaning:</div>
<div>
<br /></div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBO_wATYJdFzw58Bm41Ngd5ERcXQaEPC1AXw-iUjqrXPLblRquvNOQjdq5244rde3ldZyAZZIwMuIb1HEODWHIQIMpxIyKKX3rhZx4O74nublpPRNHksazo_e2M7LSSgze_n8opcH8b7Y/s1600/intent_area_highest.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="900" data-original-width="800" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgBO_wATYJdFzw58Bm41Ngd5ERcXQaEPC1AXw-iUjqrXPLblRquvNOQjdq5244rde3ldZyAZZIwMuIb1HEODWHIQIMpxIyKKX3rhZx4O74nublpPRNHksazo_e2M7LSSgze_n8opcH8b7Y/s400/intent_area_highest.png" width="355" /></a></div>
<div style="text-align: center;">
<i>Intent area_highest: Utterances</i></div>
<div>
<br /></div>
<div>
We create intents for largest/smallest area, highest/lowest population, highest/lowest inflation rate, and most Internet users. We'll look at the backing Lambda functions later in this post. Once again, there's so much additional data we could mine. </div>
<div>
<br /></div>
<h3>
Playing National Anthems</h3>
<div>
The CIA World Factbook data includes audio clips for most countries' national anthems. Being able to play this audio in the skill is one of my favorite features.</div>
<div>
<br /></div>
<div>
To support this in our skill took some work, because Alexa imposes some <a href="https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html#audio" target="_blank">limitations on audio clips</a>:</div>
<div>
<ul>
<li>Audio clips must be hosted at an HTTPS endpoint.</li>
<li>The MP3 must be an MPEG version 2 file.</li>
<li>The audio file cannot be longer than 240 seconds.</li>
<li>The bit rate must be 48 kbps.</li>
<li>The sample rate must be 22050Hz, 24000Hz, or 16000Hz.</li>
</ul>
</div>
<div>
These are not great specs for music audio, but we have no choice if we are going to be able to play our clips in our Alexa skill. </div>
<div>
<br /></div>
<div>
After obtaining the audio clips for each country, it was necessary to transform them to meet the above specifications. Following the <a href="https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html#h3_converting_mp3" target="_blank">AWS guidance on audio conversio</a>n, the following steps were performed for each national anthem MP3 file, using a free audio tool named <a href="http://www.audacityteam.org/" target="_blank">Audacity</a>.</div>
<div>
<ol>
<li>Open the nation anthem MP3.</li>
<li>Change the Audactity projects' sampling rate to 16000.</li>
<li>Export the audio to MP3, setting a bit rate of 48kbps.</li>
</ol>
</div>
<div>
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVncdejNbh9hbj5iFu-zo8uttGNV1XpYRcl2Wm11VRxWH8chTHX6d7gY7kvF5vNK_pK3mlNE6JVapI49X5Uncj2UtXoAUHXXq0JCEzImqD7kkOM3zMhGge02fEK6Gk_fDj2vtfbFg2drs/s1600/Audacity.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="707" data-original-width="926" height="305" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjVncdejNbh9hbj5iFu-zo8uttGNV1XpYRcl2Wm11VRxWH8chTHX6d7gY7kvF5vNK_pK3mlNE6JVapI49X5Uncj2UtXoAUHXXq0JCEzImqD7kkOM3zMhGge02fEK6Gk_fDj2vtfbFg2drs/s400/Audacity.png" width="400" /></a></div>
<div style="text-align: center;">
<i>Converting Audio files to 48 kbps with Audacity</i></div>
<br />
After converting all the country national anthem files, they were uploaded to S3 which is where the Alexa Skill will play them from. We'll see how when we look at the backing Lambda Function.</div>
<div>
<br /></div>
<div>
Here's a sample national anthem clip for <a href="https://s3.amazonaws.com/factbookaudio/Austria.mp3" target="_blank">Austria</a>.</div>
<div>
<br /></div>
<h2>
Lambda Function</h2>
<div>
Our Alexa Skill depends on a Lambda Function writtein in Node.js. Starting with the Color Picker sample gives us a basic voice app, which we will now turn into Country World Data. Although this is just one Lambda function, it calls into several sub-functions we'll need to review.<br />
<br />
<h3>
onIntent</h3>
The onIntent function responds to an intent by calling an appropriate handler function based on the intent name:
<br />
<br />
<ul>
<li>Scalar value requests and text briefing requests are handled by the <span style="color: #666666;">lookup </span>function.</li>
<li>List value requests are handled by the <span style="color: #666666;">lookupList </span>function.</li>
<li>Top countries in a category requests are handled by the <span style="color: #666666;">lookupTop </span>function.</li>
</ul>
<pre class="brush:javascript">/**
* Called when the user specifies an intent for this skill.
*/
function onIntent(intentRequest, session, callback) {
console.log(`onIntent requestId=${intentRequest.requestId}, sessionId=${session.sessionId}`);
const intent = intentRequest.intent;
const intentName = intentRequest.intent.name;
if (intentName === 'about') { lookup('introduction.background', '{value}{end}', intent, session, callback); }
else if (intentName === 'area') { lookup('geography.area.total.value', '{country} is {value} square kilometers in size.{end}', intent, session, callback); }
else if (intentName === 'climate') { lookup('geography.climate', '{value}{end}', intent, session, callback); }
else if (intentName === 'count_mobile_phones') { lookup('communications.telephones.mobile_cellular.total_subscriptions', 'There are {value} mobile phones in {country}.{end}', intent, session, callback); }
else if (intentName === 'count_land_phones') { lookup('communications.telephones.fixed_lines.total_subscriptions', 'There are {value} land lines in {country}.{end}', intent, session, callback); }
else if (intentName === 'economy') { lookup('economy.overview', '{value}{end}', intent, session, callback); }
else if (intentName === 'terrain') { lookup('geography.terrain', '{value}{end}', intent, session, callback); }
else if (intentName === 'where') { lookup('geography.location', '{value}{end}', intent, session, callback); }
else if (intentName === 'population') { lookup('people.population.total', 'The population of {country} is {value}{end}.', intent, session, callback); }
else if (intentName === 'urban_population') { lookup('people.urbanization.urban_population.value', 'The urban population of {country} is {value} percent.{end}', intent, session, callback); }
else if (intentName === 'literacy_rate') { lookup('people.literacy.total_population.value', 'The literacy rate of {country} is {value} percent.{end}', intent, session, callback); }
else if (intentName === 'play_national_anthem') { lookup(null, '{audio}{end}', intent, session, callback); }
else if (intentName === 'agricultual_products') { lookupList('economy.agriculture_products.products', null, '{country} has these agricultural products: {list}.{end}', intent, session, callback); }
else if (intentName === 'bordered_by') { lookupList('geography.land_boundaries.border_countries', 'country', '{country} is bordered by: {list}.{end}', intent, session, callback); }
else if (intentName === 'industries') { lookupList('economy.industries.industries', null, '{country} has these industries: {list}.{end}', intent, session, callback); }
else if (intentName === 'languages') { lookupList('people.languages.language', 'name', 'In {country}, these languages are spoken: {list}.{end}', intent, session, callback); }
else if (intentName === 'major_cities') { lookupList('people.major_urban_areas.places', 'place', 'In {country}, the major urban areas are: {list}.{end}', intent, session, callback); }
else if (intentName === 'resources') { lookupList('geography.natural_resources.resources', null, '{country} has these natural resources: {list}.{end}', intent, session, callback); }
else if (intentName === 'area_highest') { lookupTop('report-area-highest', 'The countries with the largest area are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'area_lowest') { lookupTop('report-area-lowest', 'The countries with the smallest area are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'exports_highest') { lookupTop('report-exports-highest', 'The countries with the highest exports are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'exports_lowest') { lookupTop('report-exports-lowest', 'The countries with the lowest exports are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'imports_highest') { lookupTop('report-imports-highest', 'The countries with the highest imports are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'imports_lowest') { lookupTop('report-imports-lowest', 'The countries with the lowest imports are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'internet_users_most') { lookupTop('report-internet-users-highest', 'The countries with the most Internet users are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'population_highest') { lookupTop('report-population-highest', 'The countries with the highest population are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'population_lowest') { lookupTop('report-population-lowest', 'The countries with the lowest population are {country1}, {country2}, and {country3}.{end}', intent, session, callback); }
else if (intentName === 'AMAZON.HelpIntent') { help(intent, session, callback); }
else if (intentName === 'AMAZON.StopIntent' || intentName === 'AMAZON.CancelIntent') { handleSessionEndRequest(callback); }
else if (intentName === 'AMAZON.FallbackIntent') { huh(intent, session, callback); }
else { throw new Error('Invalid intent: ' + intentName); }
}
</pre>
<div style="text-align: center;">
<i>onIntent function</i></div>
<div style="text-align: center;">
<br />
<div style="text-align: left;">
Now let's take a look at our three primary handlers: lookup, lookupList, and lookupTop.<br />
<br /></div>
</div>
<h3>
lookup</h3>
<div>
<br /></div>
<span style="color: #666666;">lookup </span>is called to get a scalar value, such as the <span style="color: #666666;">people.population.total</span> value in the JSON below.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGIsSwOYi_OxzYPfan7Hh_potKfPGPQipSqriTZVLzqPQmc-tHvvIiY07JAynFowcqbDgOmcZo08tzGNSt0fxtJZKE7NWwnc_fxpk01WiulGphxxR_wP-h9vzUUfR9AFaasu9Fur2mEZw/s1600/json_population.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="536" data-original-width="387" height="320" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhGIsSwOYi_OxzYPfan7Hh_potKfPGPQipSqriTZVLzqPQmc-tHvvIiY07JAynFowcqbDgOmcZo08tzGNSt0fxtJZKE7NWwnc_fxpk01WiulGphxxR_wP-h9vzUUfR9AFaasu9Fur2mEZw/s320/json_population.png" width="231" /></a></div>
<div class="separator" style="clear: both; text-align: center;">
<i>JSON snippet - Total Population for Greece</i></div>
<br />
We can call the lookup function with the following path to retrieve the population total:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">lookup('people.population.total', 'The population of {country} is {value}.{end}', intent, session, callback);</span><br />
<br />
The <span style="color: #666666;">lookup </span>function is passed a JSON document path; a response template; and intent, session, and callback variables. The intent can be inspected, the session can be used to store or retrieve session state, and the callback is invoked to return a response. Here's the code to <span style="color: #666666;">lookup</span>:<br />
<pre class="brush:javascript">// --------------- lookup - look up a value - e.g. What is the {property} of {country}? | What is the population of France?
// path: a dotted path to the data, as in people.population.total
function lookup(path, response, intent, session, callback) {
const repromptText = 'Please ask me a country fact, such as "What is the population of France"?';
const sessionAttributes = {};
let shouldEndSession = false;
let speechOutput = '';
FlagImageUrl = null;
MapImageUrl = null;
let cardTitle = 'World Country Data';
let country = normalizeCountryName(intent.slots.country.value);
if (!inCountryList(country)) { // also sets FlagImageUrl & MapImageUrl if country name recognized
console.log('lookup: country not recognized: ' + country);
cardTitle = 'World Country Data - Country Not Recognized';
speechOutput = 'Sorry, I don\'t recognize that country name. ' + Tag;
callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
else {
cardTitle = 'World Country Data - ' + country;
const AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
var params = {
TableName: 'factbook',
ExpressionAttributeNames: {
'#name': 'name',
'#source': 'source'
},
ExpressionAttributeValues: {
':name': country,
':source': 'Factbook'
},
KeyConditionExpression: '#name = :name and #source = :source'
};
docClient.query(params, function(err, data) {
if (err) {
console.log('lookup: Query Error - ' + err.toString());
speechOutput = 'Sorry, an error occurred looking up the data.';
shouldEndSession = true;
} else {
if (!data || data.Items.length===0) {
speechOutput = 'Sorry, I found no data. ' + Tag;
}
else {
try {
response = replace(response, '{country}', country);
response = replace(response, '{value}', eval('data.Items[0].' + path));
response = replace(response, '{end}', Tag);
response = replace(response, '{audio}', '<audio src="https://s3.amazonaws.com/factbookaudio/' + replace(country, ' ', '+') + '.mp3"/>');
speechOutput = response;
}
catch(e) {
console.log('lookup: Exception - ' + e.toString());
speechOutput = "Sorry, I had a problem looking that up.";
shouldEndSession = true;
}
}
// Setting repromptText to null signifies that we do not want to reprompt the user.
// If the user does not respond or says something that is not understood, the session
// will end.
callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
});
}
}
</pre>
<div style="text-align: center;">
<i>lookup function</i></div>
<div style="text-align: center;">
<br /></div>
The above code calls <span style="color: #666666;">normalizeCountryName </span>to normalize the country name (line 14). Many countries have alternate or historical names a user might refer to, and we need to arrive at a standard name that will match the JSON record in DynamoDB and the filenames in S3. For example, a user can request data on America, the U.S., or the U.S.A. and the country name will be normalized to United States.<br />
<br />
Next (lines 16-21) we check whether the country name is in our list of country names. If it isn't, we won't be able to retrieve the requested data and we respond <i>Sorry, I don't recognize that country name</i>. The response speech is routed back by calling <span style="color: #666666;">buildSpeechletResponse</span>, which we'll review later.<br />
<br />
If we do have a recognized country name, it's time to retrieve the requested data. A DynamoDB client is instantiated (lines 24-26), query parameters are set up to retrieve the JSON country record (lines 28-39), and the JSON document is retrieved (lines 41-71). The code uses JavaScript's <span style="color: #666666;">eval </span>function to get to the data, which isn't a great practice; we'll be looking to rewrite that code in the near future and not use <span style="color: #666666;">eval</span>.<br />
<br />
We've been passing spoken responses and referring to them as <i>templates</i>; this is something I created, not an Alexa feature. To return the spoken response, the template response text passed in has values replaced:<br />
<br />
<ul>
<li>{country} is replaced with the normalized country name;</li>
<li>{value} is replaced with the desired value by evaluating the property path that was passed in to the function.</li>
<li>{audio} is replaced with markup for the national anthem sound clip. </li>
<li>{end} is replaced with a 1-second pause and "What else would you like to know?" prompt.</li>
</ul>
The response is passed back to Alexa by calling <span style="color: #666666;">buildSpeechletResponse </span>(line 69).<br />
<br />
The response to <i>What is the population of Greece?</i> is <b>The population of Greece is 10 million 761 thousand 523.</b><br />
<br />
<h3>
lookupList</h3>
<div>
<br /></div>
lookupList is very similar to lookup, but has different code for retrieving the value. Instead of a single property, an array must be iterated through with an inner property extracted to speak. Here's an example of the JSON array for languages in the JSON record for Spain. In this case, the <i>path </i>to the array is<span style="color: #666666;"> people.languages.language</span> but the <i>property </i>to be extracted from each array element is <span style="color: #666666;">name</span>.<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibweCee2Iep4gjhSTRj9SgYIx7L4ouYU-9G1COGNv7dmtxoI5FghqbsQ0n3k9L3MK3s_WQs7WVyE4JgQ750DGaEcWRq3PLXljK2xwopo3uYFr16Y4T2iR93LjgT6_c3QfaM-UGKnyAaWE/s1600/json_languages.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="764" data-original-width="411" height="400" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibweCee2Iep4gjhSTRj9SgYIx7L4ouYU-9G1COGNv7dmtxoI5FghqbsQ0n3k9L3MK3s_WQs7WVyE4JgQ750DGaEcWRq3PLXljK2xwopo3uYFr16Y4T2iR93LjgT6_c3QfaM-UGKnyAaWE/s400/json_languages.png" width="215" /></a></div>
<br />
We can call <span style="color: #666666;">lookupList </span>with the following parameters to extract a list of languages:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">lookupList('people.languages.language', 'name', 'In {country}, these languages are spoken: {list}.{end}', intent, session, callback);</span><br />
<br />
Here's the code to lookupList:<br />
<pre class="brush:javascript">// --------------- lookupList - look up a list - e.g. What languages are spoken in {country}? | What ethnic groups live in France?
// path: a dotted path to array data, as in people.languages.language
// property: property of a list item to vocalize - ex: name
function lookupList(path, property, response, intent, session, callback) {
const repromptText = 'Please ask me a country fact, such as "What is the population of France"?';
const sessionAttributes = {};
let shouldEndSession = false;
let speechOutput = '';
FlagImageUrl = null;
MapImageUrl = null;
let cardTitle = 'World Country Data';
let country = normalizeCountryName(intent.slots.country.value);
if (!inCountryList(country)) { // also sets FlagImageUrl & MapImageUrl if country name recognized
console.log('lookupList: country not recognized: ' + country);
cardTitle = 'World Country Data - Country Not Recognized';
speechOutput = 'Sorry, I don\'t recognize that country name. ' + Tag;
callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
else {
cardTitle = 'World Country Data - ' + country;
const AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
var params = {
TableName: 'factbook',
ExpressionAttributeNames: {
'#name': 'name',
'#source': 'source'
},
ExpressionAttributeValues: {
':name': country,
':source': 'Factbook'
},
KeyConditionExpression: '#name = :name and #source = :source'
};
docClient.query(params, function(err, data) {
if (err) {
console.log('lookupList: Query Error - ' + err.toString());
speechOutput = 'Sorry, an error occurred looking up the data.';
shouldEndSession = true;
} else {
if (!data || data.Items.length===0) {
speechOutput = 'Sorry, I found no data. ' + Tag;
}
else {
try {
var listText = '';
var listData = eval('data.Items[0].' + path);
if (listData != '') {
for (var i = 0; i < listData.length; i++) {
if (i > 0) {
listText += ", ";
}
if (property===null) {
listText += listData[i];
}
else {
listText += listData[i][property];
}
}
}
response = replace(response, '{country}', country);
response = replace(response, '{list}', listText);
response = replace(response, '{end}', Tag);
response = replace(response, '{audio}', '<audio src="https://s3.amazonaws.com/factbookaudio/' + replace(country, ' ', '+') + '.mp3"/>');
speechOutput = response;
}
catch(e) {
console.log('lookupList: Exception - ' + e.toString());
speechOutput = "Sorry, I had a problem looking that up. ";
shouldEndSession = true;
}
}
// Setting repromptText to null signifies that we do not want to reprompt the user.
// If the user does not respond or says something that is not understood, the session
// will end.
callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
});
}
}
</pre>
<div style="text-align: center;">
<i>lookupList function</i></div>
<div style="text-align: center;">
<br /></div>
lookupList is nearly identical to lookup. It also normalizes and validates the country name, and retrieves the JSON country record from DynamoDB. The big difference is lines 56-70 where the code iterates through the array at <i>path </i>and extracts variable <i>property </i>from each array element to form a list to speak. The response template can specify {list} as a placeholder for the list.<br />
<br />
The spoken response to <i>What languages are spoken in Spain?</i> is <b>In Spain, these languages are spoken: Castilian Spanish, Catalan, Galician, Basque, Aranese along with Catalan, speakers</b>.<br />
<br /></div>
<div>
<h3>
listTop</h3>
<div>
<br /></div>
When a user asks a country ranking question like "which countries are largest?", the listTop function handles the request. listTop runs a query to get a Top 10 country list, such as the 10 countries with largest area. These are the same queries we used to get column charts in the web site in <a href="http://davidpallmann.blogspot.com/2019/02/cia-world-factbook-data-on-aws-part-2.html" target="_blank">Part 2</a>.<br />
<br />
We can call <span style="color: #666666;">lookupTop </span>with the following parameters to hear the top countries in a category:<br />
<br />
<span style="font-family: "courier new" , "courier" , monospace;">lookupTop('report-area-highest', 'The countries with the largest area are {country1}, {country2}, and {country3}.{end}', intent, session, callback);</span><br />
<div>
<span style="font-family: "courier new" , "courier" , monospace;"><br /></span></div>
<div>
Here's the code to listTop. The report name parameter is used to set the index, projection expression, and sort direction for the DynamoDB query. The response template may specify {country1}, {country2}, and {country3} for the names of the top 3 countries in the result.</div>
<pre class="brush:javascript">// --------- lookupTop - look up top (leading) countries for a report - e.g. which country has the highest exports?: which countries are biggest?
// report: report name, such as 'report-exports-highest'
// response: speach to output, which may include embeddeed placeholders {country1}, {country2}, {country3}
function lookupTop(report, response, intent, session, callback) {
const repromptText = 'Please ask me a country fact, such as "What is the population of France"?';
const sessionAttributes = {};
let shouldEndSession = false;
let speechOutput = '';
var index = null;
var projectionExpression = null;
var scanIndexForward = true;
var FlagImageUrl = null;
var MapImageUrl = null;
const cardTitle = 'World Country Data';
switch(report) {
case 'report-area-highest':
index = 'rank-area-index';
projectionExpression = "#name, global_rank_area, global_value_area";
scanIndexForward = true;
break;
case 'report-area-lowest':
index = 'rank-area-index';
projectionExpression = "#name, global_rank_area, global_value_area";
scanIndexForward = false;
break;
case 'report-exports-highest':
index = 'rank-exports-index';
projectionExpression = "#name, global_rank_exports, global_value_exports";
scanIndexForward = true;
break;
case 'report-exports-lowest':
index = 'rank-exports-index';
projectionExpression = "#name, global_rank_exports, global_value_exports";
scanIndexForward = false;
break;
case 'report-imports-highest':
index = 'rank-imports-index';
projectionExpression = "#name, global_rank_imports, global_value_imports";
scanIndexForward = true;
break;
case 'report-imports-lowest':
index = 'rank-imports-index';
projectionExpression = "#name, global_rank_imports, global_value_imports";
scanIndexForward = false;
break;
case 'report-internet-users-highest':
index = 'rank-internet-users-index';
projectionExpression = "#name, global_rank_internet_users, global_value_internet_users";
scanIndexForward = true;
break;
case 'report-population-highest':
index = 'rank-population-index';
projectionExpression = "#name, global_rank_population, global_value_population";
scanIndexForward = true;
break;
case 'report-population-lowest':
index = 'rank-population-index';
projectionExpression = "#name, global_rank_population, global_value_population";
scanIndexForward = false;
break;
default:
report = null;
break;
}
if (report===null) {
speechOutput = "Sorry, I could not find that data. ";
shouldEndSession = true;
callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
else {
const AWS = require('aws-sdk');
AWS.config.update({region: 'us-east-1'});
const docClient = new AWS.DynamoDB.DocumentClient({region: 'us-east-1'});
var params = {
TableName: 'factbook',
IndexName: index,
ExpressionAttributeNames: {
'#name': 'name',
'#source': 'source'
},
ExpressionAttributeValues: {
':source': 'Factbook',
},
KeyConditionExpression: '#source = :source',
ProjectionType : "ALL",
ProjectionExpression: projectionExpression,
Limit: 10,
ScanIndexForward: scanIndexForward
};
docClient.query(params, function(err, data) {
if(err) {
console.log('lookupTop: Error - ' + err.toString());
speechOutput = 'Sorry, an error occurred looking that up.';
shouldEndSession = true;
} else {
if (!data || data.Items.length===0) {
speechOutput = 'Sorry, I found no data. ' + Tag;
}
else {
try {
response = replace(response, '{country1}', data.Items[0].name);
response = replace(response, '{country2}', data.Items[1].name);
response = replace(response, '{country3}', data.Items[2].name);
response = replace(response, '{end}', Tag);
speechOutput = response;
}
catch(e) {
console.log('lookupTop: Exception - ' + e.toString());
speechOutput = "Sorry, I had a problem looking that up.";
}
}
// Setting repromptText to null signifies that we do not want to reprompt the user.
// If the user does not respond or says something that is not understood, the session
// will end.
callback(sessionAttributes, buildSpeechletResponse(cardTitle, speechOutput, repromptText, shouldEndSession));
}
});
}
}
</pre>
<div style="text-align: center;">
<i>listTop Function</i></div>
<div style="text-align: center;">
<br /></div>
The response to <i>Which countries are largest?</i> is <b>The countries with the largest area are Russia, Antarctica, and Canada.</b><br />
<b><br /></b>
<br />
<h3>
buildSpeechletResponse</h3>
<div>
<br /></div>
<div style="font-size: medium; font-weight: 400;">
We've made several references to a buildSpeechletResponse function, which assembles the response to send back to Alexa. Here's the code to buildSpeechletResponse:</div>
<br />
<pre class="brush:javascript">// --------------- Helpers that build all of the responses -----------------------
function buildSpeechletResponse(title, output, repromptText, shouldEndSession) {
var outputSpeech = null;
var cardText = replace(output, '<break time="1s"/>', '\r\n\r\n');
var pos = cardText.indexOf('<audio');
if (pos != -1) cardText = 'Playing National Anthem\r\n\r\nWhat else would you like to know?';
if (output.indexOf('<') != -1) {
outputSpeech = { // output contains markup (audio, breaks) - output SSML
type: 'SSML',
ssml: '<speak>' + output + '</speak>',
};
}
else {
outputSpeech = { // output is just text
type: 'PlainText',
text: output
};
}
return {
outputSpeech: outputSpeech,
card: {
type: 'Standard',
title: `${title}`,
text: cardText,
content: `SessionSpeechlet - ${output}`,
image: {
"smallImageUrl": FlagImageUrl,
"largeImageUrl": MapImageUrl
}
},
reprompt: {
outputSpeech: {
type: 'PlainText',
text: repromptText,
},
},
shouldEndSession,
};
}
</pre>
<div style="font-size: medium; font-weight: 400; text-align: center;">
<i>buildSpeechletResponse Function</i></div>
<div style="font-size: medium; font-weight: 400;">
<br /></div>
<div style="font-size: medium; font-weight: 400;">
The above code assembles a repsonse that includes an outputSpeech object. In the original sample used as a starting point for this project, outSpeech was just text with a type of 'PlainText'. However, our responses sometimes include <break time="1s"> markup to pause a second; and <audio ...=""> tags to play national anthems. For these reason our response is of type <a href="https://developer.amazon.com/docs/custom-skills/speech-synthesis-markup-language-ssml-reference.html" target="_blank">SSML</a><br />
<br /></div>
</div>
<h2>
Certification</h2>
Having put the work into creating this skill, I decided to submit it for certification so anyone could use it. This was my first time going through the certification process, and I was pleased to find it a smooth process.<br />
<br />
The first step was to polish the voice app as much as I could. Alexa voice apps are easy to get started, but getting them to a good production-ready state is another thing; it requires thinking through all the different ways someone might express an intent and a lot of testing. In particular, it requires getting input from multiple people since you won't think of everything yourself. After convincing my family to assist me with testing, I felt I was ready for my first submission.<br />
<br />
The Amazon developer console takes you through a Distribution area for describing your app and answering some questions about it; you can then run a validation and automated test to pick up some low-hanging fruit about areas that need attention. When you're past all that you can submit for certification, then sit back and await feedback email. I submitted my first attempt on a Sunday evening and when I went to my computer Monday morning feedback was waiting for me. There were just two very reasonable issues to address, explained in a helpful way.<br />
<br />
One issue had to do with my responses. I'd designed the app to stay open until you expressly tell it to exit; the reasoning being that if you're getting country facts, you probably want to ask a series of questions. The feedback said I could only do that if my responses prompted the user for something more. That was easy to address: now when a question is answered, there's a one-second pause followed by "What else would you like to know?"<br />
<br />
The second issue had to do with <i>cards</i>, which is what Alexa displays when used from a device with a display (such as my TV with Amazon FireStick). The default sample app I used as a starting point output very technical titles like 'SpeeachApplet'. I overhaued the card output, and now a card is display that includes a friendly-worded title; a map of the country being described (or its flag on small-size display); and the text of the response. Here for example is the card displayed in response to <i style="text-align: center;">Where is French Polynesia?</i><br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-M353FsghvCdys9MkgB1F7yle5VTJQ8u3LUaFzLG5LuA-ZTgUzWYDg3Al05epffpgD_1CGGlP3p-idKKlCU9BRkTH_aQehWVMgmoQmQR7SlOrPdiqadKt5py_M9vSWe3ERl1nSfSK60k/s1600/card_where.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="471" data-original-width="803" height="233" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg-M353FsghvCdys9MkgB1F7yle5VTJQ8u3LUaFzLG5LuA-ZTgUzWYDg3Al05epffpgD_1CGGlP3p-idKKlCU9BRkTH_aQehWVMgmoQmQR7SlOrPdiqadKt5py_M9vSWe3ERl1nSfSK60k/s400/card_where.png" width="400" /></a></div>
<div style="text-align: center;">
<i>Card Response to "Where is French Polynesia?"</i></div>
<br />
I resubmitted Monday mid-morning, and pass certification overnight. All in all, a satisfying certification process. Here's what the skill listing looks like on Amazon.com:<br />
<br />
<div class="separator" style="clear: both; text-align: center;">
<a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiasYa2sPgdvmE9FkKBM6PKoduhj6MvY9XGhka5UJqzkd4FfUpRnHXQOa0_6Ew-FO7GTVDcYZ4tQoxe5vi2XwPmcpMahgHJKMeThkkr_aFdhGa3UOgMq-hOpg-Vq486D9DYuVEWOk4alF4/s1600/amazon_skill_listing.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"><img border="0" data-original-height="596" data-original-width="1600" height="148" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiasYa2sPgdvmE9FkKBM6PKoduhj6MvY9XGhka5UJqzkd4FfUpRnHXQOa0_6Ew-FO7GTVDcYZ4tQoxe5vi2XwPmcpMahgHJKMeThkkr_aFdhGa3UOgMq-hOpg-Vq486D9DYuVEWOk4alF4/s400/amazon_skill_listing.png" width="400" /></a></div>
<br />
<h2>
In Conclusion</h2>
In this series, I showed how public-domain data from the CIA World Factbook can be hosted on Amazon Web Services. After bringing that data into DynamoDB and creating a Lambda Function serverless API, and then creating a web site, we tackled an Alexa Skill in this final part of the series. You can access the skill with <b>"Alexa, Open World Country Data"</b>.<br />
<br />
Our skill was able to answer questions about specific values for a country, such as its population or area; as well as lists such as the languages spoken in a country. Country ranking inquiries can also be made, such as which countries have the lowest exports or highest inflation. Although we covered many data points, there's a great deal more that can be mined out of this data source.<br />
<br />
<div>
<br /></div>
David Pallmannhttp://www.blogger.com/profile/14482909040736697277noreply@blogger.com1