CARVIEW |
Select Language
HTTP/2 302
server: nginx
date: Sat, 02 Aug 2025 04:11:47 GMT
content-type: text/plain; charset=utf-8
content-length: 0
x-archive-redirect-reason: found capture at 20081222124409
location: https://web.archive.org/web/20081222124409/https://feeds.feedburner.com/oreilly/fyi/blog
server-timing: captures_list;dur=0.484804, exclusion.robots;dur=0.019085, exclusion.robots.policy;dur=0.008499, esindex;dur=0.010269, cdx.remote;dur=59.100635, LoadShardBlock;dur=166.427623, PetaboxLoader3.datanode;dur=73.837509, PetaboxLoader3.resolve;dur=37.348052
x-app-server: wwwb-app211
x-ts: 302
x-tr: 246
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
set-cookie: wb-p-SERVER=wwwb-app211; path=/
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
HTTP/2 200
server: nginx
date: Sat, 02 Aug 2025 04:11:47 GMT
content-type: text/xml;charset=utf-8
x-archive-orig-date: Mon, 22 Dec 2008 12:44:08 GMT
x-archive-orig-server: Apache
x-archive-orig-x-fb-host: app12
x-archive-orig-last-modified: Mon, 22 Dec 2008 11:45:42 GMT
x-archive-orig-etag: DnAT+51VpPkjVORc3IoXzWTmL4c
x-archive-orig-p3p: CP="ALL DSP COR NID CUR OUR NOR"
x-archive-orig-connection: close
cache-control: max-age=1800
x-archive-guessed-content-type: text/xml
x-archive-guessed-charset: utf-8
memento-datetime: Mon, 22 Dec 2008 12:44:09 GMT
link: ; rel="original", ; rel="timemap"; type="application/link-format", ; rel="timegate", ; rel="first memento"; datetime="Tue, 06 May 2008 17:34:53 GMT", ; rel="prev memento"; datetime="Tue, 06 May 2008 17:34:53 GMT", ; rel="memento"; datetime="Mon, 22 Dec 2008 12:44:09 GMT", ; rel="next memento"; datetime="Fri, 13 Feb 2009 03:00:33 GMT", ; rel="last memento"; datetime="Fri, 13 Feb 2009 03:00:33 GMT"
content-security-policy: default-src 'self' 'unsafe-eval' 'unsafe-inline' data: blob: archive.org web.archive.org web-static.archive.org wayback-api.archive.org athena.archive.org analytics.archive.org pragma.archivelab.org wwwb-events.archive.org
x-archive-src: 51_7_20081222021213_crawl101-c/51_7_20081222124332_crawl107.arc.gz
server-timing: captures_list;dur=1.718560, exclusion.robots;dur=0.029666, exclusion.robots.policy;dur=0.013299, esindex;dur=0.016488, cdx.remote;dur=6.485060, LoadShardBlock;dur=155.465418, PetaboxLoader3.datanode;dur=120.647216, PetaboxLoader3.resolve;dur=81.719004, load_resource;dur=121.068267
x-app-server: wwwb-app211
x-ts: 200
x-tr: 307
server-timing: TR;dur=0,Tw;dur=0,Tc;dur=0
x-location: All
x-rl: 0
x-na: 0
x-page-cache: MISS
server-timing: MISS
x-nid: DigitalOcean
referrer-policy: no-referrer-when-downgrade
permissions-policy: interest-cohort=()
O'Reilly FYI Blog
tag:fyi.oreilly.com,2008-06-17://48
2008-11-22T00:15:31Z
Movable Type Pro 4.21-en
The Adobe AIR Cookbook Cook-Off Contest Winning Entry Posted Here
tag:fyi.oreilly.com,2008://48.34255
2008-11-21T23:12:03Z
2008-11-22T00:15:31Z
Recently O'Reilly sponsored the Adobe AIR Cookbook Cook-Off contest, a chance for developers to submit recipes and win prizes. And many of the top entries can be found in O'Reilly's latest, Adobe AIR 1.5 Cookbook, including the winning entry from Greg Jastrab. In this excerpt from the book, we give you Greg's prize-winning contribution, Migrating Serialization Changes in ActionScript.
Sara Peyton
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://oreilly.com/catalog/9780596522506/index.html"><img alt="9780596522506_cat.gif" src="https://fyi.oreilly.com/2008/11/21/9780596522506_cat.gif" width="180" height="236" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a></span><p>
Recently O'Reilly sponsored the Adobe AIR Cookbook Cook-Off contest, a chance for developers to submit recipes and win prizes. And many of the top entries can be found in O'Reilly's latest, <a href="https://oreilly.com/catalog/9780596522506/index.html">Adobe AIR 1.5 Cookbook</a>, including the winning entry from Greg Jastrab. In this excerpt from the book, we give you Greg's prize-winning contribution, Migrating Serialization Changes in ActionScript.</p>
<p><em>Contributed by Greg Jastrab (<a href="https://www.smartlogicsolutions.com" target="_blank">https://www.smartlogicsolutions.com</a>)</em></span></p>
<p>This is the winning entry for the Adobe AIR Cookbook Cook-Off
contest, sponsored by O’Reilly. The judges—a team of
RIA experts—chose this entry because it shows how to
accomplish a single task in a clear, concise, and clever manner. It
was also selected because of its importance to AIR developers. As
developers store instances of classes on the local file system or
in the embedded SQLite database, this problem will become even more
commonplace. Greg’s solution provides a fix that will be easy
for developers to implement. Great job, Greg!</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="aacb_badge.png" src="https://fyi.oreilly.com/2008/11/21/aacb_badge.png" width="85" height="85" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></span>
<p><b>Problem</b></p>
<p>Your AIR application stores an instance of
a custom <code class="literal">IExternalizable</code> class to
disk, and a later update to the application adds new variables to
the class that would cause a runtime error in your <code class=
"literal">readExternal</code> method call if you try to read in the
new variables.</p>
<p><b>Solution</b></p>
<p>Include a version marker in your serialization class so that you
may parse the data according to the appropriate version that is
stored.</p>
<p><b>Discussion</b></p>
<p>Consider an AIR application that stores historical weather data
about a town. The data object is written as a class implementing
<code class="literal">IExternalizable</code> so that reading and
writing the data is as simple as calling <code class=
"literal">readObject</code> or <code class=
"literal">writeObject</code>. Assume the first version of the
serialization class simply stores the date and a high temperature
of that date.</p>
<pre class="programlisting">
public class WeatherData implements IExternalizable {
public var date:Date;
public var high:Number;
}
</pre>
<p><b>Poor Serialization Choice</b></p>
<p>Typically, the <code class="literal">readExternal</code> and
<code class="literal">writeExternal</code> functions would be
implemented in a straightforward manner:</p>
<pre class="programlisting">
function readExternal(input:IDataInput):void {
date = input.readObject() as Date;
high = input.readFloat();
}
function writeExternal(output:IDataOutput):void {
output.writeObject(date);
output.writeFloat(high);
}
</pre>
<p>This may seem fine, but what if you want to add the low
temperature for the day in a later version? You could add
<code class="literal">low = input.readFloat</code> to the
<code class="literal">readExternal</code> function, but because the
data was written to disk without the low data, it would cause a
runtime error when a user who upgraded the application runs it
again.</p>
<p><b>Migratable Serialization</b></p>
<p>To avoid this error, you should add a version marker to the
beginning of the serialization so that it can be read first in
order to determine how the data should be read:</p>
<pre class="programlisting">
public class WeatherData implements IExternalizable {
<span class=
"bold"><strong>namespace wd1_0 = "WD1.0";</strong></span>
<span class=
"bold"><strong>namespace wd1_1 = "WD1.1";</strong></span>
protected var version:String;
public var date:Date;
public var low:Number;
public var high:Number;
public function WeatherData() {
version = "WD1.1";
date = new Date();
low = high = 0;
}
public function readExternal(input:IDataInput):void {
<span class=
"bold"><strong>version = input.readUTF();</strong></span>
<span class=
"bold"><strong> var ns:Namespace = new Namespace(version);</strong></span>
<span class="bold"><strong> ns::parse(input);</strong></span>
}
public function writeExternal(output:IDataOutput):void {
output.writeUTF(version);
output.writeObject(date);
output.writeFloat(low);
output.writeFloat(high);
}
wd1_0 function parse(input:IDataInput):void {
date = input.readObject() as Date;
high = input.readFloat();
}
wd1_1 function parse(input:IDataInput):void {
date = input.readObject() as Date;
low = input.readFloat();
high = input.readFloat();
}
}
</pre>
<p>This allows the class to be properly read if the user had run
the initial version of the application that wrote the WD1.0 version
of <code class="literal">WeatherData</code> and then ran an updated
version for the first time with this as the <code class=
"literal">WeatherData</code> code.</p>
<p><b>Adding Members in Future Versions</b></p>
<p>Now whenever you need to add a field to the class, you need to
do the following:</p>
<ol type="1">
<li>
<p>Add the variable to the class.</p>
</li>
<li>
<p>Modify the <code class="literal">writeExternal</code> method to
include that variable in the serialization.</p>
</li>
<li>
<p>Increment the version string in the constructor.</p>
</li>
<li>
<p>Add a namespace for this new version.</p>
</li>
<li>
<p>Add a parse function scoped to the namespace you just added and
implement <code class="literal">readExternal</code> to correspond
to your updated <code class="literal">writeExternal</code>
method.</p>
</li>
</ol>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/461330326" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2831
text
https://fyi.oreilly.com/2008/11/21/9780596522506_cat.gif
https://fyi.oreilly.com/2008/11/adobe-air-15-cookbooks-excerpt.html
Juval Lowy explains Service-Orientation
tag:fyi.oreilly.com,2008://48.34181
2008-11-18T21:07:34Z
2008-11-19T17:19:52Z
Kathryn Barrett
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="9780596521301_cat.gif" src="https://fyi.oreilly.com/9780596521301_cat.gif" width="180" height="236" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></span><p><a href="https://www.oreillynet.com/pub/au/741"><strong>Juval Lowy</strong></a>'s <a href="https://oreilly.com/catalog/9780596521301/"><strong>Programming WCF Services</strong></a> is considered to be the most definitive treatment of Microsoft's WCF (Windows Communication Foundation) available. In it, Juval provides both the guidance and insight needed to master the skills for building maintainable, extensible, and reusable WCF-based applications. Juval's talent as a teacher—that for tackling vast subjects and making them easy to learn—comes through especially well in this appendix from his book: <em>An Introduction to Service-Orientation</em>. These days, there's no avoiding the phrase "service-oriented," but few people can explain what it means and why it's so important. Juval gets to the heart of the matter in this excerpt.</p>
<p><strong><a name="introduction_to_service-orientation" id=
"introduction_to_service-orientation"></a>Appendix A. Introduction
to Service-Orientation</strong></p>
<br />
<p><b>Table of Contents</b></p>
<dl>
<dt><a href="#a_brief_history_of_software_engineering">A Brief History of Software Engineering</a></dt>
<dd>
<dl>
<dt><a href="#objectorientation">Object-Orientation</a></dt>
<dt><a href="#componentorientation">Component-Orientation</a></dt>
</dl>
</dd>
<dt><a href="#serviceorientation">Service-Orientation</a></dt>
<dd>
<dl>
<dt><a href="#benefitsofserviceorientation">Benefits of Service-Orientation</a></dt>
<dt><a href="#serviceorientedapplications">Service-Oriented Applications</a></dt>
</dl>
</dd>
<dt><a href="#tenetsandprinciples">Tenets and Principles</a></dt>
<dd>
<dl>
<dt><a href="#practicalprinciples">Practical Principles</a></dt>
<dt><a href="#optionalprinciples">Optional Principles</a></dt>
</dl>
</dd>
<dt><a href="#whatsnext">What's Next?</a></dt>
<dd>
<dl>
<dt><a href="#aserviceorientedplatform">A Service-Oriented Platform</a></dt>
</dl>
</dd>
</dl>
<p>This book is all about designing and developing service-oriented
applications using WCF—yet there is considerable confusion
and hype concerning what service-orientation is and what it means.
To make matters worse, most of the vendors in this space equate
their definition of service-orientation with their products and
services. The vendors (Microsoft included) add to the confusion by
equating service-orientation with high-end Enterprise applications,
where handling high scalability and throughput is a must (mostly
because they all contend for that market, where the business
margins are made).</p>
<p>This appendix presents my understanding of what
service-orientation is all about and attempts to put it in a
concrete context. My take is different from that of the large
vendors, but I believe it is more down-to-earth, rooted as it is in
trends and the natural evolution of our industry. As you will see,
I believe that service-orientation is not a breakthrough or a
quantum leap of thought, but rather the next gradual step (and
probably not the last step) in a long journey that spans
decades.</p>
<p>To understand where the software industry is heading with
service-orientation, you should first appreciate where it came
from. After a brief discussion of the history of software
engineering and its overarching trend, this appendix defines
service-oriented applications (as opposed to mere architecture),
explains what services themselves are, and examines the benefits of
the methodology. It then presents the main principles of
service-orientation and augments the abstract tenets with a few
more practical and concrete points to which most applications
should adhere. Finally, the appendix concludes with a look to the
future.</p>
<p><strong><a name="abriefhistoryofsoftwareengineering" id="a_brief_history_of_software_engineering">A Brief History of Software Engineering</a></strong></p>
<p>The first modern computer was an electromechanical,
typewriter-sized device developed in Poland in the late 1920s for
enciphering messages. The device was later sold to the German
Commerce Ministry, and in the 1930s the German military adopted it
for enciphering all wireless communication. Today we know it as the
Enigma.</p>
<p>Enigma used mechanical rotors to change the route of electrical
current flow to a light board in response to a letter key being
pressed, resulting in a different letter being output (the ciphered
letter). Enigma was not a general-purpose computer: it could only
do enciphering and deciphering (which today we call encryption and
decryption). If the operator wanted to change the encryption
algorithm, he had to physically alter the mechanical structure of
the machine by changing the rotors, their order, their initial
positions, and the wired plugs that connected the keyboard to the
light board. The "program" was therefore coupled in the extreme to
the problem it was designed to solve (encryption), and to the
mechanical design of the computer.</p>
<p>The late 1940s and the 1950s saw the introduction of the first
general-purpose electronic computers for defense purposes. These
machines could run code that addressed any problem, not just a
single predetermined task. The downside was that the code executed
on these computers was in a machine-specific "language" with the
program coupled to the hardware itself. Code developed for one
machine could not run on another. In fact, at the time there was no
distinction between the software and the hardware (indeed, the word
"software" was coined only in 1958). Initially this was not a cause
for concern, since there were only a handful of computers in the
world anyway. As machines became more prolific, this did turn into
a problem. In the early 1960s the emergence of assembly language
decoupled the code from specific machines, enabling it to run on
multiple computers. That code, however, was now coupled to the
machine architecture: code written for an 8-bit machine could not
run on a 16-bit machine, let alone withstand differences in the
registers or available memory and memory layout. As a result, the
cost of owning and maintaining a program began to escalate. This
coincided more or less with the widespread adoption of computers in
the civilian and government sectors, where the more limited
resources and budgets necessitated a better solution.</p>
<p>In the 1960s, higher-level languages such as COBOL and FORTRAN
introduced the notion of a <em>compiler</em>: the developer would write in
an abstraction of machine programming (the language), and the
compiler would translate that into actual assembly code. Compilers
for the first time decoupled the code from the hardware and its
architecture. The problem with those first-generation languages was
that the code resulted in nonstructured programming, where the code
was internally coupled to its own structure via the use of jump or
go-to statements. Minute changes to the code structure often had
devastating effects in multiple places in the program.</p>
<p>The 1970s saw the emergence of structured programming via
languages such as C and Pascal, which decoupled the code from its
internal layout and structure using functions and structures. The
1970s was also the first time developers and researchers started to
examine software as an engineered entity. To drive down the cost of
ownership, companies had to start thinking about reuse—that
is, what would make a piece of code able to be reused in other
contexts. With languages like C, the basic unit of reuse is the
<em>function</em>. But the problem
with function-based reuse is that the function is coupled to the
data it manipulates, and if the data is global, a change to benefit
one function in one reuse context is likely to damage another
function used somewhere else.</p>
<p><strong><a name="objectorientation" id="objectorientation">Object-Orientation</a></strong></p>
<p>The solution to these problems that emerged in the 1980s, with
languages such as Smalltalk and later C++, was object-orientation.
With object-orientation, the functions and the data they
manipulated were packaged together in an object. The functions (now
called <em>methods</em>) encapsulated
the logic, and the object encapsulated the data. Object-orientation
enabled domain modeling in the form of a class hierarchy. The
mechanism of reuse was class-based, enabling both direct reuse and
specialization via inheritance. But object-orientation was not
without its own acute problems. First, the generated application
(or code artifact) was a single, monolithic application. Languages
like C++ have nothing to say about the binary representation of the
generated code. Developers had to deploy huge code bases every time
they needed to make a change, however minute, and this had a
detrimental effect on the development process and on application
quality, time to market, and cost. While the basic unit of reuse
was a class, it was a class in source format. Consequently, the
application was coupled to the language used—you could not
have a Smalltalk client consuming a C++ class or deriving from it.
Language-based reuse implied uniformity of skill (all developers in
the organization had to be skilled enough to use C++), which led to
staffing problems. Language-based reuse also inhibited economy of
scale, because if the organization was using multiple languages it
necessitated duplication of investments in framework and common
utilities. Finally, having to access the source files in order to
reuse an object coupled developers to each other, complicated
source control, and coupled teams together, since it made
independent builds difficult. Moreover, inheritance turned out to
be a poor mechanism for reuse, often harboring more harm than good
because the developer of the derived class needed to be intimately
aware of the implementation of the base class (which introduced
vertical coupling across the class hierarchy).</p>
<p>Object-orientation was oblivious to real-life challenges, such
as deployment and versioning issues. Serialization and persistence
posed yet another set of problems. Most applications did not start
by plucking objects out of thin air; they had some persistent state
that needed to be hydrated into objects. However, there was no way
of enforcing compatibility between the persisted state and the
potentially new object code. Object-orientation assumed the entire
application was always in one big process. This prevented fault
isolation between the client and the object, and if the object blew
up, it took the client (and all other objects in the process) with
it. Having a single process implies a single uniform identity for
the clients and the objects, without any security isolation. This
makes it impossible to authenticate and authorize clients, since
they have the same identity as the object. A single process also
impedes scalability, availability, responsiveness, throughput, and
robustness. Developers could manually place objects in separate
processes, yet if the objects were distributed across multiple
processes or machines there was no way of using raw C++ for the
invocations, since C++ required direct memory references and did
not support distribution. Developers had to write host processes
and use some remote call technology (such as TCP sockets) to remote
the calls, but such invocations looked nothing like native C++
calls and did not benefit from object-orientation.</p>
<p><strong><a name="componentorientation" id="componentorientation">Component-Orientation</a></strong></p>
<p>The solution for the problems of object-orientation evolved over
time, involving technologies such as the static library
(<em>.lib</em>) and the dynamic
library (<em>.dll</em>), culminating
in 1994 with the first component-oriented technology, called COM
(Component Object Model). Component-orientation provided
interchangeable, interoperable binary components. With this
approach, instead of sharing source files, the client and the
server agree on a binary type system (such as IDL) and a way of
representing the metadata inside the opaque binary components. The
components are discovered and loaded at runtime, enabling scenarios
such as dropping a control on a form and having that control be
automatically loaded at runtime on the client's machine. The client
only programs against an abstraction of the service: a contract
called the <em>interface</em>. As
long as the interface is immutable, the service is free to evolve
at will. A proxy can implement the same interface and thus enable
seamless remote calls by encapsulating the low-level mechanics of
the remote call. The availability of a common binary type system
enables cross-language interoperability, so a Visual Basic client
can consume a C++ COM component. The basic unit of reuse is the
interface, not the component, and polymorphic implementations are
interchangeable. Versioning is controlled by assigning a unique
identifier for every interface, COM object, and type
library.</p>
<p>While COM was a fundamental breakthrough in modern software
engineering, most developers found it unpalatable. COM was
unnecessarily ugly because it was bolted on top of an operating
system that was unaware of it, and the languages used for writing
COM components (such as C++ and Visual Basic) were at best
object-oriented but not component-oriented. This greatly
complicated the programming model, requiring frameworks such as ATL
to partially bridge the two worlds. Recognizing these issues,
Microsoft released .NET 1.0 in 2002. .NET is (in the abstract)
nothing more than cleaned-up COM, MFC, C++, and Windows, all
working seamlessly together under a single new component-oriented
runtime. .NET supports all the advantages of COM and mandates and
standardizes many of its ingredients, such as type metadata
sharing, dynamic component loading, serialization, and
versioning.</p>
<p>While .NET is at least an order of magnitude easier to work with
than COM, both COM and .NET suffer from a similar set of
problems:</p>
<dl>
<dt><em>Technology and
platform</em></dt>
<dd>
<p>The application and the code are coupled to the technology and
the platform. Both COM and .NET are available only on Windows. Both
also expect the client and the service to be either COM or .NET and
cannot interoperate natively with other technologies, be they
Windows or not. While bridging technologies such as web services
make interoperability possible, they force the developers to let go
of almost all of the benefits of working with the native framework,
and they introduce their own complexities and coupling with regard
to the nature of the interoperability mechanism. This, in turn,
breaks economy of scale.</p>
</dd>
<dt><em>Concurrency
management</em></dt>
<dd>
<p>When a vendor ships a component, it cannot assume that its
clients will not access it with multiple threads concurrently. In
fact, the only safe assumption the vendor can make is that the
component will be accessed by multiple threads. As a result, the
components must be thread-safe and must be equipped with
synchronization locks. However, if an application developer is
building an application by aggregating multiple components from
multiple vendors, the introduction of multiple locks renders the
application deadlock-prone. Avoiding the deadlocks couples the
application and the components.</p>
</dd>
<dt><em>Transactions</em></dt>
<dd>
<p>If multiple components are to participate in a single
transaction, the application that hosts them must coordinate the
transaction and flow the transaction from one component to the
next, which is a serious programming endeavor. This also introduces
coupling between the application and the components regarding the
nature of the transaction coordination.</p>
</dd>
<dt><em>Communication
protocols</em></dt>
<dd>
<p>If components are deployed across process or machine boundaries,
they are coupled to the details of the remote calls, the transport
protocol used, and its implications for the programming model
(e.g., in terms of reliability and security).</p>
</dd>
<dt><em>Communication
patterns</em></dt>
<dd>
<p>The components may be invoked synchronously or asynchronously,
and they may be connected or disconnected. A component may or may
not be able to be invoked in either one of these modes, and the
application must be aware of its exact preference. With COM and
.NET, developing asynchronous or even queued solutions was still
the responsibility of the developer, and any such custom solutions
were not only difficult to implement but also introduced coupling
between the solution and the components.</p>
</dd>
<dt><em>Versioning</em></dt>
<dd>
<p>Applications may be written against one version of a component
and yet encounter another in production. Both COM and .NET bear the
scars of DLL Hell (which occurs when the client at runtime is
trying to use a different, incompatible version of the component
than the one against which it was compiled), so both provide a
guarantee to the client: that the client would get at runtime
exactly the same component versions it was compiled against. This
conservative approach stifled innovation and the introduction of
new components. Both COM and .NET provided for custom
version-resolution policies, but doing so risked DLL Hell-like
symptoms. There was no built-in versioning tolerance, and dealing
robustly with versioning issues coupled the application to the
components it used.</p>
</dd>
<dt><em>Security</em></dt>
<dd>
<p>Components may need to authenticate and authorize their callers,
but how does a component know which security authority it should
use, or which user is a member of which role? Not only that, but a
component may want to ensure that the communication from its
clients is secure. That, of course, imposes certain restrictions on
the clients and in turn couples them to the security needs of the
component.</p>
</dd>
</dl>
<p><strong>Off-the-shelf plumbing</strong></p>
<p>In the abstract, interoperability, concurrency, transactions,
protocols, versioning, and security are the glue—the
plumbing—that holds any application together.</p>
<p>In a decent-sized application, the bulk of the development
effort and debugging time is spent on addressing such plumbing
issues, as opposed to focusing on business logic and features. To
make things even worse, since the end customer (or the development
manager) rarely cares about plumbing (as opposed to features), the
developers typically are not given adequate time to develop robust
plumbing. Instead, most handcrafted plumbing solutions are
proprietary (which hinders reuse, migration, and hiring) and are of
low quality, because most developers are not security or
synchronization experts and because they were not given the time
and resources to develop the plumbing properly.</p>
<p>The solution was to use ready-made plumbing that offered such
services to components. The first attempt at providing decent
off-the-shelf plumbing was MTS (Microsoft Transactions Server),
released in 1996. MTS offered support for much more than
transactions, including security, hosting, activation, instance
management, and synchronization. MTS was followed by J2EE (1998),
COM+ (2000), and .NET Enterprise Services (2002). All of these
application platforms provided adequate, decent plumbing (albeit
with varying degrees of ease of use), and applications that used
them had a far better ratio of business logic to plumbing. However,
by and large these technologies were not adopted on a large scale,
due to what I term the <em>boundary
problem</em>. Few systems are an island; most have to
interact and interoperate with other systems. If the other system
doesn't use the same plumbing, you cannot interoperate smoothly.
For example, there is no way of propagating a COM+ transaction to a
J2EE component. As a result, when crossing the system boundary, a
component (say, component A) had to dumb down its interaction to
the (not so large) common denominator between the two platforms.
But what about component B, next to component A? As far as B was
concerned, the component it interacted with (A) did not speak its
flavor of the plumbing, so B also had to be dumbed down. As a
result, system boundaries tended to creep from the outside inward,
preventing the ubiquitous use of off-the-shelf plumbing.
Technologies like Enterprise Services and J2EE were useful, but
they were useful in isolation.</p>
<p><strong><a name="serviceorientation" id="serviceorientation">Service-Orientation</a></strong></p>
<p>If you examine the brief history of software engineering just
outlined, you'll notice a pattern: every new methodology and
technology incorporates the benefits of its preceding technology
and improves on the deficiencies of the preceding technology.
However, every new generation also introduces new challenges.
Therefore, I say that <em>modern software
engineering is the ongoing refinement of the ever-increasing
degrees of decoupling</em>.</p>
<p>Put differently, coupling is bad, but coupling is unavoidable.
An absolutely decoupled application would be useless, because it
would add no value. Developers can only add value by coupling
things together. Indeed, the very act of writing code is coupling
one thing to another. The real question is how to wisely choose
what to be coupled to. I believe there are two types of coupling,
good and bad. Good coupling is business-level coupling. Developers
add value by implementing a system use case or a feature, by
coupling software functionality together. Bad coupling is anything
to do with writing plumbing. What was wrong with .NET and COM was
not the concept; it was the fact that developers could not rely on
off-the-shelf plumbing and still had to write so much of it
themselves. The real solution is not just off-the-shelf plumbing,
but rather <em>standard</em>
off-the-shelf plumbing. If the plumbing is standard, the boundary
problem goes away, and applications can utilize ready-made
plumbing. However, all technologies (.NET, Java, etc.) use the
client thread to jump into the object. How can you possibly take a
.NET thread and give it to a Java object? The solution is to avoid
call-stack invocation and instead to use message exchange. The
technology vendors can standardize the format of the message and
agree on ways to represent transactions, security credentials, and
so on. When the message is received by the other side, the
implementation of the plumbing there will convert the message to a
native call (on a .NET or a Java thread) and proceed to call the
object. Consequently, any attempt to standardize the plumbing has
to be message-based.</p>
<p>And so, recognizing the problems of the past, in the late 2000s
the service-oriented methodology has emerged as the answer to the
shortcomings of component-orientation. In a service-oriented
application, developers focus on writing business logic and expose
that logic via interchangeable, interoperable service endpoints.
Clients consume those endpoints (not the service code, or its
packaging). The interaction between the clients and the service
endpoint is based on a standard message exchange, and the service
publishes some standard metadata describing what exactly it can do
and how clients should invoke operations on it. The metadata is the
service equivalent of the C++ header file, the COM type library, or
the .NET assembly metadata, yet it contains not just operation
metadata (such as methods and parameters) but also plumbing
metadata. Incompatible clients—that is, clients that are
incompatible with the plumbing expectations of the
object—cannot call it, since the call will be denied by the
platform. This is an extension of the object- and
component-oriented compile-time notion that a client that is
incompatible with an object's metadata cannot call it. Demanding
compatibility with the plumbing (on top of the operations) is
paramount. Otherwise, the object must always check on every call
that the client meets its expectations in terms of security,
transactions, reliability and so on, and thus the object invariably
ends up infused with plumbing. Not only that, but the service's
endpoint is reusable by any client compatible with its interaction
constraints (such as synchronous, transacted, and secure
communication), regardless of the client's implementation
technology.</p>
<p>In many respects, a service is the natural evolution of the
component, just as the component was the natural evolution of the
object, which was the natural evolution of the function.
Service-orientation is, to the best of our knowledge as an
industry, the correct way to build maintainable, robust, and secure
applications.</p>
<p>The result of improving on the deficiencies of
component-orientation (i.e., classic .NET) is that when developing
a service-oriented application, you decouple the service code from
the technology and platform used by the client from many of the
concurrency management issues, from transaction propagation and
management, and from communication reliability, protocols, and
patterns. By and large, securing the transfer of the message itself
from the client to the service is also outside the scope of the
service, and so is authenticating the caller. The service may still
do its own local authorization, however, if the requirements so
dictate. Similarly, as long as the endpoint supports the contract
the client expects, the client does not care about the version of
the service. There are also tolerances built into the standards to
deal with versioning tolerance of the data passed between the
client and the service.</p>
<p><strong><a name="benefitsofserviceorientation" id="benefits_of_serviceorientation">Benefits of
Service-Orientation</a></strong></p>
<p>Service-orientation yields maintainable applications because the
applications are decoupled on the correct aspects. As the plumbing
evolves, the application remains unaffected. A service-oriented
application is robust because the developers can use available,
proven, and tested plumbing, and the developers are more productive
because they get to spend more of the cycle time on the features
rather than the plumbing. This is the true value proposition of
service-orientation: enabling developers to extract the plumbing
from their code and invest more in the business logic and the
required features.</p>
<p>The many other hailed benefits, such as cross-technology
interoperability, are merely a manifestation of the core benefit.
You can certainly interoperate without resorting to services, as
was the practice until service-orientation. The difference is that
with ready-made plumbing you rely on the plumbing to provide the
interoperability for you.</p>
<p>When you write a service, you usually do not care which platform
the client executes on—that is immaterial, which is the whole
point of seamless interoperability. However, a service-oriented
application caters to much more than interoperability. It enables
developers to cross boundaries. One type of boundary is the
technology and platform, and crossing that boundary is what
interoperability is all about. But other boundaries may exist
between the client and the service, such as security and trust
boundaries, geographical boundaries, organizational boundaries,
timeline boundaries, transaction boundaries, and even business
model boundaries. Seamlessly crossing each of these boundaries is
possible because of the standard message-based interaction. For
example, there are standards for how to secure messages and
establish a secure interaction between the client and the service,
even though both may reside in domains (or sites) that have no
direct trust relationship. There is also a standard that enables
the transaction manager on the client side to flow the transaction
to the transaction manager on the service side, and have the
service participate in that transaction, even though the two
transaction managers never enlist in each other's transactions
directly.</p>
<p>I believe that every application should be service-oriented, not
just Enterprise applications that require interoperability and
scalability. Writing plumbing in any type of application is wrong,
constituting a waste of your time, effort, and budget, resulting in
degradation of quality. Just as with .NET every application was
component-oriented (which was not so easy to do with COM alone) and
with C++ every application was object-oriented (which was not so
easy to do with C alone), when using WCF, every application should
be service-oriented.</p>
<p><strong><a name="serviceorientedapplications" id="serviceorientedapplications">Service-Oriented
Applications</a></strong></p>
<p>A <em>service</em> is a unit of
functionality exposed to the world over standard plumbing. A
<em>service-oriented application</em>
is simply the aggregation of services into a single logical,
cohesive application, much as an
object-oriented application is the aggregation of objects.</p>
<p>The application itself may expose the aggregate as a new
service, just as an object can be composed of smaller objects.</p>
<p>Inside services, developers still use concepts such as specific
programming languages, versions, technologies and frameworks,
operating systems, APIs, and so on. However, between services you
have the standard messages and protocols, contracts, and metadata
exchange.</p>
<p>The various services in an application can be all in the same
location or be distributed across an intranet or the Internet, and
they may come from multiple vendors and be developed across a range
of platforms and technologies, versioned independently, and even
execute on different timelines. All of those plumbing aspects are
hidden from the clients in the application interacting with the
services. The clients send the standard messages to the services,
and the plumbing at both ends marshals away the differences between
the clients and the services by converting the messages to and from
the neutral wire representation.</p>
<p><strong><a name="tenetsandprinciples" id="tenetsandprinciples">Tenets and Principles</a></strong></p>
<p>The service-oriented methodology governs what happens in the
space between services. There is a small
set of principles and best practices for building service-oriented
applications, referred to as the <em>tenets
of service-oriented architecture</em>:</p>
<dl>
<dt><em>Service
boundaries are explicit</em></dt>
<dd>
<p>Any service is always confined behind boundaries, such as
technology and location. The service should not make the nature of
these boundaries known to its clients by exposing contracts and
data types that betray such details. Adhering to this tenet will
make aspects such as location and technology irrelevant. A
different way of thinking about this tenet is that the more the
client knows about the implementation of the service, the more the
client is coupled to the service. To minimize the potential for
coupling, the service has to explicitly expose functionality, and
only operations (or data contracts) that are explicitly exposed
will be shared with the client. Everything else is encapsulated.
Service-oriented technologies should adopt an "opt-out by default"
programming model, and expose only those things explicitly
opted-in. This tenet is the modern incarnation of the old
object-oriented adage that the application should maximize
encapsulation and information hiding.</p>
</dd>
<dt><em>Services are
autonomous</em></dt>
<dd>
<p>A service should need nothing from its clients or other
services. The service should be operated and versioned
independently from the clients, enabling it to evolve separately
from them. The service should also be secured independently, so it
can protect itself and the messages sent to it regardless of the
degree to which the client uses security. Doing this (besides being
common sense) further decouples the client and the service.</p>
</dd>
<dt><em>Services share
operational contracts and data schema, not type-specific
metadata</em></dt>
<dd>
<p>What the service decides to expose across its boundary should be
type-neutral. The service must be able to convert its native data
types to and from some neutral representation and should not share
indigenous, technology-specific things such as its assembly version
number or its type. In addition, the service should not let its
client know about local implementation details such as its instance
management mode or its concurrency management mode. The service
should only expose logical operations. How the service goes about
implementing those operations and how it behaves should not be
disclosed to the client.</p>
</dd>
<dt><em>Services are
compatible based on policy</em></dt>
<dd>
<p>The service should publish a policy indicating what it can do
and how clients can interact with it. Any access constraints
expressed in the policy (such as the need for reliable
communication) should be separate from the service implementation
details. Put differently, the service must be able to express, in a
standard representation of policy, what it does and how clients
should communicate with it. Being unable to express such a policy
indicates poor service design. Note that a non-public service may
not actually publish any such policy. This tenet simply implies
that the service should be able to publish a policy if
necessary.</p>
</dd>
</dl>
<p><strong><a name="practicalprinciples" id="practicalprinciples">Practical Principles</a></strong></p>
<p>Well-designed applications should try to maximize adherence to
the tenets just listed. However, those tenets are very abstract,
and how they are supported is largely a product of the technology
used to develop and consume the services, and of the design of the
services. Consequently, just as not all code written in C++ is
fully object-oriented, not all WCF applications may fully comply
with the basic tenets just described. I therefore supplement those
tenets with a set of more down-to-earth practical principles:</p>
<dl>
<dt><em>Services are
secure</em></dt>
<dd>
<p>A service and its clients must use secure communication. At the
very least, the transfer of messages from the clients to the
service must be secured, and the clients must have a way of
authenticating the service. The clients may also provide their
credentials in the message so that the service can authenticate and
authorize them.</p>
</dd>
<dt><em>Services leave
the system in a consistent state</em></dt>
<dd>
<p>Conditions such as partially succeeding in executing the
client's request are forbidden. All resources the service accesses
must be in a consistent state after the client's call. If an error
occurs the system state should not be only partially affected, and
the service should not require the help of its clients to recover
the system back to a consistent state after an error.</p>
</dd>
<dt><em>Services are
thread-safe</em></dt>
<dd>
<p>The service must be designed so that it can sustain concurrent
access from multiple clients. The service should also be able to
handle causality and logical thread reentrancy.</p>
</dd>
<dt><em>Services are
reliable</em></dt>
<dd>
<p>If the client calls a service, the client will always know in a
deterministic manner whether the service received the message.
In-order processing of messages is optional.</p>
</dd>
<dt><em>Services are
robust</em></dt>
<dd>
<p>The service should isolate its faults, preventing them from
taking it down (or taking down any other services). The service
should not require clients to alter their behavior according to the
type of error the service has encountered. This helps to decouple
the clients from the service on the error-handling dimension.</p>
</dd>
</dl>
<p><strong><a name="optionalprinciples" id="optionalprinciples">Optional Principles</a></strong></p>
<p>While I view the practical principles as mandatory, there is
also a set of optional principles that may not be required by all
applications (although adhering to them as well is usually a good
idea):</p>
<dl>
<dt><em>Services are
interoperable</em></dt>
<dd>
<p>The service should be designed so that any client, regardless of
its technology, can call it.</p>
</dd>
<dt><em>Services are
scale-invariant</em></dt>
<dd>
<p>It should be possible to use the same service code regardless of
the number of clients and the load on the service. This will
grossly simplify the cost of ownership of the service as the system
grows and allow different deployment scenarios.</p>
</dd>
<dt><em>Services are
available</em></dt>
<dd>
<p>The service should always be able to accept clients' requests
and should have no downtime. Otherwise, if the service has periods
of unavailability the client needs to accommodate them, which in
turn introduces coupling.</p>
</dd>
<dt><em>Services are
responsive</em></dt>
<dd>
<p>The client should not have to wait long for the service to start
processing its request. If the service is unresponsive the client
needs to plan for that, which in turn introduces coupling.</p>
</dd>
<dt><em>Services are
disciplined</em></dt>
<dd>
<p>The service should not block the client for long. The service
may perform lengthy processing, but only as long as it does not
block the client. Otherwise, the client will need to accommodate
that, which in turn introduces coupling.</p>
</dd>
</dl>
<p><strong><a name="whatsnext" id="whatsnext">What's Next?</a></strong></p>
<p>Since service-oriented frameworks provide off-the-shelf plumbing
for connecting services together, the more granular those services
are, the more use the application can make of this infrastructure,
and the less plumbing the developers have to write. Taken to the
ultimate conclusion, every class and primitive should be a service,
to maximize the use of the ready-made plumbing and to avoid
handcrafting plumbing. This, in theory, will enable effortlessly
transactional integers, secure strings, and reliable classes. But
in practice, is that viable? Can .NET support it? Will future
platforms offer this option?</p>
<p>I believe that as time goes by and service-oriented technologies
evolve, the industry will see the service boundary pushed further
and further inward, making services more and more granular, until
the most primitive building blocks will be services. This would be
in line with the historical trend of trading performance for
productivity via methodology and abstraction. As an industry, we
have always traded performance for productivity. .NET, where every
class is treated as a binary component, is slower than COM, but the
productivity benefit justifies this. COM itself is orders of
magnitude slower than C++, yet developers opted for COM to address
the problems of object-orientation. C++ is likewise slower than C,
but it did offer the crucial abstractions of objects over
functions. C in turn is a lot slower than raw assembly language,
but the productivity gains it offered more than made up for
that.</p>
<p>My benchmarks show that WCF can easily sustain hundreds of calls
per second per class, making it adequate for the vast majority of
business applications. While of course there is a performance hit
for doing so, the productivity gains more than compensate, and
historically, it is evident that this is a trade-off you should
make. WCF does have detrimental overhead, but it's to do with
ownership, not performance (which is adequate). Imagine a
decent-sized application with a few hundred classes, each of which
you wish to treat as a service. What would the <code class=
"literal">Main( )</code> method of such an application look like,
with hundreds of service host instances to be instantiated, opened,
and closed? Such a <code class="literal">Main( )</code> method
would be unmaintainable. Similarly, would a config file with many
hundreds of service and client endpoint declarations be
workable?</p>
<p>The truth is that in practical terms, WCF cannot support (out of
the box) such large-scale granular use. It is designed to be used
between applications and across layers in the same application, not
in every class. Just as COM had to use C++ and Windows, WCF is
bolted on top of .NET. The language used (C# or Visual Basic) is
merely component-oriented, not service-oriented, and the platform
(.NET) is component-oriented, not service-oriented. What is
required is a service-oriented platform, where the basic constructs
are not classes but services. The syntax may still define a class,
but it will be a service, just as every class in .NET is a binary
component, very different from a C++ class. The service-oriented
platform will support a config-less metadata repository, much like
.NET generalized the type library and IDL concepts of COM. In this
regard, WCF is merely a stopgap, a bridging technology between the
world of components and the world of service (much like ATL once
bridged the world of objects and C++ with the world of components,
until .NET stepped in to provide native support for components at
the class and primitive level).</p>
<p><strong><a name="aserviceorientedplatform" id="aserviceorientedplatform">A Service-Oriented Platform</a></strong></p>
<p>If you take a wider view, every new idea in software engineering
is implemented in three waves: first there is the methodology, then
the technology, then the platform.</p>
<p>For example, object-orientation as a methodology originated in
the late '70s. The top C developers at the time did develop
object-oriented applications, but this required manually passing
state handles between functions and managing tables of function
pointers for inheritance. Clearly, such practices required a level
of conviction and skills that only very few had. With the advent of
C++ in the early '80s came the technology, allowing every developer
to write object-oriented applications. But C++ on its own was
sterile, and required class libraries. Many developers wrote their
own, which of course was not productive or scalable. The
development of frameworks such as MFC as an object-oriented
platform, with types ranging from strings to windows, is what
liberated C++ and enabled it to take off.</p>
<p>Similarly, take component-orientation: in the first half of the
'90s, developers who wanted to use COM had to write class factories
and implement <code class="literal">IUnknown</code>, and concoct
registry scripts and DLL entries. As a methodology, COM was just
inaccessible. Then ATL came along, and this technology enabled
developers to expose mere C++ classes as binary components. But the
programming model was still too complex, since Windows knew nothing
about COM, and the language was still object-oriented, lacking
support for basic constructs such as interfaces. .NET as a
component-oriented runtime provided the missing platform support
for components at the class, primitive, language, and class library
level.</p>
<p>Service-orientation emerged as a methodology in the early 2000s,
but at the time it was practically impossible to execute. With WCF,
developers can expose mere classes as services, but the ownership
overhead prevents widespread and granular use. I do not have a
crystal ball, but I see no reason why the waves of
methodology/technology/platform should stop now. Extrapolating from
the last 30–40 years of software engineering, we are clearly
missing a service-oriented platform. I believe the next generation
of technologies from Microsoft will provide just that.</p>
<p><strong>Every class as a service</strong></p>
<p>Until we have a service-oriented platform, must we suffer the
consequences of either unacceptable ownership overhead (granular
use of WCF) or productivity and quality penalties (handcrafted
custom plumbing)?</p>
<p>Chapter 1, <i>WCF Essentials</i> introduces my <code class=
"literal">InProcFactory</code> class, which lets you instantiate a
service class over WCF:</p>
<a name="I_programlisting_d1e36928" id=
"I_programlisting_d1e36928"></a>
<pre class="programlisting">
public static class InProcFactory
{
public static I CreateInstance<S,I>( ) where I : class
where S : I;
public static void CloseProxy<I>(I instance) where I : class;
//More members
}
</pre>
<p>When using <code class="literal">InProcFactory</code>, you
utilize WCF at the class level without ever resorting to explicitly
managing the host or having client or service config files:</p>
<a name="I_programlisting_d1e36935" id=
"I_programlisting_d1e36935"></a>
<pre class="programlisting">
[ServiceContract]
interface IMyContract
{...}
class MyService : IMyContract
{...}
IMyContract proxy = InProcFactory.CreateInstance<MyService,IMyContract>( );
proxy.MyMethod( );
InProcFactory.CloseProxy(proxy);
</pre>
<p>This line:</p>
<a name="I_programlisting_d1e36939" id=
"I_programlisting_d1e36939"></a>
<pre class="programlisting">
IMyContract proxy = InProcFactory.CreateInstance<<strong class=
"userinput"><code>MyService</code></strong>,IMyContract>( );
</pre>
<p>is syntactically equivalent to the C# way of instantiating a
class type:</p>
<pre class="programlisting">
IMyContract proxy = new <strong class=
"userinput"><code>MyService</code></strong>( );
</pre>
<p>The difference syntax-wise is that with C#, there is no need to
specify the queried interfaces since the compiler will examine the
class, see if it supports the interface, and implicitly cast the
class to the assigned interface variable. As it lacks compiler
support for services, <code class="literal">InProcFactory</code>
requires you to specify the required contract.</p>
<p>However, the big difference between instantiating the class over
WCF rather than C# is that when you do this all the powerful WCF
features described in the rest of this book kick in: call timeout,
encrypted calls, authentication, identity propagation, transaction
propagation, transaction voting, instance management, error
masking, channel faulting, fault isolation, buffering and
throttling, data versioning tolerance, synchronization,
synchronization context affinity, and more. With very little
effort, you can also add tracing and logging, authorization,
security audits, profiling and instrumentation, and durability, or
intercept the calls and add many degrees of extensibility and
customization.</p>
<p><code class="literal">InProcFactory</code> lets you enjoy the
benefits of WCF without suffering the ownership overhead. To me,
<code class="literal">InProcFactory</code> is more than a useful
utility—it is a glimpse of the future.</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/457694139" height="1" width="1"/>
https://www.oreillynet.com/pub/au/1886
text
https://fyi.oreilly.com/9780596521301_little.gif
https://fyi.oreilly.com/2008/11/juval-lowy-explains-service-or.html
Taking Charge of Your New Canon Digital Rebel--Tips, Warnings, and Reminders
tag:fyi.oreilly.com,2008://48.34145
2008-11-14T21:10:16Z
2008-11-15T00:05:59Z
Two new books from O'Reilly's Companion Series offer a complete photography class, tailored specifically for folks using Canon's new Digital Rebel cameras. Both--The Canon EOS Digital Rebel XSi/450D Companion and The Canon EOS Digital Rebel XS/1000D Companion--are by producer and videographer Ben Long. In each of his handy pocket guides, Ben not only provides a detailed one-stop camera manual but he also walks you through all the basic photography theories that apply to any camera. And here Ben provides tips, warnings, and reminders from the books for using the XS cameras (which are applicable to most DSLRs). Read on to learn more.
Sara Peyton
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://fyi.oreilly.com/assets_c/2008/11/FIXED9780596154523_lrg.html" onclick="window.open('https://fyi.oreilly.com/assets_c/2008/11/FIXED9780596154523_lrg.html','popup','width=151,height=233,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="https://fyi.oreilly.com/assets_c/2008/11/FIXED9780596154523_lrg-thumb-150x231.jpg" width="150" height="231" alt="" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a></span>Two new books from O'Reilly's Companion Series offer a complete photography class, tailored specifically for folks using Canon's new Digital Rebel cameras. Both--<a href="https://oreilly.com/catalog/9780596520861/index.html">The Canon EOS Digital Rebel XSi/450D Companion</a> and <a href="https://oreilly.com/catalog/9780596154523/">The Canon EOS Digital Rebel XS/1000D Companion</a>--are by producer and videographer Ben Long. In each of his handy pocket guides, Ben not only provides a detailed one-stop camera manual but he also walks you through all the basic photography theories that apply to any camera. And here Ben provides tips, warnings, and reminders from the books for using the XS cameras (which are applicable to most DSLRs). Read on to learn more.</p>
<p><strong>Tip: If the Viewfinder Is Not Sharp</strong><br />
If you wear glasses and like to remove them when shooting, you can use the diopter control, the small knob next to the viewfinder, to compensate for some near- or farsightedness. Turn the knob until the nine autofocus boxes inside the viewfinder are sharp. Note that the diopter may not be able to completely compensate for extremely bad vision. Also, you'll have to change it back if you put your glasses back on. If the viewfinder ever inexplicably goes out of focus, it might just be that you bumped the diopter knob. Turn it until focus is restored.</p>
<p><strong>Reminder: Night Portraits Require Still Subjects</strong><br />
When shooting with Night Portrait mode, the flash will fire, but the camera's shutter will stay open for a bit. So, it's important to tell your subject not to move until after you say so.</p>
<p><strong>Warning: Do Not Remove Card When the Light Is Lit</strong><br />
Wait until the camera is completely finished writing before removing the card.If you remove the card before the write is completed, you not only will lose the images that are being written, but you might also corrupt images that have already been stored on the card.</p>
<p><strong>Warning: Manage Those Body Caps</strong><br />
Every lens has a body cap that covers the end of the lens that attaches to the camera. Unfortunately, a lot of people stick these caps in their pocket, where they get covered with lint, and then put the cap directly onto the lens when they're changing lenses. This is a great way to get dust and lint on your lens, and that debris can get transferred directly to your image sensor when you mount the lens on your camera. So, clean those body caps before you put them back on your lens!</p>
<p><strong>Reminder: All Reviewing in Moderation</strong><br />
Immediate image review is one of the great advantages of digital photography. However, the instant image review can also be a distraction if you obsessively look at every image after you shoot it. When you're out shooting, you want to be concentrating on the world around you, not on the back of your camera. Image review is great when you want to review a composition you've just shot, and it can be essential when you're in a tricky exposure situation and need to double-check your exposure decisions. We'll discuss exposure evaluation in more detail later.</p>
<p><strong>Tip: Turn Off Preview as a Courtesy</strong><br />
You might want to turn off the image review if you're shooting in a low-light situation like a concert. Because the screen can cast an obtrusive light, you'll have a lower profile if you deactivate the image review.</p>
<p><strong>Tip: If Your Computer Can't Read the Card</strong><br />
The Erase All Images command can sometimes result in directory problems on the card that can confuse some operating systems. If you find that you're consistently having trouble reading a card in your computer, even after formatting, then you might want to consider doing a low-level format. Choose the Format command as normal and then press the Erase button to check the Low Level Format checkbox. Select OK to start the low-level format.</p>
<p><strong>Reminder: It's Always in the Eyes</strong><br />
When shooting people, remember that the most important thing to consider in a portrait is the eyes. As long as the eyes are in focus, it probably won't matter if there's a little softness in the rest of the image. So, if you're using autofocus point selection, make sure the XS indicates that it has the eyes in focus. Or, switch to center-point autofocus, put the center focus point on the subject's eyes, autofocus, and then reframe. This will ensure that the eyes are sharp.</p>
<p><strong>Reminder: Steady As She Goes</strong><br />
When trying to hold the camera steady--which is especially important when using a slow shutter speed--remember to gently squeeze the trigger. Use the posture tips we discussed in Chapter 1, and don't hold your breath. Holding your breath actually makes you shakier. If possible, try to find something to lean against or that you can use to steady the camera.</p>
<p><strong>Reminder: Don't Forget to Reset Your Camera Settings</strong><br />
The XS remembers many of the settings you make, even after you turn off the camera. So, if you select a white balance preset or a high ISO, shoot a bunch, and then turn off the camera, when you come back, you'll still be using that white balance and ISO. So, it's very important to check your settings when you turn on the camera. You don't want to head out into bright daylight after a late night of shooting in a dimly lit club with weird white balance. Ideally, you should set each setting back to something more normal after you use it, but this can be hard to remember to do. Instead, get in the habit of double-checking your settings every time you turn the camera on. Look over the status screen on the back of the camera; then press Menu and then DISP to view additional status information.</p>
<p><strong>Warning: Don't Use Evaluative Metering When Focusing and Reframing</strong><br />
Earlier, you saw the technique of using a single, centered focus spot to focus on an object and then reframing your scene. When using this technique, you might find that you get better results if you don't use evaluative metering. If you're using evaluative metering, then areas of the frame that won't be in your shot will be factored into the camera's final metering. Most of the time, this won't matter, but in a scene with high dynamic range--a dark foreground and bright sky, for example--it could get you into trouble. Instead, if you want to use evaluative metering, after focusing, set your lens to Manual focus to lock focus, and then frame your shot as desired and meter.</p>
<p><strong>Warning: Pay Attention to Shutter Speed</strong><br />
Just because you now have complete control of aperture, and just because the camera is choosing a shutter speed for you, doesn't mean that you don't have to think about shutter speed at all. You still need to pay attention to the handheld shutter speed rule. If you pick an aperture that yields a shutter speed that's too slow for handholding or motion stopping, then you may end up with an annoyingly blurry image. The XS will display its selected shutter speed any time you meter.</p>
<p><strong>Warning: Beware of Hea</strong>t<br />
Noise levels in your high ISO images will increase as the camera gets warmer. It takes a fair amount of heat to create a noticeable change in noise, and the most significant source of heat is usually the camera itself. Try to avoid Live View and extensive use of the LCD screen when shooting high ISO images, because the LCD screen can heat up the camera significantly. Also, don't try to cool the camera by putting it in a refrigerator. The sudden change in temperature can damage internal components.</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/453420490" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2831
text
https://fyi.oreilly.com/FIXED9780596154523_lrg.jpg
https://fyi.oreilly.com/2008/11/taking-charge-of-your-new-digi.html
Derrick Story's Recipes for Brightening a Smile and Blotting Out a Blemish
tag:fyi.oreilly.com,2008://48.34105
2008-11-12T16:20:07Z
2008-11-13T00:08:13Z
Beauty may be skin deep, but most of us hope to look our best in photos. And the following excerpt from Derrick Story's handy new book, The Photoshop CS4 Companion for Photographers, offers a digital makeover of sorts--recipes for brightening a toothy grin and eliminating a skin blotch or two. "Even though you may not be the photographer to the stars, there will be times when you need to touch up a portrait," notes Derrick, whose new guidebook includes 18 easy-to-follow recipes for perfecting images. But remember, when it comes to digital enhancements Derrick offers this caution, "Regardless of which recipe you're working with at any given moment remember that less is more when retouching portraits." Read on to learn more.
Sara Peyton
Beauty may be skin deep, but most of us hope to look our best in photos. And the following excerpt from Derrick Story's handy new book, <a href="https://oreilly.com/catalog/9780596521936/">The Photoshop CS4 Companion for Photographers</a>, offers a digital makeover of sorts--recipes for brightening a toothy grin and eliminating a skin blotch or two. "Even though you may not be the photographer to the stars, there will be times when you need to touch up a portrait," notes Derrick, whose new guidebook includes 18 easy-to-follow recipes for perfecting images. But remember, when it comes to digital enhancements Derrick offers this caution, "Regardless of which recipe you're working with at any given moment remember that less is more when retouching portraits." Read on to learn more.
<p><strong>From Chapter 7. Two Photoshop
Recipes for Photographers</strong></p>
<p>RECIPE 1: Brightening Teeth<p>
<p>A beautiful smile is both endearing and attractive. Here's how
to add a bit of sparkle to any cheerful expression.</p>
<ol type="1">
<li>
<p>Open the image and zoom to 100 percent so that you can get a
good look at the <a class="indexterm" id="idx-CHP-7-0454" name=
"idx-CHP-7-0454"></a>teeth.</p>
</li>
<li>
<p>Go to the Adjustments panel and select Hue/Saturation (it's in
the second row). Hold down the Option (Alt) key and drag the white
mask thumbnail to the Trash icon at the bottom of the Layers
panel.</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="psc_0701.png" src="https://fyi.oreilly.com/2008/11/11/psc_0701.png" width="324" height="168" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></span>
<br class="figure-break" /></li>
<li>
<p>Click the Targeted Adjustment icon (it appears as a hand
with a finger pointing upward) to select it. It turns into an
eyedropper when you hover your mouse over the teeth. Pick an area
of the tooth surface and then click and drag the dropper to the
left. It will desaturate the area you've sampled—in this
case, the teeth. Don't worry about the effect of this adjustment on
the rest of the image. Focus on the teeth until you like what you
see.</p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="psc_0702.png" src="https://fyi.oreilly.com/2008/11/11/psc_0702.png" width="324" height="239" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></span>
<br class="figure-break" /></li>
<li>
<p>Option/Alt-click the Layer Mask icon (at the bottom of the
palette). Photoshop will create a black layer mask thumbnail to the
right of your Hue/Saturation thumbnail. It will also temporarily
hide your adjustment.</p>
</li>
<li>
<p>Set the foreground color to white in the Tools Panel.</p>
</li>
<li>
<p>Click the Brush icon in the Tools palette or just press "B" to
get the Brush tool. Choose an appropriate brush size and paint the
teeth to let the adjustment show through. You
may want to use a soft-edged brush for a more natural look. You're
literally painting away the yellow coloration.</p>
<p class="title"><b>Paint on the tooth surface with your brush to
reveal the whitening effect.</b></p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="psc_0703.png" src="https://fyi.oreilly.com/2008/11/11/psc_0703.png" width="416" height="179" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></span>
<br class="figure-break" /></li>
<li>
<p>If you paint outside the lines and need to correct a mistake,
switch the foreground color to black (by pressing the X key) for
any touch-up work (black hides the adjustment).</p>
</li>
<li>
<p>Toggle the eyeball icon off and on in the adjustment layer to
check your work.</p>
</li>
<li>
<p>If you find that you were a little overzealous in your dental
work, resulting in ultra-bright teeth, you have a couple
of options. You can go to the Opacity slider and dial it down until
you get a more natural look. Or you can double-click the
Hue/Saturation thumbnail and play with the adjustments there.</p>
</li>
<li>
<p>Save the image as a layered PSD file and place it in the same
folder as the original. Open Bridge, select both images, and group
them together in a Stack.</p>
</li>
</ol>
<p class="title"><b>TIP: Recipe Variation</b></p>
<p>This technique is also excellent for brightening the whites of
the eyes and removing redness (ruddiness) from skin tones.</p>
<p><strong>RECIPE 2: Touching Up
Blemishes</strong></p>
<p>Even on portraits that don't need touch-ups, you may want to
remove a blemish or two. Often, this is all you need to do. And the
best part is, it's easy!</p>
<ol type="1">
<li>
<p>Create a duplicate of the background layer by choosing in the
Layers panel, and pressing ⌘-J (Ctrl-J) or choosing Layer
→ Duplicate Layer.</p>
</li>
<li>
<p>Select the Spot Healing brush from the Tools panel.</p>
</li>
<li>
<p>Select a brush diameter from the Control panel that is a little
larger than the blemish you want to remove. You also can use the
right and left bracket keys to change the brush diameter on the
fly.</p>
</li>
<li>
<p>Click the blemish once to remove it. If you don't like how
Photoshop corrects the imperfection, switch to the Healing brush,
and sample an area that you want to use to correct the blemish by
Option (Alt)-clicking. In the case of a portrait, look for a
skintone similar to the area you are correcting, and set that as
your sampling area.</p>
</li>
</ol>
<p class="title"><b>Choose the Spot Healing brush from the Tools
panel.</b></p>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="psc_0704.png" src="https://fyi.oreilly.com/2008/11/11/psc_0704.png" width="342" height="226" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></span>
<br class="figure-break" />
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/450884224" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2831
text
https://fyi.oreilly.com/derrick_story.jpg
https://fyi.oreilly.com/2008/11/photoshop-recipes.html
Relational Database Technology: A Crash Course
tag:fyi.oreilly.com,2008://48.34055
2008-11-06T23:13:56Z
2008-11-07T20:52:00Z
The following is an excerpt from the newly released Programming ASP.NET 3.5 by Jesse Liberty, Dan Maharry, and Dan Hurwitz. According to them, ASP.NET 3.5 is possibly the fastest, most efficient, most reliable, and best-supported way to create interactive web applications today. Combined with the development tools available from Microsoft (both free and commercial), it is incredibly easy to create websites that look great and perform well.
Kathryn Barrett
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="smallerASPcover.gif" src="https://fyi.oreilly.com/smallerASPcover.gif" width="173" height="227" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></span>The following is an excerpt from the newly released <a href="https://oreilly.com/catalog/9780596529567/"><strong>Programming ASP.NET 3.5</strong></a> by <a href="https://www.oreillynet.com/pub/au/239"><strong>Jesse Liberty</strong></a>, <a href="https://www.oreillynet.com/pub/au/3226"><strong>Dan Maharry</strong></a>, and <a href="https://www.oreillynet.com/pub/au/814"><strong>Dan Hurwitz</strong></a>. According to them, ASP.NET 3.5 is possibly the fastest, most efficient, most reliable, and best-supported way to create interactive web applications today. Combined with the development tools available from Microsoft (both free and commercial), it is incredibly easy to create websites that look great and perform well.
<div class="appendix" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<br />
<big><strong>Appendix B. Relational Database Technology: A Crash Course</strong></big>
</div>
</div>
</div>
<div class="toc">
<p><b>Table of Contents</b></p>
<dl>
<dt><span class="sect1"><a href=
"#tables_records_and_columns">Tables, Records, and
Columns</a></span></dt>
<dt><span class="sect1"><a href="#table_design">Table
Design</a></span></dt>
<dd>
<dl>
<dt><span class="sect2"><a href=
"#normalization">Normalization</a></span></dt>
<dt><span class="sect2"><a href=
"#declarative_referential_integrity">Declarative
Referential Integrity</a></span></dt>
</dl>
</dd>
<dt><span class="sect1"><a href="#sql">SQL</a></span></dt>
<dd>
<dl>
<dt><span class="sect2"><a href="#joining_tables">Joining
Tables</a></span></dt>
<dt><span class="sect2"><a href=
"#using_sql_to_manipulate_the_database">Using SQL to
Manipulate the Database</a></span></dt>
</dl>
</dd>
<dt><span class="sect1"><a href=
"#further_reference">Further Reference</a></span></dt>
</dl>
</div>
<p>You can use .NET to access data from any data source: relational
<a class="indexterm" name="idx-CHP-B-4633" id=
"idx-CHP-B-4633"></a>databases, object databases, flat files, and
text files. The vast majority of web applications, however, will
access data from a relational database such as SQL Server, Oracle,
or MySQL. Though we could certainly write an entire book on
<a class="indexterm" name="idx-CHP-B-4634" id=
"idx-CHP-B-4634"></a>relational databases and another on SQL, the
essentials of these technologies are not hard to understand.</p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title"><a name="tip-247" id="tip-247"></a><strong>Tip</strong></h3>
<p>All of the examples in this appendix assume you are working with
either SQL Server or SQL Server Express. Users of other relational
databases will find that the lessons learned here transfer well to
their environment, but be careful with applications such as Oracle,
MySQL, and Access that use a different variation of SQL.</p>
</div>
<p>A <span class="emphasis"><em>database</em></span> is a
repository of data. A <span class="emphasis"><em>relational
database</em></span> organizes your data into <a class="indexterm"
name="idx-CHP-B-4635" id="idx-CHP-B-4635"></a>tables that are
connected to one another by the data they contain. For example, one
table might contain a customer's information and a second table
might contain information about orders, and each order is owned by
an individual customer.</p>
<p>Similarly, you might have one table of cars and a second table
of car parts. Each part can be in one or more cars, and each car is
made up of many parts. Or you might have a table for bugs and a
table for developers. Each bug is owned by one developer, and each
developer has a list of bugs he owns.</p>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name=
"tables_records_and_columns" id=
"tables_records_and_columns"></a><big><strong>Tables, Records, and Columns</strong></big></h2>
</div>
</div>
</div>
<p>The principal division of a database is into <span class=
"emphasis"><em>tables</em></span>. Every table in a relational
database is organized into <a class="indexterm" name=
"idx-CHP-B-4636" id="idx-CHP-B-4636"></a>rows, where each row
represents a single record. The <a class="indexterm" name=
"idx-CHP-B-4637" id="idx-CHP-B-4637"></a>rows are organized into
<a class="indexterm" name="idx-CHP-B-4638" id=
"idx-CHP-B-4638"></a>columns. All the rows in a table have the same
column structure. For example, a <code class=
"literal">Customer</code> table might have columns for the
<code class="literal">customer ID</code> (the unique ID of the
customer placing the order), the name of the customer, the email
address of the customer, and so forth.<a class="indexterm" name=
"idx-CHP-B-4639" id="idx-CHP-B-4639"></a></p>
<p>It is common to make an analogy between tables and <a class=
"indexterm" name="idx-CHP-B-4640" id="idx-CHP-B-4640"></a>classes
and between rows and objects. The <code class=
"literal">Customer</code> table, for example, tells you a great
number of things about a customer, just as a <code class=
"literal">Customer</code> class does. Each row in the <code class=
"literal">Customer</code> table describes a particular customer,
much as an instance of the <code class="literal">Customer</code>
would do.</p>
<p>This analogy is compelling, but limited. Tables, like <a class=
"indexterm" name="idx-CHP-B-4641" id="idx-CHP-B-4641"></a>classes,
typically describe one logical entity and all of what you know
about that entity. The mapping isn't reflexive,
though—classes can contain properties that actually map
across several different tables. This is similar to the notion of
relationships between tables to ensure that consistent data in a
database is not reflected back as relationships between
classes.</p>
<p>One of the challenges facing an object-oriented programmer is
overcoming these and other <a class="indexterm" name=
"idx-CHP-B-4642" id="idx-CHP-B-4642"></a>design differences between
the object model on the one hand and the database model on the
other. Typically, the interface between the backend <a class=
"indexterm" name="idx-CHP-B-4643" id=
"idx-CHP-B-4643"></a>relational database and the objects in the
application is managed by creating a database interface layer of
objects that negotiate between the creation of objects and the
storage of <a class="indexterm" name="idx-CHP-B-4644" id=
"idx-CHP-B-4644"></a>information in the database tables, all
created by hand. The past few years, however, have seen a number of
products known as <span class="emphasis"><em>object-relational
mappers</em></span>, which can scan the structure of a database
and, with a little help from the developer, produce a set of
classes which represent the entities and relationships and make
that transition between your code and your database that much
easier. Language Integrated Query (LINQ), covered in Chapter 10,
<i>Presenting LINQ</i>, actually includes two <a class=
"indexterm" name="idx-CHP-B-4645" id=
"idx-CHP-B-4645"></a>object-relational mappers:<a class="indexterm"
name="idx-CHP-B-4646" id="idx-CHP-B-4646"></a></p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>LINQ to SQL looks after the simpler case where your classes
generally have a one-to-one relationship with tables in the
database.</p>
</li>
<li>
<p>LINQ to Entities (available with VS2008 Service Pack 1) deals
with the more enterprise-level case where your classes generally
map to information in more than one table in your database.</p>
</li>
</ul>
</div>
<p>This distinction is not a hard and fast rule by any means, but
it does make the general distinction between the two that Microsoft
is using.</p>
<p>Several other mappers are also available, including:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p><a class="indexterm" name="idx-CHP-B-4647" id=
"idx-CHP-B-4647"></a>NHibernate (<a href=
"https://www.nhibernate.org" target=
"_top">https://www.nhibernate.org</a>)</p>
</li>
<li>
<p><a class="indexterm" name="idx-CHP-B-4648" id=
"idx-CHP-B-4648"></a>SubSonic (<a href=
"https://www.codeplex.com/subsonic" target=
"_top">https://www.codeplex.com/subsonic</a>)</p>
</li>
</ul>
</div>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="table_design" id=
"table_design"></a><big><strong>Table Design</strong></big></h2>
</div>
</div>
</div>
<p>To understand the issues in table design, consider a database
for recording orders (such as the AdventureWorksLT database used in
this book). You need to know who placed each order, and it would be
useful to know the email address, phone number, and other
identifying information about each person as well.<a class=
"indexterm" name="idx-CHP-B-4649" id="idx-CHP-B-4649"></a></p>
<p>You can imagine a form in which you display details about a
given order, and in that detail page you offer the email address
and phone number of the customer so the salesperson working on the
order can contact that customer in case of a delay or stock
issue.</p>
<p>You could store the identifying information with each order in
an <code class="literal">Orders</code> table (named <code class=
"literal">SalesOrderHeader</code> in the database, for reasons
we'll mention in a minute), but that would be inefficient. If John
Doe placed 50 orders, you'd rather not repeat John Doe's email
address and phone number in 50 records. It's also a data
maintenance nightmare. If John Doe changes his email address and
phone number, you'd have to make the change in 50 places.</p>
<p>Instead, the customer details are kept in a second table, called
<code class="literal">Customer</code>, in which each row represents
a single customer. In the <code class="literal">Customer</code>
table, there will be a column for the <code class=
"literal">CustomerID</code>. Each customer will have a unique ID,
and that field will be marked as the <span class=
"emphasis"><em>primary key</em></span> for the <code class=
"literal">Customer</code> table. A primary key is the column or
combination of columns that uniquely identifies a record in a given
table.</p>
<p>The <code class="literal">Orders</code> table will use the
<code class="literal">PersonID</code> column as a <span class=
"emphasis"><em>foreign key</em></span>. A foreign key is a column
(or combination of columns) that is a primary (or otherwise unique)
key from a different table. The <code class="literal">Orders</code>
table uses the <code class="literal">CustomerID</code>, which is
the primary key in <code class="literal">Customer</code>, to
identify which person placed the order. If you need to determine
the email address for that person, you can use the <code class=
"literal">CustomerID</code> to look up the <code class=
"literal">Customer</code> record in the <code class=
"literal">Customer</code> table and that will give you all the
detailed information about that person.</p>
<p>By "factoring out" the details of the person's address into a
<code class="literal">Customer</code> table, you reduce the
redundant information in each <code class="literal">Order</code>
record. This process of taking out redundant information from your
tables is called <span class=
"emphasis"><em>normalization</em></span>.<a class="indexterm" name=
"idx-CHP-B-4650" id="idx-CHP-B-4650"></a></p>
<p>The same process explains why an order is actually stored in two
tables—<code class="literal">SalesOrderDetail</code> and
<code class="literal">SalesOrderHeader</code>—rather than
one. An order can be split into individual requests for products
and so the <code class="literal">SalesOrderHeader</code> table
stores the details of the order as a whole—when it is due,
when it was shipped, how much it cost in total, and so
on—whereas rows in the <code class=
"literal">SalesOrderDetail</code> table contain details for each
separate product in the order.</p>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="normalization" id=
"normalization"></a><strong>Normalization</strong></h3>
</div>
</div>
</div>
<p><a class="indexterm" name="idx-CHP-B-4651" id=
"idx-CHP-B-4651"></a>Normalization makes your use of the database
more efficient, and it reduces the likelihood of data corruption.
If you kept the customer's email address in the <code class=
"literal">Customer</code> table and in the <code class=
"literal">SalesOrderHeader</code> table, you would run the risk
that a change in one table might not be reflected in the other.
Thus, if you changed the person's email address in the <code class=
"literal">Customer</code> table, that change might not be reflected
in every row in the <code class="literal">SalesOrderHeader</code>
table (or it would be a lot of work to make sure that it was
reflected). By keeping only the <code class=
"literal">CustomerID</code> in <code class=
"literal">SalesOrderHeader</code>, you are free to change the email
address or other personal information in <code class=
"literal">Customer</code>, and the change will automatically be
reflected for each order.<a class="indexterm" name="idx-CHP-B-4652"
id="idx-CHP-B-4652"></a></p>
<p>Just as Visual Basic and C# programmers want the compiler to
catch bugs at compile time rather than at runtime, database
programmers want the database to help them avoid data corruption. A
compiler helps avoid bugs by enforcing the rules of the language.
For example, in C# you can't use a variable you've not defined.
<a class="indexterm" name="idx-CHP-B-4653" id=
"idx-CHP-B-4653"></a>SQL Server and other modern <a class=
"indexterm" name="idx-CHP-B-4654" id=
"idx-CHP-B-4654"></a>relational databases help you avoid bugs by
enforcing constraints that you create. For example, the
<code class="literal">Customer</code> table marks the <code class=
"literal">CustomerID</code> field as a primary key. This creates a
primary key constraint in the database, which ensures that each
<code class="literal">CustomerID</code> is unique. If you were to
enter a person named Dan Maharry with a <code class=
"literal">PersonID</code> of 123, and then you were to try to add
Jesse Liberty with a <code class="literal">PersonID</code> of 123,
the database would reject the second record because of the primary
key constraint. You would need to give one of these people a
different, and unique, <code class="literal">CustomerID</code>.</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="declarative_referential_integrity" id=
"declarative_referential_integrity"></a><strong>Declarative Referential
Integrity</strong></h3>
</div>
</div>
</div>
<p>Relational databases use <span class="emphasis"><em>Declarative
Referential Integrity</em></span> (DRI) to establish constraints on
the relationships among the various tables. For example, you might
declare a constraint on the <code class=
"literal">SalesOrderHeader</code> table that dictates that no order
may have a <code class="literal">CustomerID</code> unless that
<code class="literal">CustomerID</code> represents a valid record
in the <code class="literal">Customer</code> table. This helps you
avoid two types of mistakes. First, you cannot enter a record with
an invalid <code class="literal">CustomerID</code>. Second, you
cannot delete a <code class="literal">Customer</code> record if
that <code class="literal">CustomerID</code> is used in any order.
The integrity of your data and the relationships among records is
thus protected.<a class="indexterm" name="idx-CHP-B-4655" id=
"idx-CHP-B-4655"></a></p>
</div>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="sql" id=
"sql"></a><big><strong>SQL</strong></big></h2>
</div>
</div>
</div>
<p>The language of choice for querying and manipulating databases
is <span class="emphasis"><em>Structured Query
Language</em></span>, often referred to as SQL. SQL is often
pronounced "sequel." SQL is a declarative language, as opposed to a
procedural language, and it can take awhile to get used to working
with a declarative language if you are used to languages such as
Visual Basic and C#.</p>
<p>Most programmers tend to think in terms of a sequence of steps:
"Find me all the orders, then get the customer's ID, then use that
ID to look up that customer's records in <code class=
"literal">Customer</code>, then get me the email address." In a
declarative language, such as SQL, you declare the entire query and
the query engine returns a set of results. You are not thinking
about a set of steps; rather, you are thinking about <a class=
"indexterm" name="idx-CHP-B-4656" id="idx-CHP-B-4656"></a>designing
and "shaping" a set of data. Your goal is to make a single
declaration that will return the right records. You do that by
creating temporary "wide" tables that include all the fields you
need and then filtering for only those records you want: "Widen the
<code class="literal">SalesOrderHeader</code> table with the
<code class="literal">Customer</code> table, joining the two on the
<code class="literal">CustomerID</code>, then filter for only those
that meet my criteria."<a class="indexterm" name=
"I_indexterm_d1e100558" id="I_indexterm_d1e100558"></a></p>
<p>The heart of <a class="indexterm" name="idx-CHP-B-4657" id=
"idx-CHP-B-4657"></a>SQL is the query. A query is a statement that
returns a set of records from the database. Typically, queries are
in this form:</p>
<a name="I_programlisting_d1e100569" id=
"I_programlisting_d1e100569"></a>
<pre class="programlisting">
Select <strong class="userinput"><code><em class=
"replaceable"><code>column,column,column</code></em></code></strong> from <strong class="userinput"><code><em class="replaceable"><code>table</code></em></code></strong> where <strong class="userinput"><code><em class="replaceable"><code>column</code></em></code></strong> = <strong class="userinput"><code><em class="replaceable"><code>value</code></em></code></strong>
</pre>
<p>For example, you might like to see <a class="indexterm" name=
"idx-CHP-B-4658" id="idx-CHP-B-4658"></a>information about the
customers served by Janet. To do so you would write:</p>
<a name="I_programlisting_d1e100592" id=
"I_programlisting_d1e100592"></a>
<pre class="programlisting">
Select FirstName, LastName, CompanyName from Customer where SalesPerson = 'Janet'
</pre>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="joining_tables" id=
"joining_tables"></a><strong>Joining Tables</strong></h3>
</div>
</div>
</div>
<p>SQL is capable of much more powerful queries (see the upcoming
"SQL Select Statement" sidebar for the full syntax as provided by
Microsoft).<a class="indexterm" name="idx-CHP-B-4659" id=
"idx-CHP-B-4659"></a><a class="indexterm" name="idx-CHP-B-4660" id=
"idx-CHP-B-4660"></a></p>
<p>For example, suppose you'd like to know about all the orders by
all the customers served by Janet after January 1, 1997. You might
create this query:</p>
<a name="I_programlisting_d1e100609" id=
"I_programlisting_d1e100609"></a>
<pre class="programlisting">
Select c.FirstName, c.LastName, c.CompanyName, o.OrderDate, o.TotalDue
from Customers c
<a class="indexterm" name="idx-CHP-B-4661" id=
"idx-CHP-B-4661"></a>inner join SalesOrderHeader o on o.customerID = c.customerID
where c.SalesPerson = 'Janet' and o.OrderDate > '1/1/97'
</pre>
<p>At first glance, you appear to be selecting <code class=
"literal">orderDate</code> from the <code class=
"literal">Customer</code> table, but that is not possible because
the <code class="literal">Customer</code> table does not have an
<code class="literal">orderDate</code>. You must take care to
identify the table that each field comes from by prefixing each
field with an "alias" defined in the query. The key phrase is:</p>
<a name="I_programlisting_d1e100629" id=
"I_programlisting_d1e100629"></a>
<pre class="programlisting">
<a class="indexterm" name="idx-CHP-B-4662" id=
"idx-CHP-B-4662"></a>inner join SalesOrderHeader o on o.customerID = c.customerID
</pre>
<p>It is as though the <code class="literal">join</code> phrase
creates a temporary table that is the width of the <code class=
"literal">Customer</code> table and the <code class=
"literal">SalesOrderHeader</code> table joined together. The
<code class="literal">on</code> keyword dictates how the tables are
joined. In this case, the tables are joined on the <code class=
"literal">CustomerID</code> column in <code class=
"literal">Customer</code> and in <code class=
"literal">SalesOrderHeader</code>.</p>
<p>Each record in <code class="literal">Customer</code>
(represented by the alias <code class="literal">c</code>) is joined
to the appropriate record in <code class="literal">Orders</code>
(represented by the alias <code class="literal">o</code>) when the
<code class="literal">CustomerID</code> fields match in both
records.</p>
<p>When you join two tables you can say "get every record that
exists in one table but not necessarily the other" (this is called
an <span class="emphasis"><em>outer join</em></span>), or you can
say, as we've done here, "get only those records that exist in both
tables" (called an <span class="emphasis"><em>inner
join</em></span>).<a class="indexterm" name="idx-CHP-B-4663" id=
"idx-CHP-B-4663"></a></p>
<div class="tip" style="margin-left: 0.5in; margin-right: 0.5in;">
<h3 class="title"><a name="tip-248" id="tip-248"></a><strong>Tip</strong></h3>
<p>Inner joins are the default, so writing <code class=
"literal">join</code> is the same as writing <code class=
"literal">inner join</code>.</p>
</div>
<p>The inner join shown in the preceding code snippet says: get
only the records in <code class="literal">Orders</code> that match
the records in <code class="literal">Customer</code> by having the
same value in the <code class="literal">CustomerID</code> field
(<code class="literal">on o.customerID = c.customerID</code>).</p>
<div class="sidebar"><a name="sql_select_statement" id=
"sql_select_statement"></a>
<p class="title"><b>SQL Select Statement</b></p>
<p>This is the complete syntax for the <code class=
"literal">SELECT</code> statement as used in <a class="indexterm"
name="idx-CHP-B-4664" id="idx-CHP-B-4664"></a>SQL Server:</p>
<a name="I_programlisting_d1e100724" id=
"I_programlisting_d1e100724"></a>
<pre class="programlisting">
<a class="indexterm" name="idx-CHP-B-4665" id=
"idx-CHP-B-4665"></a>SELECT statement ::=
< query_expression >
[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }
[ ,...n] ]
[ COMPUTE
{ { AVG | COUNT | MAX | MIN | SUM } (expression)} [ ,...n]
[ BY expression[ ,...n]]
]
[ FOR { BROWSE | XML { RAW | AUTO | EXPLICIT }
[ , XMLDATA ]
[ , ELEMENTS ]
[ , BINARY base64 ]
}
]
[ OPTION ( < query_hint > [ ,...n ]) ]
< query expression > ::=
{ < query specification > | ( < query expression > ) }
[ UNION [ ALL ] < query specification | ( < query expression > ) [...n] ]
< query specification > ::=
SELECT [ ALL | DISTINCT ]
[ { TOP integer| TOP integer PERCENT } [ WITH TIES ] ]
< select_list >
[ INTO new_table ]
[ FROM { < table_source > } [ ,...n ] ]
[ <a class="indexterm" name="idx-CHP-B-4666" id=
"idx-CHP-B-4666"></a>WHERE < search_condition > ]
[ GROUP BY [ ALL ] group_by_expression[ ,...n ]
[ WITH { CUBE | ROLLUP } ]
]
[ HAVING < search_condition > ]
</pre></div>
<p>The <code class="literal">where</code> clause further constrains
the search to those records where the <code class=
"literal">SalesPerson</code> field in <code class=
"literal">Customer</code> is an exact match for the string
<code class="literal">Janet</code> and where the <code class=
"literal">OrderDate</code> in the <code class=
"literal">Orders</code> table is greater than January 1, 1997:</p>
<a name="I_programlisting_d1e100754" id=
"I_programlisting_d1e100754"></a>
<pre class="programlisting">
where c.SalesPerson = 'Janet' and o.orderDate > '1/1/97'
</pre>
<p>But because <code class="literal">Orders</code> is the only
table with an <code class="literal">orderDate</code> column, there
is no ambiguity if we use just the column name:</p>
<a name="I_programlisting_d1e100764" id=
"I_programlisting_d1e100764"></a>
<pre class="programlisting">
where c.SalesPerson = 'Janet' and orderDate > '1/1/97'
</pre>
<p>It's often easier to read, though, if all columns are given a
prefix rather than you having to figure out which table each column
is part of. <a class="indexterm" name="idx-CHP-B-4667" id=
"idx-CHP-B-4667"></a>SQL is able to translate the string "1/1/97"
into a <code class="literal">DateTime</code> representing January
1, 1997.</p>
</div>
<div class="sect2" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h3 class="title"><a name="using_sql_to_manipulate_the_database"
id="using_sql_to_manipulate_the_database"></a><strong>Using SQL to
Manipulate the Database</strong></h3>
</div>
</div>
</div>
<p>You can use SQL to search for and retrieve data and to create,
update, and delete tables and generally manage and manipulate the
content and the structure of the database. For example, you can
update the <code class="literal">FirstName</code> of a specific
company:<a class="indexterm" name="idx-CHP-B-4668" id=
"idx-CHP-B-4668"></a></p>
<a name="I_programlisting_d1e100788" id=
"I_programlisting_d1e100788"></a>
<pre class="programlisting">
Update Customer set FirstName = 'Jesse' where CustomerId = '124'
</pre>
<p>You can add a new row to the <code class=
"literal">Customer</code> table:</p>
<a name="I_programlisting_d1e100795" id=
"I_programlisting_d1e100795"></a>
<pre class="programlisting">
INSERT INTO [Customer]
([FirstName], [LastName], [SalesPerson])
VALUES
('Dan', 'Maharry', 'Janet')
</pre>
<p>And you can delete a row from the table as well:</p>
<a name="I_programlisting_d1e100799" id=
"I_programlisting_d1e100799"></a>
<pre class="programlisting">
DELETE from Customer where FirstName='Dan' and LastName='Maharry'
</pre></div>
</div>
<div class="sect1" lang="en" xml:lang="en">
<div class="titlepage">
<div>
<div>
<h2 class="title" style="clear: both"><a name="further_reference"
id="further_reference"></a><big><strong>Further Reference</strong></big></h2>
</div>
</div>
</div>
<p>In this book, the database server of choice is Microsoft's SQL
Server 2005, but as we mentioned earlier, it is not the only kid on
the block and there are a number of different free versions of the
major databases to tide you over while you learn. They all have a
lot of good documentation installed with them as well, making them
well worth a read.</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p>SQL Server 2005 Express Edition (<a href=
"https://www.microsoft.com/express/sql/" target=
"_top">https://www.microsoft.com/express/sql/</a>)</p>
</li>
<li>
<p>Oracle 10g Express Edition (<a href=
"https://www.oracle.com/technology/software/products/database/xe/htdocs/102xewinsoft.html"
target=
"_top">https://www.oracle.com/technology/software/products/database/xe/htdocs/102xewinsoft.html</a>)</p>
</li>
<li>
<p>MySQL Community Server (<a href=
"https://dev.mysql.com/downloads/mysql/5.0.html#win32" target=
"_top">https://dev.mysql.com/downloads/mysql/5.0.html#win32</a>)</p>
</li>
</ul>
</div>
<p>Likewise, there are many good books and websites to teach you a
lot more about database design and SQL queries than you'll ever
need (probably). For example:</p>
<div class="itemizedlist">
<ul type="disc">
<li>
<p><a href="https://www.sqljunkies.com" target=
"_top">https://www.sqljunkies.com</a></p>
</li>
<li>
<p><a href="https://www.sqlservercentral.com" target=
"_top">https://www.sqlservercentral.com</a></p>
</li>
<li>
<p><em class="citetitle">Head First SQL</em> by Lynn Beighley
(O'Reilly), a cracking beginner's guide to SQL</p>
</li>
<li>
<p><em class="citetitle">SQL Visual Quickstart Guide</em> by Chris
Fehily (Peachpit), a slimmer alternative to <em class=
"citetitle">Head First SQL</em></p>
</li>
<li>
<p><em class="citetitle">SQL Queries for Mere Mortals</em> by John
L. Viescas and Michael J. Hernandez (Addison-Wesley), the book to
look at once you've got the basics of SQL in your head</p>
</li>
<li>
<p><em class="citetitle">Professional SQL Server 2005
Programming</em> by Rob Vieira (Wrox), the book to take you outside
of just writing SQL and into thinking about SQL Server as a whole
programming platform</p>
</li>
<li>
<p><em class="citetitle">Expert Oracle Database Architecture: 9i
and 10g Programming Techniques</em> by Thomas Kyte (Apress), the
equivalent to Vieira's book for Oracle users<a class="indexterm"
name="I_indexterm_d1e100858" id=
"I_indexterm_d1e100858"></a><a class="indexterm" name=
"I_indexterm_d1e100861" id="I_indexterm_d1e100861"></a></p>
</li>
</ul>
</div>
</div>
</div>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/444882069" height="1" width="1"/>
https://www.oreillynet.com/pub/au/1886
text
https://fyi.oreilly.com/SmalleryetASP.gif
https://fyi.oreilly.com/2008/11/relational-database-technology.html
Tech Terms Every Small Business Owner Should Know--A Forbes.com Special Report with Help from O'Reilly
tag:fyi.oreilly.com,2008://48.33998
2008-11-03T17:50:27Z
2008-11-03T18:31:05Z
If you're running a small business or thinking about starting one in today's brutal economic climate, a special report put together by Forbes.com can help you make the right decisions about technology. The package includes five stories illuminating everything from "hardware and networking to executing and securing transactions in cyberspace." Each story includes a glossary of terms put together by a team of O'Reilly editors: Shane Warden, Kurt Cagle, Timothy M. O'Brien, and James Turner. The stories and glossaries aim to help "entrepreneurs and their employees make smart technology decisions and purchases, communicate more effectively with in-house information technology staff and, ultimately, please their customers." Read on to learn more.
Sara Peyton
<p><a href="https://fyi.oreilly.com/2008/11/tech-terms-you-should-know.html"></a><br />
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://fyi.oreilly.com/assets_c/2008/11/forbes_home_logo.html" onclick="window.open('https://fyi.oreilly.com/assets_c/2008/11/forbes_home_logo.html','popup','width=150,height=49,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="https://fyi.oreilly.com/assets_c/2008/11/forbes_home_logo-thumb-180x58.gif" width="180" height="58" alt="forbes_home_logo.gif" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a></span><br />
If you're running a small business or thinking about starting one in today's brutal economic climate, a special report put together by <a href="https://www.forbes.com/entrepreneurs/2008/10/22/tech-starter-kit-ent-tech-cx_bn_1022techstarterkit_land.html">Forbes.com</a> can help you make the right decisions about technology. The package includes five stories illuminating everything from "hardware and networking to executing and securing transactions in cyberspace." Each story includes a glossary of terms and recommended reading put together by a team of O'Reilly editors: Shane Warden, Kurt Cagle, Timothy M. O'Brien, and James Turner. The stories and glossaries aim to help "entrepreneurs and their employees make smart technology decisions and purchases, communicate more effectively with in-house information technology staff and, ultimately, please their customers." <a href="https://fyi.oreilly.com/index.htm">Read on to learn more. </a></p>
<p><strong>Forbes Vocabulary Lesson for Entrepreneurs</strong><br />
<a href="https://www.forbes.com/entrepreneurs/2008/10/31/tech-starter-kit-ent-cx_ja_1031computernetworking.html">Computer Networking Tech Terms You Should Know</a>.<br />
<a href="https://www.forbes.com/technology/2008/10/31/tech-starter-kit-ent-tech-cx_om_1031computerhardwareglossary_slide.html?thisSpeed=20000">In Pictures: 31 Computer Networking Terms You Should Know</a></p>
<p><a href="https://www.forbes.com/home/2008/10/31/tech-starter-kit-ent-tech-cx_bc_1031computerhardwareglossary.html">Computer Hardware Terms You Should Know</a><br />
<a href="https://www.forbes.com/technology/2008/10/31/tech-starter-kit-ent-tech-cx_om_1031computerhardwareglossary_slide.html?thisSpeed=20000">In Pictures: 21 Computer Hardware Terms You Should Know</a></p>
<p><a href="https://www.forbes.com/2008/10/22/tech-starter-kit-ent-tech-cx_db_1022ecommerceglossary.html">E-commerce Tech Terms You Should Know</a><br />
<a href="https://www.forbes.com/2008/10/22/tech-starter-kit-ent-tech-cx_om_1022ecommerceglossary_slide.html?thisspeed=25000&boxes=custom">In Pictures: 25 E-commerce Tech Terms You Should Know</a></p>
<p><a href="https://www.forbes.com/2008/10/22/tech-starter-kit-ent-tech-cx_ja_1022securityglossary.html">Tech Security Terms You Should Know</a><br />
<a href="https://www.forbes.com/2008/10/21/tech-starter-kit-ent-tech-cx_om_1022securityglossary_slide.html">In Pictures: 23 Tech Security Terms You Should Know</a></p>
<p><a href="https://www.forbes.com/2008/10/22/tech-starter-kit-ent-tech-cx_br_1022socialnetworkingglossary.html">Social Networking Terms You Should Know</a><br />
<a href="https://www.forbes.com/2008/10/22/tech-starter-kit-ent-tech-cx_om_1022socialnetworkingglossary_slide.html?thisspeed=25000">In Pictures: 30 Social Networking Terms You Should Know</a></p>
<p><br />
</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/441249248" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2831
text
https://fyi.oreilly.com/forbes_home_logo.gif
https://fyi.oreilly.com/2008/11/tech-terms-you-should-know.html
Boo! dekePod's Scary Halloween Episode
tag:fyi.oreilly.com,2008://48.33877
2008-10-22T17:05:14Z
2008-10-22T19:23:37Z
A week ago Adobe began shipping Photoshop CS4 and already Deke McClelland's highly anticipated Adobe Photoshop CS4 One-on-One is climbing bestselling charts. Even better, dekePod's special Halloween episode sheds light on CS4's scariest feature, the Masks palette. "It's kind of cute, but it's got a big old knife," notes Deke. Watch dekePod now to find out how to transform the Masks palette from, in Deke's own words, "a devil doll to a responsible citizen."
Sara Peyton
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://fyi.oreilly.com/51Pc5ckinBL._SL500_AA240_.jpg"><img alt="51Pc5ckinBL._SL500_AA240_.jpg" src="https://fyi.oreilly.com/assets_c/2008/10/51Pc5ckinBL._SL500_AA240_-thumb-180x180.jpg" width="180" height="180" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a></span><br />
A week ago Adobe began shipping Photoshop CS4 and already Deke McClelland's highly anticipated <a href="https://oreilly.com/catalog/9780596521899/">Adobe Photoshop CS4 One-on-One</a> is climbing bestselling charts. Even better, <a href="https://digitalmedia.oreilly.com/dekepod/">dekePod's special Halloween episode</a> sheds light on CS4's scariest feature, the Masks palette. "It's kind of cute, but it's got a big old knife," notes Deke. "Masking is a way of making a super accurate selection."</p>
<p>And "faith is precisely what the Masks palette requires of you," adds Deke. "Everything about it is promising; little about it makes sense. The palette that makes masks also wears one. Will it be a bag of treats? Or a bundle of tricks?" </p>
<p>Watch dekePod now to find out how to transform the Masks palette from, in Deke's own words, "a devil doll to a responsible citizen."</p>
<p><embed src="https://blip.tv/play/AdTpG42XVQ" type="application/x-shockwave-flash" width="450" height="275" allowscriptaccess="always" allowfullscreen="true"></embed> </p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/428800043" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2831
text
https://fyi.oreilly.com/dekepod-008.png
https://fyi.oreilly.com/2008/10/boo-dekepods-scary-halloween-e.html
10 Tips & Tricks from the Tasmanian Adventure
tag:fyi.oreilly.com,2008://48.33856
2008-10-20T23:33:23Z
2008-10-22T16:55:53Z
As some of you may know, one of our authors, Mikkel Aaland, recently returned from a trip to Tasmania with a group of photographers and a team from Adobe. Below are tips & tricks regarding Photoshop Lightroom 2, as well as Mikkel's reflection on the trip.
Mary Rotman
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="9780596521011_cat.gif" src="https://fyi.oreilly.com/9780596521011_cat.gif" width="180" height="225" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></span>As some of you may know, one of our authors, <a href="https://www.oreillynet.com/pub/au/399">Mikkel Aaland</a>, recently returned from a trip to Tasmania with a group of photographers and a team from Adobe. This trip was in similar form to the Iceland adventure of 2006, which led to the release of <a href="https://oreilly.com/catalog/9780596100995/">Photoshop Lightroom Adventure</a>. This time around, the team was taking stunning pictures by day (see the gallery <a href="https://www.xyzadventures.com/galleries">here</a> and beta-testing Lightroom 2 by night. Upon returning, <a href="https://oreilly.com/catalog/9780596521011/index.html">Photoshop Lightroom 2 Adventure</a> was created, beautifully illustrated and eminently practical.</p>
<p>As Mikkel said,<br />
<blockquote>"The stars aligned perfectly to make this adventure a smashing success. First, Tasmania exceeded all our expectations, and we were like kids in a candy store shooting non-stop for 14 days. Working with Adobe to help improve Lightroom, was deeply satisfying. We truly went to the edge of the world to road test an amazing tool for digital photographers, and Lightroom met and exceeded our expectations. The world-class photographers on the team weren't paid, but they worked their butts off and not only provided valuable feedback to Adobe, but produced stunning images as well.</blockquote></p>
<p>In addition to the photography which Mikkel returned home with, he brought valuable tips & tricks to apply when using Lightroom 2.</p>
<ol>
<li>Do try Lightroom 2s new Library filter. It's very useful! Use the / key to hide and reveal it. Be sure "none" is selected if you don't want any filtering.
<li>Use the new Graduated filter to crate dramanitc skies, but also use it to create super vignettes. (For a tutorial on doing this go to <a href="https://www.viddler.com/explore/maaland/videos/7/">https://www.viddler.com/explore/maaland/videos/7</a>).
<li>Use the new Print to JPEG function in the Print module instead of printing to paper. You can send your layouts and files to outside vendors or share them by email.
<li>Use the new Localized Adjustment brush in the Develop module judicially to selectively adjust parts of your image. However, don't forget the intial mission of LIghtroom. It's supposed to free you from the computer so you can spend more time shooting!
<li>Download third party plugins from Smugmug, Digital Railroad, Facebook, etc, and use Lightroom to easily upload and share your photos. Visit Adobe Exchange to download them: click <a href="https://www.adobe.com/cfusion/exchange/index.cfm?s=5&from=1&o=desc&cat=278&l=-1&event=productHome&exc=25">here</a>
<li>Try out the new camera profiles found here: <a href="https://labs.adobe.com/wiki/index.php/DNG_Profiles">https://labs.adobe.com/wiki/index.php/DNG_Profiles</a>. These profiles are absolutely amazing and give your RAW files a very special look. (Follow Adobe's instructions on how to load them into Lightroom and access them via the Calibrate pane in the Develop module.)
<li>Create "handmade" video using Lightroom. See my tutorial here: <a href="https://blogs.oreilly.com/lightroom/2008/10/lightroom-scratch-making-handm.html">https://blogs.oreilly.com/lightroom/2008/10/lightroom-scratch-making-handm.html</a>
<li>Keep up with the latest Lightroom upgrades for new camera support and performance enhancements via the Adobe web site (<a href="https://www.adobe.com/downloads/updates/">https://www.adobe.com/downloads/updates</a>). Dot releases are free.</ol>
<p>If you'd like to speak with Mikkel more about the adventure or about Lightroom, he will be at PhotoPlus Expo along with many of our other authors. He, along with Bruce Dale, Katrin Eismann (<a href="https://oreilly.com/catalog/9780596100476/">Creative Digital Darkroom</a>), and Peter Krogh (<a href="https://www.oreilly.com/catalog/9780596100186">The DAM Book</a>), will be presenting a panel on the adventure on Saturday, Oct. 25th at the conference.</p>
<p>For more information on Lightroom Adventure: Tasmania, see <a href="https://digitalmedia.oreilly.com/adventure">https://digitalmedia.oreilly.com/adventure</a>.</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/426936964" height="1" width="1"/>
https://www.oreillynet.com/pub/au/3061
text
https://fyi.oreilly.com/mikkel_aaland.jpg
https://fyi.oreilly.com/2008/10/10-tips-tricks-from-the-tasman.html
Getting Ready for the Big Event
tag:fyi.oreilly.com,2008://48.33828
2008-10-17T17:51:46Z
2008-10-17T20:04:55Z
Tomorrow's the big day for you guys--opening day of Maker Faire Austin! Which means today is the big day for all of us -- setting up booths, building tables, hanging signs, and watching everything take shape so you can have the best experience possible. Check out O'Reilly's User Group Flickr account for more pictures as the weekend's events continue.
Mary Rotman
<p>Tomorrow's the big day for you guys--opening day of <a href="https://makerfaire.com">Maker Faire Austin</a>! Which means <em>today</em> is the big day for all of us -- setting up booths, building tables, hanging signs, and watching everything take shape so you can have the best experience possible.</p>
<table width="400" border="2" cellpadding="10px;" align="center">
<tr>
<td><a href="https://fyi.oreilly.com/Maker_Faire_2008_Austin_art_instructions_80714.jpg"><img src="https://fyi.oreilly.com/Maker_Faire_2008_Austin_art_instructions_80714.jpg" alt="Create your vision of the future" width="200" height="290" /></a></td>
<td><a href="https://www.flickr.com/photos/oreillyugprogram/sets/72157608095050653/"><img alt="Did You Know?" src="https://fyi.oreilly.com/2946913499_122d44e4b5.jpg" height="290" width="250" /></a></td>
</tr><tr>
<td><a href="https://www.flickr.com/photos/oreillyugprogram/sets/72157608095050653/"><img alt="Marsee" src="https://fyi.oreilly.com/2948921339_55e17d2427.jpg" width="250" height="210" /></a></td>
<td><a href="https://www.flickr.com/photos/oreillyugprogram/sets/72157608095050653/"><img alt="Maker Shed" src="https://fyi.oreilly.com/2949847106_bdf7201561.jpg" width="250" height="210" /></a></td>
</tr></a>
</table>
<p>From building tables for the "What's your vision for the future" art project at the O'Reilly Information Booth, to putting up the fun and informative "Did You Know?" posters, to Marsee, our User Group Coordinator, trying to catch up on email during some down time, things really are bustling! </p>
<p>Our own PR & Marketing team is there, building eight plywood tables for the art project and setting up 40 hay bales for a rest area. "Creating the booth has been a lot of fun. [I'm] learning how to use some tools a little better. I'm following the philosophy of the Maker ethic, to do it yourself and build it yourself," says George Snyder.</p>
<p>Check out <a href="https://www.flickr.com/photos/oreillyugprogram/sets/72157608095050653/">O'Reilly's User Group Flickr account</a> for more pictures as the weekend's events continue, be sure to stop by the booth to create your own vision of the future.</p>
<p>For a schedule and information on how to plan for these two intense days of DIY, <a href="https://blog.craftzine.com/archive/2008/10/two_ways_to_map_out_your_maker.html">check out these tips</a> from Rachel Hobson, one of our <a href="https://craftzine.com/blog">Craftzine bloggers</a>.</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/423985677" height="1" width="1"/>
https://www.oreillynet.com/pub/au/3061
text
https://fyi.oreilly.com/2949774384_18e5e269e4.jpg
https://fyi.oreilly.com/2008/10/getting-ready-for-the-big-even.html
The Talk Around the Water Cooler
tag:fyi.oreilly.com,2008://48.33797
2008-10-15T00:44:47Z
2008-10-15T00:59:22Z
Our office is buzzing with excitement as people pack up and head out to Maker Faire Austin. It's a weekend packed with adventure and surprises -- until you've experienced it you can't describe it -- and even then sometimes it's hard! From crafts to fire to demos and robots, there's something for everyone
Mary Rotman
<p>Our office is buzzing with excitement as people pack up and head out to Maker Faire Austin. It's a weekend packed with adventure and surprises -- until you've experienced it you can't describe it -- and even then sometimes it's hard! From crafts to fire to demos and robots, there's something for everyone.</p>
<p>For those of you who are craft-minded, here's the latest Craft podcast with information about what to expect at Maker Faire that might pique your interest:</p>
<p><object width="425" height="344"><param name="movie" value="https://www.youtube.com/v/W5cgx5f9UcA&hl=en&fs=1"></param><param name="allowFullScreen" value="true"></param><embed src="https://www.youtube.com/v/W5cgx5f9UcA&hl=en&fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>If you're bringing your kids along, they might enjoy the exhibit by <a href="https://austin-ecoschool.org/">Austin's EcoSchool</a>--a three day a week school that's a bridge between homeschooling and traditional schooling. As the <a href="https://blog.craftzine.com/archive/2008/10/austin_eco_school_brings_the_g.html">Craftzine blog</a> stated earlier this week, Among the creative ways the EcoSchool teachers implement their curriculum is having the children use <a href="https://www.thegameofvillage.com/">The Game of Villiage</a> to learn about other cultures, countries and periods of history. The Austin EcoSchool's set up at Maker Faire will provide visitors with the opportunity to create their own Peeps that they can then take over to the Medieval mini-village to explore and play. The village includes a castle, a jousting yard, and a market faire.</p>
<p><a href="https://blog.craftzine.com/archive/2008/10/austin_eco_school_brings_the_g.html"><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Game_of_village.jpg" src="https://fyi.oreilly.com/Game_of_village.jpg" width="600" height="131" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span></a></p>
<p>See the <a href="https://blog.craftzine.com/archive/2008/10/austin_eco_school_brings_the_g.html">blogpost</a> for more information, and we hope to see you at MakerFaire!</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/421069271" height="1" width="1"/>
https://www.oreillynet.com/pub/au/3061
text
https://fyi.oreilly.com/Austin_Eco_School.jpg
https://fyi.oreilly.com/2008/10/the-talk-around-the-water-cool.html
What will the night reveal to your digital camera?
tag:fyi.oreilly.com,2008://48.33772
2008-10-13T19:47:54Z
2008-10-14T18:29:05Z
You may be surprised! The advent of digital photography has revolutionized the practice of night photography because a digital sensor can record the spectacular colors of the night. These colors are created by light waves in spectrums that are invisible to the naked human eye. For the first time we can truly "see" the world of the night around us. In a live webcast on Friday, Oct. 17, Harold Davis, author of Practical Artistry: Light & Exposure for Digital Photographers, will show why night photography has become increasingly popular among digital photographers...
Kathryn Barrett
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="Nightphoto.gif" src="https://fyi.oreilly.com/Nightphoto.gif" width="525" height="231" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></span></p>
<p>In a letter to his brother Theo, the great artist Vincent van Gogh wrote "It often seems to me that the night is much more alive and richly colored than the day." The advent of digital photography has revolutionized the practice of night photography because a digital sensor can record the spectacular colors of the night. These colors are created by light waves in spectrums that are invisible to the naked human eye. For the first time we can truly "see" the world of the night around us.</p>
<p>Join us for this Friday's webcast, Secrets of Digital Night Photography with professional photographer Harold Davis. Harold is the author of <a href="https://oreilly.com/catalog/9780596529888/"><strong>Practical Artistry: Light & Exposure for Digital Photographers</strong></a> and creator of the <a href="https://www.photoblog2.com/"><strong>Photoblog 2.0</strong></a> and <a href="https://www.digitalnight.us"><strong>Digital Night</strong></a> web sites. In this talk, he'll show why night photography has become increasingly popular among digital photographers. He demystifies exposure techniques at night, and explains how he post-processes night photos. Following Harold's presentation, there will be time for a Q&A in which he'll answer your questions about night photography. </p>
<p>Date: Friday, October 17 at 10am PDT (17:00 GMT)<br />
Cost: Free<br />
Duration: 60 minutes<br />
Meeting link: <a href="https://oreilly.com/go/nightphotos"><strong>oreilly.com/go/nightphotos</strong></a><br />
Questions? Please send email to webcast@oreilly.com</p>
<p><strong>About Harold Davis</strong><br />
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="nightpixbig.gif" src="https://fyi.oreilly.com/nightpixbig.gif" width="250" height="170" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></span>Harold Davis is a photographer and author. His photographs have been widely published, exhibited, and collected. Many of his fine art photography posters are well known, including some recent alternatively processed digital flower images published by New York Graphic Society.</p>
<p>The author of more than twenty books, Harold has written (and illustrated with his photographs) Digital Photography: Digital Field Guide (Wiley), The Photographer's Guide to Yosemite and the High Sierra (Countryman/W.W.Norton), 100 Views of the Golden Gate (Wilderness Press). He is the lead author of a new series of books about digital photography from O'Reilly Digital Media.</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/419882168" height="1" width="1"/>
https://www.oreillynet.com/pub/au/1886
text
https://fyi.oreilly.com/nightpixsm.gif
https://fyi.oreilly.com/2008/10/what-will-the-night-reveal-to.html
Gary Bradski's Last Tip! Contributing to OpenCV's Future, 10 of 10
tag:fyi.oreilly.com,2008://48.33606
2008-10-13T18:00:41Z
2008-10-14T19:32:01Z
Dr. Gary Rost Bradski and Adrian Kaehler, the creators of OpenCV, have put their knowledge into a new book for O'Reilly. With Learning OpenCV: Computer Vision with the OpenCV Library developers and hobbyists can learn how to build simple or sophisticated vision applications. Over the last week Gary--a consulting professor at Stanford, senior scientist at Willow Garage, a robotics institute research institute/incubator, and vision team leader for Stanley, the Stanford robot that won the DARPA Grand Challenge autonomous race across the desert--shared his Top Tips and Tricks for getting the most out of OpenCV. Read on for Gary's last tip, Tip #10: Contributing to OpenCV's Future.
Sara Peyton
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://oreilly.com/catalog/9780596516130/"><img alt="" src="https://fyi.oreilly.com/assets_c/2008/09/9780596516130_lrg-thumb-180x236.jpg" width="180" height="236" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a></span>Computer vision is everywhere--in security systems, manufacturing inspection systems, medical image analysis, unnamed aerial vehicles and more. Indeed, getting machines to <em>see</em> is a challenging and often entertaining goal. <a href="https://www.oreillynet.com/pub/au/3270">Dr. Gary Rost Bradski</a> and Adrian Kaehler, the creators of OpenCV, have put their knowledge into a new book for O'Reilly. With <a href="https://oreilly.com/catalog/9780596516130/"><strong>Learning OpenCV: Computer Vision with the OpenCV Library</strong></a> developers and hobbyists can learn how to build simple or sophisticated vision applications.</p>
<p>Over the last week Gary--a consulting professor at Stanford, senior scientist at Willow Garage, a robotics institute research institute/incubator, and vision team leader for Stanley, the Stanford robot that won the DARPA Grand Challenge autonomous race across the desert--shared his <strong>Top Ten Tips and Tricks</strong> for getting the most out of OpenCV.</strong> And here's his last one! Thank you Gary.</p>
<p><strong>Tip #10: Contributing to OpenCV's Future</strong></p>
<p>Chapter 14 in <a href="https://oreilly.com/catalog/9780596516130/index.html">Learning OpenCV</a> discusses the future of OpenCV. Some of that future is coming from:</p>
<p>- the authors,<br />
- the group of five full time developers in Russia my company <a href="https://www.willowgarage.com/">Willow Garage</a> is supporting. You can also see our group meeting notes any time at: <a href="https://www.willowgarage.com/">https://pr.willowgarage.com/wiki/OpenCV</a>.<br />
- the core group of already active OpenCV developers.<br />
- And some of it can can come from you.</p>
<p>One can always go to the OpenCV sites:<br />
You can ask questions and post your own apps on the OpenCV Yahoo Group's site:<br />
<a href="https://tech.groups.yahoo.com/group/OpenCV/">https://tech.groups.yahoo.com/group/OpenCV/</a></p>
<p>You can get source code and ask questions at the sourceforge site:<br />
<a href="https://sourceforge.net/projects/opencvlibrary/">https://sourceforge.net/projects/opencvlibrary/</a></p>
<p>You can read from and contribute to the OpenCV wiki:<br />
<a href="https://opencvlibrary.sourceforge.net/">https://opencvlibrary.sourceforge.net/</a></p>
<p>I (<a href="https://www.oreillynet.com/pub/au/3270">Gary</a>) am going to oversee the growth of stereo, laser+camera, 3D data types and object recognition based on 2D + 3D features. You can add to this, or contribute in areas that aren't currently my focus:<br />
- medical imaging<br />
- security<br />
- industrial inspection<br />
- image stitching<br />
- video search and summarization<br />
- motion tracking<br />
- structure from motion<br />
- face recognition <br />
- vision for user interface<br />
- video editing<br />
- image editing<br />
- advanced image processing<br />
- underwater imaging<br />
- And many other areas.</p>
<p>Look for OpenCV to increase it's presence at the major computer vision conferences and at NIPS in the future. Contributing code will be easier. We will set up a user area where people can put unmaintained code or applications. The really good, general new functionality will be moved into OpenCV. If you have a new algorithm or application. For now, you can package it up with some documentation and a simple example program of its use. Email it, or your idea to <a href="mailto:OpenCVcode@gmail.com">OpenCVcode@gmail.com</a>.</p>
<p>OpenCV is growing at a critical time for the development of robotics and the Web. Look for rapid advances.</p>
<p>Our book, <a href="https://oreilly.com/catalog/9780596516130/">Learning OpenCV Computer Vision with the OpenCV Library</a>, will get you booted up fast. It is:<br />
(1) A tutorial covering a wide range of computer vision<br />
(2) A user's guide to OpenCV<br />
(3) A great source of code examples for using OpenCV and vision<br />
(4) A detailed guide to OpenCV's functions and structures</p>
<p>We look forward to hearing from you.</p>
<p><strong>Tip #9: Prospects for Projects</strong></p>
<p>OK, you're teaching or taking a computer vision course. You grab <a href="https://oreilly.com/catalog/9780596516130/">Learning OpenCV</a>. It's (IAHO In the Authors Humble Opinion) helpful right off the bat because it gives you the gist of some of the hard algorithms, making it much easier to understand and remember those algorithms when you have to learn them from original papers. But now it's course project time. There are 6 to 8 weeks remaining. What projects can you leverage using Learning OpenCV? Here are a few examples:</p>
<p><strong>- Well earlier, we already suggested a video security application using stereo to do background-foreground modeling:</strong><br />
Fast lighting independent background subtraction (2000) [32 citations -- 7 self] <a href="https://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=DDA5EFE297D70541657818DA06073DFF?doi=10.1.1.21.935&rep=rep1&type=pdf">PDF</a> </p>
<p> Or see newer work on this topic on Federico Tombari's web page <a href="https://vision.deis.unibo.it/fede">https://vision.deis.unibo.it/fede/</a> under "Change detection and Video-surveillance."</p>
<p><strong>- Extend the use of Random Forests (which are trivial to implement and no-brainer parallel algorithms) to object recognition and segmentation:</strong><br />
Schroff, F. , Criminisi, A. and Zisserman, A.<br />
<strong>Object Class Segmentation using Random Forests</strong><br />
Proceedings of the British Machine Vision Conference (2008) <br />
<a href="https://www.robots.ox.ac.uk/%7Evgg/publications/html/schroff08-bibtex.html">Bibtex source</a> | <a href="https://www.robots.ox.ac.uk/%7Evgg/publications/html/schroff08-abstract.html">Abstract</a> | Document: <a href="https://www.robots.ox.ac.uk/%7Evgg/publications/papers/schroff08.pdf">PDF</a></p>
<p><strong>- Use the above Random Forest algorithm to invent and study new features</strong></p>
<p><strong>- Using cellphone cameras plus GPS to do image stitching</strong><br />
Use GPS location and feature points detectors such as Harris corners along with, say histogram or contour descriptors of those feature points to stitch images you take with a cell phone (for example the iPhone) together at a given geographic location. (This is project that could be sold as a business). To get ideas about stitching, go to Richard Szeliski's site <a href="https://research.microsoft.com/~szeliski/">https://research.microsoft.com/~szeliski/</a></p>
<p><strong>- Stereo correspondence evaluation</strong><br />
Take the stereo correspondence code in OpenCV, evaluate it on the datasets at <br />
<a href="https://vision.middlebury.edu/stereo/">https://vision.middlebury.edu/stereo/</a><br />
Make improvements using post processing and re-evaluate it.</p>
<p><strong>- Optical flow evaluation</strong><br />
Start with the Lukas Kanade in Pyramid optical flow code in OpenCV. <br />
Evaluate it on the data at: <a href="https://vision.middlebury.edu/flow/">https://vision.middlebury.edu/flow/</a> Improve the results by better filtering.</p>
<p><strong>- Video content summarizing</strong><br />
The goal is to grab scenes from videos and put them together into a collage in such a way as to intuitively summarize the video in one image. You can for example use color and lighting histograms to determine scene changes and scene returns. Scenes with longer time periods can be shown as a larger sub-image in the summarizing collage and quick scenes can be shown as smaller image in the final collage etc.</p>
<p><strong>- Cheap flying vehicle navigation work</strong><br />
Take sequential aerial imagery from MS maps and attempt to "fly" the same course in Google Map imagery.</p>
<p><strong>- Visual Radio control</strong><br />
Using flashing LEDs on a radio controlled airplane, helicopter or car, get several stereo cameras (using OpenCV) and automatically control these.</p>
<p><strong>- Life logging</strong><br />
Get a flip video or just a canon camera with video and wear it recording video over several days time. Use histograms, optical flow, machine learning to summarize and index this video so that you can retrieve things from it later.</p>
<p>I could go on and on. Such projects can make for fun exercises, great class projects, research papers, and even as businesses.</p>
<p> </p>
<p><strong>Tip #8: Perceiving is deceiving, illusions and the nature of vision</strong></p>
<p>Optical illusions are cool and sometimes just stunning. Change blindness is one of the most stunning. If it is done right, you can watch a video of a street in San Francisco and not notice that the SUV in front of you changes to a sports car, or simply disappears. In change blindness, something fundamental changes in a scene and you simply fail to notice it. Try out some examples at <a href="https://www.psych.ubc.ca/~rensink/flicker/download/">https://www.psych.ubc.ca/~rensink/flicker/download/ </a> </p>
<p>Close your eyes until these files get going otherwise startup delays may ruin the effect. In these scenes, something, often large, changes and you just don't notice it. The trick in most of these videos is that a gray frame is inserted between each frame of the video. The gray frame causes your motion detection system to go nuts and thus your attention system just goes "huh?" and then the next frame of video comes on and you didn't notice the change. Many richer examples of this are on YouTube. </p>
<p>What's going on? Basically your brain just isn't big enough to process the whole world so it cheats. You focus on one thing in a scene and keep just a vague sketch of the rest. When motion triggers your attention system that something may have changed, you turn your focus to what changed. You don't keep the world in your head, you mostly look up the information when you need it, similar to how google is used now on the web. Well, people can use that cheap computational trick of your brain to fool you such as when you are watching a skilled magician. </p>
<p>There's a BBC documentary on change blindness that shows people being fooled by actors in a psychology experiment.<br />
<a href="https://www.youtube.com/watch?v=mAnKvo-fPs0">https://www.youtube.com/watch?v=mAnKvo-fPs0</a><br />
Many other examples exist on the web. </p>
<p><strong>In general, there are several types of optical illusions based on:</strong></p>
<p><strong>Processing limitation such as we saw with:</strong><br />
- Change blindness</p>
<p><strong>Image processing dynamics such as the: </strong><br />
- neon color spreading illusion <a href="https://www.michaelbach.de/ot/col_neon/index.html">https://www.michaelbach.de/ot/col_neon/index.html</a> or<br />
- <a href="https://www.blelb.ch/english/blelbspots/spot05/expspot05_en.htm">https://www.blelb.ch/english/blelbspots/spot05/expspot05_en.htm</a></p>
<p><strong>Lighting compensation such as:</strong> <br />
- Global contrast: <a href="https://www.michaelbach.de/ot/lum_adelsonCheckShadow/index.html">https://www.michaelbach.de/ot/lum_adelsonCheckShadow/index.html </a>or<br />
- Local contrast: <a href="https://www.michaelbach.de/ot/lum_dynsimcontrast/index.html">https://www.michaelbach.de/ot/lum_dynsimcontrast/index.html</a></p>
<p><strong>Pattern completion illusions such as:</strong><br />
- <a href="https://www.michaelbach.de/ot/cog_dalmatian/index.html">https://www.michaelbach.de/ot/cog_dalmatian/index.html</a></p>
<p><strong>Figure ground ambiguity, this is party based on bottom up binary pattern flipping dynamics:</strong><br />
- <a href="https://www.michaelbach.de/ot/cog_dalmatian/index.html">https://www.optillusions.com/dp/1-9.htm</a></p>
<p><strong>Motion processing illusions:</strong><br />
- <a href="https://kids.niehs.nih.gov/illusion/illusions.htm">https://kids.niehs.nih.gov/illusion/illusions.htm</a></p>
<p><strong>Build in 3D assumptions that don't fit the world of 2D images:</strong><br />
- Low level 3D cues such as <a href="https://www.michaelbach.de/ot/mot_eyeJitter/index.html">https://www.michaelbach.de/ot/mot_eyeJitter/index.html</a><br />
- Higher level 3D context: <a href="https://www.moillusions.com/2008/09/ponzo-illusion-collection.html">https://www.moillusions.com/2008/09/ponzo-illusion-collection.html</a><br />
- Pattern completion of supposed 3D occluding objects: <a href="https://www.michaelbach.de/ot/cog_kanizsa/index.html">https://www.michaelbach.de/ot/cog_kanizsa/index.html</a></p>
<p>There are many kinds of illusions, each based on violating an assumption the visual system uses to deal with the normal 3D world. The most common kind of illusion is the last bullet item above--we have strong built in models for dealing with the 3D world and these are relatively easy to fool using 2D images. </p>
<p>What does this have to do with computer vision? It tells us for one, that for object recognition and understanding, we're going to have to look harder at using 3D biases and models in order to achieve robust performance.</p>
<p></p>
<p><strong>Tip #4: Show me the money</strong><br />
Computer vision is fun and challenging no doubt--but how do you turn that string of numbers you get from the imaging arrays into identification of objects and actions? How do you turn "seeing" into "perception?" Fun, but is there any money in it? That is, can you get a job in computer vision?</p>
<p>Well, much to my surprise, the answer was "yes" when I got out of school and has only gotten better since. It turns out that machine perception is really valuable ... and it's really hard. So, what is computer vision used for commercially?</p>
<p>David Lowe, a Professor who works in computer vision at the University of British Columbia keeps a list of some of the commercial uses of computer vision at <a href="https://www.cs.ubc.ca/spider/lowe/vision.html">https://www.cs.ubc.ca/spider/lowe/vision.html</a>. </p>
<p>The topic lines there give some of the commercial span of computer vision:</p>
<p>- Automobile driver assistance<br />
- Digital Photography<br />
- Film and Video: Sports analysis<br />
- Film and Video<br />
- Games<br />
- General purpose vision systems<br />
- Image search<br />
- Industrial automation and inspection: Automotive industry, electronics industry, food and agriculture, printing and textiles <br />
- Medical and biomedical<br />
- Pedestrian tracking<br />
- Safety monitoring<br />
- Security and Biometrics<br />
- Three-dimensional modeling<br />
- Traffic management</p>
<p>Listed under each of these categories are companies that work in that area. This list is far from comprehensive. In my own area of Silicon Valley, there are two video search startups that I can think of immediately (that is, without having to Google since I (Gary) have done some work with them): Zeitera, which makes a content protection product (finds copies of videos posted on the internet), and <a href="https://www.videosurf.com/">VideoSurf,</a> which is just releasing the beta version of it's search engine for videos.</p>
<p>There a many more companies using vision computer vision, for instance the company I'm in, <a href="https://www.willowgarage.com/">Willow Garage</a> is mounting 2 stereo cameras on its robots' head, 2 pan and tilt cameras on the robot shoulders. Two cameras, one in each elbow of the robot and 2 laser ranger finders. And similarly, computer vision is one of the areas of expertise at <a href="https://www.appliedminds.com/">Applied Minds</a> where my coauthor works. Google is making extensive use of computer vision in to stitch satelight maps together in google maps, street scenes together in streetview, scan the 3D surface of books for their book scanning project, find faces and do image processing in Picasa etc. I know of at least two cell phone startups that are making use of computer vision using the cell phone camera.</p>
<p>Vision is rapidly growing--few people are aware that virtually every new manufactured product that is made or extracted has cameras involved in monitoring it. In any case, the vision described in <a href="https://oreilly.com/catalog/9780596516130/">Learning OpenCV</a> is not just a hobby these days.</p>
<p><strong>Tip #5: Leo Breiman allows us to tell what data is important</strong><br />
I'm sorry to report that Leo Breiman died of cancer some years back. He was a really great guy who was one of the key inventors of Decision Trees (Classification and Regression Trees). The others still living are Trevor Hastie, Rob Tibshirani and Jerome Friedman. All great statisticians (one of the best books on statistical learning is "The Elements of Statistical Learning" <a href="https://www-stat.stanford.edu/~tibs/ElemStatLearn/">https://www-stat.stanford.edu/~tibs/ElemStatLearn/</a>). Anyhow, Leo Breiman went on to invent this great algorithm, Random Forests. You can see it described on his still active website: <a href="https://www.stat.berkeley.edu/users/breiman/">https://www.stat.berkeley.edu/users/breiman/</a>. Well, OpenCV honors Leo by also implementing his decision trees and random trees algorithm [we had to change the names because the names are owned by Salford systems a data analysis company https://salford-systems.com/ ]). Decision Trees and Random Trees are described in the machine learning section of <a href="https://oreilly.com/catalog/9780596516130/">Learning OpenCV</a>, Chapter 13.</p>
<p>Both these algorithms offer one very important and often overlooked functionality: Variable importance. That is, you can throw datasets that have way too many features at either Random Trees or Decision Trees in OpenCV, run variable importance and it will rank how useful each feature was for predicting the class or regression level. You then get rid of the unimportant features and your algorithm gets smaller, faster and cleaner. You can also use this to learn something about the structure of the problem. We implemented this after being inspired by Looking Inside the Black Box on Leo Brieman's website <a href="https://www.stat.berkeley.edu/users/breiman/">https://www.stat.berkeley.edu/users/breiman/ </a></p>
<p>See Page 465 and the "variable importance" in the index (p 555) for a discussion of how to use and make use of this in the book.</p>
<p><strong>Tip #6: Some ordinary apps, we will donate</strong><br />
As a present to the book, in the next month or so, the authors will be donating some code:</p>
<p>Adrian will be donating a version of "multi-win" that displays multiple windows in one window, allows some basic data graphing, etc. Absolutely great for debugging your vision apps, Stanley would not have "seen" without this utility to debug what the laser's were telling the camera, and what the camera was doing with this.</p>
<p>Gary will be donating a data collection system based on background segmentation and watershed segmentation. Basically you learn a background, throw in an object. This segments it and stores: the object mask, the object bounding box and the object view into a labeled directory. It also works on ROS, the robot OS where we use it to store the 3D point cloud of an object as well.</p>
<p>Look for these ... when we can get ourselves to release this. Sheesh. </p>
<p><strong>Tip #7: OpenCV and the Robot Operating System (ROS)</strong><br />
Did I mention that I (Gary) work for Willow Garage<a href="https://www.willowgarage.com"></a>? The robot research institute/incubator that is seeking to become the Linux of Robotics? The goal is to make the robotics platform (the "horizonal" of robotics) free and open, and then develop verticals (construction robots, household robots, robot political leaders, service robots, robot overlords etc) for money fame and prizes. OK, we don't do any military stuff ... because, well, people are already pretty good at being bad and don't need our help.</p>
<p>Anyhow, Willow Garage is supporting OpenCV development, but also piling a ton of effort into a Robot Operating System (ROS)--(for purists, it isn't really an "OS", it's a bit transport layer so you can work across cores, across clusters slinging sensor and control bits around, keeping everything timed, safe, shiny, and robotical). ROS is graph based, nodes produce, publish, read and process data, working over distributed sensors, computers and multi-cores. ROS comes with serious goodies: Physics and Graphics simulators, Control and Planning software done by the best minds, Mapping, Localization and Navigation, Grasping and Manipulation. Oh, and OpenCV too for perception. The bit transport stuff stays under "ros", the goodies go under "ros-pkg." </p>
<p>Willow Garge will be shipping (what I humbly believe) will be the world's best research robot, which we call "Personal Robot 2" (PR2, see it at <a href="https://pr.willowgarage.com/hardware.html">https://pr.willowgarage.com/hardware.html</a> ), a vast improvement from PR1 that was created for Andrew Ng's ongoing STAIR project at Stanford <a href="https://stair.stanford.edu/">https://stair.stanford.edu/</a>. But ROS is not tied to any robot, it is general and already runs on 3 very differnt kinds of robots.</p>
<p>ROS is still in alpha development, but you can get it now, become a developer or robotic God (NOTE: just the opposite from humans, in the far future the robots who are scientists will insist that robots were intelligently designed, it is the religious robots who will insist that robots evolved. This is your chance to be one of those intelligent designer/Gods. Sign up now!). The ROS development page with tutorials, download and install instructions is at <a href="https://pr.willowgarage.com/wiki/ROS">https://pr.willowgarage.com/wiki/ROS</a></p>
<p>OpenCV will be at the core of the perception systems for ROS, stay tuned.<strong></p>
<p>Tip #8: OpenCV behind the scenes.</strong><br />
A new official release, 1.1 of OpenCV, is coming out in October 2008. Some people have noted that the last official release of OpenCV was in Nov. of 2006. OK, we're sorry, but the authors and main architects took some time out to join startups, found startups, join other companies, have some children, stuff like that. We were busy! Development never stopped--the CVS system on sourceforge has continuously been updated, it's just that the higher standard of an official release was more work than any of us had time to do. But do not fear! Thanks to the generosity Willow Garage <a href="www.willowgarage.com">www.willowgarage.com</a> where I work, we will be supporting five OpenCV developers full time and so regular releases are coming starting in October! More than that, look for many new features in OpenCV in the coming months (note, these are not yet in but are under active development now):</p>
<p>A full <strong>feature detection toolset</strong> (SURF features are already in CVS <a href="https://www.vision.ee.ethz.ch/~surf/">https://www.vision.ee.ethz.ch/~surf/</a> ):</p>
<ul>
<li>Interest point detectors (where are the points)</li>
</ul>
<ul>
<li>Interest point descriptors/identifiers (what point is that)</li>
</ul>
<ul>
<li>Spin features. Code originating from Andrew Ng's group at Stanford, optimized by our fine OpenCV team. Coming before December. Fast and excellent 3D point cloud features.</li>
</ul>
<ul>
<li>Features with centroid votes (see Bernt's Shiele's vision group's <a href="https://www.robots.ox.ac.uk/~vgg/publications/html/index.html">https://www.robots.ox.ac.uk/~vgg/publications/html/index.html</a> nice recent work,
<a href="https://www.mis.informatik.tu-darmstadt.de/Publications/leibe-multicue-bmvc06.pdf">Segmentation Based Multi-Cue Integration for Object Detection</a>, Bastian Leibe, Krystian Mikolajczyk, and Bernt Schiele</li>
</ul>
<ul>
<li>Boundary fragments (see Learning an Alphabet of Shape and Appearance for Multi-Class Object Detection at:
<a href="https://www.robots.ox.ac.uk/~vgg/publications/html/index.html">https://www.robots.ox.ac.uk/~vgg/publications/html/index.html</a></li>
</ul>
<ul>
<li><strong>Laser-camera calibration.</strong> Hey, both authors worked on the robot Stanley that won the $2M Darpa Grand Challenge 7 hour race across the desert (look for us under the "Team" tag in the "Software" group, "computer vision" sub-group at <a href="https://cs.stanford.edu/group/roadrunner//old/index.html">https://cs.stanford.edu/group/roadrunner//old/index.html</a> ), so we're both interested in using depth sensing with cameras.</li>
</ul>
<ul>
<li><strong>Space-Time stereo:</strong> Get very precise stereo reconstruction using random patterns of projected light over time. Great new work by Federico Tombari coming soon. For getting really good close range depth, this technique is great.</li>
</ul>
<ul>
<li><strong>3D 3D 3D.</strong> Now that we have great stereo, we need to make use of it. Look for complicated mathy things like "Bundle adjustment" and 3D to 3D point mappings.</li>
</ul>
<ul>
<li><strong>Visual SLAM. </strong> SLAM stands for: Simultaneous Localization and Update. It's how robots make maps by wandering around and then make use of those maps to navigate without hitting things. See examples of such maps at <a href="https://pr.willowgarage.com/wiki/Maps">https://pr.willowgarage.com/wiki/Maps</a>. These were made with Laser. Well, renowned stereo expert Kurt Konolige is going to do the same, but in full 3D for stereo. Look for this several months from now.</li>
</ul>
<ul>
<li><strong>Object recognition.</strong> This is a active area of work for both authors, expect to see some goodies. Parallel incremental Gentle Boost maybe. Zisserman's fast approximate K-means for huge data sets. Perhaps joint boosting see the influential paper <a href="https://web.mit.edu/torralba/www/cvpr2004.pdf">Sharing features: efficient boosting procedures for multiclass object detection</a> A. Torralba, K. P. Murphy and W. T. Freeman at<a href="https://web.mit.edu/torralba/www/"> https://web.mit.edu/torralba/www/</a> In general, we need techniques that can:
</ul>
<blockquote><blockquote><strong>Rapidly learn huge data sets</strong> -- it's best if we can parallelize learning and recognition to take advantage of all those new multi-core chips.</blockquote></blockquote>
<blockquote><blockquote><strong>The learned classifier</strong> has to remain computationally efficient. If we go from 10 to 1000 objects, we don't to take 100 times as long to recognize objects for example.</blockquote></blockquote>
<blockquote><blockquote><strong>We would like to incrementally add new objects.</strong> That is, we don't want to have to relearn the whole database for each new objects we need to learn (many techniques suffer from this problem). </blockquote></blockquote>
<blockquote><blockquote><strong>We would like to incrementally add new features.</strong> If we come up with a new feature, we want to add it without having to train everything from scratch. OK, this is hard and involves real research -- we're pursuing it with Stanford at the moment. The other powerhouse in this area is at MIT with Bill Freeman and Antonio Torralba.</blockquote></blockquote>
<p>OK, so what are the authors doing now besides trying to overcome carpal tunnel syndrome from writing the book?</p>
<p><strong>Gary Bradski</strong>, is spending time jointly between Stanford and Willow Garage <a href="https://www.willowgarage.com">www.willowgarage.com</a>, a robotics institute/incubator that is seeking to become the Linux of robotics and if funded to accomplish this task after which we'll spin off companies doing vertical applications like food service etc. It's an absolutely great environment, trust me, I'm reeeeally choosy. Yes, we're hiring computer vision programmers -- but really good programmers who would blow away a Google programming interview. We probably interview harder, but don't worry, we know you might still be great even if you "fail" -- one of our best employees is someone we unanimously rejected and only after being berated by his adviser did we give him a chance and now worship at his very coding feet. So, we're looking for fit and fitness, we know we're often wrong but hiring is harder than interviewing ... we apologize in advance, give us a try.</p>
<p><strong>Adrian Kaehler</strong>: Is an uber guy at Applied Minds. <a href="https://www.appliedminds.com/">www.appliedminds.com/</a> Remember the guy who created the connection machine? Then did great stuff for Disney imagineers and is also building a 10,000 year clock? Danny Hillis is one of he founders. A lot of their stuff is secret, but if you want to work on proteomics, multi-touch displays, robotics, satelights, movie animation, building architecture and billion pixel cameras all in the same job. This is your place. They are hiring too and we often fight over people and sometime send them back and forth (you have to be a US Citizen for Applied Minds). </p>
<p>For the CVS version of OpenCV, detail install instructions for openCV on Windows, Mac OS and Linux are in Chapter 1 of the book starting on page 8. Also see the OpenCV wiki at <a href="https://opencvlibrary.sourceforge.net">https://opencvlibrary.sourceforge.net </a>. (Please note: The opencv wiki is down due to a sourceforge changeover.)</p>
<p>But here's the basics:</p>
<p>On Windows, if you want the latest OpenCV from the CVS repository then you'll need<br />
to access the CVSROOT directory:<br />
<a href="https://pserver:anonymous@opencvlibrary.cvs.sourceforge.net:2401/cvsroot/opencvlibrary"> :pserver:anonymous@opencvlibrary.cvs.sourceforge.net:2401/cvsroot/opencvlibrary</a><br />
On Linux, you can just use the following two commands:<br />
cvs -d:pserver:<a href="mailto:anonymous@opencvlibrary.cvs.sourceforge.net">anonymous@opencvlibrary.cvs.sourceforge.net</a>:/cvsroot/opencvlibrary<br />
login<br />
When asked for password, hit return. Then use:<br />
cvs -z3 -d:pserver:<a href="mailto:anonymous@opencvlibrary.cvs.sourceforge.net">anonymous@opencvlibrary.cvs.sourceforge.net</a>:/cvsroot/opencvlibrary<br />
co -P opencv</p>
<p><strong>Tip #9: Google's Vision for OpenCV </strong><br />
Google makes extensive use of OpenCV internally for their street view, map stitching and other image processing needs. They have recently contributed some of their code back to OpenCV in the form of Daniel Filip's C++ image wrapper class cvwimage. Look for cvwimage.h in the .../cxcore/include directory. This code came too late to be documented in the book, but we will document it on the website after we ourselves get more familiar with it. Google is interested in speed and minimizing bugs, so this class wraps IplImage and concentrates on these things: </p>
<p><strong>1.</strong> Images are explicitly owned to avoid memory leak problems.<br />
<strong>2.</strong> This class provides fast access to subregions of an image, especially lines. The member functions are only things that are very fast. To call most OpenCV functionality, you expose the pointer to the image and call the OpenCV functions as usual. That means, there is little learning curve with this class.<br />
<strong>3. </strong>You can derive window pointers to sub regions of the original image.<br />
<br />
Typically in Google, they allocate a huge image space and then put all their images that they are processing into sub-regions of this huge window (see the Region of Interest "ROI" discussion starting on the bottom of page 43 in the book). This huge window becomes their processing buffer and sub-regions are allocated and passed to OpenCV or Google functions for processing. Memory managment isn't much of a problem because only one routine "owns" the huge window so it's easy to manage when this is allocated or deallocated. </p>
<p><strong>Tip #10: Now that OpenCV has a full stereo depth perception pipeline built in (see Ch 12 in the book), what can you do with it? </strong></p>
<p>Well, it makes state of the art stereo cheap. You can now put together different kinds of cameras and as long as they are time synchronized or as long as you can deal with "close enough" to time synchronized (that is looking at far distances), you can pair cheap web cameras together on up to expensive high resolution or high dynamic range cameras together and get out images plus depth maps. Wave a black and white chessboard pattern at your cameras and produce state of the art stereo depth perception. There are dozens of applications for this. </p>
<p>One area is security. Forget single cameras, go to stereo pairs. You can now get superior background segmentation results that are invariant to lighting. You do this by relating each pixel in one camera to its pair in the other via the depth or dispaity map, this becomes your two camera background scene model. The model captures the relative red,green,blue ratio between each pixel in two views. When someone or something moves into the scene, the model, based on the true depth, becomes distorted and you can not only identify a change in the scene, but know where that change is in 3D. See for example:</p>
<p><strong>Fast lighting independent background subtraction (2000) [32 citations -- 7 self]</strong><br />
Download:<br />
<a href="https://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=DDA5EFE297D70541657818DA06073DFF?doi=10.1.1.21.935&rep=rep1&type=pdf">pdf </a>| <a href="https://citeseerx.ist.psu.edu/viewdoc/download;jsessionid=DDA5EFE297D70541657818DA06073DFF?doi=10.1.1.21.935&rep=rep1&type=ps">ps</a><br />
by Yuri Ivanov, Aaron Bobick, John Liu<br />
International Journal of Computer Vision<br />
<a href="https://www-white.media.mit.edu/people/yivanov/Papers/ijcv00/ivanov-ijcv00.ps.gz">https://www-white.media.mit.edu/people/yivanov/Papers/ijcv00/ivanov-ijcv00.ps.gz</a></p>
<p>Or see newer work on this topic on Federico Tombari's web page <a href="https://vision.deis.unibo.it/fede/">https://vision.deis.unibo.it/fede/</a> under "Change detection and Video-surveillance:"</p>
<p><strong>Check back tomorrow for Tip #8 OpenCV behind the scenes</strong></p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/408387267" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2831
text
https://fyi.oreilly.com/2008/09/30/9780596516130_lrg.jpg
https://fyi.oreilly.com/2008/10/gary-bradskis-top-ten-tips-for.html
Coming Soon....David Pogue on The Basics
tag:fyi.oreilly.com,2008://48.33735
2008-10-09T20:51:01Z
2008-10-09T22:10:13Z
"Nothing I've ever written has ever prompted a reaction like last week's e-column. In six days, over 1,150 of you added comments to the online version at nytimes.com/pogue." So writes David Pogue, in his e-column today. "The column was the...
Sara Peyton
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://fyi.oreilly.com/assets_c/2008/10/david_pogue-thumb-350x402.jpg"><img alt="Thumbnail image for david_pogue.jpg" src="https://fyi.oreilly.com/assets_c/2008/10/david_pogue-thumb-350x402-thumb-180x206.jpg" width="180" height="206" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a></span>"Nothing I've ever written has ever prompted a reaction like last week's e-column. In six days, over 1,150 of you added comments to the online version at <a href="https://nytimes.com/pogue">nytimes.com/pogue</a>." So writes David Pogue, in his<a href="https://www.nytimes.com/indexes/2008/10/09/technology/circuitsemail/index.html"> e-column</a> today. "The column was the #1 most e-mailed New York Times article for two days straight...The topic, of course, was <a href="https://pogue.blogs.nytimes.com/2008/10/02/tech-tips-for-the-basic-computer-user/">essential tech tips</a> you thought everybody knew--but nobody, including you, knows them all," he adds. According to David, we're craving a "compendium of the essential tech bits"--the basics.</p>
<p>We agree with David, the founder of our witty and clearly written <a href="https://missingmanuals.com/">Missing Manuals</a> series. We need a new book that covers the basics of operating all the gadgets in our lives--our cell phones, cameras, computers, and the rest. And no one explains technology better than David Pogue. Which is why we'll be publishing this new book some time next year. Possible titles? "The Basics: The Essential Tech Tips You Should Know (But Probably Don't)" or "Pogue's Basics: The Essential Tech Tips You Should Know (But Probably Don't)."</p>
<p>The title is, of course, subject to change. So stay tuned. In the meantime, if you have a basic tip or trick you want to share, please post it here.</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/416183139" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2831
text
https://fyi.oreilly.com/assets_c/2008/10/david_pogue-thumb-350x402.jpg
https://fyi.oreilly.com/2008/10/missing-manual-sneak-peek-davi.html
Flex Author Joey Lott on a User Group Tour
tag:fyi.oreilly.com,2008://48.33704
2008-10-09T18:58:11Z
2008-10-09T21:47:01Z
Starting at Refresh Detroit earlier this month, author Joey Lott is on a cross country tour visiting as many user groups as he can. Stops include AS3 Apex (10/4) in St. Louis, Cleveland Flex User's Group (10/9), Central PA Adobe...
Marsee Henon
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://fyi.oreilly.com/9780596516215-150.png"><img alt="9780596516215-150.png" src="https://fyi.oreilly.com/assets_c/2008/10/9780596516215-150-thumb-180x236.png" width="180" height="236" class="mt-image-right" style="float: right; margin: 0 0 20px 20px;" /></a></span>Starting at <a href="https://refresh-detroit.org/2008/08/30/september-23-2008-introduction-to-adobe-air-for-flex-and-flash-developers/">Refresh Detroit</a> earlier this month, author Joey Lott is on a cross country tour visiting as many user groups as he can.<br />
<br /><br />
Stops include <a href="https://www.as3apex.com/as3/joey-lott-is-coming-to-stlouis-on-october-4th/">AS3 Apex (10/4)</a> in St. Louis, <a href="https://www.clefug.com/#app=be07&aec8-selectedIndex=2">Cleveland Flex User's Group (10/9)</a>, <a href="https://cenpennaug.blogspot.com/2008/08/adobe-flex-3-author-joey-lott-to-speak.html">Central PA Adobe User Group and Central PA Flash User Group (10/10)</a>, <a href="https://www.phflex.org/">Philadelphia Flex User Group (10/22)</a>, <a href="https://acadiana-aug.org/">Acadiana Adobe User Group (11/3)</a> in Lafayette, <a href="https://portal.blogfusion.com/blogs/austincfug/">Austin CFUG (11/5)</a>, <a href="https://www.sazmug.arizona.edu/">Tucson Adobe User Group (11/10)</a>, <a href="https://www.gotoandstop.org/index.php/2008/08/21/special-meeting-111008-how-to-architect-flex-applications-with-joey-lott/">GoToAndStop.org (11/10)</a> in Phoenix, and then <a href="https://vegasflex.org/2008/10/upcoming-noveember-meeting/">VegasFlex (11/13)</a>. <a href="https://www.themorphicgroup.com/blog/2008/09/30/joey-lott-cross-country-lecture-series/">Stay tuned</a> for the latest details.<br />
<br /><br />
Joey will be making a pitt stop at Adobe Max on November 17 to present <a href="https://max.adobe.com/na/experience/#?s=2&p=3">"The Flex Architecture Faceoff"</a> and then continues on to Santa Rosa (11/24), Salt Lake City (12/2), and Seattle (12/8).</p>
<p><a href="https://oreilly.com/catalog/9780596516215/index.html">Programming Flex 3</a> just released from Adobe Developer Library series--future titles include <a href="https://oreilly.com/catalog/9780596522520/">Search Engine Optimization for Flash</a>, <a href="https://www.oreilly.com/catalog/9780596522506/">Adobe AIR Cookbook</a>, and <a href="https://www.oreilly.com/catalog/9780596517359/">The ActionScript 3.0 Quick Reference Guide</a>.<br />
</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/416120572" height="1" width="1"/>
https://www.oreillynet.com/pub/au/2948
text
https://fyi.oreilly.com/9780596516215-150.png
https://fyi.oreilly.com/2008/10/author-joey-lott-on-a-user-gro.html
Can you make a living creating iPhone apps?
tag:fyi.oreilly.com,2008://48.33718
2008-10-08T21:00:11Z
2008-10-08T22:12:40Z
Kathryn Barrett
<p><span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="https://oreilly.com/go/iphonelive"><img alt="iPhoneLiveimage.gif" src="https://fyi.oreilly.com/iPhoneLiveimage.gif" width="520" height="192" border="0" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></a></span></p>
<p>There's been rapid change in the iPhone development world, leaving many would-be iPhone app developers wondering where they stand. In this free, one-hour live webcast, Bill Dudney and Raven Zachary, co-chairs of O'Reilly's upcoming <a href="https://en.oreilly.com/iphonelive2008/public/register?CMP=EMC-conf_iphonelive08_ext&att=webcast"><strong>iPhoneLive Conference</strong></a> on November 18 in San Jose, share a preview of the presentations they'll give at the conference. Following this preview, you'll have plenty of time to ask questions about the current state and future of iPhone application development—and how it affects you.</p>
<p>Bill's topic is <a href="https://en.oreilly.com/iphonelive2008/public/schedule/detail/5258"><strong>Introduction to iPhone Development</strong></a>. Looking to get started on iPhone development? Bill will show you how to build iPhone apps from the basics to the beautiful. In this presentation, Bill will cover some of the demo apps that will be covered in the talk and show you the tools needed to build them. Join the webcast and get a head start on Bill's talk!</p>
<p>Raven will cover <a href="https://en.oreilly.com/iphonelive2008/public/schedule/detail/5284"><strong>App Store Licensing Models</strong></a> in which he evaluates the current pricing conditions, advertising strategies, and pricing strategies for iPhone apps. This topic is crucial for anyone planning to make money in the iPhone application market.</p>
<p>Registration is free and easy. Plus, we'll send you a reminder before the webcast. Please feel free to share this news with others.</p>
<p>Date: Tuesday, October 14 at 10am PDT <br />
Cost: Free<br />
Duration: Approx. 60 minutes<br />
Meeting link: <a href="https://oreilly.com/go/iphonelive"><strong>https://oreilly.com/go/iphonelive</strong></a></p>
<p>Questions? Please send email to webcast@oreilly.com<br />
</p>
<img src="https://feeds.feedburner.com/~r/oreilly/fyi/blog/~4/415160199" height="1" width="1"/>
https://www.oreillynet.com/pub/au/1886
text
https://fyi.oreilly.com/iphoneappimage.gif
https://fyi.oreilly.com/2008/10/can-you-make-a-living-creating.html