<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-33260599</id><updated>2026-07-29T17:34:57.325-07:00</updated><category term="programming"/><category term="open source"/><category term="JavaScript"/><category term="python"/><category term="c"/><category term="projects"/><category term="xo laptop"/><category term="China"/><category term="app engine"/><category term="code"/><category term="linux"/><category term="https"/><category term="laptop"/><category term="music"/><category term="one laptop per child"/><category term="browser"/><category term="cryptography"/><category term="poetry"/><category term="q12"/><category term="server"/><category term="twitter"/><category term="Ajax"/><category term="baby"/><category term="cms"/><category term="css"/><category term="food"/><category term="free"/><category term="google"/><category term="object oriented"/><category term="operating system"/><category term="password"/><category term="puns"/><category term="scorpion server"/><category term="steganography"/><category term="style"/><category term="travel"/><category term="ubuntu"/><category term="wife"/><category term=".so"/><category term="Chrome OS"/><category term="Forbidden City"/><category term="GRE"/><category term="Greek"/><category term="Hangzhou"/><category term="Huqiu Leaning Tower"/><category term="Ming Tombs"/><category term="Shanghai"/><category term="Summer Palace"/><category term="Tea Garden"/><category term="Temple of Heaven"/><category term="The Great Wall"/><category term="The Lingering Garden"/><category term="android"/><category term="arduino"/><category term="blogger"/><category term="blogging"/><category term="books"/><category term="camping"/><category term="cellular automata"/><category term="claire"/><category term="code conventions"/><category term="codec"/><category term="currying"/><category term="daughter"/><category term="domain name"/><category term="dynamic linking"/><category term="early binding"/><category term="firefox"/><category term="fluxbuntu"/><category term="gcc"/><category term="go"/><category term="guess"/><category term="guitar"/><category term="haiku"/><category term="hardy heron"/><category term="headspace"/><category term="house"/><category term="http"/><category term="internet"/><category term="jeffscudder.com"/><category term="journal"/><category term="late binding"/><category term="learning"/><category term="limerick"/><category term="linguistics"/><category term="liturature"/><category term="live coding"/><category term="mashup"/><category term="mashupcamp"/><category term="matrix"/><category term="mercurial"/><category term="microblogging"/><category term="mp3"/><category term="nadsat"/><category term="oauth"/><category term="oauth2"/><category term="ogg vorbis"/><category term="opera"/><category term="pi day"/><category term="portable operating system"/><category term="relient k"/><category term="remodel"/><category term="rickshaw"/><category term="road trip"/><category term="scifi"/><category term="screen"/><category term="sculpture"/><category term="septoplasty"/><category term="shopping"/><category term="teaching"/><category term="techno"/><category term="test"/><category term="tiddlywiki"/><category term="valentines"/><category term="version control"/><category term="vi"/><category term="vicodin"/><category term="vim"/><category term="virtualization"/><category term="vmware"/><category term="web server"/><category term="wii"/><category term="wiki"/><category term="writing"/><category term="xml"/><category term="yum"/><title type='text'>Imposterrific - a blog by Jeff Scudder</title><subtitle type='html'>Coding can be fun!</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>107</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-33260599.post-1476844224403746282</id><published>2025-10-30T18:16:00.000-07:00</published><updated>2025-10-30T18:44:48.227-07:00</updated><title type='text'>Lutherie - The Nashbronitacaster</title><content type='html'>&lt;p&gt;How many of us are still chasing those childhood dreams? It struck me the other day that my professional and hobbyist pursuits today are a direct reflection of my interests in my teenage years. In some ways so little has changed. Still love to make music, diving deep into dissecting the sounds that tickle my eardrums. Still love to be creative. For decades now there&#39;s been a lot of programming and electric guitar. So here we have it, last post was about programming, and now, electric guitar. On brand!&lt;/p&gt;&lt;p&gt;The quest for a &lt;a href=&quot;https://blog.jeffscudder.com/2021/08/the-2021-guitar-in-search-of-guitar.html&quot;&gt;guitar that can do it all has been ongoing (as this recent post can attest)&lt;/a&gt;, and the latest iteration has brought about a transformation of &lt;a href=&quot;https://blog.jeffscudder.com/2020/09/partscaster-t-style-with-p-rails.html&quot;&gt;my first partscaster&lt;/a&gt; into what I&#39;d describe as The &lt;a href=&quot;https://blog.jeffscudder.com/2025/10/lutherie-nashbronitacaster.html&quot;&gt;Nashbronitacaster&lt;/a&gt;. A tele style, 3 pickup tone machine, with a combination of filtertron and single-coil style pickups.&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEJt9jkAZzCUMlCVduEHsmEiOP7k9vxwWfoIytnmA6TM-ewpgHIZI4-Gr5GHX0MFqS8FARCnEmHuG6jwGPdUsoKhCNu04FCDRXZsI1zItMZWKjKSlDRiocaZrHU7GcVp8iL46eo8Hc8nduhqo5jnaIlG7v22A-8KOGBaOPh8q2a3LnIA7sKmY5/s4624/PXL_20250828_224454892.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;4624&quot; data-original-width=&quot;3472&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEJt9jkAZzCUMlCVduEHsmEiOP7k9vxwWfoIytnmA6TM-ewpgHIZI4-Gr5GHX0MFqS8FARCnEmHuG6jwGPdUsoKhCNu04FCDRXZsI1zItMZWKjKSlDRiocaZrHU7GcVp8iL46eo8Hc8nduhqo5jnaIlG7v22A-8KOGBaOPh8q2a3LnIA7sKmY5/s320/PXL_20250828_224454892.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;The inspiration came from researching the guitars being used on many of today&#39;s most popular worship songs. As I contribute some sounds to the worship team on Sundays or Friday-nights, I like to try to emulate what many well-known artists have produced. Using a Kemper profiling amp to match amplifier tones and effects has been a key ingredient, but that&#39;s a topic for another time. When it comes to electric guitars, there were a few popular choices that stand out. One is the venerable Telecaster, which for many years has been my go-to instrument. Another increasingly popular choice are Gretsch-style guitars outfitted with some flavor of Filtertron pickups.&lt;/p&gt;&lt;p&gt;For example, the&amp;nbsp;Gretsch Duo Jet appears to be used by the following well known guitarists (based on various rig rundown articles and observations from recorded worship performances): Jeffrey Kunde - Jesus Culture, Nigel Hendroff - Hillsong, David Liotta - Elevation, Cory Pierce, Julian Gamboa - Upperroom. In addition, the semi-hollow Gretsch guitars like the White Falcon or other solid-bodies like the&amp;nbsp;Gretsch G6134 Penguin also appear in the stable of these same musicians. Seems these Filtertron pickups are a key ingredient with their relatively cleaner and brighter sound, compared to more prevalent humbuckers - which I&#39;ve always found a bit too muddy/dark. For a brief introduction to these pickups, check out videos like &lt;a href=&quot;https://www.youtube.com/watch?v=LSsSlNUunxc&amp;amp;t=96s&quot;&gt;What is the Filterton Sound&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;With this new tonal destination to explore, I set out to experience what these Filtertrons could do, landing on &lt;a href=&quot;https://tvjones.com/shop/guitar-pickups/tv-classic/&quot;&gt;TV Jones Classics&lt;/a&gt; as a well appreciated option. My first try with them involved buying a used Gretsch Electromatic Jet and swapping out the stock pickups for a set of TV Jones Classics. It was sonic bliss at first strum.&lt;/p&gt;&lt;p&gt;For a few months, I brought my tele style partscaster and this upgraded Gretsch to all my gigs, but the thought continued to itch - what about having one guitar with the best of both worlds. While the TV Jones Classics had great drive and a very present sound that could occupy just the right slot in a mix, there were still times that the clarity of a single coil was a better fit for a particular song or segment. Having greatly enjoyed the &lt;a href=&quot;https://www.dimarzio.com/pickups/tele/stacked-hum-canceling-tele&quot;&gt;noiseless single-coil-style Dimarzio Area pickups&lt;/a&gt; for my tele partscaster, I wondered if something like a strat-inspired &lt;a href=&quot;https://www.dimarzio.com/pickups/stacked-hum-canceling-strat/area-58&quot;&gt;Area 58&lt;/a&gt; could be incorporated into a guitar along with the TV Jones pickups. Since I was almost never using the first Partscaster I had put together, I decided to repurpose it to see if it could satisfy this itch.&lt;/p&gt;&lt;p&gt;First it needed a spot for a middle pickup&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzdha9LooHQJ8KAa5UNri_sqEQvBwYBKROSBrERQB-i6o2X6b_rLPTBGxQK6EiY7WXqYWEMdaPgVAwS0DF_u8VzoGUmBeNWKdONuEZv7rA8Bj99VqtQZixpWCgiXvuOu4PGv5OyaRf6mMr6uMdqXrtJNuOiMFLbYx7-TBKiwsFF1pahKU4gMAw/s4624/PXL_20250823_223924327.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;3472&quot; data-original-width=&quot;4624&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgzdha9LooHQJ8KAa5UNri_sqEQvBwYBKROSBrERQB-i6o2X6b_rLPTBGxQK6EiY7WXqYWEMdaPgVAwS0DF_u8VzoGUmBeNWKdONuEZv7rA8Bj99VqtQZixpWCgiXvuOu4PGv5OyaRf6mMr6uMdqXrtJNuOiMFLbYx7-TBKiwsFF1pahKU4gMAw/s320/PXL_20250823_223924327.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib42I4YkmuF0g0imN7TIA_zrLmwXT9JTNUvHXhSZB3ywDy-r7HwfZeMJafI2rX6PCi2PsThlAzXOJXHCSO2cI6UTD_7I455vm99okM6JdCl5GYnJ-EYMr0a7D4okk9E49vDBkWwm0NA3qFoJx_vKMoWF-fjk3pCiBlgVpe0EM2W4N0JtxpYPRH/s4624/PXL_20250828_042008896.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;4624&quot; data-original-width=&quot;3472&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEib42I4YkmuF0g0imN7TIA_zrLmwXT9JTNUvHXhSZB3ywDy-r7HwfZeMJafI2rX6PCi2PsThlAzXOJXHCSO2cI6UTD_7I455vm99okM6JdCl5GYnJ-EYMr0a7D4okk9E49vDBkWwm0NA3qFoJx_vKMoWF-fjk3pCiBlgVpe0EM2W4N0JtxpYPRH/s320/PXL_20250828_042008896.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh14DGXkhnLNmQI-rqFPBPHkEaro_S6FEQsQeyKDj60zC0tYZqSQMHUvDcAMYTnBnFpNkL8oU3MY8rWlTrIE_mn1Yqs9ukKmAY5qVd-ubTFAf8_136d90Rf5FbDG_slcdyt9CCrsR1jquhAqJYdqW3IpeBizrfHkhQClHOLBOFbqjzxWr3o4y9k/s4624/PXL_20250828_042356337.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;3472&quot; data-original-width=&quot;4624&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh14DGXkhnLNmQI-rqFPBPHkEaro_S6FEQsQeyKDj60zC0tYZqSQMHUvDcAMYTnBnFpNkL8oU3MY8rWlTrIE_mn1Yqs9ukKmAY5qVd-ubTFAf8_136d90Rf5FbDG_slcdyt9CCrsR1jquhAqJYdqW3IpeBizrfHkhQClHOLBOFbqjzxWr3o4y9k/s320/PXL_20250828_042356337.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;With 3 pickups, this is becoming something like a Nashville Telecaster, in which pickup selection is typically done using a strat-style 5-way blade switch. While this provides a lot of versatility in enabling different combinations of the pickups, I was interested in being able to have a neck+bridge pickup combination, similar to the original 2-pickup Gretsch. For support this combination, I decided to include a two position slider switch (the kind often found in a Jazzmaster). Here I paint it sonic blue to match the guitar&#39;s color scheme:&lt;div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjppGchSQMAKxKFxLN3Unm7Mq-DWTmlBox2l1yVmsNbDfjo-mh15vQCQN9y4LCo_svspVfor2zSQgPEzyLKsiBW_YTRiTf-KnoTs_rk9kJ9ptUtSBQTjXgsUOaQBNjJLN6whfFoCaSTf-6FBjYQWT56VcKxR70FOcwrI2xTIVd-oKKbwZmiYoX8/s4624/PXL_20250823_223147973.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;4624&quot; data-original-width=&quot;3472&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjppGchSQMAKxKFxLN3Unm7Mq-DWTmlBox2l1yVmsNbDfjo-mh15vQCQN9y4LCo_svspVfor2zSQgPEzyLKsiBW_YTRiTf-KnoTs_rk9kJ9ptUtSBQTjXgsUOaQBNjJLN6whfFoCaSTf-6FBjYQWT56VcKxR70FOcwrI2xTIVd-oKKbwZmiYoX8/s320/PXL_20250823_223147973.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;This would be placed in the control plate, which would have a single volume control and no tone knob. I found I basically never touch the tone control on the guitar, relying instead on using different presets in the Kemper amp. To create a slot for the 2-way switch, I drilled+cut a long slot and drilled screw holes to attach the switch.&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk7B0ABxxissjJYx5ZaPC8pZetIMmvTrZ9tKrLTaZixBfHi7Vw3JZMxHDUsDM9_MwRq6S1fpc6EsB5sE6TYohJpdopKuP8GSgJIMQkZwgxgwJZpzV5gVjw1jhuvG34ZyeX8_wH8gm0ceydiG0LP1afLZ63raPk-lxlejzjKFNeB2MuQGvPEIa2/s4624/PXL_20250826_032401486.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;4624&quot; data-original-width=&quot;3472&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhk7B0ABxxissjJYx5ZaPC8pZetIMmvTrZ9tKrLTaZixBfHi7Vw3JZMxHDUsDM9_MwRq6S1fpc6EsB5sE6TYohJpdopKuP8GSgJIMQkZwgxgwJZpzV5gVjw1jhuvG34ZyeX8_wH8gm0ceydiG0LP1afLZ63raPk-lxlejzjKFNeB2MuQGvPEIa2/s320/PXL_20250826_032401486.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJvUBdDZTqBPZMpbW1B603nd2nKnXkzc4or24280gKJh_zIFSZrFCFmDl3KaLYFLZmpS_Uf6cl9k4r3MVi5nAjzAQOt-bL-48lBaf8JVBoV_8rCqkzMVfVymE19DPlJRsM8MiVHmpoIreFmAF3pen3iP7z4P9Q6RFV85Z6k5F4cm2UNnkDsPld/s4624/PXL_20250826_034128931.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;3472&quot; data-original-width=&quot;4624&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjJvUBdDZTqBPZMpbW1B603nd2nKnXkzc4or24280gKJh_zIFSZrFCFmDl3KaLYFLZmpS_Uf6cl9k4r3MVi5nAjzAQOt-bL-48lBaf8JVBoV_8rCqkzMVfVymE19DPlJRsM8MiVHmpoIreFmAF3pen3iP7z4P9Q6RFV85Z6k5F4cm2UNnkDsPld/s320/PXL_20250826_034128931.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;Now it was time to wire up this frankenstein creation.&lt;/div&gt;&lt;div&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Here&#39;s the wiring diagram:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhok6egtv_zgpWRDPsyvD6sAFFy-uw7oP0p_a_7Aeh3guHzCFMMQvzIAb4nSLIfvrk8V3gNHxVXQ0twG9l6KO4xJHJ4nIzrh0toLv4rnOJSysKjlZBwTeeBNUx5bR5xVS1ytij4RnEVMVCtG9jM6C0g8SKo0T6BS2srJeOrDfAj9LW0-heH4AnL/s1414/2025-Guitar-Wiring-v4.png&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1414&quot; data-original-width=&quot;990&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhok6egtv_zgpWRDPsyvD6sAFFy-uw7oP0p_a_7Aeh3guHzCFMMQvzIAb4nSLIfvrk8V3gNHxVXQ0twG9l6KO4xJHJ4nIzrh0toLv4rnOJSysKjlZBwTeeBNUx5bR5xVS1ytij4RnEVMVCtG9jM6C0g8SKo0T6BS2srJeOrDfAj9LW0-heH4AnL/s320/2025-Guitar-Wiring-v4.png&quot; width=&quot;224&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;With the two position switch up towards the neck of the guitar, the 5-way blade switch cycles through the following pickup combinations:&lt;/p&gt;&lt;p&gt;1 - bridge&lt;/p&gt;&lt;p&gt;2 - bridge + middle&lt;/p&gt;&lt;p&gt;3 - middle&lt;/p&gt;&lt;p&gt;4 middle + neck&lt;/p&gt;&lt;p&gt;5 neck&lt;/p&gt;&lt;p&gt;When the slide switch is toggled to the other position (towards the lower bout), the middle and neck pickup positions are swapped in the 5-way switch, leading to the following combinations:&lt;/p&gt;&lt;p&gt;1 - bridge&lt;/p&gt;&lt;p&gt;2 - bridge + neck&lt;/p&gt;&lt;p&gt;3 - neck&lt;/p&gt;&lt;p&gt;4 - neck + middle&lt;/p&gt;&lt;p&gt;5 - middle&lt;/p&gt;&lt;p&gt;This unlocks the bridge+neck combination which would otherwise be impossible with a 5-way blade switch and 5 pickups. Another option would have been to use the two position toggle to make the neck pickups always engaged, a popular mod for strats. This would also make it possible to have all 3 pickups engaged at once. Personally I don&#39;t anticipate a need for all 3 at once, but to each their own.&lt;/p&gt;&lt;p&gt;Here it is wired up:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU5vW81MkmgJFbQI9wt1jW7Dccslr3-3wtYT0-whJZq7FAg895l_sRBT1r13d6w5xq-U14XsSYsEfZ107wohUO7aD773L1s1zf6k-0XUqBsHUfQy5snwWpFARjZSizL-yVWT9j10M3fmtbRo6JaRpaDFm_Igg7cIbObg4b-VbDeR7tdsg9_L_M/s4624/PXL_20250828_154731945.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;3472&quot; data-original-width=&quot;4624&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhU5vW81MkmgJFbQI9wt1jW7Dccslr3-3wtYT0-whJZq7FAg895l_sRBT1r13d6w5xq-U14XsSYsEfZ107wohUO7aD773L1s1zf6k-0XUqBsHUfQy5snwWpFARjZSizL-yVWT9j10M3fmtbRo6JaRpaDFm_Igg7cIbObg4b-VbDeR7tdsg9_L_M/s320/PXL_20250828_154731945.jpg&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;p&gt;One other item worth noting, is the inclusion of a treble/tone bleed circuit that allows some of the high end frequencies to continue to cut through as the volume is turned down. This is a favorite mod I include on just about all of my guitars after learning it was included in my 2015 American Standard Telecaster.&lt;/p&gt;&lt;p&gt;The final pickup selection was &lt;a href=&quot;https://tvjones.com/shop/guitar-pickups/tv-classic/&quot;&gt;TV Jones Classics pickups&lt;/a&gt; for the neck and bridge positions and a &lt;a href=&quot;https://www.dimarzio.com/pickups/stacked-hum-canceling-strat/area-58&quot;&gt;DiMarzio Area 58 (stacked noiseless) pickup&lt;/a&gt; for the middle slot.&lt;/p&gt;&lt;p&gt;There we have it, an amazingly versatile electric guitar:&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5monAcg5ynhfL30ItL9kFE01wTIYJRnzmDGuYfDLvxOs7hR2J4KATawfnxorwqtd_Wv1s_pGAVpy094pE3QD8Iuf4XJdDDJdniJ0BohzBXfgAULO8ivAaesoREv8IwRgNXNXiKgpoB4-jCtMN09WobREwRaF1PGaoLKDnjjAXPsv7pO84rWFq/s4624/PXL_20250828_224551785.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;4624&quot; data-original-width=&quot;3472&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh5monAcg5ynhfL30ItL9kFE01wTIYJRnzmDGuYfDLvxOs7hR2J4KATawfnxorwqtd_Wv1s_pGAVpy094pE3QD8Iuf4XJdDDJdniJ0BohzBXfgAULO8ivAaesoREv8IwRgNXNXiKgpoB4-jCtMN09WobREwRaF1PGaoLKDnjjAXPsv7pO84rWFq/s320/PXL_20250828_224551785.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHPvhvh9DwdNHkn2u6p6cdk6VLYXPbcyMjxpvmAv9YEQYfOvljWYXg0qZwgzagPRU9ErenWbzUbAQ3jU8heK16bkGSIJPLoA1iWzWkfVu2R6ufohGm125c8Tpx0h08DT3Teu9PbhhJl5fE0j_6stdcWywG3wsmpSnLdYL7Pu6J4yTw91XF95IO/s4624/PXL_20250828_224522793.jpg&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;4624&quot; data-original-width=&quot;3472&quot; height=&quot;320&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhHPvhvh9DwdNHkn2u6p6cdk6VLYXPbcyMjxpvmAv9YEQYfOvljWYXg0qZwgzagPRU9ErenWbzUbAQ3jU8heK16bkGSIJPLoA1iWzWkfVu2R6ufohGm125c8Tpx0h08DT3Teu9PbhhJl5fE0j_6stdcWywG3wsmpSnLdYL7Pu6J4yTw91XF95IO/s320/PXL_20250828_224522793.jpg&quot; width=&quot;240&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;p&gt;With Filtertron style pickups in the neck and bridge positions, it&#39;s somewhat reminiscent of a Cabronita tele, while the third pickup makes it look a bit like a Nashville tele, hence the Nashbronitacaster. This was a rewarding build and it&#39;s been my go-to guitar since completing it a few months ago.&lt;/p&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/1476844224403746282/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/1476844224403746282' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1476844224403746282'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1476844224403746282'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2025/10/lutherie-nashbronitacaster.html' title='Lutherie - The Nashbronitacaster'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiEJt9jkAZzCUMlCVduEHsmEiOP7k9vxwWfoIytnmA6TM-ewpgHIZI4-Gr5GHX0MFqS8FARCnEmHuG6jwGPdUsoKhCNu04FCDRXZsI1zItMZWKjKSlDRiocaZrHU7GcVp8iL46eo8Hc8nduhqo5jnaIlG7v22A-8KOGBaOPh8q2a3LnIA7sKmY5/s72-c/PXL_20250828_224454892.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-4384744013548757784</id><published>2025-05-31T15:54:00.000-07:00</published><updated>2025-05-31T22:12:53.433-07:00</updated><title type='text'>Polyglot - Hello World in 7 Languages</title><content type='html'>&lt;p&gt;To those who love to learn languages, I understand the appeal. Being able to communicate with a wide array of people you might meet is an empowering feeling. New ideas are unlocked that had been hidden away in previously inaccessible texts.&lt;/p&gt;&lt;p&gt;Similarly, in the world of programming, building familiarity with other programming languages exposes you to new ideas and gives you a deeper understanding of how programs work. Possessing broad capabilities prevents becoming boxed in with opportunities limited to a narrow set of technologies - some of which are undoubtedly becoming obsolete.&lt;/p&gt;&lt;p&gt;To begin to get a flavor for how today&#39;s most popular programming languages are in some ways similar while also distinct, we&#39;ll look at what it takes to run what is perhaps the simplest program in most languages: a program that says Hello World.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Here are the arguably top seven languages in today&#39;s programming circles:&lt;/p&gt;&lt;ol style=&quot;text-align: left;&quot;&gt;&lt;li&gt;Python&lt;/li&gt;&lt;li&gt;C&lt;/li&gt;&lt;li&gt;C++ &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Java&lt;/li&gt;&lt;li&gt;C# &lt;br /&gt;&lt;/li&gt;&lt;li&gt;JavaScript&lt;/li&gt;&lt;li&gt;Go&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;For each, we&#39;ll take a quick look at a program that prints Hello World along with the tooling and commands required to run each sample. I&#39;m building each of these on a Linux desktop using command-line tools. (I prefer to avoid IDEs if possible, thoughts for another time.)&lt;/p&gt;&lt;p&gt;&amp;nbsp;Lets hit it.&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;&amp;nbsp;Python&lt;/h2&gt;&lt;p&gt;A longtime favorite of mine, I began exploring Python years ago to interview for a job and was instantly drawn to it&#39;s clean and straightforward syntax. It comes as no surprise that its popularity has steadily grown. The Python interpreter comes preinstalled in many operating systems, making it perhaps the simplest language in today&#39;s list to try out.&lt;/p&gt;&lt;p&gt;Here is &lt;span style=&quot;font-family: courier;&quot;&gt;hello-world.py&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp;def main():
&lt;br /&gt;&amp;nbsp; print(&#39;Hello World&#39;) &lt;br /&gt;&amp;nbsp; return 0 &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;if __name__ == &#39;__main__&#39;: &lt;br /&gt;&amp;nbsp; main() &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;To run it, we can execute the command&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;python hello-world.py&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now experienced Python programmers may point out, this is far from the simplest Hello World program in Python. It could be as simple as&amp;nbsp;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;print(&#39;Hello World&#39;)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;For the sake of consistency though, we wrap our code in a main function to match the conventions present in many other languages. Also, the &lt;span style=&quot;font-family: courier;&quot;&gt;__name__ == &#39;__main__&#39;&lt;/span&gt; check will allow code to be executed only if the module is being run directly. It will not execute if the file is being loaded as a Python module imported by another script.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Onward to the next:&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;C&lt;/h2&gt;&lt;p&gt;This was the first programming language I&#39;ve learned, which I think has been a valuable way to start. Certainly the oldest language from our list, it&#39;s still widely used today. It&#39;s comparative simplicity sometimes requires extra work, managing memory usage stands out as a clear example, but it offers a greater degree of control. When carefully written, C can offer high performance and it&#39;s often the foundation for operating systems and other programming languages. Here&#39;s a Hello World program in C &lt;span style=&quot;font-family: courier;&quot;&gt;hello-world.c&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;#include&amp;lt;stdio.h&amp;gt; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;int main(void) { &lt;br /&gt;&amp;nbsp; printf(&quot;Hello World\n&quot;); &lt;br /&gt;&amp;nbsp; return 0; &lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The C compiler is often already available in an OS (Linux and MacOS at least) so it&#39;s easy to get started. We first compile the program into an executable, and then run it. The process can look like this:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;gcc -o hello-world hello-world.c&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;./hello-world&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Neat! &lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;C++&lt;br /&gt;&lt;/h2&gt;&lt;p&gt;Next we turn our attention to a highly popular language which extends C with the cleverly named C++. When I began learning C++ in high school (at the time it was the language used in the AP Computer Science exam), it&#39;s claim to fame was the addition of classes to support Object Oriented programming, a trend which every other language in this list continues (to at least some degree). It continues to be a popular choice for high performance applications and has a wider degree of helpful language features compared to the simpler C.&lt;/p&gt;&lt;p&gt;When it comes to our Hello World example, the differences appear relatively minor. This is &lt;span style=&quot;font-family: courier;&quot;&gt;hello-world.cpp&lt;/span&gt;:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;#include &amp;lt;iostream&amp;gt; &lt;br /&gt;using namespace std; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;int main() { &lt;br /&gt;&amp;nbsp; cout &amp;lt;&amp;lt; &quot;Hello World\n&quot;; &lt;br /&gt;&amp;nbsp; return 0; &lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Compiling and running was similarly straightforward compared to C. The compiler was already present in the Linux OS I was using:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;g++ -o hello-world hello-world.cpp&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Java&lt;/h2&gt;&lt;p&gt;I learned Java during my first programming internship and picking it up from C++ was fairly quick. It&#39;s claim to fame was the promise to &quot;write once, run everywhere&quot; thanks to it&#39;s unique approach to compile Java programs into a bytecode that could be run in an interpreter. This made it one of the few languages to offer a hybrid approach to running the programs, it was initially compiled and yet also interpreted.&lt;/p&gt;&lt;p&gt;Here&#39;s &lt;span style=&quot;font-family: courier;&quot;&gt;HelloWorld.java&lt;/span&gt;, pretty similar to what we&#39;ve seen so far with one visible difference being that this program is declared as a class, which is traditionally required for all Java programs.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;public class HelloWorld { &lt;br /&gt;&amp;nbsp; &amp;nbsp;&lt;br /&gt;&amp;nbsp; public static int main(String[] args) { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; System.out.println(&quot;Hello World&quot;);&lt;br /&gt;&amp;nbsp; } &lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;To run a Java program, you can use the java command which comes pre-installed in most Operating Systems. To compile the source code though, the Java Development Kit must be installed to run the Java compiler: &lt;span style=&quot;font-family: courier;&quot;&gt;javac&lt;/span&gt;. &lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;javac HelloWorld.java&amp;nbsp;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;java HelloWorld&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Next up, a language that is in some ways similar to Java: C#.&lt;br /&gt;&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;C#&lt;/h2&gt;&lt;p&gt;I recall learning about C# in college and trying it out a bit. Coming from Java, it felt very similar and this may have been intentional as the word on the street was that Microsoft had created C# as a competitor to Java when they were prevented from extending the language for use in their own applications. At the time, Java had taken the world by storm and C# brought similar ideas to the Microsoft ecosystem.&lt;/p&gt;&lt;p&gt;Here&#39;s a Hello World program in C#, &lt;span style=&quot;font-family: courier;&quot;&gt;hello-world.cs&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;using System; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;public class HelloWorld&lt;br /&gt;{ &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public static int Main() &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Console.WriteLine(&quot;Hello World&quot;); &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return 0; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;When it comes to running the above code, the dotnet program can both compile the code and also execute the compiled program. To perfrom compilation though, the dotnet compiler requires that a project file describe the source code and the type of program to be created. Using an IDE like Visual Studio, the program file is often generated for you. Sticking to my approach though of using command line tools only, the same can be accomplished using the dotnet command when the following csproj file is in the same directory as our source code &lt;span style=&quot;font-family: courier;&quot;&gt;hello-world.csproj&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;&amp;nbsp;&amp;lt;Project Sdk=&quot;Microsoft.NET.Sdk&quot;&amp;gt; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp; &amp;lt;PropertyGroup&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;OutputType&amp;gt;Exe&amp;lt;/OutputType&amp;gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;TargetFramework&amp;gt;net8.0&amp;lt;/TargetFramework&amp;gt; &lt;br /&gt;&amp;nbsp; &amp;lt;/PropertyGroup&amp;gt; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;With the project file in place, the program can be compiled and then run using these two commands:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;dotnet build &lt;br /&gt;dotnet run&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Next, we&#39;ll change gears to something a bit different: JavaScript.&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;JavaScript&lt;/h2&gt;&lt;p&gt;While similarly named to Java, the language has very little in common. The programming syntax looks like Java, C, really most of the languages we&#39;ve looked at, but under the hood it works very differently. JavaScript was initially launched as a language to run inside of Web Browsers and so it has historically been closely aligned with web applications. I started learning it when I began creating web pages and for a time I was programming in it heavily professionally. Concepts like prototypical inheritance and functions as first class objects make it possible to construct logic and dynamic behavior in JavaScript which is difficult to express in other languages.&lt;/p&gt;&lt;p&gt;A few years back, the NodeJS project made it possible to run JavaScript programs directly in the OS instead of being limited to only run in a browser context. This Hello World example uses the node command to interpret the following &lt;span style=&quot;font-family: courier;&quot;&gt;hello-world.js&lt;/span&gt; program:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;function main() { &lt;br /&gt;&amp;nbsp; console.log(&#39;Hello World&#39;); &lt;br /&gt;} &lt;br /&gt;&amp;nbsp;&lt;br /&gt;main();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;As with Python, this example is slightly more complex than strictly needed, for consistency. This program could be as short as console.log(&#39;Hello World&#39;);.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Running this JavaScript program can be executed with the node command. which I had to install on Linux.&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;node hello-wolrd.js&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now we&#39;re ready for our final language Go.&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;Go&lt;/h2&gt;&lt;p&gt;This is the most recent language on our list and one that I&#39;ve learned over the years at work. In some ways it blends the simplicity of C with the conciseness of Python. With it&#39;s similarity to two of my favorite languages I was instantly hooked. Some of the unique design goals I recall that motivated the creation and design of Go include simplifying parallel processing - thanks to a built-in co-routine feature called goroutines - and also making it easy to reason about the flow of complex programs - hence the elimiation of throwing exceptions in favor of functions returning multiple values, one of which would be an error indicator.&amp;nbsp;&lt;/p&gt;&lt;p&gt;Here&#39;s a simple Hello World program in Go, &lt;span style=&quot;font-family: courier;&quot;&gt;hello-world.go&lt;/span&gt;:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;package main &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;import &quot;fmt&quot; &lt;br /&gt;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&lt;br /&gt;func main() { &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; fmt.Println(&quot;Hello World&quot;) &lt;br /&gt;} &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The compiler / interpreter for Go was already present in Linux, and running the above program was as simple as executing this command:&lt;/p&gt;&lt;p&gt;&lt;span style=&quot;font-family: courier;&quot;&gt;go run hello-world.go&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Fun!&lt;/p&gt;&lt;h2 style=&quot;text-align: left;&quot;&gt;In Closing &lt;br /&gt;&lt;/h2&gt;&lt;p&gt;Looking at the languages and comparing how to do the same things in each can be a fascinating exercise that deepens understanding and appreciation for how unique each programming language can be. This has been a long time fascination for me and inspired explorations like &lt;a href=&quot;http://blog.jeffscudder.com/2007/01/simulating-classes-in-c.html&quot;&gt;how to write classes in C&lt;/a&gt;, how to &lt;a href=&quot;http://blog.jeffscudder.com/2008/04/creating-and-using-so-files-with-gcc.html&quot;&gt;load libraries dynamically in Linux&lt;/a&gt;, and &lt;a href=&quot;http://blog.jeffscudder.com/2008/04/early-vs-late-binding.html&quot;&gt;differences in how closures work&lt;/a&gt; in different languages. Hopefully this quick survey of Hello World examples has been instructive and inspires new explorations.&lt;/p&gt;&lt;p&gt;While writing the same program in 7 languages isn&#39;t the most innovative endeavor, a nice side benefit is that I now have a development environment set up for each of these languages. Another stepping stone to bigger and more exciting ideas.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp; &lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/4384744013548757784/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/4384744013548757784' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/4384744013548757784'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/4384744013548757784'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2025/05/polyglot-hello-world-in-7-languages.html' title='Polyglot - Hello World in 7 Languages'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-8747768043941240824</id><published>2023-09-30T16:58:00.007-07:00</published><updated>2023-09-30T17:20:34.257-07:00</updated><title type='text'>Guitar Wiring - Phase Switch and Blend Pot </title><content type='html'>&lt;p&gt;Half the fun of building a partscaster is to experiment with unique guitar circuitry. The first guitar that I made has been a platform for experimentation and the journey continues. A couple of things bugged me about the &lt;a href=&quot;https://blog.jeffscudder.com/2020/09/partscaster-t-style-with-p-rails.html&quot;&gt;first iteration of this guitar&#39;s wiring&lt;/a&gt;, so I decided to try a couple of new idea.

&lt;p&gt;One was to use a knob that changes the balance between the neck pickup and the bridge pickup. This is done using what&#39;s called a blend/balance potentiometer. In the middle position, there is no added resistance to either pickup, then when turned one way or the other there is added resistance (lower volume) from one of the two pickups.

&lt;p&gt;The second idea, was to add a switch to provide an out-of-phase sound. The effect is to create a thinner brighter sound because some of the waveforms that come from the two pickups are canceling each other out. Perhaps the most famous example of out of phase pickups is in a guitar called &lt;a href=&quot;https://en.wikipedia.org/wiki/Greeny_%28guitar%29&quot;&gt;Greeny&lt;/a&gt;. Here&#39;s the wiring diagram:

&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTxc1L1qwz0ELo4yBrmPHSbFIXfHi10c1gai2pb0ahpA0wzcDOOFtTi4oLFak1Ujlxwmzimo3JgQbd3E0rOLegMqLK560Emnjze1CoLE7KcKxVTOZUgS79CyaGcRcMzFSIYgm0ARbOTNRF6dd8cbsUv_MlWu__IjY91umU6QnFHX8QM2UKJ_g1/s1440/2018-Guitar-Wiring-Version-C.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; data-original-height=&quot;1080&quot; data-original-width=&quot;1440&quot; height=&quot;240&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTxc1L1qwz0ELo4yBrmPHSbFIXfHi10c1gai2pb0ahpA0wzcDOOFtTi4oLFak1Ujlxwmzimo3JgQbd3E0rOLegMqLK560Emnjze1CoLE7KcKxVTOZUgS79CyaGcRcMzFSIYgm0ARbOTNRF6dd8cbsUv_MlWu__IjY91umU6QnFHX8QM2UKJ_g1/s320/2018-Guitar-Wiring-Version-C.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;

&lt;p&gt;This was a fun experiment. Though after using this guitar for a while now, I find though that I rarely touch the blend pot, nor do I use the phase switch. The fact that the phase switch only effects the middle position when both pickups are on makes it a little limited. Also, if the blend pot isn&#39;t in the balanced center spot, the out of phase effect is greatly limited. Having a switch to brighten up the sound is still something I&#39;m interested in and I&#39;m wondering if putting in a high pass filter using a capacitor would be a more effective technique since it could apply to all pickup selection positions. </content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/8747768043941240824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/8747768043941240824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/8747768043941240824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/8747768043941240824'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2023/09/guitar-wiring-phase-switch-and-blend-pot.html' title='Guitar Wiring - Phase Switch and Blend Pot '/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiTxc1L1qwz0ELo4yBrmPHSbFIXfHi10c1gai2pb0ahpA0wzcDOOFtTi4oLFak1Ujlxwmzimo3JgQbd3E0rOLegMqLK560Emnjze1CoLE7KcKxVTOZUgS79CyaGcRcMzFSIYgm0ARbOTNRF6dd8cbsUv_MlWu__IjY91umU6QnFHX8QM2UKJ_g1/s72-c/2018-Guitar-Wiring-Version-C.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-7981837089717590300</id><published>2021-08-17T00:16:00.005-07:00</published><updated>2025-10-30T22:52:38.284-07:00</updated><title type='text'>The 2021 Guitar - In Search of the Guitar That Can Do It All</title><content type='html'>On any given Sunday, I play covers that call for a few different electric guitar styles. I like to get as close to the original sound as possible without the hassle of bringing three or four different guitars. (The Kemper mimics the sounds of multiple different amps, so that side of the equation is taken care of.) What if I could get all of those great sounds, the brightness and clarity of single coil pickups, the power and mid-range sweetness of humbuckers, in a single guitar? Here&#39;s my latest attempt.

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG1SK4fDUJs3aGWspgQifWGx9aL3mlKmUV9T5A3bqcuFC3VtcC8BGyI0m4C5Wv-40V5f0wGkgqeSEdXq3p97sm4LPgscZ5MKKNJk_6gG_RYPeZAyY8F4s-u8VZLkbQNytxlhun/s4032/PXL_20210713_054037882.jpg&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;4032&quot; data-original-width=&quot;3024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG1SK4fDUJs3aGWspgQifWGx9aL3mlKmUV9T5A3bqcuFC3VtcC8BGyI0m4C5Wv-40V5f0wGkgqeSEdXq3p97sm4LPgscZ5MKKNJk_6gG_RYPeZAyY8F4s-u8VZLkbQNytxlhun/s400/PXL_20210713_054037882.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;At it&#39;s heart, this is a Telecaster inspired machine. The grit and cutting voice of a wound-hot Tele pickup has become one of my favorite sounds and the clarity and chiminess of a Tele bridge pickup gives the Tele a versatility that works for many styles. To the Tele foundation, I added a high output humbucker pickup and stuck it in the middle position. This is a bit unusual as most humbucker equipped guitars have two pickups, with higher output on the bridge pickup. Using the humbucker in this spot provides a sound that pushes the amp much harder than the other pickups while emphasizing the mid-range frequencies, just what is needed to round out the sonic versatility of this guitar.

&lt;/p&gt;&lt;p&gt;Here&#39;s this new guitar in action, first the neck pickup, thin and chimey, then the the grittier middle humbucker pickup:

&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;&lt;iframe allowfullscreen=&quot;&quot; frameborder=&quot;0&quot; height=&quot;315&quot; src=&quot;http://www.youtube.com/embed/cSONJ_9C5I4&quot; width=&quot;560&quot;&gt;&lt;/iframe&gt;&lt;/div&gt;

&lt;p&gt;The controls for the guitar are standard modern tele controls: three way switch for the neck and bridge pickups (neck, both, bridge) with a single volume and tone control. To accomodate the additional middle pickup, I added a volume knob which can by pulled out to switch the coils into parallel, pushed down they are in series. There is a three-way toggle switch on the horn of the guitar which selects between the standard tele circuit, the middle humbucker only, or both. Using the two switches (tele blade switch, toggle on the horn) any combination of pickups can be selected. As an added bonus, the tone knob can also be pulled out to bypass the tone circuit, letting all of those glorious highs slip through.

&lt;/p&gt;&lt;p&gt;This wiring diagram describes the full circuit for the guts of the guitar:
  
&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL_GTWv4x9wkUMoHWcww8XuvHXJwiIMccQTzXGy0Nsb8CXRe4rWRsPscBcN0rMF1Cbw1xPm2IuK_UMKdUQ9Pd1ddlmb6vbxlZ5RoJ08Yk88LYY3S5qkZiraQd3E6YB5YyuGxbx/s2048/The2021GuitarWiringA.png&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;2048&quot; data-original-width=&quot;1024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhL_GTWv4x9wkUMoHWcww8XuvHXJwiIMccQTzXGy0Nsb8CXRe4rWRsPscBcN0rMF1Cbw1xPm2IuK_UMKdUQ9Pd1ddlmb6vbxlZ5RoJ08Yk88LYY3S5qkZiraQd3E6YB5YyuGxbx/s400/The2021GuitarWiringA.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;As for the look, I went for a somewhat aged 50s tele: Butterscotch blonde with a bit of relicing to show some wear, especially around the lower bout where my elbow tends to run the body of the guitar.
  
&lt;/p&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhsIHPsohOHK44a6KvuF5zR4kQMXEVU4OxanO3IRrgXC6iuFnWDvb2uHSjHigt6LGZ3WOboTwUQj8HufWNsa77xMA_djq2oVcfVG42tFYuSBDEkLKTM10GzRru4KBNrLLT8Tyz/s4032/PXL_20210711_044502424.jpg&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;4032&quot; data-original-width=&quot;3024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhsIHPsohOHK44a6KvuF5zR4kQMXEVU4OxanO3IRrgXC6iuFnWDvb2uHSjHigt6LGZ3WOboTwUQj8HufWNsa77xMA_djq2oVcfVG42tFYuSBDEkLKTM10GzRru4KBNrLLT8Tyz/s400/PXL_20210711_044502424.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv19cOHwZ8W7Lm6_bUyW93hFR2SbckYomKkTNmEFDJm12LkzfSTKxz0TE3MfcJdhTj-pla0DlnqitBFFKqMqYEDjgO-tw5dCVgjCA6f3aDuW5TubuGhjvpft-MLInQaTflsFYL/s4032/PXL_20210713_054319304.jpg&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;4032&quot; data-original-width=&quot;3024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiv19cOHwZ8W7Lm6_bUyW93hFR2SbckYomKkTNmEFDJm12LkzfSTKxz0TE3MfcJdhTj-pla0DlnqitBFFKqMqYEDjgO-tw5dCVgjCA6f3aDuW5TubuGhjvpft-MLInQaTflsFYL/s400/PXL_20210713_054319304.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGC-PCPFRDRqBB769cX9AaWGCR6nbqNa_2UT9U1q4sHD9tbcH8dcK2WskVhl88pNRmrszuAPDjnvRT564BvIte71Ivdr9zNYiEJpCZhOu2lT4nCzSvzc8y6Zemj8qUgyps7hNJ/s4032/PXL_20210713_053946196.jpg&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;4032&quot; data-original-width=&quot;3024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgGC-PCPFRDRqBB769cX9AaWGCR6nbqNa_2UT9U1q4sHD9tbcH8dcK2WskVhl88pNRmrszuAPDjnvRT564BvIte71Ivdr9zNYiEJpCZhOu2lT4nCzSvzc8y6Zemj8qUgyps7hNJ/s400/PXL_20210713_053946196.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidaiYDlaN0PonkftwP-xaTTct7i85bjYeXF6vZhCvyNcuAmPw0NkPa1x-Zl9tpeJVoWoUb7feOvOI_0T6-qulv6DY1RxN8QZrg9XOwCqJ7JPu6cBksYm6Dg4CO-VBVfvNKUfR_/s4032/PXL_20210713_053958303.jpg&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;4032&quot; data-original-width=&quot;3024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidaiYDlaN0PonkftwP-xaTTct7i85bjYeXF6vZhCvyNcuAmPw0NkPa1x-Zl9tpeJVoWoUb7feOvOI_0T6-qulv6DY1RxN8QZrg9XOwCqJ7JPu6cBksYm6Dg4CO-VBVfvNKUfR_/s400/PXL_20210713_053958303.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4T-Pa1jZblfhpXDVYdote3mauSvNTOxdpRqC4Cxem0xJaKsA_HsbFsx6atJUM76ztlqD47El2DkkybN450ykw9u2KRRedtYS5PPtMeZxRNGuvzXwhQQ7N4OVuAnTVR3DIrJtT/s4032/PXL_20210816_045636765.jpg&quot; style=&quot;display: block; padding: 1em 0px; text-align: center;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; data-original-height=&quot;4032&quot; data-original-width=&quot;3024&quot; height=&quot;400&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh4T-Pa1jZblfhpXDVYdote3mauSvNTOxdpRqC4Cxem0xJaKsA_HsbFsx6atJUM76ztlqD47El2DkkybN450ykw9u2KRRedtYS5PPtMeZxRNGuvzXwhQQ7N4OVuAnTVR3DIrJtT/s400/PXL_20210816_045636765.jpg&quot; /&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Now for the detailed specs:
&lt;/p&gt;&lt;ul&gt;
  &lt;li&gt;Body
    &lt;ul&gt;
      &lt;li&gt;Shape: Telecaster (traditional)
      &lt;/li&gt;&lt;li&gt;Wood: Alder
      &lt;/li&gt;&lt;li&gt;Finish: Nitrocellulose Laquer (Blonde undercoat, Butterscotch topcoat) then lightly reliced using high grit sandpaper. Covered with a final coat of Tru-oil.
      &lt;/li&gt;&lt;li&gt;Pickguard, solid black
      &lt;/li&gt;&lt;li&gt;Bridge: vintage brass sadles - compensated for improved intonation
    &lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Neck
    &lt;ul&gt;
      &lt;li&gt;Shape: Telecaster with Vintage/Modern truss rod access
      &lt;/li&gt;&lt;li&gt;Wood: Solid maple
      &lt;/li&gt;&lt;li&gt;Profile: Warmoth Boatneck
      &lt;/li&gt;&lt;li&gt;Radius: Warmoth compound radius (10&quot;-16&quot;)
      &lt;/li&gt;&lt;li&gt;Frets: Stainless steel size 6150 (medium jumbo)
      &lt;/li&gt;&lt;li&gt;Finish: Tru-oil
      &lt;/li&gt;&lt;li&gt;Tuners: vintage style - string inserts in the top
    &lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Electronics
    &lt;ul&gt;
      &lt;li&gt;Pickups:
        &lt;ul&gt;
          &lt;li&gt;Bridge: &lt;a href=&quot;https://www.dimarzio.com/pickups/stacked-hum-canceling-tele/area-hot-t-bridge&quot;&gt;Dimarzio Area Hot T Bridge&lt;/a&gt;
          &lt;/li&gt;&lt;li&gt;Middle: &lt;a href=&quot;https://www.dimarzio.com/pickups/high-power/super-distortion&quot;&gt;Dimarzio Super Distortion&lt;/a&gt;
          &lt;/li&gt;&lt;li&gt;Neck: &lt;a href=&quot;https://www.dimarzio.com/pickups/stacked-hum-canceling-tele/area-t-neck&quot;&gt;Dimarzio Area T Neck&lt;/a&gt;
        &lt;/li&gt;&lt;/ul&gt;
      &lt;/li&gt;
      &lt;li&gt;Pots: 250k push pull pots for tele volume and tone controls, 500k push pull pot for middle pickup volume control
      &lt;/li&gt;&lt;li&gt;Switches: Three way blade switch for tele controls, three way LP-style toggle switch for selecting between tele controls and middle pickup
      &lt;/li&gt;&lt;li&gt;Tone Capacitor: .022uF
      &lt;/li&gt;&lt;li&gt;Tone Bleed Circuits: .001uF capacitor with 150K-ohm 1/4-watt resistor in parallel. This is used on both volume knobs.
    &lt;/li&gt;&lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This was a fun build and is a blast to play. Is this the only guitar I&#39;ll be bringing to gigs? Only time will tell.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/7981837089717590300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/7981837089717590300' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/7981837089717590300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/7981837089717590300'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2021/08/the-2021-guitar-in-search-of-guitar.html' title='The 2021 Guitar - In Search of the Guitar That Can Do It All'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiG1SK4fDUJs3aGWspgQifWGx9aL3mlKmUV9T5A3bqcuFC3VtcC8BGyI0m4C5Wv-40V5f0wGkgqeSEdXq3p97sm4LPgscZ5MKKNJk_6gG_RYPeZAyY8F4s-u8VZLkbQNytxlhun/s72-c/PXL_20210713_054037882.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-770312370675791864</id><published>2020-09-17T22:39:00.006-07:00</published><updated>2021-08-15T21:52:42.631-07:00</updated><title type='text'>Partscaster: T style with P-Rails</title><content type='html'>Super pleased with this guitar that I put together from custom parts a short while ago:
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu1SEnErOQXt_obqzl8_fAYFeAzU9YNac3ccco1N-kVgFYNrcp-K-VxdwNb7U8K2c5rNYS2wRoGMZyzVmkw6-R8HgR6VCrH23vV3g3XLIvowOuIYfkF7AUM4EQNySu6kiP3Q3p/s4048/IMG_20190101_143339.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;400&quot; data-original-height=&quot;4048&quot; data-original-width=&quot;3036&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu1SEnErOQXt_obqzl8_fAYFeAzU9YNac3ccco1N-kVgFYNrcp-K-VxdwNb7U8K2c5rNYS2wRoGMZyzVmkw6-R8HgR6VCrH23vV3g3XLIvowOuIYfkF7AUM4EQNySu6kiP3Q3p/s400/IMG_20190101_143339.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;



&lt;p&gt;One of my life-long passions has been creating music. For the past decade and a half, the form that musical expression has taken is in playing the guitar. I&#39;ve played most Sundays in church for the past several years and over time, I&#39;ve been exploring different variations on amps, effects, and guitars to try to find the perfect balance of tones, to fit the mood of the moment in music.

&lt;p&gt;Since many of the songs we play are by different groups, who each use different instruments, I&#39;ve been looking for a way to have a wide variety of different sounds on tap. Ideally, this wouldn&#39;t require carting half a dozen different guitars and amps on stage each weekend. This started me looking for different styles of guitar pickups that are versatile and mimic a number of different popular configurations. When I learned about Seymour Duncan&#39;s &lt;a href=&quot;https://www.seymourduncan.com/single-product/p-rails&quot;&gt;P-Rails&lt;/a&gt; pickups, they sounded like a perfect solution for the kind of versatility I sought.

&lt;p&gt;These pickups include a P90 pickup as well as a &quot;rail&quot; style coil, both in a tidy package that fits a space for most humbucker pickups. If wired to switch between the P90, the rail pickup, or both, this one pickup could do triple-duty; matching three common pickup styles. Seymour Duncan also provides a great way to handle the switching between these different modes in their &lt;a href=&quot;https://www.seymourduncan.com/single-product/triple-shot&quot;&gt;Triple Shot mounting rings&lt;/a&gt;. These are essentially pickup rings that also include two small switches, and by flipping through different combinations, the pickups can be run as: P90-only, rail-only, both in parallel, and both in series. My mind was swimming with possibilities.

&lt;p&gt;With the pickups sorted out, now the question was, what kind of platform should these pickups be put into? I&#39;ve recently been enjoying Telecaster guitars, and the traditional shape and style of an early 1950s Telecaster has a timeless appeal that seemed like an inconspicious way to bring a surprising amount of versatility on stage. Rather than buy a Tele to rip it apart, I thought I could start fresh, and it seemed like building my own Tele-style guitar from parts might not be too far a stretch for me, as little woodworking experience as I had had at this point. The place many people turn for custom guitar parts &lt;a href=&quot;https://www.warmoth.com/&quot;&gt;Warmoth&lt;/a&gt;, which has a great reputation for high quality custom work. I choose a Telecaster &lt;a href=&quot;https://www.warmoth.com/guitar/bodies/&quot;&gt;shape&lt;/a&gt; routed for Humbucker pickups, made of Alder (same as the American Standard Telecaster I also have).

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYZru6E1dZ42mF_gMbyTILMcWftOu5Qh3T2QC_cjVOozQkXZcKJ_JcXsbEcOwpHt96kBGOJkzpt-GDQdQEBkLuQIfhS0HmQA_v6LqJ5c8PMfFg4lusKybHMmj8HCx0zRin0AlU/s4048/IMG_20181214_170322.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;400&quot; data-original-height=&quot;3036&quot; data-original-width=&quot;4048&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjYZru6E1dZ42mF_gMbyTILMcWftOu5Qh3T2QC_cjVOozQkXZcKJ_JcXsbEcOwpHt96kBGOJkzpt-GDQdQEBkLuQIfhS0HmQA_v6LqJ5c8PMfFg4lusKybHMmj8HCx0zRin0AlU/s400/IMG_20181214_170322.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;For the neck of the guitar, I had a couple of unique things in mind. First was the thickness of the neck. I have relatively long fingers, and the thin necks on some electric guitars tend to cause discomfort on long playing sessions. I&#39;ve found thicker necks to be much more comfortable, so I decided to pick a &lt;a href=&quot;https://www.warmoth.com/guitar/necks/backcontours.aspx&quot;&gt;Boatneck&lt;/a&gt; profile when ordering from Warmoth. The second non-traditional detail that I had in mind was to spring for stainless steel frets. I dislike the idea of the frets wearing down over the years as I play, and I wanted to build something that I&#39;d enjoy playing for years to come. The durability of stainless frets might mean that I&#39;ll never need to refret this neck, which sounds like a win to me.

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaOf305tS1YJ6HpGh3E4lfKvwoKJ0jv2K7Da-lyx9oUCFnq-WJfQtB2nxU1mvw-57cui9qNy9U_b9aA88kIMiN8XZ2Dnvh_DdCSwUiewG2b9uI9vWs7rLCy5NLVxk1dRw2wzIr/s4048/IMG_20181214_170007.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;400&quot; data-original-height=&quot;3036&quot; data-original-width=&quot;4048&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjaOf305tS1YJ6HpGh3E4lfKvwoKJ0jv2K7Da-lyx9oUCFnq-WJfQtB2nxU1mvw-57cui9qNy9U_b9aA88kIMiN8XZ2Dnvh_DdCSwUiewG2b9uI9vWs7rLCy5NLVxk1dRw2wzIr/s400/IMG_20181214_170007.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAnrUX9Ed7DtNatbS8kkEPwHezNiv7lHTdJIea-noQAR5sU-O9laFk1vJt8CAUCsyfXYVMECXoUpHNMomCV7L2aLKQ0FsA8OhViAlijFVv6Bl1hUTp8zxNEpVX7eZbGs-kG_ZS/s4048/IMG_20181214_170102.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;400&quot; data-original-height=&quot;3036&quot; data-original-width=&quot;4048&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAnrUX9Ed7DtNatbS8kkEPwHezNiv7lHTdJIea-noQAR5sU-O9laFk1vJt8CAUCsyfXYVMECXoUpHNMomCV7L2aLKQ0FsA8OhViAlijFVv6Bl1hUTp8zxNEpVX7eZbGs-kG_ZS/s400/IMG_20181214_170102.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;  
  
&lt;p&gt;The last question was the finish. Traditionally, the early Fender guitars were finished with nitrocellulose laquer, and even today many high end instruments use this as the weatherproof coating. While in some ways inferior to modern materials, there are two aspects to this finish that I found attractive: ease of applying the finish and repairing mistakes (thanks to its ability to &quot;burn in&quot; to previous layers) and the way that it hardens and wears over time. The worn-in look is quite popular these days, especially on telecasters, and while I have no plans to artificially relic this guitar, I&#39;d love to watch how the finish ages over the years. I decided to apply the finish myself, so I bought a few rattle cans of nitrocellulose laquer in butterscotch transparent and clear. I applied a few coats of clear as a sealer, then around 4 coats of butterscotch, followed by around 10 coats of clear on top. The neck of the guitar I sprayed with clear only. After waiting a couple of weeks for it to dry, I wet-sanded with a series of increasingly high grits of sandpaper. Starting from around 180 grit, I worked up slowly to 4000. It was pretty nerve-wracking at the start, seeing the shiny, but a bit orange-peel-y, finish turn dull and flat. Not until over 2000 grit did it start to shine again.

&lt;p&gt;The painting all finished, it was time to put it together! For the wiring, I thought it would be cool to try a 4-way switch with positions for neck pickup only, bridge pickup only, both in parallel, and both in series (to match the multiple ways to wire each pickup). This would create a dizzying array of pickup combinations - 40, to be precise, which is probably too many, but hey, if you&#39;ve got it why not! The last detail of the wiring which is somewhat unusual is the &quot;treble bleed circuit&quot; which consists of a capacitor + resistor on the volume potentiometer. It allows some of the high frequencies to continue to &quot;bleed&quot; through the volume control as it is turned down. The effect is that as the volume is turned down, the sound gets &quot;thinner&quot; and more bright, rather than darker and more muddy which would naturally happen on a volume pot without this added detail. I&#39;ve loved this feature of my American Standard Telecaster, so I decided to duplicate it here.

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHKSgIERo2fS2nvtr8-Nw4gSVpg3MnTOfPnteowSZzgkan5xTjHvNjTHteH-yVh60q3LmyGwrhCd6gZXtGi4eghV34Z5WvCxifB427QOT86_wjeg-1B7Rf9lCaLcBtsjbvxM_A/s4048/IMG_20181229_213634.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;400&quot; data-original-height=&quot;4048&quot; data-original-width=&quot;3036&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgHKSgIERo2fS2nvtr8-Nw4gSVpg3MnTOfPnteowSZzgkan5xTjHvNjTHteH-yVh60q3LmyGwrhCd6gZXtGi4eghV34Z5WvCxifB427QOT86_wjeg-1B7Rf9lCaLcBtsjbvxM_A/s400/IMG_20181229_213634.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;
  
&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWaMLH2s4Qmptyt85A8AZYCodFRR74iCRTFPNC3B_yzFiIggNmiIivCu6YFoTN9dGKyDQwXDSYQ4ggbj5AlGr0Nn66ZgIJZUPzb4lMvWFQS91-1V1_V_NDdYaVB1PCrR0_2s4X/s4048/IMG_20190111_214920.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;400&quot; data-original-height=&quot;3036&quot; data-original-width=&quot;4048&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWaMLH2s4Qmptyt85A8AZYCodFRR74iCRTFPNC3B_yzFiIggNmiIivCu6YFoTN9dGKyDQwXDSYQ4ggbj5AlGr0Nn66ZgIJZUPzb4lMvWFQS91-1V1_V_NDdYaVB1PCrR0_2s4X/s400/IMG_20190111_214920.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj48ZtoMP-ev6oN4IQ3t13j_BAa3rGcrsOgm571q-Vg4NIuJvlH9UmBVU2XlwoCDn7GPEsbm65AOlJIoEASwHp_ZN7NuAnwovvkuUc2PwMMP4nxLjORYOVM6zxujNvEOU78-suO/s4048/IMG_20190111_220701.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;400&quot; data-original-height=&quot;3036&quot; data-original-width=&quot;4048&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj48ZtoMP-ev6oN4IQ3t13j_BAa3rGcrsOgm571q-Vg4NIuJvlH9UmBVU2XlwoCDn7GPEsbm65AOlJIoEASwHp_ZN7NuAnwovvkuUc2PwMMP4nxLjORYOVM6zxujNvEOU78-suO/s400/IMG_20190111_220701.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

Here&#39;s the schematic for the wiring:

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhehKvVRlEzYcbxeOa-6v5LcaV-TvaPuI7MQJjVPLxi1hHjj9WKYpXUkxvcrCC1tkNDh7_5euv5w8hEq0LyGh4lFUkZc_MLKJ1qXHLAjduMFR6hMx4RFS8AFs4k0t-ObnsgnpZk/s1440/2018-Guitar-Wiring-Version-B.png&quot; style=&quot;display: block; padding: 1em 0; text-align: none; &quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; width=&quot;400&quot; data-original-height=&quot;1080&quot; data-original-width=&quot;1440&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhehKvVRlEzYcbxeOa-6v5LcaV-TvaPuI7MQJjVPLxi1hHjj9WKYpXUkxvcrCC1tkNDh7_5euv5w8hEq0LyGh4lFUkZc_MLKJ1qXHLAjduMFR6hMx4RFS8AFs4k0t-ObnsgnpZk/s400/2018-Guitar-Wiring-Version-B.png&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

Over the course of a few months, I worked on this over the weekends and vacations and finally wrapped it all up around Christmas time. Without further ado, the pictures:

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6wH4eXtRML5TQO_shU6tUUpj1xoMsbTJ1Xk8BrMV4WRg9BHtFm53FPFi2h43TQcAdUvsDW0Xf-eXZY8pIiQXiLSXU8T82eSDURt5m5TJcXzfYEQMtLFOQIiiH5UkKjIcHFS23/s4048/IMG_20190524_232454.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;400&quot; data-original-height=&quot;4048&quot; data-original-width=&quot;3036&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg6wH4eXtRML5TQO_shU6tUUpj1xoMsbTJ1Xk8BrMV4WRg9BHtFm53FPFi2h43TQcAdUvsDW0Xf-eXZY8pIiQXiLSXU8T82eSDURt5m5TJcXzfYEQMtLFOQIiiH5UkKjIcHFS23/s400/IMG_20190524_232454.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZv__B_gelx8MW3wVCy8iy4Mq9vK61J0esb-_NLQu1ZRiW3lBtfryvkWhSgUDHPOfRZoROg_hFJfgrBeu68AruBywkSUQvzfUlNzvxTGk_Uec4Zpjd3FyZ5v8QSnjQmqHvG0Tg/s4048/IMG_20190101_144752.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;400&quot; data-original-height=&quot;4048&quot; data-original-width=&quot;3036&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZv__B_gelx8MW3wVCy8iy4Mq9vK61J0esb-_NLQu1ZRiW3lBtfryvkWhSgUDHPOfRZoROg_hFJfgrBeu68AruBywkSUQvzfUlNzvxTGk_Uec4Zpjd3FyZ5v8QSnjQmqHvG0Tg/s400/IMG_20190101_144752.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;div class=&quot;separator&quot; style=&quot;clear: both;&quot;&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1pEiqDAldudKwHxGFRRRwfvHF6HA3i1uWLFdWkrLz8Q2L4znu3pGBEvxo_KzNIfA3Zl17Mmy3ismW7qPAnevGqnFEoeh_G97LBvQYjC1ouTtqTVugLabpJUBvdN9dFBRLy_pG/s4048/IMG_20181229_164002.jpg&quot; style=&quot;display: block; padding: 1em 0; text-align: none;&quot;&gt;&lt;img alt=&quot;&quot; border=&quot;0&quot; height=&quot;400&quot; data-original-height=&quot;4048&quot; data-original-width=&quot;3036&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi1pEiqDAldudKwHxGFRRRwfvHF6HA3i1uWLFdWkrLz8Q2L4znu3pGBEvxo_KzNIfA3Zl17Mmy3ismW7qPAnevGqnFEoeh_G97LBvQYjC1ouTtqTVugLabpJUBvdN9dFBRLy_pG/s400/IMG_20181229_164002.jpg&quot;/&gt;&lt;/a&gt;&lt;/div&gt;

&lt;p&gt;Here are the specs at a glance:
&lt;ul&gt;
  &lt;li&gt;Body
    &lt;ul&gt;
      &lt;li&gt;Shape: Telecaster (traditional)
      &lt;li&gt;Wood: Alder
      &lt;li&gt;Finish: Nitrocellulose Laquer (Butterscotch and Clear)
      &lt;li&gt;Pickguard, solid black
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Neck
    &lt;ul&gt;
      &lt;li&gt;Shape: Telecaster with &lt;a href=&quot;https://www.warmoth.com/Guitar/Necks/NeckConstructions.aspx&quot;&gt;Vintage/Modern truss rod access&lt;/a&gt;
      &lt;li&gt;Profile: &lt;a href=&quot;https://www.warmoth.com/guitar/necks/backcontours.aspx&quot;&gt;Warmoth Boatneck&lt;/a&gt;
      &lt;li&gt;Radius: &lt;a href=&quot;https://www.warmoth.com/Guitar/Necks/Radius.aspx&quot;&gt;Warmoth compound radius (10&quot;-16&quot;)&lt;/a&gt;
      &lt;li&gt;Frets: &lt;a href=&quot;https://www.warmoth.com/guitar/necks/fretsize.aspx&quot;&gt;Stainless steel size 6150 (medium jumbo)&lt;/a&gt;
      &lt;li&gt;Finish: Nitrocellulose Laquer (Clear)
      &lt;li&gt;Tuners: &lt;a href=&quot;http://www.sperzel.com/&quot;&gt;Sperzel locking tuners&lt;/a&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
  &lt;li&gt;Electronics
    &lt;ul&gt;
      &lt;li&gt;Pickups: &lt;a href=&quot;https://www.seymourduncan.com/single-product/p-rails-triple-shot-set-flat&quot;&gt;P-Rails for Neck and Bridge pickups, wired to Triple Shot mounting rings&lt;/a&gt;
      &lt;li&gt;Oak Grigsby 4 way switch
      &lt;li&gt;Treble bleed circuit on volume pot
      &lt;li&gt;CTS pots
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/770312370675791864/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/770312370675791864' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/770312370675791864'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/770312370675791864'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2020/09/partscaster-t-style-with-p-rails.html' title='Partscaster: T style with P-Rails'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhu1SEnErOQXt_obqzl8_fAYFeAzU9YNac3ccco1N-kVgFYNrcp-K-VxdwNb7U8K2c5rNYS2wRoGMZyzVmkw6-R8HgR6VCrH23vV3g3XLIvowOuIYfkF7AUM4EQNySu6kiP3Q3p/s72-c/IMG_20190101_143339.jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-8188499279025577889</id><published>2020-08-23T11:26:00.000-07:00</published><updated>2024-05-30T21:33:10.273-07:00</updated><title type='text'>Cryptopals</title><content type='html'>I&#39;ve had a longstanding interest in cryptography and recently dove into a set of exercises that teach basic concepts of cryptanalysis. I highly recommend it if you are looking to learn more about cryptography: &lt;a href=&quot;https://cryptopals.com/&quot;&gt;Cryptopals&lt;/a&gt;. </content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/8188499279025577889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/8188499279025577889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/8188499279025577889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/8188499279025577889'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2020/08/crptopals.html' title='Cryptopals'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-7247868493682071055</id><published>2020-08-23T11:22:00.000-07:00</published><updated>2020-08-23T11:22:20.407-07:00</updated><title type='text'>Early Telecasters A Visual History</title><content type='html'>Along with software development, my other passion is for making music. There have been a few instruments I&#39;ve specialized in over the years, but my far and away favorite at the moment is electric guitar, specifically a Fender Telecaster. For the past couple of years, I&#39;ve been playing a 2015 American Standard. Here are a few pictures:

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5mQAFcfIpiV64mp_6Q79dcZiYF-QrJYe2siI0L3QjelXFo1xQJsSh8TNHNt9iZaDTFcAz_Q5Z_Q_5anxwK-4nVo8XoT41XV8vY-RIDWLArscPIRYdkEU92ROMnB9rJqPoFTzc/s1600/Screen+Shot+2018-08-13+at+9.22.59+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5mQAFcfIpiV64mp_6Q79dcZiYF-QrJYe2siI0L3QjelXFo1xQJsSh8TNHNt9iZaDTFcAz_Q5Z_Q_5anxwK-4nVo8XoT41XV8vY-RIDWLArscPIRYdkEU92ROMnB9rJqPoFTzc/s1600/Screen+Shot+2018-08-13+at+9.22.59+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2MmUmn0eqHGlDp5fH3nwuurqpTYtNCGfFZMSiX9awsTsSFlhB56miu7IkVAHdSxOTqIn-y7G4ROsBHJCCKRDt_elOSJkqoEXlu-jkgvW2o3_BnhuvqE3iZqFSaNr4j0qz50Ck/s1600/Screen+Shot+2018-08-14+at+9.20.30+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg2MmUmn0eqHGlDp5fH3nwuurqpTYtNCGfFZMSiX9awsTsSFlhB56miu7IkVAHdSxOTqIn-y7G4ROsBHJCCKRDt_elOSJkqoEXlu-jkgvW2o3_BnhuvqE3iZqFSaNr4j0qz50Ck/s1600/Screen+Shot+2018-08-14+at+9.20.30+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivANfxnFZ546J3Cc9NvoZQKsi2zRUMdYJUZizRTEVOpIlKBgKVLxCt3oLBVC0WQ73Fa5lc1brIP1AufaUX67C74xDLWmbXEm5c0cSYCC4qL6g4WbQVtG4MK6sFMjz4408dUIBM/s1600/Screen+Shot+2018-08-14+at+9.46.07+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEivANfxnFZ546J3Cc9NvoZQKsi2zRUMdYJUZizRTEVOpIlKBgKVLxCt3oLBVC0WQ73Fa5lc1brIP1AufaUX67C74xDLWmbXEm5c0cSYCC4qL6g4WbQVtG4MK6sFMjz4408dUIBM/s1600/Screen+Shot+2018-08-14+at+9.46.07+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1vSkCO4IQVgMll3cdXRQmlnlsFFbqv-2Ah7cNzJaA2oxEvUZb904PMll3Bc2wPk7ccSK1z0ki88cuLLEuekJZfF8AouFE9Fe5NUHMRPhKM6XLRwq_bHYjmYIq67Hk74AxYtt/s1600/Screen+Shot+2018-08-14+at+9.33.12+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1vSkCO4IQVgMll3cdXRQmlnlsFFbqv-2Ah7cNzJaA2oxEvUZb904PMll3Bc2wPk7ccSK1z0ki88cuLLEuekJZfF8AouFE9Fe5NUHMRPhKM6XLRwq_bHYjmYIq67Hk74AxYtt/s1600/Screen+Shot+2018-08-14+at+9.33.12+AM.png&quot; /&gt;
&lt;/a&gt;
&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw2R7m-gn8nmLf1K57MCiwrHG_moEfDkqOhEMShPT9fUAK7xGJtu3Ap_x-Y8JgkE8TVPYSgbwnSrIWE15afE1WDPlLdywT3EucuVeJZZRWE9gID4dWYPuj32ayI33YzW9lEQp9/s1600/Screen+Shot+2018-08-14+at+9.42.33+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgw2R7m-gn8nmLf1K57MCiwrHG_moEfDkqOhEMShPT9fUAK7xGJtu3Ap_x-Y8JgkE8TVPYSgbwnSrIWE15afE1WDPlLdywT3EucuVeJZZRWE9gID4dWYPuj32ayI33YzW9lEQp9/s1600/Screen+Shot+2018-08-14+at+9.42.33+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaun8d04KzxcN1xgE_RkvHirldWg7eYV0YSjnWjaQcoHVclmaJI-I7I6FM4kvb30pctt99hlEm9UF4vZrMrCHEV64k1IF0l_Vo6YjAXm-Feyt5hOod0L14SzQ2ng_Kvd4696z2/s1600/Screen+Shot+2018-08-14+at+9.49.59+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhaun8d04KzxcN1xgE_RkvHirldWg7eYV0YSjnWjaQcoHVclmaJI-I7I6FM4kvb30pctt99hlEm9UF4vZrMrCHEV64k1IF0l_Vo6YjAXm-Feyt5hOod0L14SzQ2ng_Kvd4696z2/s1600/Screen+Shot+2018-08-14+at+9.49.59+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0V7FAjqIzwns2NINPTyuJcR6BD5gm-yIIGI7NngONLnF3eNHoISM0AlWLFwUqA2WB5dWwe3LWm0tEOCZqmXQszykqHSWoMwhxk9Q5h32jO-qBTA9wh_UVnHZS0vmwk8zXGla/s1600/Screen+Shot+2018-08-13+at+9.28.02+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgP0V7FAjqIzwns2NINPTyuJcR6BD5gm-yIIGI7NngONLnF3eNHoISM0AlWLFwUqA2WB5dWwe3LWm0tEOCZqmXQszykqHSWoMwhxk9Q5h32jO-qBTA9wh_UVnHZS0vmwk8zXGla/s1600/Screen+Shot+2018-08-13+at+9.28.02+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWGwBftFZJ280YiqFBzNiN3DthmbwsSjtTfzZy1wNl1VOJq0muRs3gH9Hs1rXmivVHiwtzLU_oPtNAbrd-1N7X6QdfdxOYI56G1edm8JBdP-qCFx8kH8wsO9Dot8Q0HCyZtI56/s1600/Screen+Shot+2018-08-13+at+9.22.10+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjWGwBftFZJ280YiqFBzNiN3DthmbwsSjtTfzZy1wNl1VOJq0muRs3gH9Hs1rXmivVHiwtzLU_oPtNAbrd-1N7X6QdfdxOYI56G1edm8JBdP-qCFx8kH8wsO9Dot8Q0HCyZtI56/s1600/Screen+Shot+2018-08-13+at+9.22.10+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQVUYcyVhBEgM9xCvpJDVTISoKAQHwvFNWtAxdTl5QTooD58iImhpmrwK_tvTHcHx-EjyOyZIkbuw5GrMoJ7fwA-UTPOwcOqaRZUxRahjGHQsic6kZ5BajsQ2B7GSCyVRnXSqB/s1600/Screen+Shot+2018-08-13+at+9.25.14+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiQVUYcyVhBEgM9xCvpJDVTISoKAQHwvFNWtAxdTl5QTooD58iImhpmrwK_tvTHcHx-EjyOyZIkbuw5GrMoJ7fwA-UTPOwcOqaRZUxRahjGHQsic6kZ5BajsQ2B7GSCyVRnXSqB/s1600/Screen+Shot+2018-08-13+at+9.25.14+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;p&gt;One of the things that amazes me about this instrument is the classic design which has undergone very few changes since this instrument was first introduced in 1950. As one of the very first mass produced electric guitars, the Telecaster continues to influence modern music as well as the design of electric guitars. Most electric guitar makers sell a &quot;T&quot; style guitar in their lineup.

&lt;p&gt;Lets look back at a brief visual history of the first decade of the Telecaster family of guitars.

&lt;h4&gt;1950&lt;/h4&gt;
&lt;p&gt;Beginning in 1950, the Fender Electric Instrument Manufacturing Company began selling a couple of styles of electric guitar. First, the single pickup Esquire, followed shortly by the two pickup Broadcaster.

&lt;h5&gt;Esquire&lt;/h5&gt;
&lt;p&gt;One of the surprising details to me about this guitar, is the presence of a three-way selector switch. In most electric guitars, the selector switch activates different combinations of the pickups in the guitar. Most single pickup guitars omit a selector switch (see for example, &lt;a href=&quot;https://en.wikipedia.org/wiki/Gibson_Les_Paul_Junior&quot;&gt;the Gibson Les Paul Junior&lt;/a&gt;). So what is a selector switch doing on a single pickup guitar?

&lt;p&gt;In the wiring for an Esquire, the middle position matches what most would consider a normal setup for a single pickup guitar with two knobs. In this position, the volume and tone knobs control the output from the pickups. When the switch is up towards the neck of the guitar, an additional capacitor is in the output chain in place of the tone knob. This cuts out many of the high frequencies in the output and produces a somewhat muddy sound more reminiscent of a bass guitar. &lt;a href=&quot;https://www.youtube.com/watch?v=lD2DbtBY5xU&amp;t=47&quot;&gt;This video has a great demonstration of the Esquire tones&lt;/a&gt;. A demonstration of the tones begins around &lt;a href=&quot;https://youtu.be/lD2DbtBY5xU?t=207&quot;&gt;3:27 in the video&lt;/a&gt;. This circuit position in particular is not typically found on a modern electric guitar, pretty unique! The final position, down towards the bridge is a circuit that bypasses the tone control entirely and is the least filtered of the circuit options. Only the volume control is changing the output, so you get the widest possible set of frequencies. There are a few guitars out there today that dispense with a tone control. One example is the Jim Root Telecaster, however it is a very different beast than the 1950 Fender Esquire.

&lt;p&gt;And now for the look:
&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5pcmHqooRYFS5cx979fSPyHkqgJ0Kx5P_EiisqLL17Wd_rthVgOri7c3uDzTFKNYkllSo_gzo2osNJJuOk_fSoBbvsa27e4XJlUYH45abjqOL1n1lvlz__dMyhRk86XdF8X-x/s1600/Screen+Shot+2018-08-17+at+9.33.44+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5pcmHqooRYFS5cx979fSPyHkqgJ0Kx5P_EiisqLL17Wd_rthVgOri7c3uDzTFKNYkllSo_gzo2osNJJuOk_fSoBbvsa27e4XJlUYH45abjqOL1n1lvlz__dMyhRk86XdF8X-x/s1600/Screen+Shot+2018-08-17+at+9.33.44+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZf6AoLdr7N6DiEroJJ6kgIMnpOa9jE_fl_w8tRHgibks1OgxA9fMgsyJIvSVI_IwuRUYqmPhrFaCjN6dx-fPmPQGLoTgeUTyFP-elBXkmOjoauAIBjaO9O4oKNFXcZvXE4h0l/s1600/Screen+Shot+2018-08-17+at+9.35.28+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiZf6AoLdr7N6DiEroJJ6kgIMnpOa9jE_fl_w8tRHgibks1OgxA9fMgsyJIvSVI_IwuRUYqmPhrFaCjN6dx-fPmPQGLoTgeUTyFP-elBXkmOjoauAIBjaO9O4oKNFXcZvXE4h0l/s1600/Screen+Shot+2018-08-17+at+9.35.28+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLsxnFY-kifU2vrN-a2S1wT_1jgfw3US9vJ3zUORTCrVBy_5ieQ8to2fHXZnTDr0PjWcP-ryiWkAXc7TMTrzXlp6uKwk6UY61ADbaGz9MZi78thjM-f_ecAgPAdFDalFNoNeFp/s1600/Screen+Shot+2018-08-17+at+9.44.57+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhLsxnFY-kifU2vrN-a2S1wT_1jgfw3US9vJ3zUORTCrVBy_5ieQ8to2fHXZnTDr0PjWcP-ryiWkAXc7TMTrzXlp6uKwk6UY61ADbaGz9MZi78thjM-f_ecAgPAdFDalFNoNeFp/s1600/Screen+Shot+2018-08-17+at+9.44.57+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;p&gt;While the single pickup guitar was the first to be widely available, from the beginning, Fender had planned to produce a two pickup guitar. In fact, these early Esquire guitars reportedly had a cutout for the neck pickup ready to go but hidden away under the pickguard. And that brings us to the next guitar available in 1950: the Broadcaster.

&lt;h5&gt;Broadcaster&lt;/h5&gt;

With it&#39;s two pickups mounted on a solid ash body, this is very recognizably the first example of what is today the Telecaster. Originally named the Broadcaster, it would soon have to be renamed due to a trademark dispute. Few guitars carry the Broadcaster name. 

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRqZPhFIjIvGc3mE7Nidu1qN3ww3soqAr4CjnvTnL_3jn9KiyOWrZlfwENlPU1hyphenhyphen00DxLTYAj8HSrkR2SvFY4exf8tsI2tjWzovPwUYvp3O5hAK7lPaTIM7_K3y_2_83VKQe5e/s1600/Screen+Shot+2018-08-17+at+9.51.38+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRqZPhFIjIvGc3mE7Nidu1qN3ww3soqAr4CjnvTnL_3jn9KiyOWrZlfwENlPU1hyphenhyphen00DxLTYAj8HSrkR2SvFY4exf8tsI2tjWzovPwUYvp3O5hAK7lPaTIM7_K3y_2_83VKQe5e/s1600/Screen+Shot+2018-08-17+at+9.51.38+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMBTugnNLzxE9XFg3Nby5cQP7Zv9BbwHXz_pqMRgJ4-234imHOgWb3zQBO-LMHRBHP03DKBYJlYyLqj3YVHnOUkMEOBk51YyOqaOBrDqAHH3Al1wD9GKB0OpoOeptv9iVv2Lk7/s1600/Screen+Shot+2018-08-17+at+9.52.45+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgMBTugnNLzxE9XFg3Nby5cQP7Zv9BbwHXz_pqMRgJ4-234imHOgWb3zQBO-LMHRBHP03DKBYJlYyLqj3YVHnOUkMEOBk51YyOqaOBrDqAHH3Al1wD9GKB0OpoOeptv9iVv2Lk7/s1600/Screen+Shot+2018-08-17+at+9.52.45+PM.png&quot; /&gt;
&lt;/a&gt;
&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfLmlN0a4Hd0E34D6AaCdt3dfOXuRyHVANkFYDiGv3t9mBfJN13VbMDnT3keNGB8U-1ZpIF01uyLKTBdddvqq0d9th-Trs94IbKc7Wu-HvOlMjnqJRphFh9vr2Ouufew_7RRyo/s1600/Screen+Shot+2018-08-17+at+9.56.53+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfLmlN0a4Hd0E34D6AaCdt3dfOXuRyHVANkFYDiGv3t9mBfJN13VbMDnT3keNGB8U-1ZpIF01uyLKTBdddvqq0d9th-Trs94IbKc7Wu-HvOlMjnqJRphFh9vr2Ouufew_7RRyo/s1600/Screen+Shot+2018-08-17+at+9.56.53+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEialPnHrXfOvngekPXyOOMjWSBjI3jFZbD1cYfJV2SUOGWaAJKWYvnQqX7RDG9hmnWYjWZnW9n9I3txjM_zte6637xBBbCT0InjExCNaqVN9hryy3W2Twarm6EcaPK_N9Sg7zkd/s1600/Screen+Shot+2018-08-17+at+9.54.30+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEialPnHrXfOvngekPXyOOMjWSBjI3jFZbD1cYfJV2SUOGWaAJKWYvnQqX7RDG9hmnWYjWZnW9n9I3txjM_zte6637xBBbCT0InjExCNaqVN9hryy3W2Twarm6EcaPK_N9Sg7zkd/s1600/Screen+Shot+2018-08-17+at+9.54.30+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLtMwvIxmargdyGvN6N128j1NKrB0jbdfXoR8baR_Mpw6oYT2Ju_ur8hR2JoyneZ2SSgJpmHsUrA55i72QU91iZHLC_Xx4yi0O4lYSfoAvFb3OHMZyXZTVAFbLvsvIYpGxlVjG/s1600/Screen+Shot+2018-08-17+at+10.01.07+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiLtMwvIxmargdyGvN6N128j1NKrB0jbdfXoR8baR_Mpw6oYT2Ju_ur8hR2JoyneZ2SSgJpmHsUrA55i72QU91iZHLC_Xx4yi0O4lYSfoAvFb3OHMZyXZTVAFbLvsvIYpGxlVjG/s1600/Screen+Shot+2018-08-17+at+10.01.07+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS98WNOk1vpa_-U6tGsndO3UB5FFT3LYnURCHlZTri7ufYOVTpwJ-VsRUyBRduQnFYfHfGSVRD95LKZfqd6qrYh0sd4e8p23idjCX3T6QFuMRqUK6gxZJ7KZDv2tMj0_WMANDU/s1600/Screen+Shot+2018-08-17+at+10.02.47+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiS98WNOk1vpa_-U6tGsndO3UB5FFT3LYnURCHlZTri7ufYOVTpwJ-VsRUyBRduQnFYfHfGSVRD95LKZfqd6qrYh0sd4e8p23idjCX3T6QFuMRqUK6gxZJ7KZDv2tMj0_WMANDU/s1600/Screen+Shot+2018-08-17+at+10.02.47+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;p&gt;While the Broadcaster has the recognizable two pickup configuration, two knobs, and a three way selector, the wiring is very different from what would later become what is now considered normal Telecaster wiring. In these early models, the three selector switch toggled between the following settings. (Note, more details on this &lt;a href=&quot;https://www.premierguitar.com/articles/The_Two_Pickup_Esquire_Wiring&quot;&gt;original Broadcaster wiring can be found here&lt;/a&gt;.) Here&#39;s what the different positions in a Broadcaster switch do:

&lt;p&gt;The position with the switch down towards the bridge includes the output of the bridge pickup, with no tone adjustment similar to this setting in the Esquire. However, rather than ignore the tone know, in this position, the &quot;tone&quot; knob is a &quot;blend&quot; control which adds in the output from the neck pickup. Turned one way, the neck pickup is all the way in, the other way it&#39;s all the way out. Next, the middle position includes the full output of only the neck pickup (no tone modification). The final position, up towards the neck, includes only the neck pickup with a capacitor that filters out the high frequencies. I found it fascinating that in the original Broadcaster wiring, there&#39;s no variable tone control, just pickup selection with one option being a fixed tone cut. The closest-to-bridge switch position is most similar to the middle position in modern Telecasters. Although, in a modern telecaster, there&#39;s a constant balance of output between the picksups when both are active. 

&lt;p&gt;A good example of the tones that come from this wiring can be found in &lt;a href=&quot;https://www.youtube.com/watch?v=r_UI0pjL1SI&quot;&gt;this video&lt;/a&gt;. Although this isn&#39;t an original Broadcaster, it demonstrates the different behaviors of this pickup switch. &lt;a href=&quot;https://www.youtube.com/watch?v=Ya5LrfNTz5I&amp;t=20&quot;&gt;Here&#39;s another example&lt;/a&gt;. For a video showcasing an actual 1950 Broadcaster, &lt;a href=&quot;https://www.youtube.com/watch?v=SE_3ra_jSAs&amp;t=6&quot;&gt;check out this video from Norman&#39;s Rare Guitars&lt;/a&gt;.

&lt;h4&gt;1951&lt;/h4&gt;

Over the course of 1951, the Broadcaster would be renamed to the Telecaster. Aside from the name change, the guitars&#39; design was essentially unchanged.

&lt;h5&gt;Broadcaster&lt;/h5&gt;

&lt;p&gt;In early 1951, Fender continued making Broadcaster guitars. However, the Gretsch company notified Fender that the Broadcaster name on their guitar conflicted with their trademarked &lt;a href=&quot;http://gretschdrums.com/drums/broadkaster&quot;&gt;Gretsch Broadkaster drum set&lt;/a&gt;. It doesn&#39;t sound like the two companies went to court over the name. I wonder how it would have gone had Fender decided not to change the name. Gretsch also produced electric guitars at the time, and continues to make and sell them today. In 1951, none of the &lt;a href=&quot;https://www.gretschguitars.com/&quot;&gt;Gretsch guitars&lt;/a&gt; were named Broadcaster, though they do today sell a &lt;a href=&quot;https://www.gretschguitars.com/gear/build/center-block/g6609tfm-players-edition-broadkaster-center-block-double-cut-with-string-thru-bigsby-and-flame-maple/2400700878&quot;&gt;Broadkaster Guitar&lt;/a&gt;.

&lt;h5&gt;Nocaster&lt;/h5&gt;

&lt;p&gt;Following the notice from Gretsch guitars, Fender began producing their formerly-known-as-Broadcaster guitars with no model name on the decal. The headstock of the guitar was labelled only with the name Fender, hence guitars produced in their period are dubbed &quot;Nocaster&quot; guitars. Aside from the name change on the headstock, the Nocaster is visually similar to the Broadcaster that came before it. The body is painted a translucent Butterscotch Blond with a single-ply black pickguard: 

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK1HvuAf-NinuofGwaSBKNad9lPt4Bg14cCsAK7zr54K0MEhtNMiT8vsESlPqZRcPqR1MvuBfXxpUT0dYO4fydTsW5E_hrJqcgu0V-22ovkbFx8F_KZvBp_LNgSrwN82z9pH_I/s1600/Screen+Shot+2018-08-19+at+7.34.53+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhK1HvuAf-NinuofGwaSBKNad9lPt4Bg14cCsAK7zr54K0MEhtNMiT8vsESlPqZRcPqR1MvuBfXxpUT0dYO4fydTsW5E_hrJqcgu0V-22ovkbFx8F_KZvBp_LNgSrwN82z9pH_I/s1600/Screen+Shot+2018-08-19+at+7.34.53+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOtA_5F8Mq5iQwkagVk_FZLSOoz_B0KhrQmaWGtWJsKWqRP0K1QPJYkw4zyac5s6lhv2AbWV-dEypQz0CTk-Mrx-Jxd3evS0r1ylxo_5QGzMG2z5VLQV1_mgHbmLYVckwz6x7L/s1600/Screen+Shot+2018-08-19+at+8.03.25+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhOtA_5F8Mq5iQwkagVk_FZLSOoz_B0KhrQmaWGtWJsKWqRP0K1QPJYkw4zyac5s6lhv2AbWV-dEypQz0CTk-Mrx-Jxd3evS0r1ylxo_5QGzMG2z5VLQV1_mgHbmLYVckwz6x7L/s1600/Screen+Shot+2018-08-19+at+8.03.25+AM.png&quot; /&gt;
&lt;/a&gt;
&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWBgW2buUk8OJCVrV6jt6YCzwU6gqBN_YhihqJPucbztJJXY1BQq7hmIdnbkjz2pz_pTMt_AX2Wb4le4pGwRyB7_PMrWtEdAhqa3_HeLvq7_9JmNNT4eE8thYGxsML644jWFQ/s1600/Screen+Shot+2018-08-19+at+7.46.54+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBWBgW2buUk8OJCVrV6jt6YCzwU6gqBN_YhihqJPucbztJJXY1BQq7hmIdnbkjz2pz_pTMt_AX2Wb4le4pGwRyB7_PMrWtEdAhqa3_HeLvq7_9JmNNT4eE8thYGxsML644jWFQ/s1600/Screen+Shot+2018-08-19+at+7.46.54+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL9E_RlJDt9-4jNwksgVgkgRgSAirxAcHA9mrL6l21Lu1WNIpmsMafI7V9j26N-vWio7ZLlRFX-b4OEcrDNTUN4_kGl36ufvdQhr4WLTjOaw9Ezsvso2AbZu_8Lqr5IHm1Mc8_/s1600/Screen+Shot+2018-08-19+at+8.16.12+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjL9E_RlJDt9-4jNwksgVgkgRgSAirxAcHA9mrL6l21Lu1WNIpmsMafI7V9j26N-vWio7ZLlRFX-b4OEcrDNTUN4_kGl36ufvdQhr4WLTjOaw9Ezsvso2AbZu_8Lqr5IHm1Mc8_/s1600/Screen+Shot+2018-08-19+at+8.16.12+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQk0llWjmK_UGJD7jF8e0Ox5WrCmrUOWtYTb9XMVIgguET5QrE8SB2JoGwBrK0Ia1EXrgTsIMj2RpQG6mgUmtOndhgp2TQylebozFpZsQk4LstwI5-ZpxTr26chF0E5Sy_YGhm/s1600/Screen+Shot+2018-08-19+at+8.09.13+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgQk0llWjmK_UGJD7jF8e0Ox5WrCmrUOWtYTb9XMVIgguET5QrE8SB2JoGwBrK0Ia1EXrgTsIMj2RpQG6mgUmtOndhgp2TQylebozFpZsQk4LstwI5-ZpxTr26chF0E5Sy_YGhm/s1600/Screen+Shot+2018-08-19+at+8.09.13+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWLqfXNjMYkG-fANYyWQgr9ej1gQeb9r7e_LXQQeqL5onr4SBpvAB7VnO8nCVOH4m_c_mNzGKRWWJYDaCD_zKCowoi1MS4QbwWCBhyCEquHcbtfssZApCZCId3pc87n8P9dIqw/s1600/Screen+Shot+2018-08-19+at+8.00.41+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiWLqfXNjMYkG-fANYyWQgr9ej1gQeb9r7e_LXQQeqL5onr4SBpvAB7VnO8nCVOH4m_c_mNzGKRWWJYDaCD_zKCowoi1MS4QbwWCBhyCEquHcbtfssZApCZCId3pc87n8P9dIqw/s1600/Screen+Shot+2018-08-19+at+8.00.41+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;p&gt;These Nocaster guitars are quite rare as they were produced for only a partial year. By year&#39;s end, these guitars bore their new and final name.

&lt;h5&gt;Telecaster&lt;/h5&gt;

&lt;p&gt;In late 1951, the guitar received the name that it is known by today: the Telecaster. Other than the new name on the headstock, these guitars were identical to those produced earlier in the year.

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguLzEiCzSmycRI-9huwPKeQp1sNRawqXo_xoe0p4FVY_zCfg6s57eKaQA_6dSyOE_OPikV43UCKKglXOWwHmQoFuuPQzgHV6XGyaTo5AD8SBGeDTqDgtw7JTW-lJGlGOetw9_p/s1600/Screen+Shot+2018-08-31+at+10.42.02+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEguLzEiCzSmycRI-9huwPKeQp1sNRawqXo_xoe0p4FVY_zCfg6s57eKaQA_6dSyOE_OPikV43UCKKglXOWwHmQoFuuPQzgHV6XGyaTo5AD8SBGeDTqDgtw7JTW-lJGlGOetw9_p/s1600/Screen+Shot+2018-08-31+at+10.42.02+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNqboagQ93XtvYg3S7d72yX5lalAJGB8OgevtEfggY81rFjUeC1Cgt_Y94HJEJktFB0cHGsdUc7NLAZ3vKDi3hHsiYuG-oO8QRpL1mbv_ytVjD2GgfnbUNFAEit9w5Kh5xK4bW/s1600/Screen+Shot+2018-08-31+at+10.38.58+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhNqboagQ93XtvYg3S7d72yX5lalAJGB8OgevtEfggY81rFjUeC1Cgt_Y94HJEJktFB0cHGsdUc7NLAZ3vKDi3hHsiYuG-oO8QRpL1mbv_ytVjD2GgfnbUNFAEit9w5Kh5xK4bW/s1600/Screen+Shot+2018-08-31+at+10.38.58+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIPfCg_VSzDaEntrvOSUdtFE-nVFDLA4VZIqD6O4NRqkwQwN7Tb5cfZ5iXjE6xVM4gX6FJuJdZJaAzdcTWeytlip7vGCWbWOjy_VzJAbuaiHxHvB2cEVzzYWGwcVWvHP__yZGs/s1600/Screen+Shot+2018-08-31+at+10.38.03+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhIPfCg_VSzDaEntrvOSUdtFE-nVFDLA4VZIqD6O4NRqkwQwN7Tb5cfZ5iXjE6xVM4gX6FJuJdZJaAzdcTWeytlip7vGCWbWOjy_VzJAbuaiHxHvB2cEVzzYWGwcVWvHP__yZGs/s1600/Screen+Shot+2018-08-31+at+10.38.03+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidUp286zH8LA4Km6ov9JEkBzk_hNrcM0VW0ezTEcS8IiwjCqf943xZqEzBX2LP6mGEupEwjCkIxcFMlVjDLuEq02f-kU3Y0RCNCocpAzHG6JBe5p6e2lYUrQOBdv1lqbxj90LT/s1600/Screen+Shot+2018-08-31+at+10.46.29+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidUp286zH8LA4Km6ov9JEkBzk_hNrcM0VW0ezTEcS8IiwjCqf943xZqEzBX2LP6mGEupEwjCkIxcFMlVjDLuEq02f-kU3Y0RCNCocpAzHG6JBe5p6e2lYUrQOBdv1lqbxj90LT/s1600/Screen+Shot+2018-08-31+at+10.46.29+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwOpwKfDy1eJm6z1fsohDDP1RwTL1xMpaNLq1FR-X8GY3p-frhG1-5h6Dqb42mqfRjM-Blc1isnHQl2U19mNT8WVOBmFPmICYh1bmVkzL3u-EiSP17sEbrYNRKFxszo-dfTDur/s1600/Screen+Shot+2018-08-31+at+10.44.13+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiwOpwKfDy1eJm6z1fsohDDP1RwTL1xMpaNLq1FR-X8GY3p-frhG1-5h6Dqb42mqfRjM-Blc1isnHQl2U19mNT8WVOBmFPmICYh1bmVkzL3u-EiSP17sEbrYNRKFxszo-dfTDur/s1600/Screen+Shot+2018-08-31+at+10.44.13+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRPjsF2GGipgFES085pl25_F0-4UyFQV49NOgU_PE_XCI2H4dUWkA8haUF4zEFOD_xAfGUdJ7lUYWmsovja9uttsROzJq2qP3g73VaybMsrqhrerfhj70FkVUjoWThCD2Xr1Sb/s1600/Screen+Shot+2018-08-31+at+10.43.27+PM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRPjsF2GGipgFES085pl25_F0-4UyFQV49NOgU_PE_XCI2H4dUWkA8haUF4zEFOD_xAfGUdJ7lUYWmsovja9uttsROzJq2qP3g73VaybMsrqhrerfhj70FkVUjoWThCD2Xr1Sb/s1600/Screen+Shot+2018-08-31+at+10.43.27+PM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;p&gt;While these guitars now bear their modern name, the wiring of the pickups is significantly different than what they carry today. Modern style pickup wiring was introduced in the late 1952.

&lt;h5&gt;Esquire&lt;/h5&gt;

&lt;p&gt;Fender continued to produce Esquires as well in 1951. In addition to the &quot;Butterscotch Blond&quot; color, the Esquire was also available in a &quot;Blond&quot; color which was a translucent white. The finish on these guitars tend to yellow significantly as they age, so most old guitars have a noticable yellow tint to them. Here are a few pictures:

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-9MFkr-ozF74mPb2WZXrFmD_5zDfmceyjErCUKFcEI9T_65oD3pVmY9froTpx5ToETW69ZnMeAFWjP6snfWEFObT0mdtq4yLxqwm7VoqwuxhtzTww2xu5atgh-gW7IpcvLt-S/s1600/Screen+Shot+2018-08-18+at+8.23.48+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi-9MFkr-ozF74mPb2WZXrFmD_5zDfmceyjErCUKFcEI9T_65oD3pVmY9froTpx5ToETW69ZnMeAFWjP6snfWEFObT0mdtq4yLxqwm7VoqwuxhtzTww2xu5atgh-gW7IpcvLt-S/s1600/Screen+Shot+2018-08-18+at+8.23.48+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9bR6ITp2EtI9vzzfFxIhj2hx3FUrO9nSbRD8nbMhdxa5pxavynr8TGW3MNKeigO_Ft6qbPN77uDzEPn7wlOSX2Xb9AlleUAxf0GNW5Xy4ZKXGL947J_6KDcbuNKR5LR-qLJV8/s1600/Screen+Shot+2018-08-18+at+8.28.57+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi9bR6ITp2EtI9vzzfFxIhj2hx3FUrO9nSbRD8nbMhdxa5pxavynr8TGW3MNKeigO_Ft6qbPN77uDzEPn7wlOSX2Xb9AlleUAxf0GNW5Xy4ZKXGL947J_6KDcbuNKR5LR-qLJV8/s1600/Screen+Shot+2018-08-18+at+8.28.57+AM.png&quot; /&gt;
&lt;/a&gt;
&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC_gojUh6BPwkXD0PgreJyEFRDxYjKu71IrGtyAPcTCMs-_jOLval4plFhQEJTT8bhQfmfwcmQ-KOnGsYdvx56GhNem-HRumxrKQkaNzPbEJpBZhaiFmBnBPyo5Bmg-r7JnfDa/s1600/Screen+Shot+2018-08-18+at+8.18.31+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjC_gojUh6BPwkXD0PgreJyEFRDxYjKu71IrGtyAPcTCMs-_jOLval4plFhQEJTT8bhQfmfwcmQ-KOnGsYdvx56GhNem-HRumxrKQkaNzPbEJpBZhaiFmBnBPyo5Bmg-r7JnfDa/s1600/Screen+Shot+2018-08-18+at+8.18.31+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrJrVdI-D05qY6fW4A3o5fk3X6qwXrPxRd4o6TG9nPJewpdjb1taCoyIkDBkIzqR8GdIVlhlcurQPgX2jA5AmH-xJK6Z3QLMlHRan4JoihQkCG_dhm88BkO0tHpD43ffHQ5NVB/s1600/Screen+Shot+2018-08-18+at+8.34.32+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrJrVdI-D05qY6fW4A3o5fk3X6qwXrPxRd4o6TG9nPJewpdjb1taCoyIkDBkIzqR8GdIVlhlcurQPgX2jA5AmH-xJK6Z3QLMlHRan4JoihQkCG_dhm88BkO0tHpD43ffHQ5NVB/s1600/Screen+Shot+2018-08-18+at+8.34.32+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBmlgf3THjFBEXOuaGeoGuDztmbIQJHQS5jgKqyzC4-X9cygjf2lBBcJXRDV610yNcOcWun7cufa6H7eJ_xGQY4zf-ibY2IgP6Hjy4v0kyYCq6F6i7p5m6-GiE4DTaMBQO_0A3/s1600/Screen+Shot+2018-08-18+at+8.25.24+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhBmlgf3THjFBEXOuaGeoGuDztmbIQJHQS5jgKqyzC4-X9cygjf2lBBcJXRDV610yNcOcWun7cufa6H7eJ_xGQY4zf-ibY2IgP6Hjy4v0kyYCq6F6i7p5m6-GiE4DTaMBQO_0A3/s1600/Screen+Shot+2018-08-18+at+8.25.24+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;a imageanchor=&quot;1&quot; style=&quot;margin: 0&quot;
   href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGRWkENXWBFk9iMKqnKGWS58EYs6RiZ9mGxEtGozqN90l5A6IcNfuEJ3d5wXHlfa8tXIPFR-dnx6-wxeGnHZ1MXoW5ni7OnfQHIczgKW0D0lD2EwbfZ3mjftM3cEI6NyQrFZIC/s1600/Screen+Shot+2018-08-18+at+8.40.59+AM.png&quot;&gt; 
  &lt;img border=&quot;0&quot; data-original-height=&quot;500&quot; data-original-width=&quot;420&quot; width=&quot;195px&quot;
       src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjGRWkENXWBFk9iMKqnKGWS58EYs6RiZ9mGxEtGozqN90l5A6IcNfuEJ3d5wXHlfa8tXIPFR-dnx6-wxeGnHZ1MXoW5ni7OnfQHIczgKW0D0lD2EwbfZ3mjftM3cEI6NyQrFZIC/s1600/Screen+Shot+2018-08-18+at+8.40.59+AM.png&quot; /&gt;
&lt;/a&gt;

&lt;br/&gt;

Few other instruments have been in continuous manufacture as the humble Telecaster and it still plays a major role in modern music. Here&#39;s to the next 70 years.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/7247868493682071055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/7247868493682071055' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/7247868493682071055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/7247868493682071055'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2018/09/early-telecasters-visual-history.html' title='Early Telecasters A Visual History'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj5mQAFcfIpiV64mp_6Q79dcZiYF-QrJYe2siI0L3QjelXFo1xQJsSh8TNHNt9iZaDTFcAz_Q5Z_Q_5anxwK-4nVo8XoT41XV8vY-RIDWLArscPIRYdkEU92ROMnB9rJqPoFTzc/s72-c/Screen+Shot+2018-08-13+at+9.22.59+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-3007456316155400223</id><published>2018-06-22T18:03:00.000-07:00</published><updated>2018-06-22T18:03:02.720-07:00</updated><title type='text'>Developing in GitHub using Cloud Shell</title><content type='html'>&lt;p&gt;If you&#39;re not familiar with &lt;a href=&quot;https://cloud.google.com/shell/&quot;&gt;Google Cloud Shell&lt;/a&gt;, it&#39;s a great tool for doing command line development in a Linux environment. I&#39;ve been using it as an always-on development environment for web focused projects. Whichever machine I happen to be using, my dev environment is always available.

&lt;p&gt;One of the ways I&#39;m using Cloud Shell is as a development environment for my open source projects. Cloud Shell comes with loads of developer tools pre-installed, including git which is quite handy if you are hosting projects on Github. Head over to &lt;a href=&quot;https://console.cloud.google.com/cloudshell/editor&quot;&gt;https://console.cloud.google.com/cloudshell/editor&lt;/a&gt; to start using Cloud Shell.

&lt;p&gt;Here&#39;s how you can set up your own open source development environment with Github in Cloud Shell, in three easy steps!

&lt;h4&gt;Set up your git environment&lt;/h4&gt;

&lt;p&gt;First, you&#39;ll need to have the git client available. Easy, git is already installed (yay!)

&lt;p&gt;Next, &lt;a href=&quot;From: https://help.github.com/articles/set-up-git/&quot;&gt;set up your git environment&lt;/a&gt; with the email address and name that your changes will be published under:
&lt;pre&gt;&lt;code&gt;git config --global user.name &quot;YOUR NAME&quot;
git config --global user.email &quot;YOUR EMAIL ADDRESS&quot;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you are using two factor auth for your GitHub account, you&#39;ll need to &lt;a href=&quot;https://help.github.com/articles/creating-an-access-token-for-command-line-use/&quot;&gt;generate an access token&lt;/a&gt;. Once created, you&#39;ll use the hexidecimal string instead of your GitHub account password. For example, the generate password might look something like
&lt;pre&gt;&lt;code&gt;4e6f742061207265616c206b6579203b2d29&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Clone a repo from GitHub to Cloud Shell&lt;/h4&gt;

&lt;p&gt;With command line credentials in hand, you can now clone the repository from GitHub into your Cloud Shell environment to start making changes. Step three!

&lt;p&gt;For example:
&lt;pre&gt;&lt;code&gt;git clone https://github.com/jscud/jsBytes.git&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Now the files are available in your local Cloud Shell environment and you can change them to your heart&#39;s content. There is a simple text editor available in Cloud Shell which you can launch from the command line with a command like
&lt;pre&gt;&lt;code&gt;cd jsBytes
edit README&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;Commit and publish your changes&lt;/h4&gt;

&lt;p&gt;After editing a file or two, commit your changes to your local repository and then publish them on GitHub. Remember that when prompted for the password, use the access token you generated earlier instead of your GitHub password.
&lt;pre&gt;&lt;code&gt;git status
git commit -a -m &#39;Add one usage example to README.&#39;
git push origin master&lt;/pre&gt;&lt;/code&gt;

&lt;p&gt;There you have it, an easy way to work on your GitHub project using Google Cloud Shell as your development environment.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/3007456316155400223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/3007456316155400223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/3007456316155400223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/3007456316155400223'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2018/06/developing-in-github-using-cloud-shell.html' title='Developing in GitHub using Cloud Shell'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-9080819880103592085</id><published>2017-02-24T20:45:00.002-08:00</published><updated>2017-04-17T09:14:12.108-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="arduino"/><category scheme="http://www.blogger.com/atom/ns#" term="Chrome OS"/><title type='text'>Arduino Programming in ChromeOS</title><content type='html'>Are you ready to turn your Chromebook into a lean mean Arduino programming machine? No? Maybe? Great! &lt;br /&gt;
&lt;br /&gt;
I&#39;ve recently gotten into microcontroller programming, chasing dreams of electric guitar fueled audio bliss. Several microcontrollers have played the role of distortion effects prototype, and I haven&#39;t settled on one yet, but I can say the easiest I&#39;ve found to use so far are the ones produced by Arduino. In fact, you can set up a Chromebook as development environment for programming an Arduino.&lt;br /&gt;
&lt;br /&gt;
Here are the steps you&#39;ll need complete this amazing Chromebook transformation. Note that there are some risks in tweaking the setup of your machine.&lt;br /&gt;
&lt;br /&gt;
First you&#39;ll need to enter developer mode, hold down escape and refresh while pressing the power button. Then on the warning boot screen, press ctrl+d.&lt;br /&gt;
&lt;br /&gt;
Then, install &lt;a href=&quot;https://github.com/dnschneid/crouton&quot;&gt;Crouton&lt;/a&gt;. Here&#39;s a helpful download link:&amp;nbsp;&lt;a href=&quot;https://goo.gl/fd3zc&quot;&gt;https://goo.gl/fd3zc&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Then run Crouton setup by entering the terminal, which is done by hitting ctrl+alt+t then run shell (type shell followed by enter). I ran my setup like this: &lt;code&gt;sudo sh ~/Downloads/crouton -r trusty -t xfce&lt;/code&gt;.&lt;br /&gt;
&lt;br /&gt;
To run once installed, use &lt;code&gt;sudo startxfce4&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
From time to time, as Chrome OS is updated, it may be necessary to update the Crouton installation. I&#39;ve updated by running &lt;code&gt;sudo sh ~/Downloads/crouton -r trusty -t xfce -u&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Now its time to get the development environment for Arduino. There are some helpful instructions here: &lt;a href=&quot;http://playground.arduino.cc/Linux/Ubuntu&quot;&gt;http://playground.arduino.cc/Linux/Ubuntu&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I&#39;ve set up a couple of Chromebooks with the Arduino dev environment and as time has gone on, the approach has changed a bit. In my first setup, I did the following to install it:&lt;br /&gt;
&lt;code&gt;sudo apt-get update &amp;amp;&amp;amp; sudo apt-get install arduino arduino-core&amp;nbsp;&lt;/code&gt;
&lt;br /&gt;
I then tried running arduino as root (&lt;code&gt;sudo ./arduino&lt;/code&gt;
), but had the following error:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;error while loading shared libraries: libtinfo.so.5: cannot open shared object file: No such file or directory&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
Ah, there was a missing dependency, which I was able to install as follows:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;sudo apt-get install libncurses5-dev&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
In a later version of Arduino&#39;s software, I got the following after downloading the Arduino IDE and running &lt;code&gt;sudo ./install&lt;/code&gt;
then &lt;code&gt;sudo ./arduino&lt;/code&gt;:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;Exception in thread &quot;main&quot; java.lang.UnsatisfiedLinkError: /home/.../arduino-1.6.13/java/lib/i386/libsplashscreen.so: libX11.so.6: cannot open shared object file: No such file or directory&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
I resolved a sequence of errors by installing the following&lt;br /&gt;
&lt;code&gt;sudo apt-get install libX11-6:i386&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;sudo apt install libxext6:i386&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;sudo apt-get install libxrender1:i386&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;sudo apt-get install libXtst6:i386&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;sudo apt-get install libXi6:i386&lt;/code&gt;&lt;br /&gt;
&lt;code&gt;sudo apt-get install libstdc++6:i386&lt;/code&gt;&lt;br /&gt;
&lt;br /&gt;
I also edited the audino file, which is an executable script, and removed the reference to GTKLookAndFeel. This allowed me to run the Arduino IDE without having to replace my installation of Java.&lt;br /&gt;
&lt;br /&gt;
From there I&#39;ve been able to compile programs and upload them to the Arduino to my hearts content. Happy coding!
</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/9080819880103592085/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/9080819880103592085' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/9080819880103592085'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/9080819880103592085'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2017/02/arduino-programming-in-chromeos.html' title='Arduino Programming in ChromeOS'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-1465343963707148679</id><published>2015-07-22T23:11:00.003-07:00</published><updated>2015-07-22T23:13:54.135-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="teaching"/><title type='text'>Teaching Kids to Program - Part 1</title><content type='html'>This summer, I&#39;ve been teaching my two oldest kids to program. They&#39;re ages sever and four and a half so I&#39;m tailoring our lessons to what I imagine they can grasp in what can be a very abstract field of study. I&#39;ve been super impressed with what they&#39;ve learned so far!&lt;br /&gt;
&lt;br /&gt;
The first challenge was thinking how to make programming interesting and compelling. Something too abstract feels like it would be challenging, there needs to be immediate feedback. Type this in, see what changes on the screen. How about we set out to make a game? That was one of the first pursuits that got me into programming in my teenage years.&lt;br /&gt;
&lt;br /&gt;
The second consideration was balancing simplicity and ease of use. When programming, I always felt more confident when I could understand at a pretty low level what was going on. For this reason I wanted to make sure they gained an understanding of the fundamentals. We&#39;d start with a view of a computer as a very simple machine. Even if this means there is some extra coding needed to get the desired effect on the screen. It&#39;s better (IMHO) to add abstractions later once they have an underlying understanding than to try to understand a powerful but complicated library that initially gets quick results.&lt;br /&gt;
&lt;br /&gt;
I&#39;m planning to post what we covered each week. We spend 30-60 minutes in a once a week session though some weeks we&#39;re taking off. It is summer after all!&lt;br /&gt;
&lt;br /&gt;
Here&#39;s what we covered in our first lesson.&lt;br /&gt;
&lt;br /&gt;
1. You can tell a computer what to do!&lt;br /&gt;
&lt;br /&gt;
We opened up the terminal and I told them to type&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;print &quot;Hello [name]&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Here it is, immediate feedback with the simplest possible &quot;program.&quot; To get this working, I added a bash alias print=echo. Seems like print is a more common name across programming languages for &quot;write something to stdout.&quot;&lt;br /&gt;
&lt;br /&gt;
This went over pretty well, both kids typed some things.&lt;br /&gt;
&lt;br /&gt;
Time to introduce some programming concepts. I explained that this was calling a &lt;i&gt;function&lt;/i&gt; named print. The print function writes out whatever you tell it to write. I hope purist will forgive my painting with a broad brush.&lt;br /&gt;
&lt;br /&gt;
Next I explained that the words that you give to the function to put on the screen are an &lt;i&gt;argument&lt;/i&gt;, er, well, a &lt;i&gt;parameter&lt;/i&gt;. The looks on their faces when I called these arguments made it pretty clear that they were thinking of what transpires out in the sandbox.&lt;br /&gt;
&lt;br /&gt;
So here we&#39;d covered the main ideas I wanted to teach them in the first lesson. You can tell a computer what to do! The &quot;what to do&quot; is specified using a &lt;i&gt;function&lt;/i&gt; and the &lt;i&gt;parameters&lt;/i&gt; that you pass to the function to tell it what or how you want things done.&lt;br /&gt;
&lt;br /&gt;
Time for more fun.&lt;br /&gt;
&lt;br /&gt;
Our four and a half year old can read basic words, but I imagined typing and reading might get tedious pretty fast. So next we turned to something just as simple that doesn&#39;t require reading from the screen, and not surprisingly was quite a bit of fun: the Mac say program.&lt;br /&gt;
&lt;br /&gt;
If you&#39;ve never played with this, in the Mac terminal there is command &quot;say&quot; which works like echo except it speaks whatever you give it in a computerized voice. We started with&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;say &quot;Hello [name]&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Great fun! From there I asked them what parameters we should give the say function next. This filled the rest of our time. By far the biggest hit was &lt;span style=&quot;font-family: Courier New, Courier, monospace;&quot;&gt;say &quot;[Baby&#39;s name] are you pooping?&quot;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Yup, teaching kids to program.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/1465343963707148679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/1465343963707148679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1465343963707148679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1465343963707148679'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2015/07/teaching-kids-to-program-part-1.html' title='Teaching Kids to Program - Part 1'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-1836278636069976041</id><published>2013-05-15T00:05:00.000-07:00</published><updated>2013-05-15T00:14:34.503-07:00</updated><title type='text'>Easy Raspberry Pi Setup (Using Windows)</title><content type='html'>So there I was, new &lt;a href=&quot;http://www.raspberrypi.org/&quot;&gt;Raspberry Pi&lt;/a&gt; in hand. Now to set it up. One small setback, I don&#39;t exactly have a monitor, keyboard, and mouse handy. How did I end up with so many laptops?&lt;br /&gt;
&lt;br /&gt;
Turns out setting it up and getting to a command line was a breeze, no monitor (etc.) required. All it took was an Ethernet cable and my router.&lt;br /&gt;
&lt;br /&gt;
Here&#39;s what I did.&lt;br /&gt;
&lt;br /&gt;
First, I wrote the operating system disk image to an SD card using the instructions on the &lt;a href=&quot;http://www.raspberrypi.org/quick-start-guide&quot;&gt;Raspberry Pi Quick Start Guide&lt;/a&gt;.&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Downloaded the latest image from &lt;a href=&quot;http://www.raspberrypi.org/downloads&quot;&gt;raspberrypi.org/downloads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Extracted it and found the .img file&lt;/li&gt;
&lt;li&gt;Installed &lt;a href=&quot;http://sourceforge.net/projects/win32diskimager/&quot;&gt;Win 32 Disk Imager&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Plugged in the SD card&lt;/li&gt;
&lt;li&gt;Used the disk imager to write the .img file to the drive for the SD card&lt;/li&gt;
&lt;/ul&gt;
Second, I started up the Raspberry Pi to connect to it.&lt;br /&gt;
&lt;br /&gt;
I plugged the Raspberry Pi into the router using that Ethernet cable, then powered it up!&lt;br /&gt;
&lt;br /&gt;
The next step will depend on your router but some routers will show you a list of the devices that are connected to the network from the admin screen. Here&#39;s an example&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW5rLEmEw2DsdH_OLM2VsiKlgT6DMfjoTPVwwJclxWZWGXF3y-ZSiEbCZnWvBkop6K7SLspVkMWvQrLQSavfTDFVkYz70wLkEfW41i2FKyX0TAH4ARrItHz6db2taTIxYA_EB1/s1600/raspberrypi-router-address.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;274&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW5rLEmEw2DsdH_OLM2VsiKlgT6DMfjoTPVwwJclxWZWGXF3y-ZSiEbCZnWvBkop6K7SLspVkMWvQrLQSavfTDFVkYz70wLkEfW41i2FKyX0TAH4ARrItHz6db2taTIxYA_EB1/s320/raspberrypi-router-address.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Armed with the IP address, you can ssh into the Raspberry Pi machine. (I used &lt;a href=&quot;http://www.putty.org/&quot;&gt;PuTTY&lt;/a&gt;.)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDiSahHnV0TlEsS-393x46zQslRYFHXn_wrTB2cE5PaNZ7iG13RWqKW5hie4Txtoh4OL0gjFhoL5l6TUDso26l9nrpITj84IQrhTwI3yRJaKQ3jZynSYFugmv-m85qTrnbc9xD/s1600/raspberrypi-putty.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;239&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgDiSahHnV0TlEsS-393x46zQslRYFHXn_wrTB2cE5PaNZ7iG13RWqKW5hie4Txtoh4OL0gjFhoL5l6TUDso26l9nrpITj84IQrhTwI3yRJaKQ3jZynSYFugmv-m85qTrnbc9xD/s320/raspberrypi-putty.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
There you have it. From the command line you can configure whatever else is needed and you&#39;ll never have to scrounge up one of those pesky keyboards.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/1836278636069976041/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/1836278636069976041' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1836278636069976041'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1836278636069976041'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2013/05/easy-raspberry-setup-using-windows.html' title='Easy Raspberry Pi Setup (Using Windows)'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiW5rLEmEw2DsdH_OLM2VsiKlgT6DMfjoTPVwwJclxWZWGXF3y-ZSiEbCZnWvBkop6K7SLspVkMWvQrLQSavfTDFVkYz70wLkEfW41i2FKyX0TAH4ARrItHz6db2taTIxYA_EB1/s72-c/raspberrypi-router-address.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-6559633211294588885</id><published>2012-07-19T07:12:00.000-07:00</published><updated>2012-07-19T07:12:50.597-07:00</updated><title type='text'>waitFor JavaScript</title><content type='html'>In the spirit of building the simplest thing that could possibly work, I revisit the concept in &lt;a href=&quot;http://blog.jeffscudder.com/2010/06/javascript-tricks-to-speed-up-your-site.html&quot;&gt;another of my posts&lt;/a&gt;: simple asynchronous JavaScript.&lt;br /&gt;
&lt;br /&gt;
Time and time again I see web developers relying on the order that JavaScript loads in a page to ensure that the site will work. This keeps the mental model simple, &quot;all the stuff above this code will be available here&quot;, but it means that people trying to speed up browsers and JavaScript interpreters have their hands tied. Why not instead load and execute as much JavaScript in parallel as possible, like a mutlithreaded application, and wait for your dependencies to load or preconditions to be met before your code runs.&lt;br /&gt;
&lt;br /&gt;
You could do it all in just a few lines:&lt;br /&gt;
&lt;br/&gt;
&lt;div style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;
function waitFor(condition, callback) {&lt;br /&gt;
&amp;nbsp; function waiter(condition, callback) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; return function() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; var condMet = false;&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; try {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; condMet = condition();
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } catch (e) {}&lt;br /&gt;
&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (condMet) {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; callback();&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; } else {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; setTimeout(waiter(condition, callback), 5);&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; };&lt;br /&gt;&amp;nbsp; }&lt;br /&gt;
&lt;br /&gt;&amp;nbsp; waiter(condition, callback)();&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
Using it looks a bit like this&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;
waitFor(&lt;br /&gt;
&amp;nbsp; // condition&lt;br /&gt;
&amp;nbsp; function() {return window.dependency;},&lt;br /&gt;
&amp;nbsp; // callback &lt;br /&gt;
&amp;nbsp; function() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; // do things using dependency.&lt;br /&gt;
&amp;nbsp; }&lt;br /&gt;
);&lt;/div&gt;&lt;br /&gt;
For example, here&#39;s how you might set this up to check if jQuery has been loaded and that a particular element on the page has been loaded in the DOM.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;
waitFor(function() {return $(&#39;#msgid&#39;);}, function() {&lt;br /&gt;
&amp;nbsp; $(document).ready(function(){&lt;br /&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; $(&#39;#msgid&#39;).html(&#39;jQuery says &quot;hi&quot;!&#39;);&lt;br /&gt;
&amp;nbsp; });&lt;br /&gt;
});&lt;/div&gt;
&lt;br /&gt;
Now it doesn&#39;t matter what order your script tags are in. Of course, you&#39;ll get the best performance if jQuery gets loaded before this waitFor call is made. The wait and retry loop adds some cost. If browsers had an event model available for script loading or conditions then we wouldn&#39;t have to poll using setTimeout/Interval. But for existing browsers all the way back to IE 6, this simple helper function will work.&lt;br /&gt;
&lt;br /&gt;
For managing JavaScript dependencies there&#39;s also &lt;a href=&quot;http://requirejs.org/&quot;&gt;require.js&lt;/a&gt; which does quite a bit more (and is larger). I wrote this to be lighter weight and it is more general and flexible than a framework like require.js. Using waitFor, you could set up logic that is triggered if and when certain arbitrary conditions become true.&lt;br /&gt;
&lt;br /&gt;
One little improvement, if you are waiting for lots of things then you would probably want to replace multiple timers with a single timer that will check all conditions. Like this:&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;
function waitFor(condition, callback) {&lt;br /&gt; &amp;nbsp;&amp;nbsp;waitFor.waitingFor.push([condition, callback]);&lt;br /&gt; &amp;nbsp;&amp;nbsp;waitFor.check();&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; waitFor.waitingFor = [];&lt;br /&gt; &lt;br /&gt; waitFor.check = function() {&lt;br /&gt; &amp;nbsp;&amp;nbsp;var stillWaitingFor = [];&lt;br /&gt; &amp;nbsp;&amp;nbsp;for (var i = 0; i &amp;lt; waitFor.waitingFor.length; i++) {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var condMet = false;&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;try {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;condMet = waitFor.waitingFor[i][0]();&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} catch (e) {}&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;if (condMet) {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;waitFor.waitingFor[i][1]();&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} else {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;stillWaitingFor.push(waitFor.waitingFor[i]);&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt; &amp;nbsp;&amp;nbsp;}&lt;br /&gt; &lt;br /&gt; &amp;nbsp;&amp;nbsp;waitFor.waitingFor = stillWaitingFor;&lt;br /&gt; &amp;nbsp;&amp;nbsp;if (stillWaitingFor.length &amp;gt; 0) {&lt;br /&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;setTimeout(waitFor.check, 5);&lt;br /&gt; &amp;nbsp;&amp;nbsp;}&lt;br /&gt; };&lt;/div&gt;&lt;br /&gt;
Here&#39;s a minified version. I added some newlines for formatting which you can take out.&lt;br /&gt;
&lt;br /&gt;
&lt;div style=&quot;background-color: white; font-family: &#39;Courier New&#39;, Courier, monospace;&quot;&gt;
function w(c,b){w.w.push([c,b]);w.c()}&lt;br /&gt; w.w=[];w.c=function(){for(var s=[],b=0;b&amp;lt;w.w.length;b++)&lt;br /&gt; {var d=!1;try{d=w.w[b][0]()}catch(e){}&lt;br /&gt; if(d)w.w[b][1]();else s.push(w.w[b])}w.w=s;0&amp;lt;s.length&lt;br /&gt; &amp;amp;&amp;amp;setTimeout(w.c,5)};var waitFor=w;&lt;/div&gt;&lt;br /&gt;
Happy coding!</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/6559633211294588885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/6559633211294588885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6559633211294588885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6559633211294588885'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2012/07/waitfor-javascript.html' title='waitFor JavaScript'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-2490614223836972104</id><published>2012-05-11T18:22:00.000-07:00</published><updated>2012-05-11T18:36:04.194-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="browser"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><title type='text'>JavaScript Caching: appendChild vs document.write</title><content type='html'>I found myself trying to prefetch some data which would appear in an iframe. I wanted to see if requesting the same JSON in the parent page and then in the iframe would cause the second request, made in the iframe, to hit the browser&#39;s cache in all cases. It turns out that for Internet Explorer and Web Kit based browsers it depends on how you request the JSON in the parent page.&lt;br /&gt;
&lt;br /&gt;
If you use &lt;code&gt;appendChild&lt;/code&gt; in IE the identical JS request will hit the browser cache.&lt;br /&gt;
If you use &lt;code&gt;document.write&lt;/code&gt; in IE it will not hit the cache.&lt;br /&gt;
&lt;br /&gt;
However, in Chrome and Safari if you &lt;code&gt;appendChild&lt;/code&gt; in the parent, you will miss the cache. Using &lt;code&gt;document.write&lt;/code&gt; in the parent page causes a cache hit.&lt;br /&gt;
&lt;br /&gt;
Here are the results I gathered. &lt;br /&gt;
&lt;table&gt;
  &lt;tbody&gt;
&lt;tr&gt;
    &lt;td&gt;&lt;b&gt;Cache Hit?&lt;/b&gt;&lt;/td&gt;
    &lt;td&gt;both &lt;code&gt;document.write&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;parent &lt;code&gt;document.write&lt;/code&gt;&lt;br /&gt;
iframe &lt;code&gt;appendChild&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;parent &lt;code&gt;appendChild&lt;/code&gt;&lt;br /&gt;
iframe &lt;code&gt;document.write&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;both &lt;code&gt;appendChild&lt;/code&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Internet Explorer&lt;/td&gt;
    &lt;td&gt;miss&lt;/td&gt;
    &lt;td&gt;miss&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Firefox&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Chrome&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;miss&lt;/td&gt;
    &lt;td&gt;miss&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Safari&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;miss&lt;/td&gt;
    &lt;td&gt;miss&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Opera&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
    &lt;td&gt;hit&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;Android&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
  &lt;/tr&gt;
&lt;tr&gt;
    &lt;td&gt;iOS&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
    &lt;td&gt;?&lt;/td&gt;
  &lt;/tr&gt;
&lt;/tbody&gt;&lt;/table&gt;
&lt;br /&gt;
All versions of IE behaved the same, I didn&#39;t check different versions of the other browsers.&lt;br /&gt;
&lt;br /&gt;
To test this I wrote a test web application called &lt;a href=&quot;http://code.google.com/p/json-caching-exploration/&quot;&gt;json-caching-exploration&lt;/a&gt;. It&#39;s a simple web app that runs on App Engine.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://code.google.com/p/json-caching-exploration/source/browse/main.py&quot;&gt;Server and HTML&lt;/a&gt;&lt;br /&gt;
&lt;a href=&quot;http://code.google.com/p/json-caching-exploration/source/browse/lib.js&quot;&gt;JavaScript&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I haven&#39;t run this against mobile browsers yet. If you give it a try please let me know what you find.&lt;br /&gt;
&lt;br /&gt;
It&#39;s a shame that these browsers behave differently, especially given the differences in browser behavior between loading JavaScript using &lt;code&gt;document.write&lt;/code&gt; and &lt;code&gt;appendChild&lt;/code&gt;.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/2490614223836972104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/2490614223836972104' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/2490614223836972104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/2490614223836972104'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2012/05/javascript-caching-appendchild-vs.html' title='JavaScript Caching: appendChild vs document.write'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-1027142468258233525</id><published>2011-05-28T01:35:00.001-07:00</published><updated>2011-06-09T00:29:55.031-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="app engine"/><category scheme="http://www.blogger.com/atom/ns#" term="go"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>Go on App Engine Example - Part 1</title><content type='html'>The &lt;a href=&quot;http://code.google.com/appengine/&quot;&gt;App Engine&lt;/a&gt; team recently &lt;a href=&quot;http://blog.golang.org/2011/05/go-and-google-app-engine.html&quot;&gt;announced&lt;/a&gt; support for &lt;a href=&quot;http://golang.org/&quot;&gt;Go&lt;/a&gt; as a runtime for use in apps. Summary up front, the &lt;a href=&quot;http://code.google.com/p/googleappengine/downloads/list&quot;&gt;App Engine SDK&lt;/a&gt; for the Go runtime is the easiest way I&#39;ve found yet to get started with Go. As I change my code, it is recompiled in the background when I make a request to my app, so it feels very much like developing in a scripting language.&lt;br /&gt;&lt;br /&gt;I&#39;ve been excited about the Go language for some time now (specifics on why will have to wait for another post) so I was eager to try it out in one of my favorite platforms: App Engine. I wanted to start with something small, so I wrote a simplified version of a web app that I&#39;ve been itching to write lately, a site for hosting plain text content. Specifically, I want something that preserves whitespace, allows me to line up columns of text, and supports non-English characters (Unicode). Those are the kinds of things I need to share and talk about code. Also there is a great deal more you can do with plain old monospaced text, maybe you&#39;ll find this useful as well.&lt;br /&gt;&lt;br /&gt;With that objective in mind I give you &lt;a href=&quot;http://plaintextmachine.appspot.com/&quot;&gt;the Plain Text Machine&lt;/a&gt;. This little app lets you enter a small amount of text, somewhere around 2,000 characters, and gives you a link that others can visit to see an HTML reproduction of your writing. I mentioned I wanted to keep this simple, so here&#39;s the odd little bit, this app doesn&#39;t store your text anywhere. The URL that is generated contains the text, hence the somewhat low limit on message length. It certainly keeps the app simple, the most complex logic is that which converts the text from the URL into HTML.&lt;br /&gt;&lt;br /&gt;A request starts by hitting the &lt;code&gt;Init&lt;/code&gt; function:&lt;pre&gt;func init() {&lt;br /&gt; http.HandleFunc(&quot;/&quot;, handle)&lt;br /&gt; http.HandleFunc(&quot;/show&quot;, show)&lt;br /&gt;}&lt;/pre&gt;The main page, at &lt;code&gt;/&lt;/code&gt;, is just static content, we&#39;re just interested in the &lt;code&gt;/show&lt;/code&gt; handler. It looks like this:&lt;pre&gt;func show(w http.ResponseWriter, r *http.Request) {&lt;br /&gt; w.Header().Set(&quot;Content-Type&quot;, &quot;text/html; charset=utf-8&quot;)&lt;br /&gt; // Get the message from the URL.&lt;br /&gt; PrintHtml(utf8.NewString(r.FormValue(&quot;msg&quot;)), w)&lt;br /&gt;}&lt;/pre&gt;The above does two things, sets the content type of our response so that the browser will know it is HTML, and reads the message URL parameter from the request to convert it to HTML.&lt;br /&gt;&lt;br /&gt;The PrintHtml method prints out some boilerplate HTML then reads the message one character at a time and converts each character to its HTML-safe equivalent. There&#39;s a tiny bit of complexity to make sure that the whitespace is preserved instead of being collapsed as would normally be done with repeated spaces in HTML. Here&#39;s the code:&lt;pre&gt;func PrintHtml(text *utf8.String, out http.ResponseWriter) {&lt;br /&gt; spaces := false&lt;br /&gt; &lt;br /&gt; fmt.Fprint(out, textHeader, middle)&lt;br /&gt; for i := 0; i &amp;lt; text.RuneCount(); i++ {&lt;br /&gt;  currentChar := text.At(i)&lt;br /&gt; &lt;br /&gt;  if currentChar == 32 &amp;amp;&amp;amp; !spaces {&lt;br /&gt;   // A first space.&lt;br /&gt;   fmt.Fprint(out, &quot; &quot;)&lt;br /&gt;   spaces = true&lt;br /&gt;  } else {&lt;br /&gt;   if currentChar == 32 {&lt;br /&gt;    // Space following another space&lt;br /&gt;    fmt.Fprint(out, &quot;&amp;amp;nbsp;&quot;)&lt;br /&gt;   } else if currentChar == 10 {&lt;br /&gt;    // Newline&lt;br /&gt;    fmt.Fprint(out, &quot;&amp;lt;br&amp;gt;&quot;)&lt;br /&gt;   } else if currentChar == 9 {&lt;br /&gt;    // Tab&lt;br /&gt;    fmt.Fprint(out, &quot;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp; &quot;)&lt;br /&gt;   } else if currentChar == 38 {&lt;br /&gt;    // &amp;amp;&lt;br /&gt;    fmt.Fprint(out, &quot;&amp;amp;amp;&quot;)&lt;br /&gt;   } else if currentChar == 60 {&lt;br /&gt;    // &amp;lt;&lt;br /&gt;    fmt.Fprint(out, &quot;&amp;amp;lt;&quot;)&lt;br /&gt;   } else if currentChar == 62 {&lt;br /&gt;    // &amp;gt;&lt;br /&gt;    fmt.Fprint(out, &quot;&amp;amp;gt;&quot;)&lt;br /&gt;   } else if currentChar &amp;lt; 31 || currentChar == 128 {&lt;br /&gt;    // Skip control characters.&lt;br /&gt;   } else if currentChar &amp;lt; 127 {&lt;br /&gt;    fmt.Fprintf(out, &quot;%c&quot;, currentChar)&lt;br /&gt;   } else {&lt;br /&gt;    fmt.Fprintf(out, &quot;&amp;amp;#%d;&quot;, text.At(i))&lt;br /&gt;   }&lt;br /&gt;   spaces = false&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt; fmt.Fprint(out, footer)&lt;br /&gt;}&lt;/pre&gt;The &lt;code&gt;textHeader&lt;/code&gt;, &lt;code&gt;middle&lt;/code&gt;, and &lt;code&gt;footer&lt;/code&gt; variables are string constants containing the wrapper HTML which gives style information.&lt;br /&gt;&lt;br /&gt;If you&#39;re interested in the full source code for this tiny little app, you can find it in the &lt;a href=&quot;http://code.google.com/p/plain-text-machine/&quot;&gt;Plain Text Machine open source project&lt;/a&gt;. Hopefully this example provides an easy to understand picture of what Go code for App Engine looks like.&lt;br /&gt;&lt;br /&gt;I had quite a bit of fun putting together this app. By keeping it simple I was able to go from idea to done in less time than it took me to write this blog post. As an added bonus, having an app with no persistent storage brings up some interesting philosophical questions. For example, if a message is created but no one stores the link to it, does it still exist?</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/1027142468258233525/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/1027142468258233525' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1027142468258233525'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1027142468258233525'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2011/05/go-on-app-engine-example-part-1.html' title='Go on App Engine Example - Part 1'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-5716864271332478317</id><published>2011-05-09T13:21:00.000-07:00</published><updated>2011-06-04T01:37:09.279-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="google"/><category scheme="http://www.blogger.com/atom/ns#" term="oauth"/><category scheme="http://www.blogger.com/atom/ns#" term="oauth2"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>Setup OAuth2 for Google APIs</title><content type='html'>Today I&#39;m at &lt;a href=&quot;http://www.io-bootcamp.com/&quot;&gt;I/O Bootcamp&lt;/a&gt; and helping out with a walkthrough on how to get starting using Google APIs in a variety of languages.&lt;br /&gt;&lt;br /&gt;One of the things I appreciate about the Google APIs is the authorization mechanism which lets me see which applications I&#39;ve granted access for my data and allows me to revoke access. As an application developer, there are some things that I need to do to identify my application so that Google knows which app is requesting access so that it can show the user more information about my app. The first step, then, in writing an application that uses OAuth2 is registering your app.&lt;br /&gt;&lt;br /&gt;You can begin the registration process on the &lt;a href=&quot;https://code.google.com/apis/console/&quot;&gt;Google API console&lt;/a&gt; by creating a project:&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrSqjlNRwQQU6MIChzNWvBOXvgiOhLf3VkqZhhjvdfbkE8SsxIpSc2cdixMwPd9pQHINBGKE9z_LWF-7SLg9saoYiWrJTMsrDgo8HdPgXIouj71Jr2qwpsyxpayTRMtvCaziM6/s1600/Screen+shot+2011-05-09+at+1.47.39+PM.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 255px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrSqjlNRwQQU6MIChzNWvBOXvgiOhLf3VkqZhhjvdfbkE8SsxIpSc2cdixMwPd9pQHINBGKE9z_LWF-7SLg9saoYiWrJTMsrDgo8HdPgXIouj71Jr2qwpsyxpayTRMtvCaziM6/s400/Screen+shot+2011-05-09+at+1.47.39+PM.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5604821118038430178&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFzpEeOOBTcv7mKfqsS527Re1hHLNsdWbANP6Lbbr8HyucMHJCQeA7a0tddn_UW_Zs5h4wsOS51BSQDahMBh5yMEk4SAtRK1zHPwicSeJEU1jLRZJZXwPzAZkie2LRkUA3hgPL/s1600/Screen+shot+2011-05-09+at+1.49.51+PM.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 172px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjFzpEeOOBTcv7mKfqsS527Re1hHLNsdWbANP6Lbbr8HyucMHJCQeA7a0tddn_UW_Zs5h4wsOS51BSQDahMBh5yMEk4SAtRK1zHPwicSeJEU1jLRZJZXwPzAZkie2LRkUA3hgPL/s400/Screen+shot+2011-05-09+at+1.49.51+PM.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5604821559070396498&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now that you have an application, you&#39;ll need to configure it for use with OAuth2 and get the secret tokens that your application will use in its requests. For that create an OAuth2 client ID.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_hJL5v42zpP6TCSBLn0rdFKM5tWIFHMb1Xye1SgKg45LKDHJayTYzeD_N-XyE47w8FEfSfjoDfoAv4JbNL0zfMFBGa5EFjAPnunYRTrmvgChVFfX_fS9lftA2c6kIreJXqE76/s1600/Screen+shot+2011-05-05+at+10.54.24+AM.png&quot; onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 176px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh_hJL5v42zpP6TCSBLn0rdFKM5tWIFHMb1Xye1SgKg45LKDHJayTYzeD_N-XyE47w8FEfSfjoDfoAv4JbNL0zfMFBGa5EFjAPnunYRTrmvgChVFfX_fS9lftA2c6kIreJXqE76/s400/Screen+shot+2011-05-05+at+10.54.24+AM.png&quot; border=&quot;0&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5604831660584228898&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The most vital decision to make during the sign up flow is if your application is a &quot;web application&quot; or an &quot;installed application&quot;. If you&#39;re a site accessed in a browser and you&#39;re able to send the users to a Google web page for authorization and then have the broswer redirect back to your app, then you want web application. For an installed application, the user will still need to authorize your app by visiting a web page, but once authorization is complete, the secret token will be sent to the app either using a redirect to a local running web server or by having the user copy and paste the secret into your application.&lt;br /&gt;&lt;br /&gt;For the command line samples I&#39;ve been playing with I choose installed application.&lt;br /&gt;&lt;br /&gt;After creating the client ID you should see information something like this&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;Client ID:      #######.apps.googleusercontent.com&lt;br /&gt;Client secret:  Amzz5Yip2SJPqqq5Jx&lt;br /&gt;Redirect URIs:  urn:ietf:wg:oauth:2.0:oob&lt;br /&gt;                http://localhost&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;You&#39;ll need to put this information into your application so that it can use the client ID and secret when making requests to get an authorization token from the user. This can be as simple as copying and pasting these strings into your code.&lt;br /&gt;&lt;br /&gt;The one other thing that needs to be done before you begin using OAuth2 with one of the Google APIs is to turn on the API for your application. This can be done on the developer console &quot;Services&quot; section.&lt;br /&gt;&lt;br /&gt;Let&#39;s say that I wanted to access the URL Shortener API. First I would need to enable it for my application.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEZtlr5J3vKGFU-ztEQTdC1MiETQRVq36PXOX_JgDxweRITzncswg_IAuhKzqlhcUx8rHIGBijlK24rlDAvJtSSW8lTkRV5ngpMmVuPsG3EhNnSTFa1wyHE2y3KYFLlcgAwKs3/s1600/Screen+shot+2011-05-05+at+10.53.12+AM.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 74px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhEZtlr5J3vKGFU-ztEQTdC1MiETQRVq36PXOX_JgDxweRITzncswg_IAuhKzqlhcUx8rHIGBijlK24rlDAvJtSSW8lTkRV5ngpMmVuPsG3EhNnSTFa1wyHE2y3KYFLlcgAwKs3/s400/Screen+shot+2011-05-05+at+10.53.12+AM.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5604848791539819794&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Then I would need to specify the URL Shortener&#39;s API scope when I request authorization from a specific user. The scopes that are requested by my app are turned into a list of APIs that the user must grant access to when they authorize my application.&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz7aglao2dBIu-PTsIas5cGxayw_bG_TXBhN2CPXRUqdhdfhM3m076PvOexHKupBj4OQqfd8FhjGyBQsFGBbHT7bnadJSut8s2FSchyODz0_NknnCVEJkNXq5x1aIDqBam5aTp/s1600/Screen+shot+2011-05-09+at+3.42.32+PM.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 248px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiz7aglao2dBIu-PTsIas5cGxayw_bG_TXBhN2CPXRUqdhdfhM3m076PvOexHKupBj4OQqfd8FhjGyBQsFGBbHT7bnadJSut8s2FSchyODz0_NknnCVEJkNXq5x1aIDqBam5aTp/s400/Screen+shot+2011-05-09+at+3.42.32+PM.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5604850668435594786&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The scope for an API can be found in the API documentation under authorization.&lt;br /&gt;&lt;br /&gt;For an example that brings all of these settings together, see the &lt;a href=&quot;http://code.google.com/p/google-api-python-client/source/browse/samples/urlshortener/urlshortener.py&quot;&gt;urlshortener.py&lt;/a&gt; example:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  FLOW = OAuth2WebServerFlow(&lt;br /&gt;      client_id=&#39;433807057907.apps.googleusercontent.com&#39;,&lt;br /&gt;      client_secret=&#39;jigtZpMApkRxncxikFpR+SFg&#39;,&lt;br /&gt;      scope=&#39;https://www.googleapis.com/auth/urlshortener&#39;,&lt;br /&gt;      user_agent=&#39;urlshortener-cmdline-sample/1.0&#39;)&lt;br /&gt;  ...&lt;br /&gt;  credentials = run(FLOW, storage)&lt;br /&gt;  ...&lt;br /&gt;  http = httplib2.Http()&lt;br /&gt;  http = credentials.authorize(http)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Python may not be your bag, but no worries, there are client libraries for the Google APIs in a variety of languages, and even better, there is an &lt;a href=&quot;http://code.google.com/apis/explorer/&quot;&gt;API Explorer&lt;/a&gt; that lets you try out the underlying protocol without any language specific stuff getting in the way.&lt;br /&gt;&lt;br /&gt;For example, here is getting details and stats about a short URL:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8EipsO41OAK2k34h3IVUoZKkn97BmflI4bw3W2XoN822g-Jkpr_pa1UyU0kI_njX6VGFiVRhLl1iwnO-RlYHYfYorttlIWPnczTAVx2pv0_kCg270YzssP1UaUU6p7zbuLRHu/s1600/Screen+shot+2011-05-05+at+10.40.40+AM.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 200px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj8EipsO41OAK2k34h3IVUoZKkn97BmflI4bw3W2XoN822g-Jkpr_pa1UyU0kI_njX6VGFiVRhLl1iwnO-RlYHYfYorttlIWPnczTAVx2pv0_kCg270YzssP1UaUU6p7zbuLRHu/s400/Screen+shot+2011-05-05+at+10.40.40+AM.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5604862822848144690&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;And here is creating a new short link:&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio8Uw50BP426paJOETnSAnVlzN22sMJX4cGbQiAcchMiXXNI_JT-aYIOo5pHzjCWYBincazU2UrLxWhe4Hm98q_2xMqURsrGV_bdkBcEm4yFJ9cUooO5CfpRUaXLLmo0zPvHv9/s1600/Screen+shot+2011-05-09+at+4.38.21+PM.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 112px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEio8Uw50BP426paJOETnSAnVlzN22sMJX4cGbQiAcchMiXXNI_JT-aYIOo5pHzjCWYBincazU2UrLxWhe4Hm98q_2xMqURsrGV_bdkBcEm4yFJ9cUooO5CfpRUaXLLmo0zPvHv9/s400/Screen+shot+2011-05-09+at+4.38.21+PM.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5604865058666847826&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfhzRn9YPIFCFsl_Yt3bEXhv26Si2JFWNOVYlz-Q0uZ_lb6e82_hPCuShDfd55PFAwN7Qy5xf9uwnXf4tNWzyur0QW10NANtBSwoaLIt-wWGgDDMEqSV0EwNtqJEJvBSPNFOeu/s1600/Screen+shot+2011-05-05+at+10.45.17+AM.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 239px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhfhzRn9YPIFCFsl_Yt3bEXhv26Si2JFWNOVYlz-Q0uZ_lb6e82_hPCuShDfd55PFAwN7Qy5xf9uwnXf4tNWzyur0QW10NANtBSwoaLIt-wWGgDDMEqSV0EwNtqJEJvBSPNFOeu/s400/Screen+shot+2011-05-05+at+10.45.17+AM.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5604862828690709026&quot; /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;For all the details on using these APIs, take a look at the documentation. For example here are the &lt;a href=&quot;http://code.google.com/apis/urlshortener/v1/getting_started.html&quot;&gt;URL shortener docs&lt;/a&gt;. The common first step for almost all of the Google APIs that access user information is the registration step we started with. For more details on &lt;a href=&quot;http://code.google.com/apis/accounts/docs/OAuth2.html&quot;&gt;OAuth2 with Google APIs&lt;/a&gt;, there is some excellent documentation &lt;a href=&quot;http://code.google.com/apis/accounts/docs/OAuth2.html&quot;&gt;here&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/5716864271332478317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/5716864271332478317' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/5716864271332478317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/5716864271332478317'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2011/05/setup-oauth2-for-google-apis.html' title='Setup OAuth2 for Google APIs'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgrSqjlNRwQQU6MIChzNWvBOXvgiOhLf3VkqZhhjvdfbkE8SsxIpSc2cdixMwPd9pQHINBGKE9z_LWF-7SLg9saoYiWrJTMsrDgo8HdPgXIouj71Jr2qwpsyxpayTRMtvCaziM6/s72-c/Screen+shot+2011-05-09+at+1.47.39+PM.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-3342246172076718609</id><published>2011-03-08T07:19:00.000-08:00</published><updated>2011-03-09T14:17:24.473-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="poetry"/><title type='text'>Free Verse #397</title><content type='html'>Sipping a late,&lt;br /&gt;writing a free verse poem.&lt;br /&gt;Hey look, a haiku!</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/3342246172076718609/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/3342246172076718609' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/3342246172076718609'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/3342246172076718609'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2011/03/free-verse-397.html' title='Free Verse #397'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-6819048179265099702</id><published>2011-01-23T22:12:00.000-08:00</published><updated>2011-01-24T23:17:58.959-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="mercurial"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><category scheme="http://www.blogger.com/atom/ns#" term="version control"/><title type='text'>Mercurial in Five Commands</title><content type='html'>Completing any sort of significant programming project can be nearly impossible without version control. For a class project, I recently collaborated with a small group on a large programming assignment. To keep all of our changes in sync while working miles away from each other, we used a centralized version control system.&lt;br /&gt;&lt;br /&gt;Since I&#39;ve been working quite a bit with &lt;a href=&quot;http://mercurial.selenic.com/&quot;&gt;Mercurial&lt;/a&gt; lately, we went with a free private project on &lt;a href=&quot;https://bitbucket.org/&quot;&gt;bitbucket&lt;/a&gt;. It was the first time my teammates had used Mercurial so I gave a crash course that I thought would be helpful for others as well. A distributed version control system has a large number of commands and features, but 90% of the time, you&#39;re just dealing with the basics. When working with a team you can get by with just these five Mercurial commands: clone, commit, push, pull, and update.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Setting up the Project&lt;/h4&gt;&lt;br /&gt;As I mentioned, we were using a hosted repository on bitbucket, so getting a working copy of the repository on our machines started with each of us executing &lt;code&gt;hg clone&lt;/code&gt;. It looked a little something like this:&lt;pre&gt;hg clone https://your-username@bitbucket.org/your-username/project&lt;/pre&gt;This will create a local repository with a copy of each file and you&#39;re now free to make changes. You can edit files locally and Mercurial will track the changes for you. If you want to add new files or remove existing files, make sure to use &lt;code&gt;hg add&lt;/code&gt; and &lt;code&gt;hg remove&lt;/code&gt;. (Bonus commands!). Once you&#39;re happy with your changes and you want to gather them up in a logical unit it&#39;s time for:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Local Snapshots&lt;/h4&gt;&lt;br /&gt;To save a set of changes locally, you use &lt;code&gt;hg commit&lt;/code&gt;. Be sure to write an informative description of this change set since you and others will want to remember what this set of changes was all about. There are a few arguments to the commit command that come in handy, often I do:&lt;pre&gt;hg ci -u your-username -m &#39;Reduces codebase entropy. All tests pass!&#39;&lt;/pre&gt;For more options on the commit command and any other Mercurial command you can use &lt;code&gt;hg help &amp;lt;command&amp;gt;&lt;/code&gt;. You can also see a diff of your current files compared to the most recent snapshot using the &lt;code&gt;hg diff&lt;/code&gt; command. (Bonus times two!)&lt;br /&gt;&lt;br /&gt;Pinning your changes locally is a fantastic feature of distributed version control systems. As I work I tend to take a local snapshot several times an hour. These revisions just exist in your local copy, so you don&#39;t need to worry about clashing with other people&#39;s code at this point or making sure that all changes are usable. Sometimes when I decide I&#39;ve gone down the wrong path I&#39;ll take a snapshot of the ill conceived changes before I roll them back, just in case I decide later on that some of the ideas weren&#39;t so bad after all.&lt;br /&gt;&lt;br /&gt;Once you have something that&#39;s ready for others to use, it&#39;s time to:&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Share&lt;/h4&gt;&lt;br /&gt;To get your changes into the hands of others, you can push them back up to the central repository. You do this with the &lt;code&gt;hg push&lt;/code&gt; command. Since we created our local repository using clone, your local copy knows where to send the changes. Also, if you&#39;d like to do something different, like push your changes to a different location than where we cloned from, you can take a look at more options of the push command using &lt;code&gt;hg help push&lt;/code&gt;.&lt;br /&gt;&lt;br /&gt;The push command will upload all of your local commits, along with those handy descriptions, for the rest of your team to see. &lt;br /&gt;&lt;br /&gt;Now others on your team are pushing up their changes too and it would be great to get their changes so you are all working on the same code. What&#39;s that saying, &quot;It&#39;s better to give than to...?&quot;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Receive&lt;/h4&gt;&lt;br /&gt;To get the changes others have posted to the repository into your local copy, you use &lt;code&gt;hg pull&lt;/code&gt;. Running this command copies the change sets that you haven&#39;t received yet to your local repository, but it doesn&#39;t edit your files or apply the changes just yet. Since you might want to be selective about what changes you apply, Mercurial splits applying the changes into two steps. First you pull, then you use &lt;code&gt;hg update&lt;/code&gt;. When called with no additional arguments like that, &lt;code&gt;hg update&lt;/code&gt; applies all of the changes.&lt;br /&gt;&lt;br /&gt;I recommend pulling and updating often. In our group, since there were just a few of us, we&#39;d post in a chat room when we pushed changes so others would know to pull. If you push before you pull in other people&#39;s changes, you might need to use &lt;code&gt;hg merge&lt;/code&gt;. Also, you can see all of the changes which are in your repository with the &lt;code&gt;hg log&lt;/code&gt; command. (Triple bonus, hey a hat-trick!)&lt;br /&gt;&lt;br /&gt;There you have it!&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;Want more?&lt;/h4&gt;&lt;br /&gt;I tried to keep this simple and focused, the bare minimum to work on a project with a small team. Mercurial has more to offer. I haven&#39;t touched branches yet, or looking at diffs, or creating your own local repository from scratch, or sharing your changes by running your own server locally. All of these are just single commands! For further reading take a look at &lt;a href=&quot;http://hgbook.red-bean.com/read/&quot;&gt;Mercurial: The Definitive Guide&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There are a few services which offer hosting of Mercurial repositories. For open source, &lt;a href=&quot;http://code.google.com/p&quot;&gt;Project Hosting on Google Code&lt;/a&gt; is an option as well as bitbucket which I used for the first time this past week. Any other Mercurial hosting providers that you recommend?</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/6819048179265099702/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/6819048179265099702' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6819048179265099702'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6819048179265099702'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2011/01/mercurial-in-five-commands.html' title='Mercurial in Five Commands'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-9222063360923542109</id><published>2010-09-10T22:56:00.000-07:00</published><updated>2010-09-11T01:42:59.001-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Greek"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><title type='text'>Greekish</title><content type='html'>I&#39;ve long been fascinated with other alphabets. All of these strange and unusual symbols, it&#39;s almost like a code. This love of secrets was one of the reasons that I studied Ancient Greek. After reading and writing quite a bit of Greek, reading the alphabet became second nature. I even began taking notes using the Greek alphabet but using English words (since my Greek vocabulary is sadly inadequate). Performing simple character substitution sounded like a perfect one-hour project so I whipped up a &lt;a href=&quot;http://www.jeffscudder.com/greekish&quot;&gt;simple web page&lt;/a&gt; to convert English text into a Greek alphabet equivalent. I call it &lt;a href=&quot;http://www.jeffscudder.com/greekish&quot;&gt;Greekish&lt;/a&gt;. For example, the phrase&lt;pre&gt;So long and thanks for all the fish.&lt;/pre&gt;becomes&lt;pre&gt;Σο λονγ ανδ θανκσ φορ αλλ θε φισh.&lt;/pre&gt;which would be quite confusing to a Greek speaker but perfectly natural to an English speaker who knows the Greek alphabet.&lt;br /&gt;&lt;br /&gt;Note that some English characters do not have direct equivalents in Greek. A c would be a κ, a σ, or a χ for ch. The h is one of the more interesting stories. For a leading h before a vowel Greek uses a &lt;a href=&quot;http://en.wikipedia.org/wiki/Greek_diacritics#Breathings&quot;&gt;breathing mark&lt;/a&gt;. When combined with a consonant, special characters are used, like θ for th, χ for ch, and φ for ph. I chose to use φ only for the English f, not ph, since ph does not make the f sound in some English contexts. The word u&lt;em&gt;ph&lt;/em&gt;ill is one example. Also, I didn&#39;t bother to handle the special case of s at the end of word, for which ς is used instead of σ.&lt;br /&gt;&lt;br /&gt;Now that you know more than you ever wanted to about the Greek alphabet, what is a simple project that you can tackle in an hour? Don&#39;t just think of one, go do it!</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/9222063360923542109/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/9222063360923542109' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/9222063360923542109'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/9222063360923542109'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2010/09/greekish.html' title='Greekish'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-1653518540945732437</id><published>2010-06-22T01:24:00.000-07:00</published><updated>2010-07-03T00:53:22.439-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="c"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>A Simple Testing Library for C</title><content type='html'>To prepare for a recent post graduate computer science class, I wrote a small library in C which aids in the creation of lightweight, unit-test-like programs. The code can be found &lt;a href=&quot;http://code.google.com/p/c7e3/source/browse/#hg/testing&quot;&gt;here&lt;/a&gt;, and using it looks a bit like this:&lt;pre&gt;#include&quot;asserts.h&quot;&lt;br /&gt;&lt;br /&gt;int main(void)&lt;br /&gt;{&lt;br /&gt;  c7e3_assert(1 == 1, &quot;1 should equal 1&quot;);&lt;br /&gt;  c7e3_assert(2 == 2, &quot;2 should equal 2&quot;);&lt;br /&gt;  c7e3_report();&lt;br /&gt;  return 0;&lt;br /&gt;}&lt;/pre&gt;The design follows the &lt;a href=&quot;http://en.wikipedia.org/wiki/KISS_principle&quot;&gt;KISS principle&lt;/a&gt; and I think it is a nice fit to the simplicity of C. While there is not much to it, I wrote numerous tests using it over the past couple of months and all of that testing certainly &lt;a href=&quot;http://twitter.com/jscud/status/17233896676&quot;&gt;paid off&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/1653518540945732437/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/1653518540945732437' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1653518540945732437'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/1653518540945732437'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2010/06/simple-testing-library-for-c.html' title='A Simple Testing Library for C'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-6382976484221023970</id><published>2010-06-18T00:30:00.000-07:00</published><updated>2010-06-22T01:10:08.183-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="app engine"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="open source"/><category scheme="http://www.blogger.com/atom/ns#" term="programming"/><title type='text'>JavaScript Tricks to Speed up Your Site</title><content type='html'>One of the techniques which makes the web so powerful is the ability to load code, images, and other resources from all over the Internet. So often though, the process of loading these resources and ensuring that all of the required pieces are in place leads to a slow experience for visitors. With the ability to include so much code from across the web, visiting a site could potentially be like installing a new program when it comes to the amount of stuff that needs to be downloaded.&lt;br /&gt;&lt;br /&gt;With this in mind, there are a couple of nifty tricks that can help make your app more responsive and I&#39;ve written up an example site and testing server that shows some ideas for speeding up the user experience when you need to wait for the DOM to load or for additional JavaScript to be fetched and run. We&#39;ll begin with document operations.&lt;br /&gt;&lt;br /&gt;Often the JavaScript running on a page manipulates the DOM, using &lt;code&gt;document.getElementById&lt;/code&gt; here and &lt;code&gt;document.createElement&lt;/code&gt; there. In order to ensure that all the pieces of the page are in place, web programmers often take advantage of the onload callback. It might be used like this&lt;pre&gt;&amp;lt;body onload=&quot;runMyCodeNow()&quot;&amp;gt;&lt;/pre&gt;Using this technique ensures that all of the things your code might want to read and write from the page are in place. All images have been downloaded, CSS rules have been applied, the layout is all there. However, all of this comes with a cost, your code doesn&#39;t run until every last resource has been fetched and rendered. Even the little footer at the bottom of the page, for example, that your code doesn&#39;t care about.&lt;br /&gt;&lt;br /&gt;There is a another way, we could request that resources be loaded in parallel and start executing our code before the page is fully loaded. Chances are, your code doesn&#39;t need the complete page to be loaded before it starts running, and running before &lt;code&gt;onload&lt;/code&gt; will reduce the delay for your users. Before I dive into how this can be accomplished, lets look at an example which uses the old fashioned way.&lt;br /&gt;&lt;br /&gt;Lets say you have a web page, a little HTML which includes five JavaScript files. One may be a library used to do animation, another one for loading the users data. In any case, all of these files need to be loaded and some of them depend on others.&lt;br /&gt;&lt;br /&gt;The biggest bottleneck for your users is almost certainly having all of these resources load. Network latency is a killer, and something that is often overlooked during development. To create a simulated network environment which can give a more realistic (or even pessimistic) view of the cost of loading these resources, I wrote a &quot;slow server&quot; which can introduce a delay to the file requested. Here is the code for my testing server (designed to run on &lt;a href=&quot;http://code.google.com/appengine/&quot;&gt;App Engine&lt;/a&gt;):&lt;pre&gt;def FilePath(path):&lt;br /&gt;  &quot;&quot;&quot;The requested path into a local file path.&quot;&quot;&quot;&lt;br /&gt;&lt;br /&gt;  return os.path.join(os.path.dirname(__file__), &#39;files&#39;, path[1:])&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;class SleepyRenderer(webapp.RequestHandler):&lt;br /&gt;  &quot;&quot;&quot;Serves the requested page with a client configured delay.&lt;br /&gt;&lt;br /&gt;  Delay is given as a URL parameter in hundredths of a second to delay.&lt;br /&gt;  For example, 200 means wait 2 seconds before responding.&lt;br /&gt;&lt;br /&gt;  Example request:&lt;br /&gt;  http://localhost:8080/hi.html?delay=300&amp;contenttype=text/html&lt;br /&gt;  &quot;&quot;&quot;&lt;br /&gt;&lt;br /&gt;  def get(self):&lt;br /&gt;    path = self.request.path&lt;br /&gt;    delay = self.request.get(&#39;delay&#39;)&lt;br /&gt;    content_type = self.request.get(&#39;contenttype&#39;) or &#39;text/html&#39;&lt;br /&gt;    if delay:&lt;br /&gt;      time.sleep(int(delay)/100)&lt;br /&gt;    http_status = 200&lt;br /&gt;    requested_file = None&lt;br /&gt;&lt;br /&gt;    try:&lt;br /&gt;      requested_file = open(FilePath(path))&lt;br /&gt;      self.response.out.write(requested_file.read())&lt;br /&gt;      requested_file.close()&lt;br /&gt;    except IOError:&lt;br /&gt;      http_status = 404&lt;br /&gt;&lt;br /&gt;    self.response.set_status(http_status)&lt;br /&gt;    self.response.headers[&#39;Content-Type&#39;] = content_type&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;def main():&lt;br /&gt;    application = webapp.WSGIApplication([(&#39;/.*&#39;, SleepyRenderer)],&lt;br /&gt;                                         debug=True)&lt;br /&gt;    util.run_wsgi_app(application)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;if __name__ == &#39;__main__&#39;:&lt;br /&gt;    main()&lt;/pre&gt;With the above code we can introduce a delay on each individual file. To see this in action with our example, here is some HTML which shows a traditional approach, include script includes and an onload callback when everything has loaded.&lt;pre&gt;&amp;lt;html&amp;gt;&lt;br /&gt;  &amp;lt;head&amp;gt;&lt;br /&gt;    &amp;lt;script src=&quot;/testa.js?delay=500&amp;contenttype=text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script src=&quot;/testb.js?delay=400&amp;contenttype=text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script&amp;gt;&lt;br /&gt;      function init() {&lt;br /&gt;        document.getElementById(&#39;output&#39;);&lt;br /&gt;        output.innerHTML = [&lt;br /&gt;          &#39;a is &#39; + a,&lt;br /&gt;          &#39;b is &#39; + b,&lt;br /&gt;          &#39;c is &#39; + c,&lt;br /&gt;          &#39;d is &#39; + d,&lt;br /&gt;          &#39;e is &#39; + e&lt;br /&gt;        ].join(&#39;&amp;lt;br&amp;gt;&#39;);&lt;br /&gt;      }&lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script src=&quot;/testc.js?delay=300&amp;contenttype=text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;  &amp;lt;/head&amp;gt;&lt;br /&gt;  &amp;lt;body onload=&quot;init()&quot;&amp;gt;&lt;br /&gt;    &amp;lt;script src=&quot;/testd.js?delay=200&amp;contenttype=text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;div id=&quot;output&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;    &amp;lt;script src=&quot;/teste.js?delay=100&amp;contenttype=text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;    &amp;lt;script src=&quot;/testa.js?delay=500&amp;contenttype=text/javascript&quot;&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;  &amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;/pre&gt;With the above, the page takes several seconds to load and when the very last script has loaded, the &#39;output&#39; div gets its contents. In many cases, the code really doesn&#39;t need to wait for all resources to load, only the ones that are necessary for the code to run. In this case, since the information is added to the output div, we need the output div to exist in the DOM, but we may not need the entire page to load.&lt;br /&gt;&lt;br /&gt;If you look at this loading process in a profiler you might see something like this:&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbyTyree3XP5ozhp7VZtTaG70p4v_x16ZH8bL1YJmLw5DUpF-n9zrAHQ1MVMYZ1owUZw2-m5og33P3aESAl9y4fywYU0aTOxk_Fpz-uGVyRCaRP_1c7Ami8UPEOae7-SL5_S3b/s1600/Picture+37.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 228px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbyTyree3XP5ozhp7VZtTaG70p4v_x16ZH8bL1YJmLw5DUpF-n9zrAHQ1MVMYZ1owUZw2-m5og33P3aESAl9y4fywYU0aTOxk_Fpz-uGVyRCaRP_1c7Ami8UPEOae7-SL5_S3b/s400/Picture+37.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5485348639656267714&quot; /&gt;&lt;/a&gt;Now for our first nifty trick. One way to check to see if the necessary prerequisites are present, is by polling the DOM or the JavaScript environment, to see if conditions are right for the code to run. Here is an example of how this code might be rewritten when using some polling helper functions:&lt;pre&gt;    &amp;lt;script&amp;gt;&lt;br /&gt;      loader.whenNodePresent(&#39;output&#39;,&lt;br /&gt;        function() {&lt;br /&gt;          var output = document.getElementById(&#39;output&#39;);&lt;br /&gt;          loader.whenReady(function() {return window[&#39;a&#39;];},&lt;br /&gt;              function() {&lt;br /&gt;                output.innerHTML += &#39;a is &#39; + a + &#39;&amp;lt;br&amp;gt;&#39;;&lt;br /&gt;              }); &lt;br /&gt;          loader.whenReady(function() {return window[&#39;b&#39;];},&lt;br /&gt;            function() {&lt;br /&gt;              output.innerHTML += &#39;b is &#39; + b + &#39;&amp;lt;br&amp;gt;&#39;;&lt;br /&gt;            }); &lt;br /&gt;          loader.whenReady(function() {return window[&#39;c&#39;];},&lt;br /&gt;            function() {&lt;br /&gt;              output.innerHTML += &#39;c is &#39; + c + &#39;&amp;lt;br&amp;gt;&#39;;&lt;br /&gt;            }); &lt;br /&gt;          loader.whenReady(function() {return window[&#39;d&#39;];},&lt;br /&gt;            function() {&lt;br /&gt;              output.innerHTML += &#39;d is &#39; + d + &#39;&amp;lt;br&amp;gt;&#39;;&lt;br /&gt;            }); &lt;br /&gt;          loader.whenReady(function() {return window[&#39;e&#39;];},&lt;br /&gt;            function() {&lt;br /&gt;              output.innerHTML += &#39;e is &#39; + e + &#39;&amp;lt;br&amp;gt;&#39;;&lt;br /&gt;            }); &lt;br /&gt;        })&lt;br /&gt;    &amp;lt;/script&amp;gt;&lt;/pre&gt;The code to track the prerequisites and poll is quite simple:&lt;pre&gt;loader.waiting = [];&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;loader.whenReady = function(testFunction, callback) {&lt;br /&gt;  if (testFunction()) {&lt;br /&gt;    callback();&lt;br /&gt;  } else {&lt;br /&gt;    loader.waiting.push([testFunction, callback]);&lt;br /&gt;    window.setTimeout(loader.checkWaiting, 200);&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;loader.checkWaiting = function() {&lt;br /&gt;  var oldWaiting = loader.waiting;&lt;br /&gt;  var numWaiting = oldWaiting.length;&lt;br /&gt;  loader.waiting = [];&lt;br /&gt;  for (var i = 0; i &lt; numWaiting; i++) {&lt;br /&gt;    if (oldWaiting[i][0]()) {&lt;br /&gt;      oldWaiting[i][1]();&lt;br /&gt;    } else {&lt;br /&gt;      loader.waiting.push(oldWaiting[i]);&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  if (loader.waiting.length &gt; 0) {&lt;br /&gt;    window.setTimeout(loader.checkWaiting, 200);&lt;br /&gt;  }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;loader.whenNodePresent = function(nodeId, callback) {&lt;br /&gt;  loader.whenReady(function () {&lt;br /&gt;    return document.getElementById(nodeId);&lt;br /&gt;  }, callback);&lt;br /&gt;};&lt;/pre&gt;In the above we use the &lt;code&gt;whenReady&lt;/code&gt; function which takes a couple of functions, one to return a truthy or a falsey value, and one to call back when the first function evaluates to true. If the condition function isn&#39;t true when this first call is made, we check back every so often to see if it is ready.&lt;br /&gt;&lt;br /&gt;With these changes, we shave several seconds off of the user perceived loading time. Specifically we no longer need to wait for the duplicate load (of the &lt;code&gt;testa&lt;/code&gt; script) at the end of the body. The page also appears to be more responsive because the later script&#39;s messages appear just after they load but before the page is complete.&lt;br /&gt;&lt;br /&gt;Now that we&#39;ve seen a way to work around the need for an onload callback, lets look at another place we can tweak the browser&#39;s behavior to make a web page more responsive: dynamic script loading.&lt;br /&gt;&lt;br /&gt;The most straightforward way to include new code in your page is to use a script tag, something like:&lt;pre&gt;&amp;lt;html&amp;gt;&lt;br /&gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;script src=&quot;some_great_sites_javascript&quot;&amp;gt;&lt;br /&gt;...&lt;/pre&gt;When the browser&#39;s JavaScript interpreter encounters this script src, it stops whatever it&#39;s doing and fetches that resource. It doesn&#39;t do any more rendering or executing of code until it&#39;s finished. This behavior varies a bit in different browsers and is likely an artifact of an old design in which this kind of single threaded behavior was the only option. Since some sites might depend on this linear behavior to get a script&#39;s dependencies all in order, this quirk might be with us for a long time. Most of this time, waiting like this is a really silly idea. How often do the scripts that you include depend on one another?&lt;br /&gt;&lt;br /&gt;There are a few parts to this trick. The first is to not put all of script includes in the HTML, you could have JavaScript add new script elements to the page which will cause new code to be loaded as needed. In this way, you could load only the resources that are needed at the moment, perhaps some resources would not end up being requested at all. Including a new script could be done in two ways:&lt;pre&gt;document.write(&#39;&amp;lt;script src=&quot;somefile.js&quot;&amp;gt;&amp;lt;/script&amp;gt;&#39;);&lt;/pre&gt;or&lt;pre&gt;var newScript = document.createElement(&#39;script&#39;);&lt;br /&gt;newScript.src = &#39;somefile.js&#39;;&lt;br /&gt;document.body.appendChild(newScript);&lt;/pre&gt;Each of the above is appropriate in different situations. Document write adds HTML directly into the page at the point where the page is being loaded, it should only be used for script tag inclusion if the page is not yet loaded. If that page is loaded, using &lt;code&gt;document.write&lt;/code&gt; to add the script tag will wipe out the existing body entirely. I&#39;ve seen this issue in the wild, if you assume &lt;code&gt;document.write&lt;/code&gt; is always safe, you&#39;ll be bitten when using it after the page has loaded.&lt;br /&gt;&lt;br /&gt;Instead you can perform a check to see if &lt;code&gt;document.body&lt;/code&gt; exists, if it does then use &lt;code&gt;document.body.appendChild&lt;/code&gt;. If it does not yet exist, use &lt;code&gt;document.write&lt;/code&gt;. The code for this loader logic might look something like this:&lt;pre&gt;loader.loadScript = function(url) {&lt;br /&gt;  if (document.body) {&lt;br /&gt;    var newScript = document.createElement(&#39;script&#39;);&lt;br /&gt;    newScript.type = &#39;text/javascript&#39;;&lt;br /&gt;    newScript.src = url;&lt;br /&gt;    document.body.appendChild(newScript);&lt;br /&gt;  } else {&lt;br /&gt;    document.write(&#39;&amp;lt;scr&#39; + &#39;ipt type=&quot;text\/javascript&quot; src=&quot;&#39; +&lt;br /&gt;                   url + &#39;&quot;&amp;gt;&amp;lt;\/scr&#39; + &#39;ipt&amp;gt;&#39;);&lt;br /&gt;  }&lt;br /&gt;};&lt;/pre&gt;Now we can request that new JavaScript code be loaded on the fly and it works when the page has not yet finished loaded as well as after it has. &lt;br /&gt;&lt;br /&gt;There is one more trick we can add to this loader. Some browsers will interpret the JavaScript in the order in which the scripts were requested, not the order in which they finished loading. That means that a fast loading script further down the list won&#39;t be run until a slower script, which appears above it, is loaded. One way we could defeat this delay, is to break the script includes out of linear execution in the JavaScript. If you use setTimeout to introduce a delay in adding the script include to the page, then the code which sets up the script requests can finish quickly and the browser will get back to the script requests later without the same linear constraints. In our code, we wrap the section of &lt;code&gt;loader.loadScript&lt;/code&gt; in a short timeout as follows:&lt;pre&gt;loader.loadScript = function(url) {&lt;br /&gt;  &lt;strong&gt;window.setTimeout(function() {&lt;/strong&gt;&lt;br /&gt;    if (document.body) {&lt;br /&gt;      var newScript = document.createElement(&#39;script&#39;);&lt;br /&gt;      newScript.type = &#39;text/javascript&#39;;&lt;br /&gt;      newScript.src = url;&lt;br /&gt;      document.body.appendChild(newScript);&lt;br /&gt;    } else {&lt;br /&gt;      document.write(&#39;&amp;lt;scr&#39; + &#39;ipt type=&quot;text/javascript&quot; src=&quot;&#39; +&lt;br /&gt;                     url + &#39;&quot;&amp;gt;&amp;lt;\/scr&#39; + &#39;ipt&amp;gt;&#39;);&lt;br /&gt;    }&lt;br /&gt;  &lt;strong&gt;}, 1);&lt;/strong&gt;&lt;br /&gt;};&lt;/pre&gt;With the above changes in place, our example page from before now loads like this when profiled (note that the messages appear in the order that the scripts were loaded, we don&#39;t have to wait for everything before we edit the page):&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxZg_hrHAOyVp5uizRWdmb0CsaywmjCkW3ZLNbZKu9XWTJ_ebdboY21vlrtynQ4fWfr7mgZ3RAH1pS8CXaxXD06kdX04TYHT5WJNs3fUNLnknfUi7M45ALxqfVnw3nOQ5xRb06/s1600/Picture+38.png&quot;&gt;&lt;img style=&quot;display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 400px; height: 228px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjxZg_hrHAOyVp5uizRWdmb0CsaywmjCkW3ZLNbZKu9XWTJ_ebdboY21vlrtynQ4fWfr7mgZ3RAH1pS8CXaxXD06kdX04TYHT5WJNs3fUNLnknfUi7M45ALxqfVnw3nOQ5xRb06/s400/Picture+38.png&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5485350238551895826&quot; /&gt;&lt;/a&gt;Through the course of this post, I&#39;ve written a small library for using these tricks when loading JavaScript dynamically in the page as well as a server for trying it out. These are available &lt;a href=&quot;https://code.google.com/p/c7e3/source/browse/#hg/slowserver&quot;&gt;here&lt;/a&gt; as open source code. There are some improvements that could be made here. Off the top of my head, the checkWaiting function could eventually time out if a condition continues to not be met. Also the loader could do more to check to see if a requested script has already been loaded. Any more ideas?</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/6382976484221023970/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/6382976484221023970' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6382976484221023970'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6382976484221023970'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2010/06/javascript-tricks-to-speed-up-your-site.html' title='JavaScript Tricks to Speed up Your Site'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhbyTyree3XP5ozhp7VZtTaG70p4v_x16ZH8bL1YJmLw5DUpF-n9zrAHQ1MVMYZ1owUZw2-m5og33P3aESAl9y4fywYU0aTOxk_Fpz-uGVyRCaRP_1c7Ami8UPEOae7-SL5_S3b/s72-c/Picture+37.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-7977049507605419497</id><published>2010-03-12T20:26:00.001-08:00</published><updated>2010-03-22T21:29:19.715-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="travel"/><title type='text'>Quite a View</title><content type='html'>&lt;a onblur=&quot;try {parent.deselectBloggerImageGracefully();} catch(e) {}&quot; href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG_I0deaZveGor00AonPcSJKMx51kVnGw_IVpt7ZLLUUiWZ0lQxW45R9aZOZijI9MGKb7KezrsDow5cNCJetyoSidfY4uIWJiLZik4-C5pj3a6egr9Vbb5NBvkW2v_ZY16xUwK/s1600-h/2010-03-09+11.08.21+(1).jpg&quot;&gt;&lt;img style=&quot;float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 240px; height: 320px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG_I0deaZveGor00AonPcSJKMx51kVnGw_IVpt7ZLLUUiWZ0lQxW45R9aZOZijI9MGKb7KezrsDow5cNCJetyoSidfY4uIWJiLZik4-C5pj3a6egr9Vbb5NBvkW2v_ZY16xUwK/s320/2010-03-09+11.08.21+(1).jpg&quot; border=&quot;0&quot; alt=&quot;&quot;id=&quot;BLOGGER_PHOTO_ID_5448152965481050994&quot; /&gt;&lt;/a&gt;I recently had the privilege of working out of an office near the beach. The sun, the ocean breeze, the pounding of the surf. Laptop makers should really come up with a way to sand-proof these machines.&lt;br /&gt;&lt;br /&gt;I fully expect that this will draw some inside jokes from a few of you in the &lt;a href=&quot;http://webchat.freenode.net/?channels=googleajaxapis&quot;&gt;#googleajaxapis IRC channel&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/7977049507605419497/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/7977049507605419497' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/7977049507605419497'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/7977049507605419497'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2010/03/quite-view.html' title='Quite a View'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjG_I0deaZveGor00AonPcSJKMx51kVnGw_IVpt7ZLLUUiWZ0lQxW45R9aZOZijI9MGKb7KezrsDow5cNCJetyoSidfY4uIWJiLZik4-C5pj3a6egr9Vbb5NBvkW2v_ZY16xUwK/s72-c/2010-03-09+11.08.21+(1).jpg" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-3898783742476646871</id><published>2010-02-08T22:51:00.001-08:00</published><updated>2010-03-07T09:49:17.141-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="blogger"/><category scheme="http://www.blogger.com/atom/ns#" term="css"/><title type='text'>New Blog Template</title><content type='html'>With the growing popularity of mobile phones and lower resolution netbooks, a fixed width blog format is looking less and less appealing. I decided to work on a new look for this blog. The main feature I was looking for was a set of CSS rules that would allow the main content to scale with the viewer&#39;s browser window width. If the window is too narrow, the less important content on the sidebar should flow down below the main content.&lt;br /&gt;&lt;br /&gt;I began with an existing theme for Blogger, Tekka, that pushes the right sidebar down beneath the main content when the window is narrow. I then made some CSS changes to tweak the look to fit my tastes.&lt;br /&gt;&lt;br /&gt;First things first, the default fonts must go! I drew much of my inspiration from &lt;a href=&quot;http://blog.notdot.net/&quot;&gt;Nick Johnson&#39;s blog&lt;/a&gt;, specifically the way that serif fonts are used in some places for accent while sans-serif is used for most of the content. This is a technique that I experimented with a bit in a graphic design class in college.&lt;br /&gt;&lt;br /&gt;For titles I added:&lt;pre&gt;h1, h2 {&lt;br /&gt;  ...&lt;br /&gt;  font-family: Georgia, &#39;Times New Roman&#39;, Times, serif;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;h3 {&lt;br /&gt;  ...&lt;br /&gt;  font-family: Trebuchet MS, Verdana, Sans-serif;&lt;br /&gt;}&lt;/pre&gt;To change the font used for the main text in the page, I set a template variable as follows:&lt;pre&gt;&amp;lt;Variable name=&quot;bodyFont&quot; description=&quot;Text Font&quot;&lt;br /&gt;  type=&quot;font&quot; &lt;br /&gt;  default=&quot;normal normal 100% &#39;Lucida Grande&#39;, &lt;br /&gt;    Verdana, Helvetica, sans-serif&quot; &lt;br /&gt;  value=&quot;normal normal 100% &#39;Lucida Grande&#39;, &lt;br /&gt;    Verdana, Helvetica, sans-serif&quot;&amp;gt;&lt;/pre&gt;Next I set about changing the style of the title link. You see, when someone is viewing a single post, the blog title becomes a link to the main blog page. So, the blog&#39;s title is styled like a link and I found the default link styles a bit jarring. This might seem like a minor change but so often it&#39;s the little things that matter. I set this style using&lt;pre&gt;h1 a:visited {&lt;br /&gt;  ...&lt;br /&gt;  color: #505050;&lt;br /&gt;}&lt;/pre&gt;Now that the text styling is done, the layout could use a bit of adjustment. I changed the margins on the main content to the following:&lt;pre&gt;#content-wrapper { &lt;br /&gt;  margin-top: 20px;&lt;br /&gt;  margin-$endSide: 30px;&lt;br /&gt;  margin-bottom: 30;&lt;br /&gt;  margin-$startSide: 35px;&lt;br /&gt; }&lt;/pre&gt;I removed the padding from the &lt;code&gt;h1&lt;/code&gt; title style and the date header. I also removed the style rule entirely for the description.&lt;br /&gt;&lt;br /&gt;We&#39;re nearing the end! The sidebar wasn&#39;t quite to my liking so I changed the border style. Lastly, in order to get the sidebar to flow down beneath the main content I set a minimum width. Here is the final style for the sidebar:&lt;pre&gt;#sidebar {&lt;br /&gt;  text-transform:none;&lt;br /&gt;  background-color: $sidebarBgColor;&lt;br /&gt;  color: $sidebarTextColor;&lt;br /&gt;  padding-$startSide: 20px;&lt;br /&gt;  width: 30%;&lt;br /&gt;  min-width: 215px;&lt;br /&gt;  float: $endSide;&lt;br /&gt;  font: $bodyFont;&lt;br /&gt;  border-$startSide:1px solid $mainTextColor;&lt;br /&gt;  word-wrap: break-word;&lt;br /&gt;  overflow: hidden;&lt;br /&gt;}&lt;/pre&gt;I debated about posting the whole template here, but I&#39;m not sure that it would be very readable. If you would like the whole thing, leave a comment and I can email it to you.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/3898783742476646871/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/3898783742476646871' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/3898783742476646871'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/3898783742476646871'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2010/02/new-blog-template.html' title='New Blog Template'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-354090936792118313</id><published>2010-01-13T23:45:00.000-08:00</published><updated>2010-02-08T23:06:27.610-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="css"/><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><category scheme="http://www.blogger.com/atom/ns#" term="q12"/><title type='text'>DOM Manipulation in JavaScript, a Utility</title><content type='html'>In my latest addition to the &lt;a href=&quot;http://code.google.com/p/q12/&quot;&gt;q12 JavaScript library&lt;/a&gt;, I have added a simple function to construct a nested document structure. I grew tired of writing repetitive and difficult to follow code like this &lt;pre&gt;var div = document.createElement(&#39;div&#39;);&lt;br /&gt;div[&#39;id&#39;] = &#39;outer-div&#39;;&lt;br /&gt;var link = document.createElement(&#39;a&#39;);&lt;br /&gt;link.href = &#39;http://blog.jeffscudder.com&#39;;&lt;br /&gt;link.appendChild(document.createTextNode(&#39;my blog&#39;));&lt;br /&gt;div.appendChild(link);&lt;/pre&gt;Using the new tree function this would become:&lt;pre&gt;var div = tree([&lt;br /&gt;    &#39;div&#39;, {&lt;br /&gt;        id: &#39;outer-div&#39;}, [&lt;br /&gt;      &#39;a&#39;, {&lt;br /&gt;          href: &#39;http://blog.jeffscudder.com&#39;}, [&lt;br /&gt;        &#39;my blog&#39;]]]);&lt;/pre&gt;In the process of writing this utility function, I came across another small oddity in editing HTML using JavaScript related to the style attribute. Most HTML attributes are simple text properties, however when editing the CSS style of a node, you cannot set the full content of the style attribute. &lt;pre&gt;// You cannot do this:&lt;br /&gt;div.style = &quot;color:red; font-weight:bold&quot;;&lt;/pre&gt;Instead, you set each sub item in the style attribute:&lt;pre&gt;// This works:&lt;br /&gt;div.style.color = &#39;red&#39;;&lt;br /&gt;div.style[&#39;font-weight&#39;] = &#39;bold&#39;;&lt;/pre&gt;The tree function that I&#39;ve written handles this nested style structure as well. Here&#39;s an example:&lt;pre&gt;[&#39;div&#39;, {&lt;br /&gt;    &#39;id&#39;: &#39;foo&#39;, &lt;br /&gt;    &#39;style&#39;: {&#39;color&#39;: &#39;red&#39;, &#39;font-weight&#39;: &#39;bold&#39;}}, &lt;br /&gt;  &#39;This works too!&#39;]&lt;/pre&gt;Now that you have an idea of how to use this utility, here&#39;s the code. Minus the comments it&#39;s only about twenty-one lines.&lt;pre&gt;/**&lt;br /&gt; * Creates a DOM tree from a simple list.&lt;br /&gt; * The structure of the tree passed in is as follows:&lt;br /&gt; * [&#39;elementTag&#39;, &lt;br /&gt; *      {attribute1: value,&lt;br /&gt; *       attribute2: value,&lt;br /&gt; *       style: {property1: value,&lt;br /&gt; *               property2: value}},&lt;br /&gt; *    &#39;child text node&#39;,&lt;br /&gt; *    [&#39;elementTag&#39;,&lt;br /&gt; *         {property: value},&lt;br /&gt; *       &#39;grandchild text node&#39;],&lt;br /&gt; *    &#39;third node&#39;]&lt;br /&gt; * The above will result in a DOM node which has three child nodes, the&lt;br /&gt; * first and third will be text nodes because the values were strings.&lt;br /&gt; * The second child node will be a DOM node as well.&lt;br /&gt; *&lt;br /&gt; * @param {Array} t The tree&#39;s structure as a collection of strings, lists,&lt;br /&gt; *     and simple objects. The structure is as follows&lt;br /&gt; *     [&#39;elementTag&#39;, {attributes}, child, child, child, ...]&lt;br /&gt; * @return {Element} Returns a new DOM element.&lt;br /&gt; */&lt;br /&gt;function tree(t) {&lt;br /&gt;  // Create the node using the tag which is first in the list.&lt;br /&gt;  var domNode = document.createElement(t[0]);&lt;br /&gt;  // Add all HTML attributes to the node.&lt;br /&gt;  for (var key in t[1]) {&lt;br /&gt;    // The style attributes get special treatment.&lt;br /&gt;    if (key == &#39;style&#39;) {&lt;br /&gt;      for (var styleAttribute in t[1].style) {&lt;br /&gt;        domNode.style[styleAttribute] = t[1].style[styleAttribute];&lt;br /&gt;      }&lt;br /&gt;    } else {&lt;br /&gt;      domNode[key] = t[1][key];&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  // Iterate over all child nodes, converting them to either text or HTML&lt;br /&gt;  // nodes.&lt;br /&gt;  for (var index = 2, child; child = t[index]; index++) {&lt;br /&gt;    if (typeof(child) == &#39;string&#39;) {&lt;br /&gt;      domNode.appendChild(document.createTextNode(child));&lt;br /&gt;    } else {&lt;br /&gt;      // Buid recursively.&lt;br /&gt;      domNode.appendChild(tree(child));&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  return domNode; &lt;br /&gt;}&lt;/pre&gt;What do you think, is there anything you would add?&lt;br /&gt;&lt;br /&gt;On a realted note, if you&#39;re interested in a more powerful templating system, you might want to try &lt;a href=&quot;&lt;br /&gt;http://code.google.com/closure/templates/&quot;&gt;Closure Templates&lt;/a&gt; which were &lt;a href=&quot;http://googlecode.blogspot.com/2009/11/introducing-closure-tools.html&quot;&gt;recently open sourced&lt;/a&gt;.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/354090936792118313/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/354090936792118313' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/354090936792118313'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/354090936792118313'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2010/01/dom-manipulation-in-javascript-utility.html' title='DOM Manipulation in JavaScript, a Utility'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-6782376423778260654</id><published>2009-10-22T16:00:00.000-07:00</published><updated>2009-11-09T22:24:53.478-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript"/><title type='text'>The joys of onKeyDown</title><content type='html'>I recently found myself in need of a way to detect when a user presses enter when typing in a text input box and happened upon one of the &lt;a href=&quot;http://www.quirksmode.org/js/keys.html&quot;&gt;quirkiest&lt;/a&gt; of browser features, key press detection in JavaScript. Searching the Internet provided a few ideas but nothing that quite fit what I was looking for, so I thought maybe I should get the word out about what I&#39;ve learned.&lt;br /&gt;&lt;br /&gt;Lets assume that we have a form with an input box and we want to perform some special action when the user presses the enter key while focus is on the text input box. We begin by adding an onKeyDown event to the input box (you might also consider onKeyUp, but onKeyPress seems like it might be somewhat quirkier).&lt;pre&gt;&amp;lt;form&amp;gt;&lt;br /&gt;  &amp;lt;input type=&quot;text&quot; id=&quot;my-input&quot;&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;div id=&quot;output&quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;script&amp;gt;&lt;br /&gt;  document.getElementById(&#39;my-input&#39;).onkeydown = function(e) {};&lt;br /&gt;&amp;lt;script&amp;gt;&lt;/pre&gt;Now the first hurdle is that in IE, Safari, and Chrome you can access the ASCII character code for the key which was pressed in &lt;code&gt;window.event.keyCode&lt;/code&gt; but in FireFox you&#39;ll need to get the event object and look at the &lt;code&gt;which&lt;/code&gt; member.&lt;pre&gt;&amp;lt;script&amp;gt;&lt;br /&gt; document.getElementById(&#39;my-input&#39;).onkeydown = function(e) {&lt;br /&gt;   var keyCode = 0;&lt;br /&gt;   if (window &amp;amp;&amp;amp; window.event &amp;amp;&amp;amp; window.event.keyCode) {&lt;br /&gt;     keyCode = window.event.keyCode;&lt;br /&gt;   } else if (e &amp;amp;&amp;amp; e.which) {&lt;br /&gt;     keyCode = e.which;&lt;br /&gt;   } else {&lt;br /&gt;     alert(&#39;fail&#39;);&lt;br /&gt;   }&lt;br /&gt;   document.getElementById(&#39;output&#39;).innerHTML = &#39;You pressed &#39; + keyCode;&lt;br /&gt; };&lt;br /&gt;&amp;lt;script&amp;gt;&lt;/pre&gt;Now there is one gotcha with what we&#39;ve written so far. Each key that we press when focus is on the desired input causes our code to be run, but the browser also performs the default behavior for that key. If our input is a simple text box, the characters pressed will show up in the text box. If the input is part of a form with a submit button, pressing enter will cause the form to be submitted. If the form is submitted then the browser is sent to a different page which in this case is not what we want.&lt;br /&gt;&lt;br /&gt;There are a few ways to prevent the key presses from also triggering the default behavior and do only our behavior. One of the simplest ways is to return false from the &lt;code&gt;onKeyDown&lt;/code&gt; function. If we change our handler to the below, characters will not show up in a text input box because our handler consumes them.&lt;pre&gt; document.getElementById(&#39;my-input&#39;).onkeydown = function(e) {&lt;br /&gt;   var keyCode = 0;&lt;br /&gt;   if (window &amp;amp;&amp;amp; window.event &amp;amp;&amp;amp; window.event.keyCode) {&lt;br /&gt;     keyCode = window.event.keyCode;&lt;br /&gt;   } else if (e &amp;amp;&amp;amp; e.which) {&lt;br /&gt;     keyCode = e.which;&lt;br /&gt;   } else {&lt;br /&gt;     alert(&#39;fail&#39;);&lt;br /&gt;   }&lt;br /&gt;   document.getElementById(&#39;output&#39;).innerHTML = &#39;You pressed &#39; + keyCode;&lt;br /&gt;   return false;&lt;br /&gt; };&lt;/pre&gt;With the above, the last key press is displayed in the output, but in most cases we probably do want the user to see the chracters they&#39;ve typed showing up in the input box. We just want to prevent the form submit when the user presses the enter key. To accomplish this behavior, we can return false when we don&#39;t want the key press to propoage and return true when the default behavior should also be performed.&lt;pre&gt; document.getElementById(&#39;my-input&#39;).onkeydown = function(e) {&lt;br /&gt;   var keyCode = 0;&lt;br /&gt;   if (window &amp;amp;&amp;amp; window.event &amp;amp;&amp;amp; window.event.keyCode) {&lt;br /&gt;     keyCode = window.event.keyCode;&lt;br /&gt;   } else if (e &amp;amp;&amp;amp; e.which) {&lt;br /&gt;     keyCode = e.which;&lt;br /&gt;   } else {&lt;br /&gt;     alert(&#39;fail&#39;);&lt;br /&gt;   }&lt;br /&gt;   document.getElementById(&#39;output&#39;).innerHTML = &#39;You pressed &#39; + keyCode;&lt;br /&gt;   if (keyCode == 13) { // 13 is the key code for the enter key.&lt;br /&gt;     return false;&lt;br /&gt;   } else {&lt;br /&gt;     return true;&lt;br /&gt;   }&lt;br /&gt; };&lt;/pre&gt;There you have it, a way to detect when the enter key is pressed in our input box while also preventing the form from being submitted.</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/6782376423778260654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/6782376423778260654' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6782376423778260654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/6782376423778260654'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2009/10/joys-of-onkeydown.html' title='The joys of onKeyDown'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-33260599.post-8890003236705886325</id><published>2009-09-28T22:16:00.000-07:00</published><updated>2009-09-28T22:37:27.841-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="journal"/><category scheme="http://www.blogger.com/atom/ns#" term="writing"/><title type='text'>Journaling</title><content type='html'>This evening I found my long lost journal. In dusting it off and cracking it open I learned that my last entry had been over a year ago. With the exception of this last year long hiatus, I&#39;ve regularly kept a journal since sometime in 1999 or 2000. I&#39;ve found writing my thoughts helps me crystallize them and I tend to deal with thoughts and emotions internally, mulling them for hours or days. This is one of the reasons I think I&#39;ve stuck with blogging.&lt;br /&gt;&lt;br /&gt;Keeping a private journal is a completely different feeling than keeping a blog. When I write here I&#39;m intensely (sometimes even paralyzingly) conscious of my audience. Not that it&#39;s a large one. Here I tend to focus on software related discoveries and creations. It is one creative outlet, but one decidedly different from when I journal. &lt;br /&gt;&lt;br /&gt;It was refreshing to scratch blank pages with pen, writing for an audience which understands me better than most.&lt;br /&gt;&lt;br /&gt;Okay now how many of you, when you saw the title, thought that I was going to talk about a &lt;a href=&quot;http://en.wikipedia.org/wiki/Journaling_file_system&quot;&gt;file system&lt;/a&gt; or &lt;a href=&quot;http://labs.google.com/papers/bigtable-osdi06.pdf&quot;&gt;database&lt;/a&gt;? :-) How about you, do you keep a private journal?</content><link rel='replies' type='application/atom+xml' href='http://blog.jeffscudder.com/feeds/8890003236705886325/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment/fullpage/post/33260599/8890003236705886325' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/8890003236705886325'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/33260599/posts/default/8890003236705886325'/><link rel='alternate' type='text/html' href='http://blog.jeffscudder.com/2009/09/journaling.html' title='Journaling'/><author><name>Jeff Scudder</name><uri>http://www.blogger.com/profile/13002167096451875802</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>