Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7018 Articles
article-image-windows-8-vmware-view
Packt
10 Sep 2013
3 min read
Save for later

Windows 8 with VMware View

Packt
10 Sep 2013
3 min read
(For more resources related to this topic, see here.) Deploying VMware View on Windows 8 (Advanced) If you want to get a hands-on experience with Windows 8 on VMware View and get ready for future View deployments, this should be a must-take guide for deploying it. Getting ready Let's keep the following requirements ready: You should have VMware vSphere 5.1 deployed You should have VMware View 5.1 Connection Server deployed You should have Windows 8 Release Preview installer and license keys for 32-bit version How to do it... Let's list the steps required to complete the task. To create a Windows 8 Virtual Machine, perform the following steps: Create a standard virtual hardware version 9 VM with Windows 8 as the guest operating system. As this is a testing phase, keep the memory and disk size optimal. Edit the settings in VM and under Video card , select the Enable 3D support checkbox (this step is to make sure graphics, and adobe Flash content works with Windows 8 using VMware driver). Mount the ISO image of Windows 8 in the virtual machine and proceed with the Windows 8 Installation. Enter Windows license keys appropriately available with you. Install VMware tools in the VM; Shutdown and restart the VM. Install a VMware View 5.1 agent in VM, uncheck Persona Management during agent installation. Power-on the VM, set the network option to DHCP, and disable Windows Defender. Create a snapshot of VM and power the VM down. Now, we are ready with Windows 8 Parent virtual machine with Snapshot. To create a pool for Windows 8 in View Admin console, perform the following steps: Launch the Connection Server Admin console and navigate to the Pool Creation wizard. Select the Automated pool type (you can use either Dedicated or Floating ). Choose a View Composer linked-clone-based pool. Navigate through the rest of the wizard accepting all defaults, and choosing the snapshot of your Windows 8 VM with the View Agent installed. Use QuickPrep for instant customization. You may require to manually restart the VM if Quickprep doesn't get initiated by itself once the VM boots. Allow provisioning to proceed. Make sure you set Allow users to choose protocol: to No , else 3D rendering gets disabled automatically. If you want to set Allow users to choose protocol: to Yes , make sure you stick to the RDP protocol and not PCoIP in the Default display protocol: field, else you will end up with a black screen. To install View Client, perform the following step: Install View Client 5.1 on any device with iOS/Android/Linux/Windows. To view a list of supported clients, visit http://www.vmware.com/support/viewclients/doc/viewclients_pubs.html. How it works... Once all the preceding steps are performed, you should have Windows 8 with VMware View 5.x ready. You should be able to see the VM in ready status under Desktop Resources in VMware View Admin console. You should be able to launch Windows 8 with View Client now. Please note that you have to entitle the users to the respective pools before users can access the VM. More information You can even refer to http://kb.vmware.com/kb/2033640 to know more on how to install Windows 8 in a VM. Resources for Article : Further resources on this subject: Cloning and Snapshots in VMware Workstation [Article] Creating an Image Profile by cloning an existing one [Article] Building a bar graph cityscape [Article]
Read more
  • 0
  • 0
  • 5979

article-image-features-cloudflare
Packt
10 Sep 2013
5 min read
Save for later

Features of CloudFlare

Packt
10 Sep 2013
5 min read
(For more resources related to this topic, see here.) Top 5 features you need to know about Here we will go over the various security, performance, and monitoring features CloudFlare has to offer. Malicious traffic Any website is susceptible to attacks from malicious traffic. Some attacks might try to take down a targeted website, while others may try to include their own spam. Worse attacks might even try and trick your users to provide information or compromise user accounts. CloudFlare has tools available to mitigate various types of attacks. Distributed denial of service A common attack on the Internet is the distributed denial-of-service(DDoS) attack. A distributed denial-of-service attack involves producing so many requests for a service that it cannot fulfill them, and crumbles under the load. A common way this is handled in practice is by having the attacker make a server request, but never listen for the response. Typically a response will be presented by the client notifying the server that it received data, but if a client does not acknowledge, the server will keep trying for quite a while. A single client could send thousands of these requests per second, but the server would not be able to handle many at once. Another twist to these attacks is the dynamic denial-of-service attack. This attack will be spread across many machines, making it difficult to tell where the attacks are coming from. CloudFlare can help with this because it can monitor when users are trying an attack and reject access, or require a captcha challenge to gain access. It also monitors all of its customers for this, so if there is an attack happening on another CloudFlare site, it can protect yours from the traffic attacking the site as well. It is a difficult problem to solve. Sometimes traffic just spikes if big news article are run. It is hard to tell when it's legitimate traffic and when it is an attack. For this, CloudFlare offers multiple levels of DoS protection. On the CloudFlare settings the Securitytab is where you can configure this advanced protection: On the CloudFlare settings the Security tab is where you can configure this advanced protection: The basic settings are rolled into the Basic protection level setting: SQL injection SQL injection is a more involved attack. On a web page, you may have a field like a username/password field. That field will probably be checked against a database for validity. The database queries to do this are simple text strings. This means that if the query is written in a way that doesn't explicitly prevent it, an attacker can start writing their own queries. A site that is not equipped to handle these cases would be susceptible to hackers destroying data, gaining access by pretending to be other users, or accessing data they otherwise would not have access to. It is a difficult problem to check against when building a software. Even big companies have had issues. CloudFlare mitigates this by looking for requests containing things that look like database queries. Almost no websites take in raw database commands as normal queries. This means that CloudFlare can search for suspicious traffic and prevent it from accessing your page. Cross-site scripting Cross-site scripting is similar to SQL injection except that it deals with JavaScript and not database SQL. If you have a site that has comments, for example, an unprotected site might allow a hacker to put their own JavaScript on it. Any other user of the site could execute that JavaScript. They could do things like sniff for passwords, or even credit card information. CloudFlare prevents this in a similar fashion by looking for requests that contain JavaScript and blocking them. Open ports Often, services available on a server can be available without the sysadmin knowing about it. If Telnet is allowed, for example, an attacker could simply log in to the system and start checking out source code, looking into the database, or taking down the website. CloudFlare acts as a firewall to ensure that the ports are blocked even if the server has them open. Challenge page When CloudFlare receives a request from a suspect user, it will usually show a challenge page asking the user to fill out a captcha to access the site. The options for customizing these settings is on the Security Settings tab: You can also configure how that page looks by clicking on Customize. By default, it will look something like the following: E-mail address obfuscation E-mail address obfuscation scrambles any e-mail addresses on your page, then runs some JavaScript to decode it so that the text ends up being readable. This is nice in order to avoid getting spam in your user's e-mails, but the downside is that if a user has JavaScript disabled, they will not be able to read e-mail addresses: Summary In this article, we have looked at the various security features provided by CloudFlare against malicious traffic, distributed denial of service, e-mail address obfuscation, and so on. Therefore, it can be concluded that CloudFlare is one of the better website-designing options available in the market today. Resources for Article: Further resources on this subject: Getting Started with RapidWeaver [Article] LESS CSS Preprocessor [Article] Translations in Drupal 6 [Article]
Read more
  • 0
  • 0
  • 10964

article-image-external-tools-and-puppet-ecosystem
Packt
10 Sep 2013
16 min read
Save for later

External Tools and the Puppet Ecosystem

Packt
10 Sep 2013
16 min read
(For more resources related to this topic, see here.) Introduction to Puppet Facts Puppet is a useful tool by itself, but you can get much greater benefits from using Puppet in combination with other tools and frameworks. We'll look at some ways of getting data into Puppet, including custom Facter facts, external facts, and Hiera databases, and tools to generate Puppet manifests automatically from existing configuration. You'll also learn how to extend Puppet by creating your own custom functions, resource types, and providers; how to use an external node classifier script to integrate Puppet with other parts of your infrastructure; how to use public modules from Puppet Forge; and how to test your code with rspec-puppet. Creating custom facts While Facter's built-in facts are useful, it's actually quite easy to add your own facts. For example, if you have machines in different data centers or hosting providers, you could add a custom fact for this so that Puppet can determine if any local settings need to be applied (for example, local DNS servers or network routes). How to do it… Here's an example of a simple custom fact: Run the following command: ubuntu@cookbook:~/puppet$ mkdir -p modules/facts/lib/facter Create the file modules/facts/lib/facter/hello.rb with the following contents: Facter.add(:hello) dosetcode do"Hello, world"endend Modify your manifests/nodes.pp file as follows: node 'cookbook' {notify { $::hello: }} Run Puppet: ubuntu@cookbook:~/puppet$ papplyNotice: Hello, worldNotice: /Stage[main]//Node[cookbook]/Notify[Hello, world]/message:defined 'message' as 'Hello, world'Notice: Finished catalog run in 0.24 seconds How it works... The built-in facts in Facter are defined in the same way as the custom fact that we just created. This architecture makes it very easy to add or modify facts, and provides a standard way for you to read information about the host into your Puppet manifests. Facts can contain any Ruby code, and the last value evaluated inside the setcode do ... end block will be the value returned by the fact. For example, you could make a more useful fact that returns the number of users currently logged in: Facter.add(:users) dosetcode do%x{/usr/bin/who |wc -l}.chompendend To reference the fact in your manifests, just use its name like a built-in fact: notify { "${::users} users logged in": }Notice: 2 users logged in You can add custom facts to any Puppet module. You might like to create a dedicated facts module to contain them, as in the example, or just add facts to whichever existing module seems appropriate. There's more... You can extend the use of facts to build a completely nodeless Puppet configuration; in other words, Puppet can decide what resources to apply to a machine, based solely on the results of facts. Jordan Sissel has written about this approach at: http://www.semicomplete.com/blog/geekery/puppet-nodeless-configuration.html You can find out more about custom facts, including how to make sure that OS-specific facts work only on the relevant systems, and how to weight facts so that they're evaluated in a specific order, at the Puppet Labs website: http://docs.puppetlabs.com/guides/custom_facts.html Adding external facts The Creating custom facts recipe describes how to add extra facts to Puppet for use in manifests, but these won't show up in the command-line version of Facter. If you want to make your facts available to both Facter and Puppet, you can create external facts instead. External facts live in the /etc/facter/facts.d directory, and have a simple key=value format, like this: message="Hello, world" Getting ready... Here's what you need to do to prepare your system for adding external facts: You'll need at least Facter 1.7 to use external facts, so run this command to check your Facter version: ubuntu@cookbook:~$ facter -v1.7.1 If your version is pre-1.7, you can install a more recent Facter version from the Puppet Labs APT repo. If you haven't already configured your system to use this repo. Then, run the following commands: ubuntu@cookbook:~$ sudo apt-get updateubuntu@cookbook:~$ sudo apt-get install facter You'll also need to create the external facts directory, using the following command: ubuntu@cookbook:~$ sudo mkdir -p /etc/facter/facts.d How to do it... In this example we'll create a simple external fact that returns a message, as in the Creating custom facts recipe. Create the file /etc/facter/facts.d/myfacts.txt with the following contents: theanswer=42 Run the following command: ubuntu@cookbook:~$ facter theanswer42 Well, that was easy! You can add more facts to the same file, or other files, of course: theanswer=42world_population='7 billion'breakfast=johnnycakes But what if you need to compute a fact in some way; for example, the number of logged-in users? You can create executable facts to do this. Create the file /etc/facter/facts.d/users.sh with the following contents: #!/bin/shecho users=`who |wc -l` Make this file executable with the following command: ubuntu@cookbook:~$ sudo chmod a+x /etc/facter/facts.d/users.sh Now check the fact value with the following command: ubuntu@cookbook:~$ facter users1 How it works... Facter will look in /etc/facter/facts.d and parse any non-executable files there, as lists of key=value pairs, as in the myfacts.txt example. If it finds a key matching the one you requested, it will print the associated value: ubuntu@cookbook:~$ facter theanswer42 In the case of executable files, Facter will assume that their output is a list of key=value pairs. It will execute all the files in the facts.d directory and search their output for the requested key. In the users example, Facter will execute the users.sh script, which results in the following output: users=1 It will then search this output for users and return the matching value: ubuntu@cookbook:~$ facter users1 If there are multiple matches for the key you specified, Facter will return the one parsed first, which is generally the one from the file whose name is alphanumerically first. There's more... You're not limited to using the key=value format for text facts; you can also use YAML or JSON format, and Facter will detect the format based on the file extension. For example, here are some facts in YAML format: ---robin: Erithacus rubeculabluetit: Cyanistes caerulusblackbird: Turdus merula And here are the same facts in JSON format: {"robin": "Erithacus rubecula","bluetit": "Cyanistes caerulus","blackbird": "Turdus merula"} Be careful with the file extension; for YAML files the extension must be .yaml (.yml won't work, for example). JSON files should have a .json extension. For executable facts, however, the output has to be in key=value format. Facter can't auto-detect the format of executable facts (yet). Debugging external facts If you're having trouble getting Facter to recognize your external facts, run Facter in debug mode to see what's happening: ubuntu@cookbook:~/puppet$ facter -d robinFact file /etc/facter/facts.d/myfacts.json was parsed but returned anempty data set The X was parsed but returned an empty data set error means Facter didn't find any key=value pairs in the file or (in the case of an executable fact) in its output. Note that if you have external facts present, Facter parses or runs all the facts in the /etc/facter/facts.d directory every time you query Facter. If some of these scripts take a long time to run, that can significantly slow down anything that uses Facter (run Facter with the —timing switch to troubleshoot this). Unless a particular fact needs to be recomputed every time it's queried, consider replacing it with a cron job that computes it every so often and writes the result to a text file in the Facter directory. Using external facts in Puppet Any external facts you create will be available to both Facter and Puppet. To reference external facts in your Puppet manifests, just use the fact name in the same way you would for a built-in or custom fact: notify { "There are $::users people logged in right now.": } Make sure you don't create facts with the same name as an existing or built-in fact, or strange and probably unwelcome things may happen. Setting facts as environment variables Another handy way to get information into Puppet and Facter is to pass it in using environment variables. Any environment variable whose name starts with FACTER_ will be interpreted as a fact. For example, try the following command: ubuntu@cookbook:~/puppet$ FACTER_moonphase=full facter moonphasefull It works just as well with Puppet, so let's run through an example. How to do it... Follow these steps to see how to set facts using environment variables: Modify your manifests/nodes.pp file as follows: node 'cookbook' {notify { "The moon is $::moonphase": }} Run the following command: ubuntu@cookbook:~/puppet$ FACTER_moonphase="waxing crescent"puppet apply manifests/site.ppNotice: The moon is waxing crescentNotice: /Stage[main]//Node[cookbook]/Notify[The moon is waxingcrescent]/message: defined 'message' as 'The moon is waxingcrescent'Notice: Finished catalog run in 0.06 seconds Importing configuration data with Hiera A key principle of good programming is to separate data and code. Many Puppet manifests are full of site-specific data that makes it hard to share and re-use the manifests. Grouping all such data into structured text files and moving it outside the Puppet manifests makes it easier to maintain, as well as easier to re-use and share code with other people. Ideally, we'd not only be able to look up configuration parameters from a data file, but also choose a different data file depending on things like the environment, the operating system, and other facts about the machine. We'd also like to be able to organize the data hierarchically so that we can override certain values with other, higher-priority values. Puppet has a mechanism named Hiera (as in 'hierarchy') to do just this. The hiera function lets you look up configuration data from within your manifest, and Hiera takes care of returning the correct value for the current environment. Getting ready… In this example we'll see how to set up a minimal Hiera data file, and read some information out of it. First, we need to configure Puppet to retrieve data from Hiera. Follow these steps: Create the file hiera.yaml in your Puppet directory with the following contents: :hierarchy:- common:backends:- yaml:yaml::datadir: '/home/ubuntu/puppet/data' Create the data directory in your Puppet directory: ubuntu@cookbook:~/puppet$ mkdir data Modify your modules/puppet/files/papply.sh script as follows: The sudo puppet apply command is all on one line. #!/bin/shsudo puppet apply /home/ubuntu/puppet/manifests/site.pp--modulepath=/home/ubuntu/puppet/modules/ --hiera_config=/home/ubuntu/puppet/hiera.yaml $* Make sure that your node includes the puppet module, as follows: node 'cookbook' {include puppet} Run Puppet to update the papply script: ubuntu@cookbook:~/puppet$ papplyNotice: /Stage[main]/Puppet/File[/usr/local/bin/papply]/content:content changed '{md5}171896840d39664c00909eb8cf47a53c' to '{md5}6d104081905bcb5e1611ac9b6ae6d3b9'Notice: Finished catalog run in 0.26 seconds How to do it… We've now enabled Hiera, so we're ready to use it. Follow these steps to see how to read Hiera data into your Puppet manifest. Create the file data/common.yaml with the following contents: magic_word : 'xyzzy' Add the following to your manifest: $message = hiera('magic_word')notify { $message: } Run Puppet: ubuntu@cookbook:~/puppet$ papplyNotice: xyzzy How it works… When you look up a bit of data using the hiera function, Hiera has to do several things. First, it has to find its data directory, which is set in hiera.yaml here as /home/ubuntu/puppet/data. Then it needs to know which data file to read. This is determined by the hierarchy setting, which in our example simply contains common. So Hiera will read common.yaml and look for the parameter magic_word. When it finds it, it will read the value (xyzzy) and return it to the manifest. Finally, this value is stored in the $message variable and printed out for our enjoyment. There's more… Hiera is a very powerful mechanism for importing configuration data and we don't have space to explore all its possibilities here. But let's look at a simple improvement to our Hiera setup: adding node-specific settings. Setting node-specific data with Hiera In order to have Hiera read different data files depending on the name of the node, we need to make a couple of changes to the configuration in the previous example, as follows: Modify your hiera.yaml file as follows: :hierarchy:- %{hostname}- common:backends:- yaml:yaml::datadir: '/home/ubuntu/puppet/data' Create the file data/cookbook.yaml (if your machine is named cookbook; otherwise, name it after your hostname) with the following contents: greeting : "Hello, I'm the cookbook node!" Modify your data/common.yaml file as follows: greeting : "Hello, I'm some other node!" Modify your manifests/nodes.pp file as follows: node 'cookbook', 'cookbook2' {$message = hiera('greeting')notify { $message: }} Run Puppet: ubuntu@cookbook:~/puppet$ papplyNotice: Hello, I'm the cookbook node! What's happening here? Recall that Hiera uses the hierarchy setting to determine which data files to search, and in which order. In our example, the first value of hierarchy is: %{hostname} This tells Hiera to look for a .yaml file matching the machine's hostname. If it can't find one, it will go on to the next value in the list: common So for all calls to the hiera function, Hiera will first look for data/cookbook.yaml (or whatever the hostname is), and then data/common.yaml. This allows us to set certain bits of data which are specific to a named node, in this case, cookbook: greeting : "Hello, I'm the cookbook node!" If Hiera can't find a data file matching the machine's hostname, it will look in common.yaml and use the value of the greeting parameter from that file. We can test this by temporarily setting the machine's hostname to something different as follows: ubuntu@cookbook:~/puppet$ sudo hostname cookbook2ubuntu@cookbook:~/puppet$ papplysudo: unable to resolve host cookbook2dnsdomainname: Name or service not knowndnsdomainname: Name or service not knowndnsdomainname: Name or service not knownNotice: Hello, I'm some other node!Notice: /Stage[main]//Node[cookbook2]/Notify[Hello, I'm some othernode!]/message: defined 'message' as 'Hello, I'm some other node!'Notice: Finished catalog run in 0.08 secondsubuntu@cookbook:~/puppet$ sudo hostname cookbook The values you specify for hierarchy can include Facter facts (as in the hostname example) or even Puppet variables. For example, if you had a variable $::vagrant which is true on a Vagrant virtual machine and false otherwise, you could specify: :hierarchy:- vagrant_%{::vagrant} Depending on the value of $::vagrant, Hiera will either look for the data in vagrant_true.yaml or vagrant_false.yaml. This is a great way to modify the node's configuration depending on some external factor without having to use lot of conditional statements and selectors in your Puppet code. Plus, you can store and version the Hiera data separately from your Puppet manifests (and for production use, this is a good idea; it means you can use different data depending on the Puppet environment setting). Looking up data with Hiera There are several ways to look up config data using Hiera: the hiera function, as we saw in the example, simply returns the first match found in the hierarchy for the specified key. However, you can also use hiera_array and hiera_hash to return multiple values. With these functions, Hiera will return all the matches found, including those at different levels of the hierarchy. If you're using Hiera to store your configuration data, there's a gem available called hiera-gpg which adds an encryption backend to Hiera to achieve the same result. Getting ready... To set up hiera-gpg, follow these steps: Run this command to install hiera-gpg: ubuntu@cookbook:~$ sudo gem install hiera-gpg --no-ri --no-rdocFetching: json_pure-1.8.0.gem (100%)Fetching: hiera-1.2.1.gem (100%)Fetching: gpgme-2.0.2.gem (100%)Building native extensions. This could take a while...Fetching: hiera-gpg-1.1.0.gem (100%)Successfully installed json_pure-1.8.0Successfully installed hiera-1.2.1Successfully installed gpgme-2.0.2Successfully installed hiera-gpg-1.1.04 gems installed Modify your hiera.yaml file as follows: :hierarchy:- secret- common:backends:- yaml- gpg:yaml::datadir: '/home/ubuntu/puppet/data':gpg::datadir: '/home/ubuntu/puppet/data' How to do it... In this example we'll create a piece of encrypted data and retrieve it using hiera-gpg. Create the file data/secret.yaml with the following contents: top_secret: 'xyzzy' Encrypt the secret.yaml file to this key using the following command (replace the john@bitfieldconsulting.com with the e-mail address you specified when creating the key). This will create the file secret.gpg: ubuntu@cookbook:~/puppet$ cd dataubuntu@cookbook:~/puppet/data$ gpg -e -o secret.gpg -r john@bitfieldconsulting.com secret.yaml Remove the plaintext secret.yaml file: ubuntu@cookbook:~/puppet/data$ rm secret.yaml Modify your manifests/nodes.pp file as follows: node 'cookbook' {$message = hiera('top_secret')notify { $message: }} Now run Puppet: ubuntu@cookbook:~/puppet$ papplyNotice: xyzzyNotice: /Stage[main]//Node[cookbook]/Notify[xyzzy]/message:defined 'message' as 'xyzzy'Notice: Finished catalog run in 0.29 seconds How it works... When you install hiera-gpg, it adds to Hiera, the ability to decrypt .gpg files. So you can put any secret data into a .yaml file that you then encrypt to the appropriate key with GnuPG. Only machines that have the right secret key will be able to access this data. For example, you might encrypt the MySQL root password using hiera-gpg and install the corresponding key only on your database servers. Although other machines may also have a copy of the secret.gpg file, it's not readable to them unless they have the decryption key. There's more... You might also like to know about hiera-eyaml, another secret-data backend for Hiera that supports encryption of individual values within a Hiera data file. This could be handy if you need to mix encrypted and unencrypted facts within a single file. Find out more about hiera-eyaml here: https://github.com/TomPoulton/hiera-eyaml Summary In this article we learned how to create custom facts, add external facts, set facts as environment variables, import configuration data with Hiera, and store secret data with hiera-gpg. Resources for Article: Further resources on this subject: Quick start – Using the core Puppet resource types [Article] Puppet: Integrating External Tools [Article] Tasks and templates [Article]
Read more
  • 0
  • 0
  • 2679

article-image-paths-and-curves-raphael-js-vector-graphics
Packt
10 Sep 2013
4 min read
Save for later

Paths and curves in Raphael JS Vector Graphics

Packt
10 Sep 2013
4 min read
(For more resources related to this topic, see here.) Path drawing concepts The process of drawing with a pen on paper can be broken down into the following steps: You place your pen at a particular point on a piece of paper. You press and move the pen freely from this point to another point. You keep your pen at this point or lift up the pen and place it at another point on the paper. he process is repeated until you have finished drawing. Path drawing works in much the same way. The point at which you place your pen, known as the current point, defines the start of a path while the free movement of the pen describes the path itself. Consider drawing an arbelos shape. We first place our pen at a point (100, 180) on our canvas and draw an arc to the point (380, 180) as shown: We then create an arc from the point (380, 180) to the point (200, 180): Finally, we create an arc back to the point (100, 180) to complete the path: The example of the arbelos demonstrates the drawing of a single path, where we did not lift up the pen at any point during the drawing process. Were we to lift up the pen, the subsequent drawing would technically create subpaths on the main path element. In the example, creating a triangle as a subpath has the effect of adding to our single path element. Notice also that the fill attribute is applied to the overall path rather than individual subpaths: Drawing Curves There are three types of curve path: quadratic Bézier curves, cubic Bézier curves, and arcs. Bézier curves are curves defined between a start and end point but whose direction we can determine by using control points. Drawing quadratic Bézier curves A quadratic Bézier curve is a curve between two points with a single control point. To appreciate how quadratic Bézier curves are drawn, you should experiment with the animated demo at http://www.jasondavies.com/animated-bezier/. As shown here, the curve is drawn from a point P0 to a point P2 with a control point P1. The control point P1 relative to P0 and P2 determines the extent to which the curve bends: from start to finish, the curve starts off heading in the direction of the control point P1 and then bends towards the end point P2 from the direction of P1. There are two quadratic Bézier curve commands, the syntax for which is given here: Command Parameters Example Q or q (x1, y1, x, y)+ Q 100 50 200 250 T or t (x y)+ T 400 250 The Q command (or q for relative points) describes a curve drawn from the current point on a path to the point (x, y) using (x1, y1) as a control point. For example, consider the following code: paper.path(['M', 50, 150, 'Q', 225, 20, 400, 150]); This draws the quadratic Bézier curve shown. The equivalent path using the lowercase variant of the command would be "M 50,150 q 175,-130 350,0", where the (x, y) and (x1, y1) parameters are the relative distances from the start point (50, 100): Moving the control point affects the way that the path is drawn. For example, the path "M 50, 150 Q 100,40 400,150" is shown as: As with the other commands we have encountered so far, parameters can be repeatable, which allows us to draw multiple connected quadratic Bézier curves. Consider the following code: paper.path([ 'M', 50, 150 'Q', 225, 20, 400, 150, 575, 20, 750, 150]); This has the effect of drawing a second curve from (400, 150) to the point (750, 150) with a control point at (575, 20): The T or t command is shorthand whereby the control point coordinates are not specified. Instead, the control point is determined automatically as a reflection of the previous control point. Consider the path drawn by the following code: paper.path([ 'M', 50, 150, 'Q', 225, 20, 400, 150, 'T', 750, 150 ]); This creates two curves as shown in the following screenshot. The current point at the start of the path drawn by T is (400, 150). Relative to this point, a reflection of the previous control point (225, 20) is (575, 280): Summary In this article we have successfully covered a quadratic Bézier curve. Resources for Article: Further resources on this subject: Getting Started with Impressive Presentations [Article] So, what is EaselJS? [Article] Creating a Simple Application in Sencha Touch [Article]
Read more
  • 0
  • 0
  • 5121

article-image-architecture-javascriptmvc
Packt
10 Sep 2013
2 min read
Save for later

The architecture of JavaScriptMVC

Packt
10 Sep 2013
2 min read
(For more resources related to this topic, see here.) DocumentJS DocumentJS is an independent JavaScript documentation application and provides the following: Inline demos with source code and HTML panels Adds tags to the documentation Adds documentation as favorite Auto suggest search Test result page Comments Extends the JSDoc syntax Adds undocumented code because it understands JavaScript FuncUnit FuncUnit is an independent web testing framework and provides the following: Test clicking, typing, moving mouse cursor, and drag-and-drop utility Follows users between pages Multi browser and operating system support Continuous integration solution Writes and debugs tests in the web browser Chainable API that parallels jQuery jQueryMX jQueryMX is the MVC part of JavaScriptMVC and provides the following: Encourages logically separated, deterministic code MVC layer Uniform client-side template interface (supports jq-tmpl, EJS, JAML, Micro, and Mustache) Ajax fixtures Useful DOM utilities Language helpers JSON utilities Class system Custom events StealJS StealJS is an independent code manager and build tool and provides the following powerful features: Dependency management Loads JavaScript and CoffeeScript Loads CSS, Less, and Sass files Loads client-side templates such as TODO Loasd individual files only once Loads files from a different domain Concatenation and compression Google Closure compressor Makes multi-page build Pre processes TODO Can conditionally remove specified code from the production build Builds standalone jQuery plugins Logger Logs messages in a development mode Code generator Generates an application skeleton Adds the possibility to create your own generator Package management Downloads and install plugins from SVN and Git repositories Installs the dependencies Runs install scripts Loads individual files only once Loads files from a different domain Code cleaner Runs JavaScript beautifier against your codebase Runs JSLint against your codebase Resources for Article : Further resources on this subject: YUI Test [Article] From arrays to objects [Article] Writing Your First Lines of CoffeeScript [Article]
Read more
  • 0
  • 0
  • 2154

article-image-regression-models-weka
Packt
06 Sep 2013
4 min read
Save for later

Regression models in Weka

Packt
06 Sep 2013
4 min read
(For more resources related to this topic, see here.) Getting ready Let's look at an example of a house price-based regression model, and create some real data to examine. These are actual numbers from houses for sale, and we will be trying to find the value of a house we are supposed to sell: Size (m2) Land (m2) Rooms Granite Extra bathroom Price 1076 2801 6 0 0 €324.500,00 990 3067 5 1 1 €466.000,00 1229 3094 5 0 1 €425.900,00 731 4315 4 1 0 €387.120,00 671 2926 4 0 1 €312.100,00 1078 6094 6 1 1 €603.000,00 909 2854 5 0 1 €383.400,00 975 2947 5 1 1 ?? To load files in Weka, we have to put the table in the ARFF file format and save it as house.arff. Make sure the attributes are numeric, as shown here: @RELATION house@ATTRIBUTE size NUMERIC@ATTRIBUTE land NUMERIC@ATTRIBUTE rooms NUMERIC@ATTRIBUTE granite NUMERIC@ATTRIBUTE extra_bathroom NUMERIC@ATTRIBUTE price NUMERIC@DATA1076,2801,6,0,0,324500990,3067,5,1,1,4660001229,3094,5,0,1,425900731,4315,4,1,0,387120671,2926,4,0,1,3121001078,6094,6,1,1,603000909,2854,5,0,1,383400975,2947,5,1,1,? How to do it… Use the following snippet: import java.io.BufferedReader;import java.io.FileReader;import weka.core.Instance;import weka.core.Instances;import weka.classifiers.functions.LinearRegression;public class Regression{public static void main(String args[]) throws Exception{//load dataInstances data = new Instances(new BufferedReader(newFileReader("dataset/house.arff")));data.setClassIndex(data.numAttributes() - 1);//build modelLinearRegression model = new LinearRegression();model.buildClassifier(data); //the last instance with missingclass is not usedSystem.out.println(model);//classify the last instanceInstance myHouse = data.lastInstance();double price = model.classifyInstance(myHouse);System.out.println("My house ("+myHouse+"): "+price);}} Here is the output: Linear Regression Modelprice =195.2035 * size +38.9694 * land +76218.4642 * granite +73947.2118 * extra_bathroom +2681.136My house (975,2947,5,1,1,?): 458013.16703945777 How it works… Import a basic regression model named weka.classifiers.functions.LinearRegression: import java.io.BufferedReader;import java.io.FileReader;import weka.core.Instance;import weka.core.Instances;import weka.classifiers.functions.LinearRegression; Load the house dataset: Instances data = new Instances(new BufferedReader(newFileReader("dataset/house.arff")));data.setClassIndex(data.numAttributes() - 1); Initialize and build a regression model. Note, that the last instance is not used for building the model since the class value is missing: LinearRegression model = new LinearRegression();model.buildClassifier(data); Output the model: System.out.println(model); Use the model to predict the price of the last instance in the dataset: Instance myHouse = data.lastInstance();double price = model.classifyInstance(myHouse);System.out.println("My house ("+myHouse+"): "+price); There’s more This section lists some additional algorithms. Other regression algorithms There is a wide variety of implemented regression algorithms one can use in Weka: weka.classifiers.rules.ZeroR: The class for building and using an 0-R classifier. Predicts the mean (for a numeric class) or the mode (for a nominal class) and it is considered as a baseline; that is, if your classifier's performance is worse than average value predictor, it is not worth considering it. weka.classifiers.trees.REPTree: The fast decision tree learner. Builds a decision/regression tree using information gain/variance and prunes it using reduced-error pruning (with backfitting). It only sorts values for numeric attributes once. Missing values are dealt with by splitting the corresponding instances into pieces (that is, as in C4.5). weka.classifiers.functions.SMOreg: SMOreg implements the support vector machine for regression. The parameters can be learned using various algorithms. The algorithm is selected by setting the RegOptimizer. The most popular algorithm (RegSMOImproved) is due to Shevade, Keerthi, and others, and this is the default RegOptimizer. weka.classifiers.functions.MultilayerPerceptron: A classifier that uses backpropagation to classify instances. This network can be built by hand, or created by an algorithm, or both. The network can also be monitored and modified during training time. The nodes in this network are all sigmoid (except for when the class is numeric in which case the output nodes become unthresholded linear units). weka.classifiers.functions.GaussianProcesses: Implements Gaussian Processes for regression without hyperparameter-tuning. Summary We learned how to use models that predict a value of numerical class, in contrast to classification, which predicts the value of a nominal class. Given a set of attributes, the regression builds a model, usually an equation that is used to compute the predicted class value. Resources for Article: Further resources on this subject: Java in Oracle Database [Article] Installing and Setting up JavaFX for NetBeans and Eclipse IDE [Article] Getting Started with JavaFX [Article]
Read more
  • 0
  • 0
  • 10835
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-kendo-mvvm-framework
Packt
06 Sep 2013
19 min read
Save for later

The Kendo MVVM Framework

Packt
06 Sep 2013
19 min read
(For more resources related to this topic, see here.) Understanding MVVM – basics MVVM stands for Model ( M ), View ( V ), and View-Model ( VM ). It is part of a family of design patterns related to system architecture that separate responsibilities into distinct units. Some other related patterns are Model-View-Controller ( MVC ) and Model-View-Presenter ( MVP ). These differ on what each portion of the framework is responsible for, but they all attempt to manage complexity through the same underlying design principles. Without going into unnecessary details here, suffice it to say that these patterns are good for developing reliable and reusable code and they are something that you will undoubtedly benefit from if you have implemented them properly. Fortunately, the good JavaScript MVVM frameworks make it easy by wiring up the components for you and letting you focus on the code instead of the "plumbing". In the MVVM pattern for JavaScript through Kendo UI, you will need to create a definition for the data that you want to display and manipulate (the Model), the HTML markup that structures your overall web page (the View), and the JavaScript code that handles user input, reacts to events, and transforms the static markup into dynamic elements (the View-Model). Another way to put it is that you will have data (Model), presentation (View), and logic (View-Model). In practice, the Model is the most loosely-defined portion of the MVVM pattern and is not always even present as a unique entity in the implementation. The View-Model can assume the role of both Model and View-Model by directly containing the Model data properties within itself, instead of referencing them as a separate unit. This is acceptable and is also seen within ASP.NET MVC when a View uses the ViewBag or the ViewData collections instead of referencing a strongly-typed Model class. Don't let it bother you if the Model isn't as well defined as the View-Model and the View. The implementation of any pattern should be filtered down to what actually makes sense for your application. Simple data binding As an introductory example, consider that you have a web page that needs to display a table of data, and also provide the users with the ability to interact with that data, by clicking specifically on a single row or element. The data is dynamic, so you do not know beforehand how many records will be displayed. Also, any change should be reflected immediately on the page instead of waiting for a full page refresh from the server. How do you make this happen? A traditional approach would involve using special server-side controls that can dynamically create tables from a data source and can even wire-up some JavaScript interactivity. The problem with this approach is that it usually requires some complicated extra communication between the server and the web browser either through "view state", hidden fields, or long and ugly query strings. Also, the output from these special controls is rarely easy to customize or manipulate in significant ways and reduces the options for how your site should look and behave. Another choice would be to create special JavaScript functions to asynchronously retrieve data from an endpoint, generate HTML markup within a table and then wire up events for buttons and links. This is a good solution, but requires a lot of coding and complexity which means that it will likely take longer to debug and refine. It may also be beyond the skill set of a given developer without significant research. The third option, available through a JavaScript MVVM like Kendo UI, strikes a balance between these two positions by reducing the complexity of the JavaScript but still providing powerful and simple data binding features inside of the page. Creating the view Here is a simple HTML page to show how a view basically works: <!DOCTYPE html> <html > <head> <title>MVVM Demo 1</title> <script src ="/Scripts/kendo/jquery.js"></script> <script src ="/Scripts/kendo/kendo.all.js"></script> <link href="/Content/kendo/kendo.common.css" rel="stylesheet" /> <link href="/Content/kendo/kendo.default.css" rel="stylesheet" /> <style type="text/css"> th { width: 135px; } </style> </head> <body> <table> <caption>People Data</caption> <thead> <tr> <th>Name</th> <th>Hair Color</th> <th>Favorite Food</th> </tr> </thead> <tbody data-template="row-template" data-bind="source: people"></tbody> </table> </body> </html> Here we have a simple table element with three columns but instead of the body containing any tr elements, there are some special HTML5 data-* attributes indicating that something special is going on here. These data-* attributes do nothing by themselves, but Kendo UI reads them (as you will see below) and interprets their values in order to link the View with the View-Model. The data-bind attribute indicates to Kendo UI that this element should be bound to a collection of objects called people. The data-template attribute tells Kendo UI that the people objects should be formatted using a Kendo UI template. Here is the code for the template: <script id="row-template" type="text/x-kendo-template"> <tr> <td data-bind="text: name"></td> <td data-bind="text: hairColor"></td> <td data-bind="text: favoriteFood"></td> </tr> </script> This is a simple template that defines a tr structure for each row within the table. The td elements also have a data-bind attribute on them so that Kendo UI knows to insert the value of a certain property as the "text" of the HTML element, which in this case means placing the value in between <td> and </td> as simple text on the page. Creating the Model and View-Model In order to wire this up, we need a View-Model that performs the data binding. Here is the View-Model code for this View: <script type="text/javascript"> var viewModel = kendo.observable({ people: [ {name: "John", hairColor: "Blonde", favoriteFood: "Burger"}, {name: "Bryan", hairColor: "Brown", favoriteFood: "Steak"}, {name: "Jennifer", hairColor: "Brown", favoriteFood: "Salad"} ] }); kendo.bind($("body"), viewModel); </script> A Kendo UI View-Model is declared through a call to kendo.observable() which creates an observable object that is then used for the data-binding within the View. An observable object is a special object that wraps a normal JavaScript variable with events that fire any time the value of that variable changes. These events notify the MVVM framework to update any data bindings that are using that variable's value, so that they can update immediately and reflect the change. These data bindings also work both ways so that if a field bound to an observable object variable is changed, the variable bound to that field is also changed in real time. In this case, I created an array called people that contains three objects with properties about some people. This array, then, operates as the Model in this example since it contains the data and the definition of how the data is structured. At the end of this code sample, you can see the call to kendo.bind($("body"), viewModel) which is how Kendo UI actually performs its MVVM wiring. I passed a jQuery selector for the body tag to the first parameter since this viewModel object applies to the full body of my HTML page, not just a portion of it. With everything combined, here is the full source for this simplified example: <!DOCTYPE html> <html > <head> <title>MVVM Demo 1</title> <scriptsrc ="/Scripts/kendo/jquery.js"></script> <scriptsrc ="/Scripts/kendo/kendo.all.js"></script> <link href="/Content/kendo/kendo.common.css" rel="stylesheet" /> <link href="/Content/kendo/kendo.default.css" rel="stylesheet" /> <style type="text/css"> th { width: 135px; } </style> </head> <body> <table> <caption>People Data</caption> <thead> <tr> <th>Name</th> <th>Hair Color</th> <th>Favorite Food</th> </tr> </thead> <tbody data-template="row-template" data-bind="source: people"></tbody> </table> <script id="row-template" type="text/x-kendo-template"> <tr> <td data-bind="text: name"></td> <td data-bind="text: hairColor"></td> <td data-bind="text: favoriteFood"></td> </tr> </script> <script type="text/javascript"> var viewModel = kendo.observable({ people: [ {name: "John", hairColor: "Blonde", favoriteFood: "Burger"}, {name: "Bryan", hairColor: "Brown", favoriteFood: "Steak"}, { name: "Jennifer", hairColor: "Brown", favoriteFood: "Salad" } ] }); kendo.bind($("body"), viewModel); </script> </body> </html> Here is a screenshot of the page in action. Note how the data from the JavaScript people array is populated into the table automatically: Even though this example contains a Model, a View, and a View-Model, all three units appear in the same HTML file. You could separate the JavaScript into other files, of course, but it is also acceptable to keep them together like this. Hopefully you are already seeing what sort of things this MVVM framework can do for you. Observable data binding Binding data into your HTML web page (View) using declarative attributes is great, and very useful, but the MVVM framework offers some much more significant functionality that we didn't see in the last example. Instead of simply attaching data to the View and leaving it at that, the MVVM framework maintains a running copy of all of the View-Model's properties, and keeps references to those properties up to date in real time. This is why the View-Model is created with a function called "observable". The properties inside, being observable, report changes back up the chain so that the data-bound fields always reflect the latest data. Let's see some examples. Adding data dynamically Building on the example we just saw, add this horizontal rule and form just below the table in the HTML page: <hr /> <form> <header>Add a Person</header> <input type="text" name="personName" placeholder="Name" data-bind="value: personName" /><br /> <input type="text" name="personHairColor" placeholder="Hair Color" data-bind="value: personHairColor" /><br /> <input type="text" name="personFavFood" placeholder="Favorite Food" data-bind="value: personFavFood" /><br /> <button type="button" data-bind="click: addPerson">Add</button> </form> This adds a form to the page so that a user can enter data for a new person that should appear in the table. Note that we have added some data-bind attributes, but this time we are binding the value of the input fields not the text. Note also that we have added a data-bind attribute to the button at the bottom of the form that binds the click event of that button with a function inside our View-Model. By binding the click event to the addPerson JavaScript method, the addPerson method will be fired every time this button is clicked. These bindings keep the value of those input fields linked with the View-Model object at all times. If the value in one of these input fields changes, such as when a user types something in the box, the View-Model object will immediately see that change and update its properties to match; it will also update any areas of the page that are bound to the value of that property so that they match the new data as well. The binding for the button is special because it allows the View-Model object to attach its own event handler to the click event for this element. Binding an event handler to an event is nothing special by itself, but it is important to do it this way (through the data-bind attribute) so that the specific running View-Model instance inside of the page has attached one of its functions to this event so that the code inside the event handler has access to this specific View-Model's data properties and values. It also allows for a very specific context to be passed to the event that would be very hard to access otherwise. Here is the code I added to the View-Model just below the people array. The first three properties that we have in this example are what make up the Model. They contain that data that is observed and bound to the rest of the page: personName: "", // Model property personHairColor: "", // Model property personFavFood: "", // Model property addPerson: function () { this.get("people").push({ name: this.get("personName"), hairColor: this.get("personHairColor"), favoriteFood: this.get("personFavFood") }); this.set("personName", ""); this.set("personHairColor", ""); this.set("personFavFood", ""); } The first several properties you see are the same properties that we are binding to in the input form above. They start with an empty value because the form should not have any values when the page is first loaded. It is still important to declare these empty properties inside the View-Model in order that their value can be tracked when it changes. The function after the data properties, addPerson , is what we have bound to the click event of the button in the input form. Here in this function we are accessing the people array and adding a new record to it based on what the user has supplied in the form fields. Notice that we have to use the this.get() and this.set() functions to access the data inside of our View-Model. This is important because the properties in this View-Model are special observable properties so accessing their values directly may not give you the results you would expect. The most significant thing that you should notice about the addPerson function is that it is interacting with the data on the page through the View-Model properties. It is not using jQuery, document.querySelector, or any other DOM interaction to read the value of the elements! Since we declared a data-bind attribute on the values of the input elements to the properties of our View-Model, we can always get the value from those elements by accessing the View-Model itself. The values are tracked at all times. This allows us to both retrieve and then change those View-Model properties inside the addPerson function and the HTML page will show the changes right as it happens. By calling this.set() on the properties and changing their values to an empty string, the HTML page will clear the values that the user just typed and added to the table. Once again, we change the View-Model properties without needing access to the HTML ourselves. Here is the complete source of this example: <!DOCTYPE html> <html > <head> <title>MVVM Demo 2</title> <scriptsrc ="/Scripts/kendo/jquery.js"></script> <scriptsrc ="/Scripts/kendo/kendo.all.js"></script> <link href="/Content/kendo/kendo.common.css" rel="stylesheet" /> <link href="/Content/kendo/kendo.default.css" rel="stylesheet" /> <style type="text/css"> th { width: 135px; } </style> </head> <body> <table> <caption>People Data</caption> <thead> <tr> <th>Name</th> <th>Hair Color</th> <th>Favorite Food</th> </tr> </thead> <tbody data-template="row-template" data-bind="source: people"></tbody> </table> <hr /> <form> <header>Add a Person</header> <input type="text" name="personName" placeholder="Name"data-bind="value: personName" /><br /> <input type="text" name="personHairColor" placeholder="Hair Color"data-bind="value: personHairColor" /><br /> <input type="text" name="personFavFood" placeholder="Favorite Food"data-bind="value: personFavFood" /><br /> <button type="button" data-bind="click: addPerson">Add</button> </form> <script id="row-template" type="text/x-kendo-template"> <tr> <td data-bind="text: name"></td> <td data-bind="text: hairColor"></td> <td data-bind="text: favoriteFood"></td> </tr> </script> <script type="text/javascript"> var viewModel = kendo.observable({ people: [ {name: "John", hairColor: "Blonde", favoriteFood: "Burger"}, {name: "Bryan", hairColor: "Brown", favoriteFood: "Steak"}, {name: "Jennifer", hairColor: "Brown", favoriteFood: "Salad"} ], personName: "", personHairColor: "", personFavFood: "", addPerson: function () { this.get("people").push({ name: this.get("personName"), hairColor: this.get("personHairColor"), favoriteFood: this.get("personFavFood") }); this.set("personName", ""); this.set("personHairColor", ""); this.set("personFavFood", ""); } }); kendo.bind($("body"), viewModel); </script> </body> </html> And here is a screenshot of the page in action. You will see that one additional person has been added to the table by filling out the form. Try it out yourself to see the immediate interaction that you get with this code: Using observable properties in the View We just saw how simple it is to add new data to observable collections in the View-Model, and how this causes any data-bound elements to immediately show that new data. Let's add some more functionality to illustrate working with individual elements and see how their observable values can update content on the page. To demonstrate this new functionality, I have added some columns to the table: <table> <caption>People Data</caption> <thead> <tr> <th>Name</th> <th>Hair Color</th> <th>Favorite Food</th> <th></th> <th>Live Data</th> </tr> </thead> <tbody data-template="row-template" data-bind="source: people"></tbody> </table> The first new column has no heading text but will contain a button on the page for each of the table rows. The second new column will be displaying the value of the "live data" in the View-Model for each of the objects displayed in the table. Here is the updated row template: <script id="row-template" type="text/x-kendo-template"> <tr> <td><input type="text" data-bind="value: name" /></td> <td><input type="text" data-bind="value: hairColor" /></td> <td><input type="text" data-bind="value: favoriteFood" /></td> <td><button type="button" data-bind="click: deletePerson">Delete</button></td> <td><span data-bind="text: name"></span>&nbsp;-&nbsp; <span data-bind="text: hairColor"></span>&nbsp;-&nbsp; <span data-bind="text: favoriteFood"></span></td> </tr> </script> Notice that I have replaced all of the simple text data-bind attributes with input elements and valuedata-bind attributes. I also added a button with a clickdata-bind attribute and a column that displays the text of the three properties so that you can see the observable behavior in real time. The View-Model gets a new method for the delete button: deletePerson: function (e) { var person = e.data; var people = this.get("people"); var index = people.indexOf(person); people.splice(index, 1); } When this function is called through the binding that Kendo UI has created, it passes an event argument, here called e, into the function that contains a data property. This data property is a reference to the model object that was used to render the specific row of data. In this function, I created a person variable for a reference to the person in this row and a reference to the people array; we then use the index of this person to splice it out of the array. When you click on the Delete button, you can observe the table reacting immediately to the change. Here is the full source code of the updated View-Model: <script id="row-template" type="text/x-kendo-template"> <tr> <td><input type="text" data-bind="value: name" /></td> <td><input type="text" data-bind="value: hairColor" /></td><td><input type="text" data-bind="value: favoriteFood" /></td> <td><button type="button" data-bind="click: deletePerson">Delete</button></td> <td><span data-bind="text: name"></span>&nbsp;-&nbsp; <span data-bind="text: hairColor"></span>&nbsp;-&nbsp; <span data-bind="text: favoriteFood"></span></td></tr> </script><script type="text/javascript"> var viewModel = kendo.observable({ people: [ {name: "John", hairColor: "Blonde", favoriteFood: "Burger"}, {name: "Bryan", hairColor: "Brown", favoriteFood: "Steak"}, {name: "Jennifer", hairColor: "Brown", favoriteFood: "Salad"} ], personName: "", personHairColor: "", personFavFood: "", addPerson: function () { this.get("people").push({ name: this.get("personName"), hairColor: this.get("personHairColor"), favoriteFood: this.get("personFavFood") }); this.set("personName", ""); this.set("personHairColor", ""); this.set("personFavFood", ""); }, deletePerson: function (e) { var person = e.data; var people = this.get("people"); var index = people.indexOf(person); people.splice(index, 1); } }); kendo.bind($("body"), viewModel); </script> </body> </html> Here is a screenshot of the new page: Click on the Delete button to see an entry disappear. You can also see that I have added a new person to the table and that I have made changes in the input boxes of the table and that those changes immediately show up on the right-hand side. This indicates that the View-Model is keeping track of the live data and updating its bindings accordingly.
Read more
  • 0
  • 0
  • 5064

article-image-recursive-queries
Packt
06 Sep 2013
5 min read
Save for later

Recursive queries

Packt
06 Sep 2013
5 min read
(For more resources related to this topic, see here.) XML is one solution to dealing with hierarchical data, but it isn't the most natural for the relational database. Instead, you often wind up with nested categories, or filesystem-like folder hierarchies, or links back to older records. A popular way to structure a relational database for data with this shape is using a self reference, a link back to a parent object in the same table.For instance, you might want to model categories that can have subcategories with arbitrary nesting. A simple table might look like this: CREATE TABLE categories ( id SERIAL PRIMARY KEY, name VARCHAR, parent_id INTEGER REFERENCES categories); What makes this structure recursive is that self-referencing parent_id column, which refers to the table we're defining from within its own definition. We would treat categories with a NULL value for the parent_id column as top-level categories, categories that do not belong within any other category. To get a feel for the kind of data, let's put a few categories in there for an online retailer. Say we sell shirts and books, and books we further divide into fiction and non-fiction, and then we'll put programming books inside non-fiction. It might look like the following: INSERT INTO categories (id, name, parent_id) VALUES(1, 'Shirts', NULL),(2, 'Books', NULL),(3, 'Fiction', 2),(4, 'Non-fiction', 2),(5, 'Programming', 4); Usually you won't put these in manually like this, but you can see that Fiction and Non-fiction are children of the Books category because their parent_id values are 2, the value for Books is NULL and Programming has the parent_id value as 4, which is the id value for Non-fiction. Suppose you want to make navigation breadcrumbs given a category. You need to look up that category and then you need to look up the parent category. You need to do this until the parent category is NULL. In a procedural pseudocode, the process might look like the following: def write_breadcrumbs(category): row = getOne("SELECT * FROM categories WHERE id = ?", category) while row['parent_id'] != NULL: write(row['name']) write(' > ') row = getOne("SELECT * FROM categories WHERE id = ?", row['parent_id']) This kind of solution leads to the N+1 query problem. There's an action you want to take for a particular value, but to take that action you have to run an arbitrary number of separate queries. Recursive queries in PostgreSQL provide you with a way to have the database do the heavy lifting instead. Because we'll be using recursion in the SQL, let's first see what a recursion formulation would look like in our pseudocode: def write_breadcrumbs(category): row = getOne("SELECT * FROM categories WHERE id = ?", category) write(row['name']) if row['parent_id'] != NULL: write(' > ') write_breadcrumbs(row['parent_id']) It's debatable whether this is better code; it's shorter, and it has fewer bugs, but it also might expose the developer to the possibility of stack overflows. Recursive functions always have some similar structure though, some number of base cases that do not call the function recursively and some number of inductive cases that work by calling the same function again on slightly different data. The final destination will be one of the base cases. The inductive cases will peel off a small piece of the problem and solve it, then delegate the rest of the work to an invocation of the same function. PostgreSQL's recursive query support works with something called the common table expressions (CTEs). The idea is to make a named alias for a query. We won't delve into the details too much here, but all recursive queries will have the same basic structure: WITH RECURSIVE recursive-query-name AS ( SELECT <base-case> FROM table UNION ALL SELECT <inductive-case> FROM table JOIN <recursive-query-name> ON )SELECT * FROM <recursive-query-name>; For an example, let's get all the categories above Programming. The base case will be the Programming category itself. The inductive case will be to find the parent of a category we've already seen: WITH RECURSIVE programming_parents AS ( SELECT * FROM categories WHERE id = 5 UNION ALL SELECT categories.* FROM categories JOIN programming_parents ON programming_parents.parent_id = categories.id)SELECT * FROM programming_parents; This works as we'd hope. Output of a simple recursive query Without using this trick we'd have to do three separate queries to get this information, but with the trick it will always take one query no matter how deeply nested the categories are. We can also go in the other direction and build up something like a tree underneath a category by searching for categories that have a category we've already seen as a parent category. We can make the hierarchy more explicit by building up a path as we go: WITH RECURSIVE all_categories AS ( SELECT *, name as path FROM categories WHERE parent_id IS NULL UNION ALL SELECT c.*, p.path || '/' || c.name FROM categories AS c JOIN all_categories p ON p.id = c.parent_id)SELECT * FROM all_categories; Finding all the categories with their path We can be more discriminating with the search by looking for a particular category as the starting value in the base case: WITH RECURSIVE all_categories AS ( SELECT *, name as path FROM categories WHERE id = 2 UNION ALL SELECT c.*, p.path || '/' || c.name FROM categories AS c JOIN all_categories p ON p.id = c.parent_id)SELECT * FROM all_categories; The category tree rooted at Books This is hugely useful with hierarchical data. Summary In this article we learned about recursive queries as one of the most important features of PostgreSQL. Resources for Article: Further resources on this subject: Introduction to PostgreSQL 9 [Article] PostgreSQL: Tips and Tricks [Article] Obtaining a binary backup [Article]
Read more
  • 0
  • 0
  • 5701

article-image-playing-max-6-framework
Packt
06 Sep 2013
17 min read
Save for later

Playing with Max 6 Framework

Packt
06 Sep 2013
17 min read
(For more resources related to this topic, see here.) Communicating easily with Max 6 – the [serial] object The easiest way to exchange data between your computer running a Max 6 patch and your Arduino board is via the serial port. The USB connector of our Arduino boards includes the FTDI integrated circuit EEPROM FT-232 that converts the RS-232 plain old serial standard to USB. We are going to use again our basic USB connection between Arduino and our computer in order to exchange data here. The [serial] object We have to remember the [serial] object's features. It provides a way to send and receive data from a serial port. To do this, there is a basic patch including basic blocks. We are going to improve it progressively all along this article. The [serial] object is like a buffer we have to poll as much as we need. If messages are sent from Arduino to the serial port of the computer, we have to ask the [serial] object to pop them out. We are going to do this in the following pages. This article is also a pretext for me to give you some of my tips and tricks in Max 6 itself. Take them and use them; they will make your patching life easier. Selecting the right serial port we have used the message (print) sent to [serial] in order to list all the serial ports available on the computer. Then we checked the Max window. That was not the smartest solution. Here, we are going to design a better one. We have to remember the [loadbang] object. It fires a bang, that is, a (print) message to the following object as soon as the patch is loaded. It is useful to set things up and initialize some values as we could inside our setup() block in our Arduino board's firmware. Here, we do that in order to fill the serial port selector menu. When the [serial] object receives the (print) message, it pops out a list of all the serial ports available on the computer from its right outlet prepended by the word port. We then process the result by using [route port] that only parses lists prepended with the word port. The [t] object is an abbreviation of [trigger]. This object sends the incoming message to many locations, as is written in the documentation, if you assume the use of the following arguments: b means bang f means float number i means integer s means symbol l means list (that is, at least one element) We can also use constants as arguments and as soon as the input is received, the constant will be sent as it is. At last, the [trigger] output messages in a particular order: from the rightmost outlet to the leftmost one. So here we take the list of serial ports being received from the [route] object; we send the clear message to the [umenu] object (the list menu on the left side) in order to clear the whole list. Then the list of serial ports is sent as a list (because of the first argument) to [iter]. [iter] splits a list into its individual elements. [prepend] adds a message in front of the incoming input message. That means the global process sends messages to the [umenu] object similar to the following: append xxxxxx append yyyyyy Here xxxxxx and yyyyyy are the serial ports that are available. This creates the serial port selector menu by filling the list with the names of the serial ports. This is one of the typical ways to create some helpers, in this case the menu, in our patches using UI elements. As soon as you load this patch, the menu is filled, and you only have to choose the right serial port you want to use. As soon as you select one element in the menu, the number of the element in the list is fired to its leftmost outlet. We prepend this number by port and send that to [serial], setting it up to the right-hand serial port. Polling system One of the most used objects in Max 6 to send regular bangs in order to trigger things or count time is [metro]. We have to use one argument at least; this is the time between two bangs in milliseconds. Banging the [serial] object makes it pop out the values contained in its buffer. If we want to send data continuously from Arduino and process them with Max 6, activating the [metro] object is required. We then send a regular bang and can have an update of all the inputs read by Arduino inside our Max 6 patch. Choosing a value between 15 ms and 150 ms is good but depends on your own needs. Let's now see how we can read, parse, and select useful data being received from Arduino. Parsing and selecting data coming from Arduino First, I want to introduce you to a helper firmware inspired by the Arduino2Max page on the Arduino website but updated and optimized a bit by me. It provides a way to read all the inputs on your Arduino, to pack all the data read, and to send them to our Max 6 patch through the [serial] object. The readAll firmware The following code is the firmware. int val = 0; void setup() { Serial.begin(9600); pinMode(13,INPUT); } void loop() { // Check serial buffer for characters incoming if (Serial.available() > 0){ // If an 'r' is received then read all the pins if (Serial.read() == 'r') { // Read and send analog pins 0-5 values for (int pin= 0; pin<=5; pin++){ val = analogRead(pin); sendValue (val); } // Read and send digital pins 2-13 values for (int pin= 2; pin<=13; pin++){ val = digitalRead(pin); sendValue (val); } Serial.println();// Carriage return to mark end of data flow. delay (5); // prevent buffer overload } } } void sendValue (int val){ Serial.print(val); Serial.write(32); // add a space character after each value sent } For starters, we begin the serial communication at 9600 bauds in the setup() block. As usual with serial communication handling, we check if there is something in the serial buffer of Arduino at first by using the Serial.available() function. If something is available, we check if it is the character r. Of course, we can use any other character. r here stands for read, which is basic. If an r is received, it triggers the read of both analog and digital ports. Each value (the val variable) is passed to the sendValue()function; this basically prints the value into the serial port and adds a space character in order to format things a bit to provide an easier parsing by Max 6. We could easily adapt this code to only read some inputs and not all. We could also remove the sendValue() function and find another way of packing data. At the end, we push a carriage return to the serial port by using Serial.println(). This creates a separator between each pack of data that is sent. Now, let's improve our Max 6 patch to handle this pack of data being received from Arduino. The ReadAll Max 6 patch The following screenshot is the ReadAll Max patch that provides a way to communicate with our Arduino: Requesting data from Arduino First, we will see a [t b b] object. It is also a trigger, ordering bangs provided by the [metro] object. Each bang received triggers another bang to another [trigger] object, then another one to the [serial] object itself. The [t 13 r] object can seem tricky. It just triggers a character r and then the integer 13. The character r is sent to [spell] that converts it to ASCII code and then sends the result to [serial]. 13 is the ASCII code for a carriage return. This structure provides a way to fire the character r to the [serial] object, which means to Arduino, each time that the metro bangs. As we already see in the firmware, it triggers Arduino to read all its inputs, then to pack the data, and then to send the pack to the serial port for the Max 6 patch. To summarize what the metro triggers at each bang, we can write this sequence: Send the character r to Arduino. Send a carriage return to Arduino. Bang the [serial] object. This triggers Arduino to send back all its data to the Max patch. Parsing the received data Under the [serial] object, we can see a new structure beginning with the [sel 10 13] object. This is an abbreviation for the [select] object. This object selects an incoming message and fires a bang to the specific output if the message equals the argument corresponding to the specific place of that output. Basically, here we select 10 or 13. The last output pops the incoming message out if that one doesn't equal any argument. Here, we don't want to consider a new line feed (ASCII code 10). This is why we put it as an argument, but we don't do anything if that's the one that has been selected. It is a nice trick to avoid having this message trigger anything and even to not have it from the right output of [select]. Here, we send all the messages received from Arduino, except 10 or 13, to the [zl group 78] object. The latter is a powerful list for processing many features. The group argument makes it easy to group the messages received in a list. The last argument is to make sure we don't have too many elements in the list. As soon as [zl group] is triggered by a bang or the list length reaches the length argument value, it pops out the whole list from its left outlet. Here, we "accumulate" all the messages received from Arduino, and as soon as a carriage return is sent (remember we are doing that in the last rows of the loop() block in the firmware), a bang is sent and all the data is passed to the next object. We currently have a big list with all the data inside it, with each value being separated from the other by a space character (the famous ASCII code 32 we added in the last function of the firmware). This list is passed to the [itoa] object. itoa stands for integer to ASCII . This object converts integers to ASCII characters. The [fromsymbol] object converts a symbol to a list of messages. Finally, after this [fromsymbol] object we have our big list of values separated by spaces and totally readable. We then have to unpack the list. [unpack] is a very useful object that provides a way to cut a list of messages into individual messages. We can notice here that we implemented exactly the opposite process in the Arduino firmware while we packed each value into a big message. [unpack] takes as many arguments as we want. It requires knowing about the exact number of elements in the list sent to it. Here we send 12 values from Arduino, so we put 12 i arguments. i stands for integer . If we send a float, [unpack] would cast it as an integer. It is important to know this. Too many students are stuck with troubleshooting this in particular. We are only playing with the integer here. Indeed, the ADC of Arduino provides data from 0 to 1023 and the digital input provides 0 or 1 only. We attached a number box to each output of the [unpack] object in order to display each value. Then we used a [change] object. This latter is a nice object. When it receives a value, it passes it to its output only if it is different from the previous value received. It provides an effective way to avoid sending the same value each time when it isn't required. Here, I chose the argument -1 because this is not a value sent by the Arduino firmware, and I'm sure that the first element sent will be parsed. So we now have all our values available. We can use them for different jobs. But I propose to use a smarter way, and this will also introduce a new concept. Distributing received data and other tricks Let's introduce here some other tricks to improve our patching style. Cordless trick We often have to use some data in our patches. The same data has to feed more than one object. A good way to avoid messy patches with a lot of cord and wires everywhere is to use the [send] and [receive] objects. These objects can be abbreviated with [s] and [r], and they generate communication buses and provide a wireless way to communicate inside our patches. These three structures are equivalent. The first one is a basic cord. As soon as we send data from the upper number box, it is transmitted to the one at the other side of the cord. The second one generates a data bus named busA. As soon as you send data into [send busA], each [receive busA] object in your patch will pop out that data. The third example is the same as the second one, but it generates another bus named busB. This is a good way to distribute data. I often use this for my master clock, for instance. I have one and only one master clock banging a clock to [send masterClock], and wherever I need to have that clock, I use [receive masterClock] and it provides me with the data I need. If you check the global patch, you can see that we distribute data to the structures at the bottom of the patch. But these structures could also be located elsewhere. Indeed, one of the strengths of any visual programming framework such as Max 6 is the fact that you can visually organize every part of your code exactly as you want in your patcher. And please, do that as much as you can. This will help you to support and maintain your patch all through your long development months. Check the previous screenshot. I could have linked the [r A1] object at the top left corner to the [p process03] object directly. But maybe this will be more readable if I keep the process chains separate. I often work this way with Max 6. This is one of the multiple tricks I teach in my Max 6 course. And of course, I introduced the [p] object, that is the [patcher] abbreviation. Let's check a couple of tips before we continue with some good examples involving Max 6 and Arduino. Encapsulation and subpatching When you open Max 6 and go to File | New Patcher , it opens a blank patcher. The latter, if you recall, is the place where you put all the objects. There is another good feature named subpatching . With this feature, you can create new patchers inside patchers, and embed patchers inside patchers as well. A patcher contained inside another one is also named a subpatcher. Let's see how it works with the patch named ReadAllCutest.maxpat. There are four new objects replacing the whole structures we designed before. These objects are subpatchers. If you double-click on them in patch lock mode or if you push the command key (or Ctrl for Windows), double-click on them in patch edit mode and you'll open them. Let's see what is there inside them. The [requester] subpatcher contains the same architecture that we designed before, but you can see the brown 1 and 2 objects and another blue 1 object. These are inlets and outlets. Indeed, they are required if you want your subpatcher to be able to communicate with the patcher that contains it. Of course, we could use the [send] and [receive] objects for this purpose too. The position of these inlets and outlets in your subpatcher matters. Indeed, if you move the 1 object to the right of the 2 object, the numbers get swapped! And the different inlets in the upper patch get swapped too. You have to be careful about that. But again, you can organize them exactly as you want and need. Check the next screenshot: And now, check the root patcher containing this subpatcher. It automatically inverts the inlets, keeping things relevant. Let's now have a look at the other subpatchers: The [p portHandler] subpatcher The [p dataHandler] subpatcher The [p dataDispatcher] subpatcher In the last figure, we can see only one inlet and no outlets. Indeed, we just encapsulated the global data dispatcher system inside the subpatcher. And this latter generates its data buses with [send] objects. This is an example where we don't need and even don't want to use outlets. Using outlets would be messy because we would have to link each element requesting this or that value from Arduino with a lot of cords. In order to create a subpatcher, you only have to type n to create a new object, and type p, a space, and the name of your subpatcher. While I designed these examples, I used something that works faster than creating a subpatcher, copying and pasting the structure on the inside, removing the structure from the outside, and adding inlets and outlets. This feature is named encapsulate and is part of the Edit menu of Max 6. You have to select the part of the patch you want to encapsulate inside a subpatcher, then click on Encapsulate , and voilà! You have just created a subpatcher including your structures that are connected to inlets and outlets in the correct order. Encapsulate and de-encapsulate features You can also de-encapsulate a subpatcher. It would follow the opposite process of removing the subpatcher and popping out the whole structure that was inside directly outside. Subpatching helps to keep things well organized and readable. We can imagine that we have to design a whole patch with a lot of wizardry and tricks inside it. This one is a processing unit, and as soon as we know what it does, after having finished it, we don't want to know how it does it but only use it . This provides a nice abstraction level by keeping some processing units closed inside boxes and not messing the main patch. You can copy and paste the subpatchers. This is a powerful way to quickly duplicate process units if you need to. But each subpatcher is totally independent of the others. This means that if you need to modify one because you want to update it, you'd have to do that individually in each subpatcher of your patch. This can be really hard. Let me introduce you to the last pure Max 6 concept now named abstractions before I go further with Arduino. Abstractions and reusability Any patch created and saved can be used as a new object in another patch. We can do this by creating a new object by typing n in a patcher; then we just have to type the name of our previously created and saved patch. A patch used in this way is called an abstraction . In order to call a patch as an abstraction in a patcher, the patch has to be in the Max 6 path in order to be found by it. You can check the path known by Max 6 by going to Options | File Preferences . Usually, if you put the main patch in a folder and the other patches you want to use as abstractions in that same folder, Max 6 finds them. The concept of abstraction in Max 6 itself is very powerful because it provides reusability . Indeed, imagine you need and have a lot of small (or big) patch structures that you are using every day, every time, and in almost every project. You can put them into a specific folder on your disk included in your Max 6 path and then you can call (we say instantiate ) them in every patch you are designing. Since each patch using it has only a reference to the one patch that was instantiated itself, you just need to improve your abstraction; each time you load a patch using it, the patch will have up-to-date abstractions loaded inside it. It is really easy to maintain all through the development months or years. Of course, if you totally change the abstraction to fit with a dedicated project/patch, you'll have some problems using it with other patches. You have to be careful to maintain even short documentation of your abstractions. Let's now continue by describing some good examples with Arduino.
Read more
  • 0
  • 0
  • 3034

article-image-understanding-geolocation-api-simple
Packt
06 Sep 2013
7 min read
Save for later

Understanding the Geolocation API (Simple)

Packt
06 Sep 2013
7 min read
(For more resources related to this topic, see here.) How to do it... The web can be accessed from different types of hardware, such as desktop computers, laptops, tablets, phones, and embedded systems. The World Wide Web Consortium (W3C) finalizes specifications in such a way that the web continues to support each of these platforms. Your operating system, Internet service provider, device type, and location all should not matter; the web is universal. All of this means that the web may be the most important publishing medium in the history of human civilization—a medium that anyone can publish to and consume. However, because each device has slightly different capabilities, each feature may have slightly different characteristics from user to user. For example, in HTML5, some web browsers can play certain video formats, while other web browsers can play other video formats. In the Geolocation API, these changes relate to how location is computed, and as a result, how accurate it is. Here's how the Geolocation API works from the user's perspective. You can see it in action by visiting my demo at http://benwerd.com/lab/geo.php. Visit an application or website that requires location information. The application attempts to determine your location with the Geolocation API. The browser asks you whether you want to reveal the location to the application. If you consent to sharing your location, your location is determined using available hardware and software, and sent to the application. If you do not consent to sharing your location, no location information is sent to the application, and it is notified that no location information will be sent. Your application needs the Geolocation API if: You want to adjust the application's functionality based on the user's location You want to adjust a site's content or redirect the user based on his/her location You want to empower the user to track his/her location over time Your application cannot use the Geolocation API if: You want to track the user without his/her explicit consent You need real-time, extremely accurate location information We will discuss why in the next section. How it works... The request for information is an important step to protect user privacy. The Geolocation API specification explicitly states, "User Agents must not send location information to Web sites without the express permission of the user." It's sadly true that the user's location can often still be determined without his/her consent through other means, such as IP geolocation or by sharing data between applications. However, these are unrelated to the Geolocation API, and we will not be discussing them here. Here's what a location request looks like when using Google Chrome on my MacBook Pro using a home broadband Internet connection: Note the ribbon above the main web page content. The entire content of the page has been sent to the browser; once location information has been sent, JavaScript could change the content of the page (for example, using the jQuery framework), submit the content elsewhere using a callback, or forward the browser to another page. Here's what it looks like in the Android Chrome browser: You can test your browser's geolocation capabilities by visiting http://benwerd.com/lab/geo.php. Here's what it looks like when using Google Chrome on my MacBook Pro using cable Internet: Here you can see that although my latitude and longitude have been calculated reasonably accurately, my altitude, heading, and speed details are not available. This is because these details are determined using GPS(Global Positioning System) technology, and my laptop does not have this capability. Instead, my web browser needs to guess my location based on various environmental factors. Here's what the same Geolocation API test looks like on my Android Chrome browser on my cell phone: You might be surprised to see that my altitude, heading, and speed information is still not present, despite having been determined on a cellphone that has hardware GPS support. In fact, this is because(if you use the default Geolocation API configuration) Chrome on Android attempts to use WiFi location first, where it's available, before resorting to the relatively battery-intensive (but more accurate) GPS location. Here's what the test page looks like on an iPad: Because the iPad did use GPS data to determine my location, altitude information is available. However, I wasn't moving, so there's no speed or heading information. Only latitude, longitude, and accuracy are guaranteed to be there. The other fields are entirely dependent on the user's device, movement, and location context. Where GPS is not available, the browser will use a process called trilateration to determine the location. Trilateration looks at environmental factors such as available wireless networks and their relative signal strengths, proximity to cellphone towers, and current network IP address, and matches them against a remote database of environmental factors against known locations. For most browsers, this database turns out to be run by Google, but some providers use a solution from Skyhook Wireless, and there are others too. Apple maintains its own database for its products, for example, which have probably been crowdsourced from consumer iPhone and iPad usage. Database information could also have been gathered from special cars, such as those used to take photographs for Google StreetView, and other crowdsourcing techniques. It's important to note that the user's location is being sent to a third party in these instances, and that the returned location will only be as good as the service's database. How this location is determined is not part of the Geolocation API specification; all that is required for you to know is that some location information is returned. There's more... All modern browsers across both desktop and mobile platforms, except for Opera Mini, support the Geolocation API. Most have done so for enough time that you should be comfortable using the API in your web applications. Microsoft Internet Explorer from Version 9.0 onwards (March 14, 2010) Mozilla Firefox from Version 3.5 onwards (June 30, 2009) Google Chrome from Version 5.0 onwards (May 25, 2010) Android Browser from Version 2.1 onwards (January, 2010) Apple Safari on the desktop from Version 5.1 onwards (July 20, 2011) Apple Safari on iOS from Version 3.2 onwards (April 3, 2010) Opera from Version 10.6 onwards (July 1, 2010) BlackBerry Browser from Version 7.0 onwards (May, 2011) (Source: CanIUse.com) It's worth noting that because Microsoft Internet Explorer 9.0 was the first version to not support Windows XP, there remains a significant enterprise userbase—Internet Explorer users with Windows XP operating systems—that cannot use applications based on the Geolocation API. At the time of writing, this represents 24 percent of all web users worldwide according to theie8countdown.com. For this and a host of other reasons, including their own security, let's hope that they will upgrade soon. The lack of Opera Mini support also means that many mobile phone users, particularly in developing nations or users with feature phones, are not able to use the Geolocation API. This situation is likely to change soon, as open source mobile operating systems such as Android and Firefox OS are gaining traction in those markets. Further resources Here are some relevant resources for further research: Can I Use Geolocation: An up-to-date list of browsers that support the Geolocation API (http://caniuse.com/#feat=geolocation) Geolocation API specification: http://dev.w3.org/geo/api/spec-source.html Summary In this article we discussed some basic points about the Geolocation API. At its core, the Geolocation API is a series of simple JavaScript calls that retrieve the aspects such as latitude and longitude, altitude, and the accuracy of the latitude and longitude. Resources for Article :   Further resources on this subject: Building HTML5 Pages from Scratch [Article] WebSocket – a Handshake! [Article] Implementing Alfresco JavaScript API Functionalities [Article]
Read more
  • 0
  • 0
  • 3085
article-image-aperture-action
Packt
06 Sep 2013
14 min read
Save for later

Aperture in Action

Packt
06 Sep 2013
14 min read
Controlling clipped highlights The problem of clipped highlights is a very common issue that a photographer will often have to deal with. Digital cameras only have limited dynamic range, so clipping becomes an issue, especially with high-contrast scenes. However, if you shoot RAW, then your camera will often record more highlighted information than is visible in the image. You may already be familiar with recovering highlights by using the recovery slider in Aperture, but there are actually a couple of other ways that you can bring this information back into range. The three main methods of controlling lost highlights in Aperture are: Using the recovery slider Using curves Using shadows and highlights For many cases, using the recovery slider will be good enough, but the recovery slider has its limitations. Sometimes it still leaves your highlights looking too bright, or it doesn't give you the look you wish to achieve. The other two methods mentioned give you more control over the process of recovery. If you use a Curves adjustment, you can control the way the highlight rolls off, and you can reduce the artificial look that clipped highlights can give your image, even if technically the highlight is still clipped. A highlights & shadows adjustment is also useful because it has a different look, as compared to the one that you get when using the recovery slider. It works in a slightly different way, and includes more of the brighter tones of your image when making its calculations. The highlights and shadows adjustment has the added advantage of being able to be brushed in. So, how do you know which one to use? Consider taking a three-stepped approach. If the first step doesn't work, move on to the second, and so on. Eventually, it will become second nature, and you'll know which way will be the best by just looking at the photograph. Step 1 Use the recovery slider. Drag the slider up until any clipped areas of the image start to reappear. Only drag the slider until the clipped areas have been recovered, and then stop. You may find that if your highlights are completely clipped, you may need to drag the slider all the way to the right, as per the following screenshot: For most clipped highlight issues, this will probably be enough. If you want to see what's going on, add a Curves adjustment and set the Range field to the Extended range. You don't have to make any adjustments at this point, but the histogram in the Curves adjustment will now show you how much image data is being clipped, and how much data that you can actually recover. Real world example In the following screenshot, the highlights on the right-hand edge of the plant pot have been completely blown out: If we zoom in, you will be able to see the problem in more detail. As you can see, all the image information has been lost from the intricate edge of this cast iron plant pot. Luckily this image had been shot in RAW, and the highlights are easily recovered. In this case, all that was necessary was the use of the recovery slider. It was dragged upward until it reached a value of around 1.1, and this brought most of the detail back into the visible range. As you can see from the preceding image, the detail has been recovered nicely and there are no more clipped highlights. The following screenshot is the finished image after the use of the recovery slider: Step 2 If the recovery slider brought the highlights back into range, but still they are too bright, then try the Highlights & Shadows adjustment. This will allow you to bring the highlights down even further. If you find that it is affecting the rest of your image, you can use brushes to limit the highlight adjustment to just the area you want to recover. You may find that with the Highlight and Shadows adjustment, if you drag the sliders too far the image will start to look flat and washed out. In this case, using the mid-contrast slider can add some contrast back into the image. You should use the mid-contrast slider carefully though, as too much can create an unnatural image with too much contrast. Step 3 If the previous steps haven't addressed the problem to your satisfaction, or if the highlight areas are still clipped, you can add a roll off to your Curves adjustment. The following is a quick refresher on what to do: Add a Curves adjustment, if you haven't already added one. From the pop-up range menu at the bottom of the Curves adjustment, set the range to Extended. Drag the white point of the Curves slider till it encompasses all the image information. Create a roll off on the right-hand side of the curve, so it looks something like the following screenshot: If you're comfortable with curves, you can skip directly to step 3 and just use a Curves adjustment, but for better results, you should combine the preceding differing methods to best suit your image. Real world example In the following screenshot (of yours truly), the photo was taken under poor lighting conditions, and there is a badly blown out highlight on the forehead: Before we fix the highlights, however, the first thing that we need to do is to fix the overall white balance, which is quite poor. In this case, the easiest way to fix this problem is to use the Aperture's clever skin tone white-balance adjustment. On the White Balance adjustment brick from the pop-up menu, set the mode to Skin Tone. Now, select the color picker and pick an area of skin tone in the image. This will set the white balance to a more acceptable color. (You can tweak it more if it's not right, but this usually gives satisfactory results.) The next step is to try and fix the clipped highlight. Let's use the three-step approach that we discussed earlier. We will start by using the recovery slider. In this case, the slider was brought all the way up, but the result wasn't enough and leaves an unsightly highlight, as you can see in the following screenshot: The next step is to try the Highlight & Shadows adjustment. The highlights slider was brought up to the mid-point, and while this helped, it still didn't fix the overall problem. The highlights are still quite ugly, as you can see in the following screenshot: Finally, a Curves adjustment was added and a gentle roll off was applied to the highlight portion of the curve. While the burned out highlight isn't completely gone, there is no longer a harsh edge to it. The result is a much better image than the original, with a more natural-looking highlight as shown in the following screenshot: Finishing touches To take this image further, the face was brightened using another Curves adjustment, and the curves was brushed in over the facial area. A vignette was also added. Finally, a skin softening brush was used over the harsh shadow on the nose, and over the edges of the halo on the forehead, just to soften it even further. The result is a much better (and now useable) image than the one we started with. Fixing blown out skies Another common problem one often encounters with digital images is blown out skies. Sometimes it can be as a result of the image being clipped beyond the dynamic range of the camera, whereas other times the day may simply have been overcast and there is no detail there to begin with. While there are situations when the sky is too bright and you just need to bring the brightness down to better match the rest of the scene, that is easily fixed. But what if there is no detail there to recover in the first place? That scenario is what we are going to look at in the next section. This covers what to do when the sky is completely gone and there's nothing left to recover. There are options open to you in this case. The first is pretty obvious. Leave it as it is. However, you might have an image that is nicely lit otherwise, but all that's ruining it is a flat washed-out sky. What would add a nice balance to an image in such a scenario is some subtle blue in the sky, even if it's just a small amount. Luckily, this is fairly easy to achieve in Aperture. Perform the following steps: Try the steps outlined in the previous section to bring clipped highlights back into range. Sometimes simply using the recovery slider will bring clipped skies back into the visible range, depending on the capabilities of your camera. In order for the rest of this trick to work, your highlights must be in the visible range. If you have already made any enhancements using the Enhance brick and you want to preserve those, add another Enhance brick by choosing Add New Enhance adjustment from the cog pop-up on the side of the interface. If the Tint controls aren't visible on the Enhance brick, click on the little arrow beside the word Tint to reveal the Tint controls. Using the right-hand Tint control (the one with the White eyedropper under it), adjust the control until it adds some blue back to the sky. If this is adding too much blue to other areas of your image, then brush the enhance adjustment in by choosing Brush Enhance In from the cog pop-up menu. Real world example In this example, the sky has been completely blown out and has lost most of its color detail. The first thing to try is to see whether any detail can be recovered by using the recovery slider. In this case, some of the sky was recovered, but a lot of it was still burned out. There is simply no more information to recover. The next step is to use the tint adjustment as outlined in the instructions. This puts some color back in the sky and it looks more natural. A small adjustment of the Highlights & Shadows also helps bring the sky back into the range. Finishing touches While the sky has now been recovered, there is still a bit of work to be done. To brighten up the rest of the image, a Curves adjustment was added, and the upper part of the curve was brought up, while the shadows were brought down to add some contrast. The following is the Curves adjustment that was used: Finally, to reduce the large lens flare in the center of the image, I added a color adjustment and reduced the saturation and brightness of the various colors in the flare. I then painted the color adjustment in over the flare, and this reduced the impact of it on the image. This is the same technique that can be used for getting rid of color fringing, which will be discussed later in this article. The following screenshot is the final result: Removing objects from a scene One of the myths about photo workflow applications such as Aperture is that they're not good for pixel-level manipulations. People will generally switch over to something such as Photoshop if they need to do more complex operations, such as cloning out an object. However, Aperture's retouch tool is surprisingly powerful. If you need to remove small distracting objects from a scene, then it works really well. The following is an example of a shot that was entirely corrected in Aperture: It is not really practical to give step-by-step instructions for using the tool because every situation is different, so instead, what follows is a series of tips on how best to use the retouch function: To remove complex objects you will have to switch back and forth between the cloning and healing mode. Don't expect to do everything entirely in one mode or the other. To remove long lines, such as the telegraph wires in the preceding example, start with the healing tool. Use this till you get close to the edge of an object in the scene you want to keep. Then switch to the cloning tool to fix the areas close to the kept object. The healing tool can go a bit haywire near the edges of the frame, or the edges of another object, so it's often best to use the clone tool near the edges. Remember when using the clone tool that you need to keep changing your clone source so as to avoid leaving repetitive patterns in the cloned area. To change your source area, hold down the option key, and click on the image in the area that you want to clone from. Sometimes doing a few smaller strokes works better than one long, big stroke. You can only have one retouch adjustment, but each stroke is stored separately within it. You can delete individual strokes, but only in the reverse order in which they were created. You can't delete the first stroke, and keep the following ones if for example, you have 10 other strokes. It is worth taking the time to experiment with the retouch tool. Once you get the hang of this feature, you will save yourself a lot of time by not having to jump to another piece of software to do basic (or even advanced) cloning and healing. Fixing dust spots on multiple images A common use for the retouch tool is for removing sensor dust spots on an image. If your camera's sensor has become dirty, which is surprisingly common, you may find spots of dust creeping onto your images. These are typically found when shooting at higher f-stops (narrower apertures), such as f/11 or higher, and they manifest as round dark blobs. Dust spots are usually most visible in the bright areas of solid color, such as skies. The big problem with dust spots is that once your sensor has dust on it, it will record that dust in the same place in every image. Luckily Aperture's tools makes it pretty easy to remove those dust spots, and once you've removed them from one image, it's pretty simple to remove them from all your images. To remove dust spots on multiple images, perform the following steps: Start by locating the image in your batch where the dust spots are most visible.   Zoom in to 1:1 view (100 percent zoom), and press X on your keyboard to activate the retouch tool.   Switch the retouch tool to healing mode and decrease the size of your brush till it is just bigger than the dust spot. Make sure there is some softness on the brush. Click once over the spot to get rid of it. You should try to click on it rather than paint when it comes to dust spots, as you want the least amount of area retouched as possible. Scan through your image when viewing at 1:1, and repeat the preceding process until you have removed all the dust spots Close the retouch tool's HUD to drop the tool. Zoom back out. Select the lift tool from the Aperture interface (it's at the bottom of the main window). In the lift and stamp HUD, delete everything except the Retouch adjustment in the Adjustments submenu. To do this, select all the items except the retouch entry, and press the delete (or backspace) key. Select another image or group of images in your batch, and press the Stamp Selected Images button on the Lift and Stamp HUD. Your retouched settings will be copied to all your images, and because the dust spots don't move between shots, the dust should be removed on all your images.
Read more
  • 0
  • 0
  • 2148

article-image-different-kind-database
Packt
06 Sep 2013
9 min read
Save for later

A Different Kind of Database

Packt
06 Sep 2013
9 min read
(For more resources related to this topic, see here.) Explosive growth Relational databases worked well when systems were serving hundreds or even thousands of users, but the Internet has changed all of that. The number of users and volume of data is growing exponentially. A variety of social applications have proved that applications can quickly attract millions of users. Relational databases were never built to handle this level of concurrent access. Semi-structured data In addition to the staggering growth, data is no longer simple rows and columns. Semi-structured data is everywhere. Extensible Markup Language (XML) and JavaScript Object Notation (JSON) are the lingua franca of our distributed applications. These formats allow complex relationships to be modeled through hierarchy and nesting. Relational databases struggle to effectively represent these data patterns. Due to this impedance mismatch, our applications are littered with additional complexity. Object relational mapping (ORM) tools have helped but not solved this problem. With the growth of Software as a Service (SaaS) and cloud-based applications, the need for flexible schemas has increased. Each tenant is hosted on a unified infrastructure but they must retain the flexibility to customize their data model to meet their unique business needs. In these multi-tenant environments, a rigid schema structure imposed by a relational database does not work. Architecture changes While data is still king, how we architect our data-dependent systems has changed significantly over the past few decades. In many systems, the database acted as the integration point for different parts of the application. This required the data to be stored in a uniform way since the database was acting as a form of API. The following diagram shows the architectural transitions: With the move to Service Oriented Architectures (SOA), how data is stored for a given component has become less important. The application interfaces with the service, not the database. The application has a dependency on the service contract, not on the database schema. This shift has opened up the possibilities to store data based on the needs of the service. Rethinking the database The factors we have been discussing have led many in our industry to rethink the idea of a database. Engineers wrestled with the limitations of the relational database and set out to build modern web-scale databases. The term NoSQL was coined to label this category of databases. Originally, the term stood for No SQL but has evolved to mean Not Only SQL. To confuse matters further, some NoSQL databases support a form of the SQL dialect. However, in all cases they are not relational databases. While the NoSQL landscape continues to expand with more projects and companies getting in the action, there are four basic categories that databases fall into: Document (CouchDB, MongoDB, RavenDB) Graph (Neo4J, Sones) Key/Value (Cassandra, SimpleDB, Dynamo, Voldemort) Tabular/Wide Column (BigTable, Apache Hbase) Document databases Document databases are made up of semi-structure and schema free data structures known as documents. In this case, the term document is not speaking of a PDF or Word document. Rather, it refers to a rich data structure that can represent related data from the simple to the complex. In document databases, documents are usually represented in JavaScript Object Notation (JSON). A document can contain any number of fields of any length. Fields can also contain multiple pieces of data. Each document is independent and contains all of the data elements required by the entity. The following is an example of a simple document: {Name: "Alexander Graham Bell",BornIn: "Edinburgh, United Kingdom",Spouse: "Mabel Gardiner Hubbard"} And the following is an example of a more complex document: { Name: "Galileo Galilei", BornIn: "Pisa, Italy",YearBorn: "1564", Children: [ { Name: "Virginia", YearBorn: "1600" }, { Name: "Vincenzo", YearBorn: "1606" } ]} Since documents are JSON-based, the impedance mismatch that exists between the object-oriented and relational database worlds is gone. An object graph is simply serialized into JSON for storage. Now, the complexity of the entity has a small impact on the performance. Entire object graphs can be read and written in one database operation. There is no need to perform a series of select statements or create complex stored procedures to read the related objects. JSON documents also add flexibility due to their schema free design. This allows for evolving systems without forcing the existing data to be restructured. The schema free nature simplifies data structure evolution and customization. However, care must be given to the evolving data structure. If the evolution is a breaking change, documents must be migrated or additional intelligence needs to be built into the application. A document database for the .NET platform Prior to RavenDB, document databases such as CouchDB treated .NET as an afterthought. In 2010, Oren Eini from Hibernating Rhinos decided to bring a powerful document database to the .NET ecosystem. According to his blog: Raven is an OSS (with a commercial option) document database for the .NET/Windows platform. While there are other document databases around, such as CouchDB or MongoDB, there really isn't anything that a .NET developer can pick up and use without a significant amount of friction. Those projects are excellent in what they do, but they aren't targeting the .NET ecosystem. RavenDB is built to be a first-class citizen on the .NET platform offering developers the ability to easily extend and embed the database in their applications. A few of the key features that make RavenDB compelling to .NET developers are as follows: RavenDB comes with a fully functional .NET client API, which implements unit of work, change tracking, read and write optimizations, and much more. It also has a REST-based API, so you can access it via the JavaScript directly. It allows developers to define indexes using LINQ (Language Integrated Queries). Supports map/reduce operations on top of your documents using LINQ. It supports System.Transactions and can take part in distributed transactions. The server can be easily extended by adding a custom .NET assembly. RavenDB architecture RavenDB leverages existing storage infrastructure called ESENT that is known to scale to amazing sizes. ESENT is the storage engine utilized by Microsoft Exchange and Active Directory. The storage engine provides the transactional data store for the documents. RavenDB also utilizes another proven technology called Lucene.NET for its high-speed indexing engine. Lucene.NET is an open source Apache project used to power applications such as AutoDesk, StackOverflow, Orchard, Umbraco, and many more. The following diagram shows the primary components of the RavenDB architecture: Storing documents When a document is inserted or updated, RavenDB performs the following: A document change comes in and is stored in ESENT. Documents are immediately available to load by ID, but won't appear in searches until they are indexed. Asynchronous indexing task takes work from the queue and updates the Lucene index. The index can be created manually or dynamically based on the queries executed by the application. The document now appears in queries. Typically, index updates have an average latency of 20 milliseconds. RavenDB provides an API to wait for updates to be indexed if needed. Searching and retrieving documents When a document request comes in, the server is able to pull them directly from the RavenDB database when a document ID is provided. All searches and other inquiries hit the Lucene index. These methods provide near instant access, regardless of the database size. A key difference between RavenDB and a relational database is the way index consistency is handled. A relational database ties index updates to data modifications. The insert, update, or delete only completes once the indexes have been updated. This provides users a consistent view of the data but can quickly degrade when the system is under heavy load. RavenDB on the other hand uses a model for indexes known as eventual consistency. Indexes are updated asynchronously from the document storage. This means that the visibility of a change within an index is not always available immediately after the document is written. By queuing the indexing operation on a background thread, the system is able to continue servicing reads while the indexing operation catches up. Eventual consistency is a bit counter-intuitive. We do not want the user to view stale data. However, in a multiuser system our users view stale data all the time. Once the data is displayed on the screen, it becomes stale and may have been modified by another user. The following diagram illustrates stale data in a multiuser system: In many cases, this staleness does not matter. Consider a blog post. When you publish a new article, does it really matter if the article becomes visible to the entire world that nanosecond? Will users on the Internet really know if it wasn't? What typically matters is providing feedback to the user who made the change. Either let them know when the change becomes available or pausing briefly while the indexing catches up. If a user did not initiate the data change, then it is even easier. The change will simply become available when it enters the index. This provides a mechanism to give each user personal consistency. The user making the change can wait for their own changes to take affect while other users don't need to wait. Eventual consistency is a tradeoff between application responsiveness for all users and consistency between indexes and documents. When used appropriately, this tradeoff becomes a tool for increasing the scalability of a system. Summary As you can see, RavenDB is truly a different kind of database. It makes fundamental changes to what we expect from a database. It requires us to approach problems from a fresh perspective. It requires us to think differently. Resources for Article: Further resources on this subject: Amazon SimpleDB versus RDBMS [Article] So, what is MongoDB? [Article] Getting Started with CouchDB and Futon [Article]
Read more
  • 0
  • 0
  • 6305

article-image-out-process-distributed-caching
Packt
06 Sep 2013
7 min read
Save for later

Out-of-process distributed caching

Packt
06 Sep 2013
7 min read
(For more resources related to this topic, see here.) Getting ready Out-of-process caching is a way of distributing your caching needs in a different JVM and/or infrastructure. Ehcache provides a convenient deployable WAR file that works on most web containers/standalone servers whose mission is to provide an easy API interface to distributed cache. At the moment of writing, you can download it from http://sourceforge.net/projects/ehcache/files/ehcache-server/, or you can include it in your Maven POM and will be delivered as a WAR file. The cache server requires no special configuration on the Tomcat container. However, if you are running GlassFish, Jetty, WebLogic, or any other application server (or servlet container), there are minimal configuration changes to do. Please refer to the Ehcache cache server documentation for details on these. While using the RESTful interface, it is important to note that you have three ways to set the MIME type for exchanging data back and forth to the cache server, namely Text/XML, application/JSON, and application/x-java-serialized-object. You can use any programming language to invoke the web service interface and cache your objects (except for application/x-java-serialized-object for obvious reasons). Refer to the recipe8 project directory within the source code bundle for a fully working sample of this recipe content and further information related to this topic. How to do it... Add Ehcache and Ehcache cache server dependencies to your POM.xml file. <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache-server</artifactId> <version>1.0.0</version> <type>war</type> </dependency> <dependency> <groupId>net.sf.ehcache</groupId> <artifactId>ehcache</artifactId> <version>2.6.0</version> <type>pom</type> </dependency> Edit ehcache.xml in the cache server to hold your cache setup (the cache name is very important).You can find this file here: ${CACHE_SERVER}/WEB-INF/classes/ehcache.xml. <?xml version="1.0" encoding="UTF-8"?> <ehcache xsi_noNamespaceSchemaLocation="ehcache.xsd" updateCheck="true" monitoring="autodetect" dynamicConfig="true"> <!-- Set cache eternal (of course not to do in production) --> <cache name="remoteCache" maxElementsInMemory="10000" eternal="true" diskPersistent="true" overflowToDisk="true"/> ... Disable the SOAP interface in the cache server web.xml (since we are going to use RESTful) file:You can find this file here: ${CACHE_SERVER}/WEB-INF/web.xml. <?xml version="1.0" encoding="UTF-8"?> <web-app xsi_schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> ... <!-- SOAP Servlet Comment out (or remove) to disable SOAP Web Services <servlet> <servlet-name>EhcacheWebServiceEndpoint</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>EhcacheWebServiceEndpoint</servlet-name> <url-pattern>/soap/EhcacheWebServiceEndpoint</url-pattern> </servlet-mapping> <session-config> <session-timeout>60</session-timeout> </session-config> <listener> <listener-class> com.sun.xml.ws.transport.http.servlet.WSServletContextListener </listener-class> </listener> --> ... Make your objects-to-be-cached serializable: import java.io.Serializable; public final class Item implements Serializable { Invoke the RESTful (or SOAP) interface to save/retrieve/delete cached objects: ... public void saveItemInCache(String key, Serializable item) { //sample URL: http://localhost:8080/ehcache/rest/cacheName/{id} //here cacheName is the cache name you set up in the cache-server ehcache.xml String url = CACHE_SERVER_URL + "cacheName" + "/" + key; //initialize Apache HTTP Client client = new DefaultHttpClient(); //create Cache Element to be sent Element element = new Element(key, item); //serialize object to be sent to EhCache Server byte[] itemToByteArray = SerializationUtils.serialize(element); //create PUT request HttpPut putRequest = new HttpPut(url); //set header to read java-serialized-object mime type putRequest.setHeader ("Content-Type", "application/x-java-serialized-object"); ... How it works... The Ehcache cache server utility is a versatile tool that lets us distribute cache engines in a very flexible way. It provides a very simple API exposure via RESTful or SOAP-based web services. We start by editing the ehcache.xml configuration file within the cache server application by adding a cache that we would like to use for our cached objects: ... <!-- Set cache eternal (of course not to do in production) --> <cache name="remoteCache" maxElementsInMemory="10000" eternal="true" diskPersistent="true" overflowToDisk="true"/> ... The cache name defined here is very important because this will be the endpoint of our RESTful URL pattern that the cache server will identify and use. Then, we need to edit the web.xml file within the cache server application (located in {CACHE-SERVER}/WEB-INF/) in order to comment out (or completely remove) service definitions that we are not going to use (that is, SOAP if you are using RESTful or vice versa). <!-- SOAP Servlet Comment out to disable SOAP Web Services <servlet> <servlet-name>EhcacheWebServiceEndpoint</servlet-name> <servlet-class>com.sun.xml.ws.transport.http.servlet.WSServlet </servlet-class> <load-on-startup>1</load-on-startup> </servlet> ... In order to cache an object (specially a Java object), we need to make it serializable simply by implementing the Serializable interface (this is not a requirement for MIME types different from the application/x-java-serialized-object). import java.io.Serializable; public final class Item implements Serializable { Finally, we invoke the RESTful endpoint from our code to store/retrieve/delete the object from/to the cache layer. //sample URL: http://localhost:8080/ehcache/rest/cacheName/{id} //here cacheName is the cache name you set up in the cache-server ehcache.xml String url = CACHE_SERVER_URL + "cacheName" + "/" + key; //set header to read json mime type putRequest.setHeader("Content-Type", "application/json"); It is important to note here that the cacheName URL parameter represents the cache name you defined in the ehcache.xml configuration file in the cache server application. You have defined your cache name as follows: <!-- Set cache eternal (of course not to do in production) --> <cache name="remoteCache" maxElementsInMemory="10000" ... Now, your URL would be something like this: //sample URL: http://localhost:8080/ehcache/rest/remoteCache/{id} Here, id is just the key value you assign to the cached object. Finally, you just use any http/SOAP client library (or Java default Net API classes) to invoke the web service. In the case of RESTful services, you need to be aware that the HTTP method sent determines whether you are storing, updating, retrieving, or deleting a cached item. They are as follows: GET /{cache}/{element}: This retrieves an object by its key from the O-O-P cache layer. PUT /{cache}/{element}: This stores an item in the O-O-P cache layer. DELETE /{cache}/{element}: This deletes an item from the O-O-P cache layer. HEAD /{cache}/{element}: This retrieves metadata (cache configuration values) from the O-O-P cache layer. OPTIONS /{cache}/{element}: This returns the WADL describing operations. For changing the context you can edit the file ${CACHE_SERVER}/META-INF/context.xml and place your desired context name. As for security, look for the file ${CACHE_SERVER}/WEB-INF/server_security_config.xml_rename_to_activate and open it to read the instructions. Summary This article provided details on implementing distributed caching using the Ehcache server, and also explained in brief what out-of-process caching is. Resources for Article : Further resources on this subject: PostgreSQL 9: Reliable Controller and Disk Setup [Article] Play Framework: Data Validation Using Controllers [Article] Building Applications with Spring Data Redis [Article]
Read more
  • 0
  • 0
  • 2130
article-image-creating-puzzle-app
Packt
06 Sep 2013
11 min read
Save for later

Creating a Puzzle App

Packt
06 Sep 2013
11 min read
(For more resources related to this topic, see here.) A quick introduction to puzzle games Puzzle games are a genre of video games that have been around for decades. These types of games challenge players to use logic and critical thinking to complete patterns. There is a large variety of puzzle games available, and in this article, we'll start by learning how to create a 3-by-3 jigsaw puzzle titled My Jigsaw Puzzle. In My Jigsaw Puzzle, players will have to complete a jigsaw puzzle by using nine puzzle pieces. Each puzzle piece will have an image on it, and the player will have to match the puzzle piece to the puzzle board by dragging the pieces from right to left. When the puzzle piece matches the correct location, the game will lock in the piece. Let's take a look at the final game product. Downloading the starter kit Before creating our puzzle app, you can get the starter kit for the jigsaw puzzle from the code files available with this book. The starter kit includes all of the graphics that we will be using in this article. My Jigsaw Puzzle For the Frank's Fitness app, we used Corona's built-in new project creator to help us with setting up our project. With My Jigsaw Puzzle, we will be creating the project from scratch. Although creating a project from scratch can be more time consuming, the process will introduce you to each element that goes into Corona's new project creator. Creating the project will include creating the build.settings, config.lua, main.lua, menu.lua, and gameplay.lua files. Before we can start creating the files for our project, we will need to create a new project folder on your computer. This folder will hold all of the files that will be used in our app. build.settings The first file that we will create is the build.settings file. This file will handle our device orientation and specify our icons for the iPhone. Inside our build.settings file, we will create one table named settings, which will hold two more tables named orientation and iphone. The orientation table will tell our app to start in landscape mode and to only support landscapeLeft and landscapeRight. The iphone table will specify the icons that we want to use for our app. To create the build.settings file, create a new file named build.settings in your project's folder and input the following code: settings = { orientation = { default = "landscapeRight", supported = { "landscapeLeft", "landscapeRight" }, }, iphone = { plist = { CFBundleIconFile = "Icon.png", CFBundleIconFiles = { "Icon.png", "Icon@2x.png", "Icon-72.png", } } }} config.lua Next, we will be creating a file named config.lua in our project's folder. The config.lua file is used to specify any runtime properties for our app. For My Jigsaw Puzzle, we will be specifying the width, height, and scale methods. We will be using the letterbox scale method, which will uniformly scale content as much as possible. When letterbox doesn't scale to the entire screen, our app will display black borders outside of the playable screen. To create the config.lua file, create a new file named config.lua in your project's folder and input the following code: application ={ content = { width = 320, height = 480, scale = "letterbox" }} main.lua Now that we've configured our project, we will be creating the main.lua file—the start point for every app. For now, we are going to keep the file simple. Our main. lua file will hide the status bar while the app is active and redirect the app to the next file—menu.lua. To create main.lua, create a new file named main.lua in your project's folder and copy the following code into the file: display.setStatusBar ( display.HiddenStatusBar )local storyboard = require ( "storyboard" )storyboard.gotoScene("menu") menu.lua Our next step is to create the menu for our app. The menu will show a background, the game title, and a play button. The player can then tap on the PLAY GAME button to start playing the jigsaw puzzle. To get started, create a new file in your project's folder called menu.lua. Once the file has been created, open menu.lua in your favorite text editor. Let's start the file by getting the widget and storyboard libraries. We'll also set up Storyboard by assigning the variable scene to storyboard.newScene(). local widget = require "widget"local storyboard = require( "storyboard" )local scene = storyboard.newScene() Next, we will set up our createScene() function. The function createScene() is called when entering a scene for the first time. Inside this function, we will create objects that will be displayed on the screen. Most of the following code should look familiar by now. Here, we are creating two image display objects and one widget. Each object will also be inserted into the variable group to let our app know that these objects belong to the scene menu.lua. function scene:createScene( event ) local group = self.view background = display.newImageRect( "woodboard.png", 480, 320 ) background.x = display.contentWidth*0.5 background.y = display.contentHeight*0.5 group:insert(background) logo = display.newImageRect( "logo.png", 400, 54 ) logo.x = display.contentWidth/2 logo.y = 65 group:insert(logo) function onPlayBtnRelease() storyboard.gotoScene("gameplay") end playBtn = widget.newButton{ default="button-play.png", over="button-play.png", width=200, height=83, onRelease = onPlayBtnRelease } playBtn.x = display.contentWidth/2 playBtn.y = display.contentHeight/2 group:insert(playBtn)end After the createScene() function, we will set up the enterScene() function. The enterScene() function is called after a scene has moved on to the screen. In My Jigsaw Puzzle, we will be using this function to remove the gameplay scene. We need to make sure we are removing the gameplay scene so that the jigsaw puzzle is reset and the player can play a new game. function scene:enterScene( event ) storyboard.removeScene( "gameplay" )end After we've created our createScene() and enterScene() functions, we need to set up our event listeners for Storyboard. scene:addEventListener( "createScene", scene )scene:addEventListener( "enterScene", scene ) Finally, we end our menu.lua file by adding the following line: return scene This line of code lets our app know that we are done with this scene. Now that we've added the last line, we have finished editing menu.lua, and we will now start setting up our jigsaw puzzle. gameplay.lua By now, our game has been configured and we have set up two files—main.lua and menu.lua. In our next step, we will be creating the jigsaw puzzle. The following screenshot shows the puzzle that we will be making: Getting local libraries To get started, create a new file called gameplay.lua and open the file in your favorite text editor. Similar to our menu.lua file, we need to start the file by getting in other libraries and setting up Storyboard. local widget = require("widget")local storyboard = require( "storyboard" )local scene = storyboard.newScene() Creating variables After our local libraries, we are going to create some variables to use in gameplay. lua. When you separate the variables from the rest of your code, the process of refining your app later becomes easier. _W = display.contentWidth_H = display.contentHeightpuzzlePiecesCompleted = 0totalPuzzlePieces = 9puzzlePieceWidth = 120puzzlePieceHeight = 120puzzlePieceStartingY = { 80,220,360,500,640,780,920,1060,1200 }puzzlePieceSlideUp = 140puzzleWidth, puzzleHeight = 320, 320puzzlePieces = {}puzzlePieceCheckpoint = { {x=-243,y=76}, {x=-160, y=76}, {x=-76, y=74}, {x=-243,y=177}, {x=-143, y=157}, {x=-57, y=147}, {x=-261,y=258}, {x=-176,y=250}, {x=-74,y=248}}puzzlePieceFinalPosition = { {x=77,y=75}, {x=160, y=75}, {x=244, y=75}, {x=77,y=175}, {x=179, y=158}, {x=265, y=144}, {x=58,y=258}, {x=145,y=251}, {x=248,y=247}} Here's a breakdown of what we will be using each variable for in our app: _W and _H: These variables capture the width and height of the screen. In our app, we have already specified the size of our app to be 480 x 320. puzzlePiecesCompleted: This variable is used to track the progress of the game by tracking the number of puzzle pieces completed. totalPuzzlePieces: This variable allows us to tell our app how many puzzle pieces we are using. puzzlePieceWidth and puzzlePieceHeight: These variables specify the width and height of our puzzle piece images within the app. puzzlePieceStartingY: This table contains the starting Y location of each puzzle piece. Since we can't have all nine puzzle pieces on screen at the same time, we are displaying the first two pieces and the other seven pieces are placed off the screen below the first two. We will be going over this in detail when we add the puzzle pieces. puzzlePieceSlideUp: After a puzzle piece is added, we will slide the puzzle pieces up; this variable sets the sliding distance. puzzleWidth and puzzleHeight: These variables specify the width and height of our puzzle board. puzzlePieces: This creates a table to hold our puzzle pieces once they are added to the board. puzzlePieceCheckpoint: This table sets up the checkpoints for each puzzle piece in x and y coordinates. When a puzzle piece is dragged to the checkpoint, it will be locked into position. When we add the checkpoint logic, we will learn more about this in greater detail. puzzlePieceFinalPosition: This table sets up the final puzzle location in x and y coordinates. This table is only used once the puzzle piece passes the checkpoint. Creating display groups After we have added our variables, we are going to create two display groups to hold our display objects. Display groups are simply a collection of display objects that allow us to manipulate multiple display objects at once. In our app, we will be creating two display groups—playGameGroup and finishGameGroup. playGameGroup will contain objects that are used when the game is being played and the finishGameGroup will contain objects that are used when the puzzle is complete.Insert the following code after the variables: playGameGroup = display.newGroup()finishGameGroup = display.newGroup() The shuffle function Our next task is to create a shuffle function for My Jigsaw Puzzle. This function will randomize the puzzle pieces that are presented on the right side of the screen. Without the shuffle function, our puzzle pieces would be presented in a 1, 2, 3 manner, while the shuffle function makes sure that the player has a new experience every time. Creating the shuffle function To create the shuffle function, we will start by creating a function named shuffle. This function will accept one argument (t) and proceed to randomize the table for us. We're going to be using some advanced topics in this function, but before we start explaining it, let's add the following code to gameplay.lua under our display group: function shuffle(t) local n = #t while n > 2 do local k = math.random(n) t[n] = t[k] t[k] = t[n] n = n - 1 end return tend At first glance, this function may look complex; however, the code gets a lot simpler once it's explained. Here's a line-by-line breakdown of our shuffle function. The local n = #t line introduces two new features—local and #. By using the keyword local in front of our variable name, we are saying that this variable (n) is only needed for the duration of the function or loop that we are in. By using local variables, you are getting the most out of your memory resources and practicing good programming techniques. For more information about local variables, visit www.lua.org/pil/4.2.html. In this line, we are also using the # symbol. This symbol will tell us how many pieces or elements are in a table. In our app, our table will contain nine pieces or elements. Inside the while loop, the very first line is local k = math.random(n). This line is assigning a random number between 1 and the value of n (which is 9 in our app) to the local variable k. Then, we are randomizing the elements of the table by swapping the places of two pieces within our table. Finally, we are using n = n – 1 to work our way backwards through all of the elements in the table. Summary After reading this article, you will have a game that is ready to be played by you and your friends. We learned how to use Corona's feature set to create our first business app. In My Jigsaw Puzzle, we only provided one puzzle for the player, and although it's a great puzzle, I suggest adding more puzzles to make the game more appealing to more players. Resources for Article: Further resources on this subject: Atmosfall – Managing Game Progress with Coroutines [Article] Creating and configuring a basic mobile application [Article] Defining the Application's Policy File [Article]
Read more
  • 0
  • 0
  • 12273

article-image-introduction-bluestacks
Packt
05 Sep 2013
4 min read
Save for later

Introduction to BlueStacks

Packt
05 Sep 2013
4 min read
(For more resources related to this topic, see here.) So, what is BlueStacks? BlueStacks is a suite of tools designed to allow you to run Android apps easily on a Windows or Mac computer. The following screenshot shows how it looks: At the time of writing, there are two elements to the BlueStacks suite, which are listed as follows: App Player: This is the engine, which runs the Android apps Cloud Connect: This is a synchronization tool As the BlueStacks tools can be freely downloaded, anyone with a PC running on Windows or Mac can download them and start experimenting with their capabilities. This article will walk you through the process of running BlueStacks on a computer and show you some of the ways in which you can make the most out of this emerging technology. There are other ways by which you can run an emulation of Android on your computer. You can, for instance, run a virtual machine or install the Android Software Development Kit (SDK). These assume a degree of technical understanding that isn't necessarily required with BlueStacks, making BlueStacks the quickest and easiest way of running apps on your computer. BlueStacks is particularly interesting for users of Windows 8 tablets, as it opens up a whole library of mature software designed for a touch interface. This is particularly useful for those wanting to use many, free, or cheap Android apps on their laptop or tablet. It is worth noting that, at the time of writing this article, these tools are beta releases, so it is important that you take time to report the bugs that you may find to the developers through their website. The ongoing development and success of the software depends upon this feedback and results in a better product. If you become reliant on a particular feature, it is a good idea to highlight your love to the developers too. This can help influence which features are to be kept and improved upon as the product matures. App Player BlueStacks App Player allows a Windows or Mac user to run Android apps on their desktop or laptop. It does this by running an emulated version of Android within a window that you can interact with using your keyboard and mouse. The App Player can be downloaded and installed for free from the BlueStacks website, http://www.bluestacks.com. Currently, there are two main versions available for different operating systems that are enlisted as follows: Mac OS X Windows XP, Vista, 7, and 8 Once you have installed the software, an Android emulator runs on your machine. This is a light version of Android that can access app stores so that you can download and run free and paid apps and content. Most apps are compatible with App Player; however, there are some which are not (for technical reasons) and some which have been prevented by the App developers from running. If you are running any another operating system on your computer, the more computing power you can make available to the App Player the better. Otherwise, you might experience slow loading apps or worse still ones that do not function properly. To increase your chances of success, first try running App Player without running any other applications (for example, Word). Cloud Connect Cloud Connect provides a means to synchronize the apps running on an existing phone or tablet with the App Player. This means that you do not have to manually install lots of apps. Instead, you install an app on your device and sign up so that your App Player has exactly the same apps as your device. Summary Thus we learned the basics of BlueStacks and saw a brief of App Player and Cloud Connect feature of BlueStacks Resources for Article: Further resources on this subject: So, what is Spring for Android? [Article] Animating Properties and Tweening Pages in Android 3-0 [Article] New Connectivity APIs – Android Beam [Article]
Read more
  • 0
  • 0
  • 19239
Modal Close icon
Modal Close icon