Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
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

7019 Articles
article-image-your-first-application
Packt
15 Jan 2014
7 min read
Save for later

Your First Application

Packt
15 Jan 2014
7 min read
(For more resources related to this topic, see here.) Sketching out the application We are going to build a browsable database of cat profiles. Visitors will be able to create pages for their cats and fill in basic information such as the name, date of birth, and breed for each cat. This application will support the default Create-Retrieve-Update-Delete operations (CRUD). We will also create an overview page with the option to filter cats by breed. All of the security, authentication, and permission features are intentionally left out since they will be covered later. Entities, relationships, and attributes Firstly, we need to define the entities of our application. In broad terms, an entity is a thing (person, place, or object) about which the application should store data. From the requirements, we can extract the following entities and attributes: Cats, which have a numeric identifier, a name, a date of birth, and a breed Breeds, which only have an identifier and a name This information will help us when defining the database schema that will store the entities, relationships, and attributes, as well as the models, which are the PHP classes that represent the objects in our database. The map of our application We now need to think about the URL structure of our application. Having clean and expressive URLs has many benefits. On a usability level, the application will be easier to navigate and look less intimidating to the user. For frequent users, individual pages will be easier to remember or bookmark and, if they contain relevant keywords, they will often rank higher in search engine results. To fulfill the initial set of requirements, we are going to need the following routes in our application: Method Route Description GET / Index GET /cats Overview page GET /cats/breeds/:name Overview page for specific breed GET /cats/:id Individual cat page GET /cats/create Form to create a new cat page POST /cats Handle creation of new cat page GET /cats/:id/edit Form to edit existing cat page PUT /cats/:id Handle updates to cat page GET /cats/:id/delete Form to confirm deletion of page DELETE /cats/:id Handle deletion of cat page We will shortly learn how Laravel helps us to turn this routing sketch into actual code. If you have written PHP applications without a framework, you can briefly reflect on how you would have implemented such a routing structure. To add some perspective, this is what the second to last URL could have looked like with a traditional PHP script (without URL rewriting): /index.php?p=cats&id=1&_action=delete&confirm=true. The preceding table can be prepared using a pen and paper, in a spreadsheet editor, or even in your favorite code editor using ASCII characters. In the initial development phases, this table of routes is an important prototyping tool that forces you to think about URLs first and helps you define and refine the structure of your application iteratively. If you have worked with REST APIs, this kind of routing structure will look familiar to you. In RESTful terms, we have a cats resource that responds to the different HTTP verbs and provides an additional set of routes to display the necessary forms. If, on the other hand, you have not worked with RESTful sites, the use of the PUT and DELETE HTTP methods might be new to you. Even though web browsers do not support these methods for standard HTTP requests, Laravel uses a technique that other frameworks such as Rails use, and emulates those methods by adding a _method input field to the forms. This way, they can be sent over a standard POST request and are then delegated to the correct route or controller method in the application. Note also that none of the form submissions endpoints are handled with a GET method. This is primarily because they have side effects; a user could trigger the same action multiple times accidentally when using the browser history. Therefore, when they are called, these routes never display anything to the users. Instead, they redirect them after completing the action (for instance, DELETE /cats/:id will redirect the user to GET/cats). Starting the application Now that we have the blueprints for the application, let's roll up our sleeves and start writing some code. Start by opening a new terminal window and create a new project with Composer, as follows: $ composer create-project laravel/laravel cats --prefer-dist $ cd cats Once Composer finishes downloading Laravel and resolving its dependencies, you will have a directory structure identical to the one presented previously. Using the built-in development server To start the application, unless you are running an older version of PHP (5.3.*), you will not need a local server such as WAMP on Windows or MAMP on Mac OS since Laravel uses the built-in development server that is bundled with PHP 5.4 or later. To start the development server, we use the following artisan command: $ php artisan serve Artisan is the command-line utility that ships with Laravel and its features will be covered in more detail later. Next, open your web browser and visit http://localhost:8000; you will be greeted with Laravel's welcome message. If you get an error telling you that the php command does not exist or cannot be found, make sure that it is present in your PATH variable. If the command fails because you are running PHP 5.3 and you have no upgrade possibility, simply use your local development server (MAMP/WAMP) and set Apache's DocumentRoot to point to cats-app/public/. Writing the first routes Let's start by writing the first two routes of our application inside app/routes.php. This file already contains some comments as well as a sample route. You can keep the comments but you must remove the existing route before adding the following routes: Route::get('/', function(){   return "All cats"; }); Route::get('cats/{id}', function($id){   return "Cat #$id"; }); The first parameter of the get method is the URI pattern. When a pattern is matched, the closure function in the second parameter is executed with any parameters that were extracted from the pattern. Note that the slash prefix in the pattern is optional; however, you should not have any trailing slashes. You can make sure that your routes work by opening your web browser and visiting http://localhost:8000/cats/123. If you are not using PHP's built-in development server and are getting a 404 error at this stage, make sure that Apache's mod_rewrite configuration is enabled and works correctly. Restricting the route parameters In the pattern of the second route, {id} currently matches any string or number. To restrict it so that it only matches numbers, we can chain a where method to our route as follows: Route::get('cats/{id}', function($id){ return "Cat #$id"; })->where('id', '[0-9]+'); The where method takes two arguments: the first one is the name of the parameter and the second one is the regular expression pattern that it needs to match. Summary We have covered a lot in this article. We learned how to define routes, prepare the models of the application, and interact with them. Moreover, we have had a glimpse at the many powerful features of Eloquent, Blade, as well as the other convenient helpers in Laravel to create forms and input fields: all of this in under 200 lines of code! Resources for Article: Further resources on this subject: Laravel 4 - Creating a Simple CRUD Application in Hours [Article] Creating and Using Composer Packages [Article] Building a To-do List with Ajax [Article]
Read more
  • 0
  • 0
  • 2573

article-image-find-friends-facebook
Packt
22 Sep 2015
13 min read
Save for later

Find Friends on Facebook

Packt
22 Sep 2015
13 min read
 In this article by the authors, Vikram Garg and Sharan Kumar Ravindran, of the book, Mastering Social Media Mining with R, we learn about data mining using Facebook as our resource. (For more resources related to this topic, see here.) We will see how to use the R package Rfacebook, which provides access to the Facebook Graph API from R. It includes a series of functions that allow us to extract various data about our network such as friends, likes, comments, followers, newsfeeds, and much more. We will discuss how to visualize our Facebook network and we will see some methodologies to make use of the available data to implement business cases. Rfacebook package installation and authentication The Rfacebook package is authored and maintained by Pablo Barbera and Michael Piccirilli. It provides an interface to the Facebook API. It needs Version 2.12.0 or later of R and it is dependent on a few other packages, such as httr, rjson, and httpuv. Before starting, make sure those packages are installed. It is preferred to have Version 0.6 of the httr package installed. Installation We will now install the Rfacebook packages. We can download and install the latest package from GitHub using the following code and load the package using the library function. On the other hand, we will also install the Rfacebook package from the CRAN network. One prerequisite for installing the package using the function install_github is to have the package devtools loaded into the R environment. The code is as follows: library(devtools) install_github("Rfacebook", "pablobarbera", subdir="Rfacebook") library(Rfacebook) After installing the Rfacebook package for connecting to the API, make an authentication request. This can be done via two different methods. The first method is by using the access token generated for the app, which is short-lived (valid for two hours); on the other hand, we can create a long-lasting token using the OAuth function. Let's first create a temporary token. Go to https://developers.facebook.com/tools/explorer, click on Get Token, and select the required user data permissions. The Facebook Graph API explorer will open with an access token. This access token will be valid for two hours. The status of the access token as well as the scope can be checked by clicking on the Debug button. Once the tokens expire, we can regenerate a new token. Now, we can access the data from R using the following code. The access token generated using the link should be copied and passed to the token variable. The use of username in the function getUsers is deprecated in the latest Graph API; hence, we are passing the ID of a user. You can get your ID from the same link that was used for token generation. This function can be used to pull the details of any user, provided the generated token has the access. Usually, access is limited to a few users with a public setting or those who use your app. It is also based on the items selected in the user data permission check page during token generation. In the following code, paste your token inside the double quotes, so that it can be reused across the functions without explicitly mentioning the actual token. token<- "XXXXXXXXX" A closer look at how the package works The getUsers function using the token will hit the Facebook Graph API. Facebook will be able to uniquely identify the users as well as the permissions to access information. If all the check conditions are satisfied, we will be able to get the required data. Copy the token from the mentioned URL and paste it within the double quotes. Remember that the token generated will be active only for two hours. Use the getUsers function to get the details of the user. Earlier, the getUsers function used to work based on the Facebook friend's name as well as ID; in API Version 2.0, we cannot access the data using the name. Consider the following code for example: token<- "XXXXXXXXX" me<- getUsers("778278022196130", token, private_info = TRUE) Then, the details of the user, such as name and hometown, can be retrieved using the following code: me$name The output is also mentioned for your reference: [1] "Sharan Kumar R" For the following code: me$hometown The output is as follows: [1] "Chennai, Tamil Nadu" Now, let's see how to create a long-lasting token. Open your Facebook app page by going to https://developers.facebook.com/apps/ and choosing your app. On theDashboard tab, you will be able to see the App ID and Secret Code values. Use those in the following code. require("Rfacebook") fb_oauth<- fbOAuth(app_id="11",app_secret="XX",extended_permissions = TRUE) On executing the preceding statements, you will find the following message in your console: Copy and paste into Site URL on Facebook App Settings: http://localhost:1410/ When done, press any key to continue... Copy the URL displayed and open your Facebook app; on the Settings tab, click on the Add Platform button and paste the copied URL in the Site URL text box. Make sure to save the changes. Then, return to the R console and press any key to continue, you will be prompted to enter your Facebook username and password. On completing that, you will return to the R console. If you find the following message, it means your long-lived token is ready to use. When you get the completion status, you might not be able to access any of the information. It is advisable to use the OAuth function a few minutes after creation of the Facebook application. Authentication complete. Authentication successful. After successfully authenticating, we can save it and load on demand using the following code: save(fb_oauth, file="fb_oauth") load("fb_oauth") When it is required to automate a few things or to use Rfacebook extensively, it will be very difficult as the tokens should be generated quite often. Hence, it is advisable to create a long-lasting token to authenticate the user, and then save it. Whenever required, we can just load it from a local file. Note that Facebook authentication might take several minutes. Hence, if your authentication fails on the retry, please wait for some time before pressing any key and check whether you have installed the httr package Version 0.6. If you continue to experience any issues in generating the token, then it's not a problem. We are good to go with the temporary token. Exercise Create an app in Facebook and authenticate by any one of the methods discussed. A basic analysis of your network In this section, we will discuss how to extract Facebook network of friends and some more information about the people in our network. After completing the app creation and authentication steps, let's move forward and learn to pull some basic network data from Facebook. First, let's find out which friends we have access to, using the following command in R. Let's use the temporary token for accessing the data: token<- "XXXXXXXXX" friends<- getFriends(token, simplify = TRUE) head(friends) # To see few of your friends The preceding function will return all our Facebook friends whose data is accessible. Version 1 of the API would allow us to download all the friends' data by default. But in the new version, we have limited access. Since we have set simplify as TRUE, we will pull only the username and their Facebook ID. By setting the same parameter to FALSE, we will be able to access additional data such as gender, location, hometown, profile picture, relationship status, and full name. We can use the function getUsers to get additional information about a particular user. The following information is available by default: gender, location, and language. We can, however, get some additional information such as relationship status, birthday, and the current location by setting the parameter private_info to TRUE: friends_data<- getUsers(friends$id, token, private_info = TRUE) table(friends_data$gender) The output is as follows: female male 5 21 We can also find out the language, location, and relationship status. The commands to generate the details as well as the respective outputs are given here for your reference: #Language table(substr(friends_data$locale, 1, 2)) The output is as follows: en 26 The code to find the location is as follows: # Location (Country) table(substr(friends_data$locale, 4, 5)) The output is as follows: GB US 1 25 Here's the code to find the relationship status: # Relationship Status table(friends_data$relationship_status) Here's the output: Engaged Married Single 1 1 3 Now, let's see what things were liked by us in Facebook. We can use the function getLikes to get the like data. In order to know about your likes data, specify user as me. The same function can be used to extract information about our friends, in which case we should pass the user's Facebook ID. This function will provide us with a list of Facebook pages liked by the user, their ID, name, and the website associated with the page. We can even restrict the number of results retrieved by setting a value to the parameter n. The same function will be used to get the likes of people in our network; instead of the keyword me, we should give the Facebook ID of those users. Remember we can only access data of people with accessibility from our app. The code is as follows: likes<- getLikes(user="me", token=token) head(likes) After exploring the use of functions to pull data, let's see how to use the Facebook Query Language using the function getFQL, which can be used to pass the queries. The following query will get you the list of friends in your network: friends<- getFQL("SELECT uid2 FROM friend WHERE uid1=me()", token=token) In order to get the complete details of your friends, the following query can be used. The query will return the username, Facebook ID, and the link to their profile picture. Note that we might not be able to access the complete network of friends' data, since access to data of all your friends are deprecated with Version 2.0. The code is as follows: # Details about friends Friends_details<- getFQL("SELECT uid, name, pic_square FROM user WHERE uid = me() OR uid IN (SELECT uid2 FROM friend WHERE uid1 = me())", token=token) In order to know more about the Facebook Query Language, check out the following link. This method of extracting the information might be preferred by people familiar with query language. It can also help extract data satisfying only specific conditions (https://developers.facebook.com/docs/technical-guides/fql). Exercise Download your Facebook network and do an exploration analysis on the languages your friends speak, places where they live, the total number of pages they have liked, and their marital status. Try all these with the Facebook Query Language as well. Network analysis and visualization So far, we used a few functions to get the details about our Facebook profile as well as friends' data. Let's see how to get to know more about our network. Before learning to get the network data, let's understand what a network is as well as a few important concepts about the network. Anything connected to a few other things could be a network. Everything in real life is connected to each other, for example, people, machines, events, and so on. It would make a lot of sense if we analyzed them as a network. Let's consider a network of people; here, people will be the nodes in the network and the relationship between them would be the edges (lines connecting them). Social network analysis The technique to study/analyze the network is called social network analysis. We will see how to create a simple plot of friends in our network in this section. To understand the nodes (people/places/etc) in a network in social network analysis, we need to evaluate the position of the nodes. We can evaluate the nodes using centrality. Centrality can be measured using different methods like degree, betweenness, and closeness. Let's first get our Facebook network and then get to know the centrality measures in detail. We use the function getNetwork to download our Facebook network. We need to mention how we would like to format the data. When the parameter format is set to adj.matrix, it will produce the data in matrix format where the people in the network would become the row names and column names of the matrix and if they are connected to each other, then the corresponding cell in the matrix will hold a value. The command is as follows: network<- getNetwork(token, format="adj.matrix") We now have our Facebook network downloaded. Let's visualize our network before getting to understand the centrality concept one by one with our own network. To visualize the network, we need to use the package called igraph in R. Since we downloaded our network in the adjacency matrix format, we will use the same function in igraph. We use the layout function to determine the placement of vertices in the network for drawing the graph and then we use the plot function to draw the network. In order to explore various other functionalities in these parameters, you can execute the ?<function_name> function in RStudio and the help window will have the description of the function. Let’s use the following code to load the package igraph into R. require(igraph) We will now build the graph using the function graph.adjacency; this function helps in creating a network graph using the adjacency matrix. In order to build a force-directed graph, we will use the function layout.drl. The force-directed graph will help in making the graph more readable. The commands are as follows: social_graph<- graph.adjacency(network) layout<- layout.drl(social_graph, options=list(simmer.attraction=0)) At last, we will use the plot function with various built in parameters to make the graph more readable. For example, we can name the nodes in our network, we can set the size of the nodes as well as the edges in the network, and we can color the graph and the components of the graph. Use the following code to see what the network looks like. The output that was plotted can be saved locally using the function dev.copy, and the size of the image as well as the type can be passed as a parameter to the function: plot(social_graph, vertex.size=10, vertex.color="green", vertex.label=NA, vertex.label.cex=0.5, edge.arrow.size=0, edge.curved=TRUE, layout=layout.fruchterman.reingold) dev.copy(png,filename= "C:/Users/Sharan/Desktop/3973-03-community.png", width=600, height=600); dev.off (); With the preceding plot function, my network will look like the following one. In the following network, the node labels (name of the people) have been disabled. They can be enabled by removing the vertex.label parameter. Summary In this article, we discussed how to use the various functions implemented in the Rfacebook package, analyze the network. This article covers the important techniques that helps in performing vital network analysis and also enlightens us about the wide range of business problems that could be addressed with the Facebook data. It gives us a glimpse of the great potential for implementation of various analyses. Resources for Article: Further resources on this subject: Using App Directory in HootSuite[article] Supervised learning[article] Warming Up [article]
Read more
  • 0
  • 0
  • 2572

article-image-rhomobile-faqs
Packt
21 Jul 2011
3 min read
Save for later

Rhomobile FAQs

Packt
21 Jul 2011
3 min read
  Rhomobile Beginner's Guide Step-by-step instructions to build an enterprise mobile web application from scratch         Read more about this book       (For more resources on this topic, see here.) Q: Does Rhomobile create a pure Native Application? A: Yes. Rhomobile creates a pure Native Application. This Application is similar to an Application available in i-store. This application can use device capabilities such as GPS, PIM contacts and calendar, camera, native mapping, push, barcode, signature capture, and Bluetooth. These are much faster than Browser-based applications.   Q: I am new to Ruby should I use Rhomobile? A: Although you need to know Ruby to write Rhodes applications, we realize that many folks learn both Ruby and Rhomobile at the same time. As Rhomobile products require an elementary level of Ruby knowledge, this will not affect your learning curve. But I recommend that you go to any Ruby tutorial online.   Q: Is Rhomobile Free? A: Rhodes is free and open source under MIT Licence. To use RhoSync, you must purchase a commercial license when development commences or you must open source your app under the GPL license. The pricing and details can be found at www.rhomobile.com.   Q: Is support available for Rhomobile? A: Yes. However, you have to purchase a Rhodes Enterprise License and the Rhodes Commercial License to get commercial support. Apart from the Rhomobile support, there are various webinars and tutorials available on www.rhomobile.com. Another good support resource is the Rhomobile Google group, where Rhomobile experts are there to help you.   Q: What about Rhomobile security? A: Both Rhodes and RhoSync support use of https as a transport. In fact it is easier with Rhodes than with native code. You just list the https URL and Rhodes will connect to the backend appropriately. This is simple in contrast to underlying SDKs where significantly different code is written to connect to an https URL.   Q: Does Rhomobile support HTML5? A: Yes, Rhomobile supports HTML5 tags provided the device you are targeting also supports them.   Q: Can we write unit test case for the code? A: Yes, we can write unit test case in Rhodes.   Q: Can we use Ruby gems with Rhodes? A: Yes, we can use Ruby gems with Rhodes. We have to include them in the Rhodes configuration file.   Q: Do we need to have knowledge of different device databases? A: No, we don't need to have prior knowledge of those databases, Rhodes will take care of this. We write our query using Object-relational mapping (ORM) called Rhom and it is the work of ORM to shape the query.   Summary In this article we saw some of the most frequently asked questions on Rhomobile. Further resources on this subject: An Introduction to Rhomobile [Article] Getting Started with Internet Explorer Mobile [Article] jQuery Mobile: Organizing Information with List Views [Article] jQuery Mobile: Collapsible Blocks and Theming Content [Article] Fundamentals of XHTML MP in Mobile Web Development [Article]
Read more
  • 0
  • 0
  • 2570

article-image-using-mongoid
Packt
09 Dec 2013
12 min read
Save for later

Using Mongoid

Packt
09 Dec 2013
12 min read
(For more resources related to this topic, see here.) Introducing Origin Origin is a gem that provides the DSL for Mongoid queries. Though at first glance, a question may seem to arise as to why we need a DSL for Mongoid queries; If we are finally going to convert the query to a MongoDB-compliant hash, then why do we need a DSL? Origin was extracted from Mongoid gem and put into a new gem, so that there is a standard for querying. It has no dependency on any other gem and is a standalone pure query builder. The idea was that this could be a generic DSL that can be used even without Mongoid! So, now we have a very generic and standard querying pattern. For example, in Mongoid 2.x we had the criteria any_in and any_of, and no direct support for the and, or, and nor operations. In Mongoid 2.x, the only way we could fire a $or or a $and query was like this: Author.where("$or" => {'language' => 'English', 'address.city' => 'London '}) And now in Mongoid 3, we have a cleaner approach. Author.or(:language => 'English', 'address.city' => 'London') Origin also provides good selectors directly in our models. So, this is now much more readable: Book.gte(published_at: Date.parse('2012/11/11')) Memory maps, delayed sync, and journals As we have seen earlier, MongoDB stores data in memory-mapped files of at most 2 GB each. After the data is loaded for the first time into the memory mapped files, we now get almost memory-like speeds for access instead of disk I/O, which is much slower. These memory-mapped files are preallocated to ensure that there is no delay of the file generation while saving data. However, to ensure that the data is not lost, it needs to be persisted to the disk. This is achieved by journaling. With journaling, every database operation is written to the oplog collection and that is flushed to disk every 100 ms. Journaling is turned on by default in the MongoDB configuration. This is not the actual data but the operation itself. This helps in better recovery (in case of any crash) and also ensures the consistency of writes. The data that is written to various collections are flushed to the disk every 60 seconds. This ensures that the data is persisted periodically and also ensures the speed of data access is almost as fast as memory. MongoDB relies on the operating system for the memory management of its memory-mapped files. This has the advantage of getting inherent OS benefits as the OS is improved. Also, there's the disadvantage of lack of control on how memory is managed by MongoDB. However, what happens if something goes wrong (server crashes, database stops, or disk is corrupted)? To ensure durability, whenever data is saved in files, the action is logged to a file in a chronological order. This is the journal entry, which is also a memory-mapped file but is synced with the disk every 100 ms. Using the journal, the database can be easily recovered in case of any crash. So, in the worst case scenario, we could potentially lose 100 ms of information. This is a fair price to pay for the benefits of using MongoDB. MongoDB journaling makes it a very robust and durable database. However, it also helps us decide when to use MongoDB and when not to use it. 100 ms is a long time for some services, such as financial core banking or maybe stock price updates. In such applications, MongoDB is not recommended. For most cases that are not related to heavy multi-table transactions like most financial applications MongoDB can be suitable. All these things are handled seamlessly, and we don't usually need to change anything. We can control this behavior via the configuration of MongoDB but usually it's not recommended. Let's now see how we save data using Mongoid. Updating documents and attributes As with ActiveModel specifications, save will update the changed attributes and return the updated object, otherwise it will return false on failure. The save! function will raise an exception on the error. In both cases, if we pass validate: false as a parameter to save, it will bypass the validations. A lesser-known persistence option is the upsert action. An upsert action creates a new document if it does not find it and overwrites the object if it finds it. A good reason to use upsert is in the find_and_modify action. For example, suppose we want to reserve a book in our Sodibee system, and we want to ensure that at any one point, there can be only one reservation for a book. In a traditional scenario: t1: Request-1 searches for a for a book which is not reserved and finds it t2: Now, it saves the book with the reservation information t3: Request-2 searches for a reservation for the same book and finds that the book is reserved t4: Request-2 handles the situation with either error or waits for reservation to be freed So far so good! However in a concurrent model, especially for web applications, it creates problems. t1: Request-1 searches for a book which is not reserved and finds it t2: Request-2 searches for a reservation for the same book and also gets back that book since it's not yet reserved t3: Request-1 saves the book with its reservation information t4: Request-2 now overwrites previous update and saves the book with its reservation information Now we have a situation where two requests think that the reservation for the book was successful and that is against our expectations. This is a typical problem that plagues most web applications. The various ways in which we can solve this is discussed in the subsequent sections. Write concern MongoDB helps us ensure write consistency. This means that when we write something to MongoDB, it now guarantees the success of the write operation. Interestingly, this is a configurable option and is set to acknowledged by default. This means that the write is guaranteed because it waits for an acknowledgement before returning success. In earlier versions of Mongoid, safe: true was turned off by default. This meant that success of the write operation was not guaranteed. The write concern is configured in Mongoid.yml as follows: development:sessions:default:hosts:- localhost:27017options:write:w: 1 The default write concern in Mongoid is configured with w: 1, which means that the success of a write operation is guaranteed. Let's see an example: class Authorinclude Mongoid::Documentfield :name, type: Stringindex( {name: 1}, {unique: true, background: true})end Indexing blocks read and write operations. Hence, its recommended to configure indexing in the background in a Rails application. We shall now start a Rails console and see how this reacts to a duplicate key index by creating two Author objects with the same name. irb> Author.create(name: "Gautam") => #<Author _id: 5143678345db7ca255000001, name: "Gautam"> irb> Author.create(name: "Gautam") Moped::Errors::OperationFailure: The operation: #<Moped::Protocol::Command @length=83 @request_id=3 @response_to=0 @op_code=2004 @flags=[] @full_collection_name="sodibee_development.$cmd" @skip=0 @limit=-1 @selector={:getlasterror=>1, :w=>1} @fields=nil> failed with error 11000: "E11000 duplicate key error index: sodibee_ development.authors.$name_1 dup key: { : "Gautam" }" As we can see, it has raised a duplicate key error and the document is not saved. Now, let's have some fun. Let's change the write concern to unacknowledged: development:sessions:default:hosts:- localhost:27017options:write:w: 0 The write concern is now set to unacknowledged writes. That means we do not wait for the MongoDB write to eventually succeed, but assume that it will. Now let's see what happens with the same command that had failed earlier. irb > Author.where(name: "Gautam").count=> 1irb > Author.create(name: "Gautam")=> #<Author _id: 5287cba54761755624000000, name: "Gautam">irb > Author.where(name: "Gautam").count=> 1 There seems to be a discrepancy here. Though Mongoid create returned successfully, the data was not saved to the database. Since we specified background: true for the name index, the document creation seemed to succeed as MongoDB had not indexed it yet, and we did not wait for acknowledging the success of the write operation. So, when MongoDB tries to index the data in the background, it realizes that the index criterion is not met (since the index is unique), and it deletes the document from the database. Now, since that was in the background, there is no way to figure this out on the console or in our Rails application. This leads to an inconsistent result. So, how can we solve this problem? There are various ways to solve this problem: We leave the Mongoid default write concern configuration alone. By default, it is w: 1 and it will raise an exception. This is the recommended approach as prevention is better than cure! Do not specify the background: true option. This will create indexes in the foreground. However, this approach is not recommended as it can cause a drop in performance because index creations block read and write access. Add drop_dups: true. This deletes data, so you have to be really careful when using this option. Other options to the index command create different types of indexes as shown in the following table: Index Type Example Description sparse index({twitter_name: 1}, { sparse: true}) This creates sparse indexes, that is, only the documents containing the indexed fields are indexed. Use this with care as you can get incomplete results. 2d 2dsphere index({:location => "2dsphere"}) This creates a two-dimensional spherical index. Text index MongoDB 2.4 introduced text indexes that are as close to free text search indexes as it gets. However, it does only basic text indexing—that is, it supports stop words and stemming. It also assigns a relevance score with each search. Text indexes are still an experimental feature in MongoDB, and they are not recommended for extensive use. Use ElasticSearch, Solr (Sunspot), or ThinkingSphinx instead. The following code snippet shows how we can specify a text index with weightage: index({ "name" => 'text',"last_name" => 'text'},{weights: {'name' => 10,'last_name' => 5,},name: 'author_text_index'}) There is no direct search support in Mongoid (as yet). So, if you want to invoke a text search, you need to hack around a little. irb> srch = Mongoid::Contextual::TextSearch.new(Author.collection,Author.all, 'john')=> #<Mongoid::Contextual::TextSearchselector: {}class: Authorsearch: johnfilter: {}project: N/Alimit: N/Alanguage: default>irb> srch.execute=> {"queryDebugString"=>"john||||||", "language"=>"english","results"=>[{"score"=>7.5, "obj"=>{"_id"=>BSON::ObjectId('51fc058345db7c843f00030b'), "name"=>"Bettye Johns"}}, {"score"=>7.5, "obj"=>{"_id"=>BSON::ObjectId('51fc058345db7c843f00046d'), "name"=>"John Pagac"}},{"score"=>7.5, "obj"=>{"_id"=>BSON::ObjectId('51fc058345db7c843f000578'),"name"=>"Jeanie Johns"}}, {"score"=>7.5, "obj"=>{"_id"=>BSON::ObjectId('51fc058445db7c843f0007e7')...{"score"=>7.5, "obj"=>{"_id"=>BSON::ObjectId('51fc058a45db7c843f0025f1'), "name"=>"Alford Johns"}}], "stats"=>{"nscanned"=>25,"nscannedObjects"=>0, "n"=>25, "nfound"=>25, "timeMicros"=>31103},"ok"=>1.0} By default, text search is disabled in MongoDB configuration. We need to turn it on by adding setParameter = textSearchEnabled=true in the MongoDB configuration file, typically /usr/local/mongo.conf. This returns a result with statistical data as well the documents and their relevance score. Interestingly, it also specifies the language. There are a few more things we can do with the search result. For example, we can see the statistical information as follows: irb> a.stats=> {"nscanned"=>25, "nscannedObjects"=>0, "n"=>25, "nfound"=>25,"timeMicros"=>31103} We can also convert the data into our Mongoid model objects by using project, as shown in the following command: > a.project(:name).to_a=> [#<Author _id: 51fc058345db7c843f00030b, name: "Bettye Johns",last_name: nil, password: nil>, #<Author _id: 51fc058345db7c843f00046d,name: "John Pagac", last_name: nil, password: nil>, #<Author _id:51fc058345db7c843f000578, name: "Jeanie Johns", last_name: nil, password:nil> ... Some of the important things to remember are as follows: Text indexes can be very heavy in memory. They can return the documents, so the result can be large. We can use multiple keys (or filters) along with a text search. For example, the index with index ({ 'state': 1, name: 'text'}) will mandate the use of the state for every text search that is specified. A search for "john doe" will result in a search for "john"or "doe"or both. A search for "john"and "doe" will search for all "john"and "doe"in a random order. A search for ""john doe"", that is, with escaped quotes, will search for documents containing the exact phrase "john doe". A lot more data can be found at http://docs.mongodb.org/manual/tutorial/search-for-text/ Summary This article provides an excellent reference for using Mongoid. The article has examples with code samples and explanations that help in understanding the various features of Mongoid. Resources for Article: Further resources on this subject: Installing phpMyAdmin [Article] Integrating phpList 2 with Drupal [Article] Documentation with phpDocumentor: Part 1 [Article]
Read more
  • 0
  • 0
  • 2570

article-image-introduction-mobile-web-arcgis-development
Packt
05 Mar 2015
9 min read
Save for later

Introduction to Mobile Web ArcGIS Development

Packt
05 Mar 2015
9 min read
In this article by Matthew Sheehan, author of the book Developing Mobile Web ArcGIS Applications, GIS is a location-focused technology. Esri's ArcGIS platform provides a complete set of GIS capabilities to store, access, analyze, query, and visualize spatial data. The advent of cloud and mobile computing has increased the focus on location technology dramatically. By leveraging the GPS capabilities of most mobile devices, mobile users are very interested in finding out who and what is near them. Mobile maps and apps that have a location component are increasingly becoming more popular. ArcGIS provides a complete set of developer tools to satisfy these new location-centric demands. (For more resources related to this topic, see here.) Web ArcGIS development The following screenshot illustrates different screen sizes: Web ArcGIS development is focused to provide users access to ArcGIS Server, ArcGIS Online, or Portal for ArcGIS services. This includes map visualization and a slew of geospatial services, which include providing users the ability to search, identify, buffer, measure, and much more. Portal for ArcGIS provides the same experience as ArcGIS Online, but within an organization's infrastructure (on-premises or in the cloud). This is a particularly good solution where there are concerns around security. The ArcGIS JavaScript API is the most popular among the web development tools provided by Esri. The API can be used both for mobile and desktop web application development. Esri describes the ArcGIS API for JavaScript as "a lightweight way to embed maps and tasks in web applications." You can get these maps from ArcGIS Online, your own ArcGIS Server or others' servers." The API documents can be found at https://developers.arcgis.com/Javascript/jshelp/. Mobile Web Development is different Developers new to mobile web development need to take into consideration the many differences in mobile development as compared to traditional desktop web development. These differences include screen size, user interaction, design, functionality, and responsiveness. Let's discuss these differences in more depth. Screen size and pixel density There are large variations in the screen sizes of mobile devices. These can range from 3.5 inch for smartphones to more than 10.1 inches for tablets. Similarly, pixel density varies enormously between devices. These differences affect both the look and feel of your mobile ArcGIS app and user interaction. When building a mobile web application, the target device and pixel density needs careful consideration. Interaction Mobile ArcGIS app interaction is based on the finger rather than the mouse. That means tap, swipe and pinch. The following screenshot illustrates the Smartphone ArcGIS finger interactions: Often, it is convenient to include some of the more traditional map interaction tools, such as zoom sliders, but most users will pan and zoom using finger gestures. Any onscreen elements such as buttons need to be large to allow for the lack of precision of a finger tap. Mobile ArcGIS app also provides new data input mechanisms. Data input relies on a screen-based, touch-driven keyboard. Usually, multiple keyboards are available, these are for character input, numeric input, and date input respectively. Voice input might also be another input mechanism. Providing mobile users feedback is very important. If a button is tapped, it is good practice to give a visual cue of state change, such as changing the button color. For example, as shown in the following screenshots, a green-coloured button with the label, 'Online', changes to red and the label changes to 'Offline' after a user tap: Design A simple and intuitive design is key to the success of any mobile ArcGIS application. If your mobile application is hard to use or understand, you will soon lose users' attention and interest. Workflows should be easy. One screen should flow logically to the next. It should be obvious to the user how to return to the previous or home screen. The following screenshot describes small pop ups open to attributes screen: ArcGIS mobile applications are usually map-focused . Tools often sit over the map or hide the map completely. Developers need to carefully consider the design of the application so that it is easy for users to return to the map. GIS maps are made up of a basemap with the so called feature overlays. These overlays are map layers and represent geographic features, either through a point, line, or a polygon . Points may represent water valves, lines may be buried pipelines, while polygons may represent parks. Mobile devices can change orientation from profile to landscape. On screen elements will appear different in each of these modes. Orientation again needs consideration during mobile application development. The Bootstrap JavaScript framework helps automatically adjust onscreen elements based on orientation and a device's screen size. Often, mobile ArcGIS applications have a multi-column layout. This commonly includes a layer list on the left side, a central map, and a set of tools on the right side. This works well on larger devices, but less well on smaller smartphones. Applications often need to be designed so that they can collapse into a single column when they are accessed from these smaller devices. The following screenshot illustrates the multiple versus single column layouts: Mobile applications often need to be styled for a specific platform. Apple and Android have styling and design guidelines. Much can be done with stylesheets to ensure that an application has the look and feel of a specific platform. Functionality Mobile ArcGIS applications often have different uses to their desktop-based cousins. Desktop web ArcGIS applications are often built with many tools and are commonly used for analysis. In contrast, mobile ArGIS applications provide a simpler, focused functionality. The mobile user base is also more varied and includes both GIS and non-GIS trained users. Maintenance staff, surveyors, attorneys, engineers, and consumers are increasingly interested in using mobile ArcGIS applications. Developers need to carefully consider both the target users and the functionality provided when they build any mobile ArcGIS web application. Mobile ArcGIS users do not want applications that provide a plethora of complex tools. Being simple and focused is the key. Responsiveness Users expect mobile applications to be fast and responsive. Think about how people use their mobile devices today. Gaming and social media are extremely popular. High performance is always expected . Extra effort and attention is needed during mobile web development to optimize performance. Sure, network issues are out of your hands, but much can be done to ensure that your mobile ArcGIS application is fast. Mobile Browsers There are an increasing number of mobile browsers that are now available. These include Safari, Chrome, Opera, Dolphin, and IE. Many are built using the WebKit rendering engine, which provides the most current browser capabilities. The following icons shows different mobile web browsers that are now available: As with desktop web development, cross-browser testing is crucial as you cannot predict which browsers your users will use. Mobile functionality that works well in one browser may not work quite so well in a different browser. There are an increasing number of resources to help you with the challenges of testing such as modernizer.com, yepnopejs.com, and caniuse.com. See the excellent article in Mashable on mobile testing tools at http://mashable.com/2014/02/26/browser-testing-tools/. Web, native and hybrid mobile applications The following screenshot illustrates three different types of mobile applications: There are three main types of mobile applications: web, native, and hybrid. At one point of time, native was the preferred approach for mobile development . However, web technology is advancing at a rapid rate and in many situations, it could now be argued to be actually a better choice than native. Flexibility is a key benefits of mobile web as one code base runs across all devices and platforms. Another key advantage of a web approach is that a browser-based application, built with the ArcGIS JavaScript API, can be converted into an installable native-like application using technologies such as PhoneGap. These are called hybrid mobile apps. Mobile frameworks, toolkits and libraries JavaScript is one of the most popular languages in the world. It is an implementation of the ECMAScript language open standard . There are a plethora of available tools, built by the JavaScript community. The ArcGIS JavacSript API is built on the Dojo framework. This is an open source JavaScript framework used for constructing dynamic web user interfaces. Dojo provides modules, widgets, and plugins, making it an very flexible development framework. Another extremely useful framework is jQuery Mobile. This is another excellent option for ArcGIS JavaScript developers. Bootstrap is a popular framework for developing responsive mobile applications, as the following screenshot illustrates Bootstrap: The framework provides automatic layout adaptation. This includes adapting to changes in device orientation and screen size. Using this framework means your ArcGIS web application will look good and be usable on all mobile devices: smartphones, phablet, and tablets. PhoneGap/Cordova allows developers to convert web mobile applications to installable hybrid apps. This is another excellent open source framework. The following screenshot illustrates how to convert a web app to hybrid using Phonegap: Hybrid apps built using PhoneGap can access mobile resources, such as GPS, camera, SD card, compass, and accelerometer, and be distributed through the various mobile app stores just like a native app. Cordova is the open source framework that is managed by the Apache Foundation. PhoneGap is based on Cordova and PhoneGap is owned and managed by Adobe. For more information, go to http://cordova.apache.org/. The names are often used interchangeably, and in fact, the two are very similar. However, there is a legal and technical difference between them. Summary In this article, we introduced mobile web development by leveraging the ArcGIS JavaScript API. We discussed some of the key areas in which mobile web development is different than traditional desktop development. These areas include screen size, user interaction, design, functionality, and responsiveness. Some of the many advantages of mobile web ArcGIS development were also discussed, including flexibility wherein one application runs on all platforms and devices. Finally, we introduced hybrid apps and how a browser-based web application can be converted into an installable app using PhoneGap. As location becomes ever more important to mobile users, so will the demand for web-based ArcGIS mobile applications. Therefore, those who understand the ArcGIS JavaScript API should have a bright future ahead. Resources for Article: Further resources on this subject: Adding Graphics to the Map [article] ArcGIS Spatial Analyst [article] Python functions – Avoid repeating code [article]
Read more
  • 0
  • 0
  • 2568

article-image-introduction-akka
Packt
04 Feb 2016
15 min read
Save for later

Introduction to Akka

Packt
04 Feb 2016
15 min read
In this article written by Prasanna Kumar Sathyanarayanan and Suraj Atreya (the authors of this book, Reactive Programming with Scala and Akka), we will see what the Akka framework is all about in detail. Akka is a framework to write distributed, asynchronous, concurrent, and scalable applications. Akka actors react to the messages that are sent to them. Actors can be viewed as a passive component unless an external message is triggered. They are a higher level abstraction and provide a neat way to handle concurrency instead of a traditional multithreaded application. (For more resources related to this topic, see here.) One of the examples of Akka actor is handling request response in a web server. A web server typically handles millions of requests per second. These requests must be handled concurrently to cater to the user requests. One way is to have a pool of threads and let these threads accept the requests and hand it off to the actual worker threads. In this case, the thread pool has to be managed by the application developer including error handling, thread locking, and synchronization. Most often, the application logic is intertwined with the business logic. In case of the web server, the thread pool has to be manually handled. Whereas, using actors, the thread pool is managed by the Akka engine and actors receive messages asynchronously. Each request can be thought of as a message to the actor, and the actor reacts to the message. Actors are very light weight event-driven processes. Several million actors can exist within a GB of heap memory. Actor mailbox Every actor has a mailbox. Since actors communicate exclusively using messages, every actor maintains a queue of messages called mailbox. Therefore, an actor will read the messages in the order that it was sent. Actor systems An ActorSystem is a heavyweight process which is the first step before creating actors. During initialization, it allocates 1 to N threads per ActorSystem. Before creating an actor, an actor system must be created and this process involves the creation of a hierarchical structure of actors. Since an actor can create other actors, the handling of failure is also a vital part of the Akka engine, which handles it gracefully. This design helps to take action if an actor dies or has an unexpected exception for some reason. When an actor system is first created, three actors are created as shown in the figure: Root guardian (/): The root guardian is the grand parent of all the actors. This actor supervises all actors under the user actors. Since the root guardian is the supervisor of all the actors underneath it, there is no supervisor for the root guardian itself. Root guardian actor is not a real actor and it will terminate the actor system if it finds any throwables from its children. User ( /user): The user guardian actor supervises all the actors that are created by the users. If the user guardian actor terminates, all its children will also terminate. System guardian ( /system): This is a special actor that oversees the orderly shutdown of actors while logging remains active. This is achieved by having the system guardian watch the user guardian and initialize a shut-down sequence when the Terminated message is received. Message passing The figure at the end of this section shows the different steps that are involved when a message is passed to an actor. For example, let's assume there is a pizza website and a customer wants to order some pizzas. For simplicity, let's remove the non-essential details, such as billing and other information, and instead focus on just the order of a pizza. If a customer is some kind of an application (pizza customer) and the one who receives orders is a chef (pizza chef), then each request for a pizza can be illustrated as an asynchronous request to the chef. The figure shows how when a message is passed to an actor, all the different components such as mailbox and dispatcher does its job. Broadly these are explained in the following six steps when a message is passed to the actor: A PizzaCustomer creates and uses the ActorSystem. This is the first step before sending a message to an actor. The PizzaCustomer acquires a PizzaChef. In Akka, an actor is created using the actorOf(...) function call. Akka doesn't return the actual actor but instead returns a reference to the actor reference PizzaChef for safety. The PizzaRequest is sent to this PizzaChef. The PizzaChef sends this message to the Dispatcher. Dispatcher then enqueues the message into the PizzaChef's actor mailbox. Dispatcher then puts the mailbox on the thread. Finally, the mailbox dequeues and sends the message to the PizzaChef receive method. Creating an actor system An actor system is the first thing that should be created before creating actors. The actor system is created using the following API: val system = ActorSystem("Pizza") The string "Pizza" is just a name given to the actor system. Creating an ActorRef The following snippet shows the creation of an actor inside the previously created actor system: val pizzaChef: ActorRef = system.actorOf(Props[PizzaChef]) An actor is created using the actorOf(...) function call. The actorOf() call doesn't return the actor itself, instead returns a reference to the actor. Once an actor's reference is obtained, clients can send messages using the ActorRef. This is a safe way of communicating between actors since the state of the actor itself is not manipulated in any way. Sending a PizzaRequest to the ActorRef Now that we have an actor system and a reference to the actor, we would like to send requests to the pizzaChef actor reference. We send the message to an actor using the ! also called Tell. Here in the code snippet, we Tell the message MarinaraRequest to the pizza ActorRef: pizzaChef ! MarinaraRequest The Tell is also called as fire-forget. There is no acknowledgement returned from a Tell. When the message is sent to an actor, the actor's receive method will receive the message and processes it further. receive is a partial function and has the following signature: def receive: PartialFunction[Any, Unit] The return type receive suggests it is Unit and therefore this function is side effecting. The following code is what we discussed: import akka.actor.{Actor, ActorRef, Props, ActorSystem} sealed trait PizzaRequest case object MarinaraRequest extends PizzaRequest case object MargheritaRequest extends PizzaRequest class PizzaChef extends Actor {   def receive = {     case MarinaraRequest => println("I have a Marinara request!")     case MargheritaRequest => println("I have a Margherita request!")   } } object PizzaCustomer{     def main(args: Array[String]) : Unit = {     val system = ActorSystem("Pizza")     val pizzaChef: ActorRef = system.actorOf(Props[PizzaChef])     pizzaChef ! MarinaraRequest     pizzaChef ! MargheritaRequest   } } The preceding code shows the receive block that handles two kinds of requests; one for MarinaraRequest, and the other for MargheritaRequest. These two requests are defined as case objects. Actor message We saw when a message needs to be sent, ! (Tell) was used. But, we didn't discuss how exactly this message is processed. We will explore how the ideas of dispatcher and execution context are used to carry out the message passing techniques between actors. In the pizza example, we used two kinds of messages: MarinaraRequest and MargheritaRequest. For simplicity, all that these messages did was to print on the console. When PizzaCustomer sent PizzaRequest to PizzaChef ActorRef, the messages are sent to the dispatcher. The dispatcher then sends this message to the corresponding actor's mailbox. Mailbox Every time a new actor is created, a corresponding mailbox is also created. There are exceptions to this rule when multiple actors share a same mailbox. PizzaChef will have a mailbox. This mailbox stores the messages that appear asynchronously in a FIFO manner. Therefore, when a new message is sent to an actor, Akka guarantees that the messages are enqueued and dequeued in a FIFO manner. Here is the signature of the mailbox from the Akka source: It can be found at https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala private[akka] abstract class Mailbox(val messageQueue: MessageQueue)     extends ForkJoinTask[Unit]       with SystemMessageQueue with Runnable From this signature, we can see that Mailbox takes a MessageQueue as an input. Also, we can see that it extends Runnable and suggests that Mailbox is a thread. We will see why the Mailbox is a thread, in a bit. Dispatcher Dispatchers dispatch actors to threads. There is no one-to-one mapping between actors and threads. If that was the case, then the whole system would crumble under its own weight. Also, the amount of context switching would be much more than the actual work. Therefore, it is important to understand that creating a number of actors is not equal to creating the same number of threads. The main objective of dispatcher is to coordinate between the actors and its messages to the underlying threads. A dispatcher picks the actor next in the queue based on the dispatcher policy and the actor's message in the queue. These two are then passed on to one of the available threads in the execution context. To illustrate this point, let's see the code snippet: protected[akka] override   def registerForExecution(mbox: Mailbox, ...): Boolean = {   ...      if (mbox.setAsScheduled()) {      try {          executorService execute mbox          true       }   } This code snippet shows us that the dispatcher accepts a Mailbox as a parameter and has ExecutorService wrapped around to execute the mailbox. We saw that Mailbox is a thread and the dispatcher executes this Mailbox against this ExecutorService. When the mailbox's run method is triggered, it dequeues a message from Mailbox and passes it to the actor for processing. This is the code snippet of run from Mailbox.scala from the Akka source code: The source code can be found at https://github.com/akka/akka/blob/master/akka-actor/src/main/scala/akka/dispatch/Mailbox.scala override final def run(): Unit = {     try {       if (!isClosed) { //Volatile read, needed here         processAllSystemMessages() //First, deal with any system messages         processMailbox() //Then deal with messages       }     } finally {       setAsIdle() //Volatile write, needed here       dispatcher.registerForExecution(this, false, false)     }   } Actor Path The interesting thing about actor system is that actors are created in a hierarchical manner. All the user created actors are created under the /user actor. The actor path looks very similar to the UNIX file system hierarchy, for example, /home/akka/akka_book. We will see how this is similar to the Akka path in the following code example. Let's take our pizza example, and let's add a few toppings on the pizza. So, whenever a customer gives MarinaraRequest, he will get extra cheese too: class PizzaToppings extends Actor{   def receive = {     case ExtraCheese => println("Aye! Extra cheese it is")     case Jalapeno => println("More Jalapenos!")   } } class PizzaSupervisor extends Actor {   val pizzaToppings =         context.actorOf(Props[PizzaToppings], "PizzaToppings")   def receive = {     case MarinaraRequest   =>       println("I have a Marinara request with extra cheese!")       println(pizzaToppings.path)       pizzaToppings ! ExtraCheese     case MargheritaRequest =>       println("I have a Margherita request!")     case PizzaException    =>      throw new Exception("Pizza fried!")   } } The PizzaSupervisor class is very similar to our earlier example of pizza actor. However, if you observe carefully, there is another actor created within this PizzaSupervisor called the PizzaToppings actor. This PizzaToppings is created using context.actorOf(...) instead of using system.actorOf(...). Therefore, PizzaToppings will become the child of PizzaSupervisor. The actor path of PizzaSupervisor will look like this: akka://Pizza/user/PizzaSupervisor The actor path for PizzaToppings will look like this: akka://Pizza/user/PizzaSupervisor/PizzaToppings When this main program is run, the actor system is created using system.actorOf(...) and prints the path of the pizza actor system and its corresponding child as shown previously: object TestActorPath {   def main(args: Array[String]): Unit = {     val system = ActorSystem("Pizza")     val pizza: ActorRef =  system.actorOf(Props[PizzaSupervisor],                    "PizzaSupervisor")     println(pizza.path)     pizza ! MarinaraRequest     system.shutdown()   } } The following is the output:akka://Pizza/user/PizzaSupervisorI have a Marinara request with extra cheese!akka://Pizza/user/PizzaSupervisor/PizzaToppingsAye! Extra cheese it is The name akka in the actor path is fixed and the actors created are shown under the user. If you remember from earlier discussions, all the user-created actors are created under the user guardian. Therefore, the actor path shows that it is a user-created actor. The name pizza is the name we gave to the actor system while it was being created. Therefore, the hierarchy explains that pizza is the actor system and all the actors are children below it. In the following figure, we can clearly see the actor hierarchy and its actor path: Actor lifecycle Akka actors have a life cycle that is very useful for writing a bug free concurrent code. Akka follows a philosophy of Let it crash and it is assumed that actors too can crash. But if an actor crashes, several actions can be taken including restarting it. As usual let's look at our pizza baking process. As before, we will have an actor to accept the pizza requests. But, this time we will see the workflow of the pizza baking process! Using this example, we will see how the actor life cycle works: class PizzaLifeCycle extends Actor with ActorLogging {   override def preStart() = {     log.info("Pizza request received!")   }   def receive = {     case MarinaraRequest   => log.info("I have a Marinara request!")     case MargheritaRequest => log.info("I have a Margherita request!")     case PizzaException    => throw new Exception("Pizza fried!")   }  //Old actor instance   override def preRestart(reason: Throwable, message: Option[Any]) = {     log.info("Pizza baking restarted because " + reason.getMessage)     postStop()   }   //New actor instance   override def postRestart(reason: Throwable) = {     log.info("New Pizza process started because earlier " + reason.getMessage)     preStart()   }   override def postStop() = {     log.info("Pizza request finished")   } } The PizzaLifeCycle actor takes pizza requests but with additional states. An actor can go through many different states during its lifetime. Let's send some messages to find out what happens with our PizzaLifeCycle actor and how it behaves:     pizza ! MarinaraRequest         pizza ! PizzaException         pizza ! MargheritaRequest Here is the output for the preceding requests sent:Pizza request received!I have a Marinara request!Pizza fried!java.lang.Exception: Pizza fried!at PizzaLifeCycle$$anonfun$receive$1.applyOrElse(PizzaLifeCycle.scala:12)at akka.actor.Actor$class.aroundReceive(Actor.scala:467)at PizzaLifeCycle.aroundReceive(PizzaLifeCycle.scala:3)at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)Pizza baking restarted because Pizza fried!Pizza request finishedNew Pizza process started because Pizza fried!Pizza request received!I have a Margherita request! When we sent our first MarinaraRequest request, we see the following in the log we received: Pizza request received! I have a Marinara request! Akka called the preStart() method and then entered the receive block. Then, we simulated an exception by sending PizzaException and as expected, we got an exception: Pizza fried!java.lang.Exception: Pizza fried!  at PizzaLifeCycle$$anonfun$receive$1.applyOrElse(PizzaLifeCycle.scala:12)  at akka.actor.Actor$class.aroundReceive(Actor.scala:467)  at PizzaLifeCycle.aroundReceive(PizzaLifeCycle.scala:3)  at akka.actor.ActorCell.receiveMessage(ActorCell.scala:516)Pizza baking restarted because Pizza fried!Pizza request finished There are some interesting things to note here. Although we got an exception Pizza fried!, we also got two other log messages. The reason for this is quite simple. When we have an exception, Akka called preRestart(). During preRestart(), is called on the old instance of the actor and have a chance to clean-up some of the resources here. But in our example, we just called postStop(). During preRestart(), the old instance prepares to handoff to the new actor instance. Finally, we sent another request called MargheritaRequest. Here, we get these log messages: New Pizza process started because Pizza fried!Pizza request received!I have a Margherita request! We saw that the old instance actor was stopped. Here, the requests are handled by a new actor instance. The postRestart()is now called on the new actor instance, which calls preStart() to resume normal operations of our pizza baking process. During the preRestart() and postRestart() methods, we got a reason as to why the old actor died. Summary In this article, you learned about the details of the Akka framework, the actor mailbox, actor systems, how to create an actor system and ActorRef, how to send PizzaRequest to ActorRef, and so on. Resources for Article:   Further resources on this subject: The Design Patterns Out There and Setting Up Your Environment [article] Creating First Akka Application [article] Content-based recommendation [article]
Read more
  • 0
  • 0
  • 2567
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 $19.99/month. Cancel anytime
Packt
16 Sep 2013
16 min read
Save for later

Linux Shell Scripting – various recipes to help you

Packt
16 Sep 2013
16 min read
(For more resources related to this topic, see here.) The shell scripting language is packed with all the essential problem-solving components for Unix/Linux systems. Text processing is one of the key areas where shell scripting is used, and there are beautiful utilities such as sed, awk, grep, and cut, which can be combined to solve problems related to text processing. Various utilities help to process a file in fine detail of a character, line, word, column, row, and so on, allowing us to manipulate a text file in many ways. Regular expressions are the core of pattern-matching techniques, and most of the text-processing utilities come with support for it. By using suitable regular expression strings, we can produce the desired output, such as filtering, stripping, replacing, and searching. Using regular expressions Regular expressions are the heart of text-processing techniques based on pattern matching. For fluency in writing text-processing tools, one must have a basic understanding of regular expressions. Using wild card techniques, the scope of matching text with patterns is very limited. Regular expressions are a form of tiny, highly-specialized programming language used to match text. A typical regular expression for matching an e-mail address might look like [a-z0-9_]+@[a-z0-9]+\.[a-z]+. If this looks weird, don't worry, it is really simple once you understand the concepts through this recipe. How to do it... Regular expressions are composed of text fragments and symbols, which have special meanings. Using these, we can construct any suitable regular expression string to match any text according to the context. As regex is a generic language to match texts, we are not introducing any tools in this recipe. Let's see a few examples of text matching: To match all words in a given text, we can write the regex as follows: ( ?[a-zA-Z]+ ?) ? is the notation for zero or one occurrence of the previous expression, which in this case is the space character. The [a-zA-Z]+ notation represents one or more alphabet characters (a-z and A-Z). To match an IP address, we can write the regex as follows: [0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3} Or: [[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3}\.[[:digit:]]{1,3} We know that an IP address is in the form 192.168.0.2. It is in the form of four integers (each from 0 to 255), separated by dots (for example, 192.168.0.2). [0-9] or [:digit:] represents a match for digits from 0 to 9. {1,3} matches one to three digits and \. matches the dot character (.). This regex will match an IP address in the text being processed. However, it doesn't check for the validity of the address. For example, an IP address of the form 123.300.1.1 will be matched by the regex despite being an invalid IP. This is because when parsing text streams, usually the aim is to only detect IPs. How it works... Let's first go through the basic components of regular expressions (regex): regex Description Example ^ This specifies the start of the line marker. ^tux matches a line that starts with tux. $ This specifies the end of the line marker. tux$ matches a line that ends with tux. . This matches any one character. Hack. matches Hack1, Hacki, but not Hack12 or Hackil; only one additional character matches. [] This matches any one of the characters enclosed in [chars]. coo[kl] matches cook or cool. [^] This matches any one of the characters except those that are enclosed in [^chars]. 9[^01] matches 92 and 93, but not 91 and 90. [-] This matches any character within the range specified in []. [1-5] matches any digits from 1 to 5. ? This means that the preceding item must match one or zero times. colou?r matches color or colour, but not colouur. + This means that the preceding item must match one or more times. Rollno-9+ matches Rollno-99 and Rollno-9, but not Rollno-. * This means that the preceding item must match zero or more times. co*l matches cl, col, and coool. () This treats the terms enclosed as one entity ma(tri)?x matches max or matrix. {n} This means that the preceding item must match n times. [0-9]{3} matches any three-digit number. [0-9]{3} can be expanded as [0-9][0-9][0-9]. {n,} This specifies the minimum number of times the preceding item should match. [0-9]{2,} matches any number that is two digits or longer. {n, m} This specifies the minimum and maximum number of times the preceding item should match. [0-9]{2,5} matches any number has two digits to five digits. | This specifies the alternation-one of the items on either of sides of | should match. Oct (1st | 2nd) matches Oct 1st or Oct 2nd. \ This is the escape character for escaping any of the special characters mentioned previously. a\.b matches a.b, but not ajb. It ignores the special meaning of . because of \. For more details on the regular expression components available, you can refer to the following URL: http://www.linuxforu.com/2011/04/sed-explained-part-1/ There's more... Let's see how the special meanings of certain characters are specified in the regular expressions. Treatment of special characters Regular expressions use some characters, such as $, ^, ., *, +, {, and }, as special characters. But, what if we want to use these characters as normal text characters? Let's see an example of a regex, a.txt. This will match the character a, followed by any character (due to the '.' character), which is then followed by the string txt . However, we want '.' to match a literal '.' instead of any character. In order to achieve this, we precede the character with a backward slash \ (doing this is called escaping the character). This indicates that the regex wants to match the literal character rather than its special meaning. Hence, the final regex becomes a\.txt. Visualizing regular expressions Regular expressions can be tough to understand at times, but for people who are good at understanding things with diagrams, there are utilities available to help in visualizing regex. Here is one such tool that you can use by browsing to http://www.regexper.com; it basically lets you enter a regular expression and creates a nice graph to help understand it. Here is a screenshot showing the regular expression we saw in the previous section: Searching and mining a text inside a file with grep Searching inside a file is an important use case in text processing. We may need to search through thousands of lines in a file to find out some required data, by using certain specifications. This recipe will help you learn how to locate data items of a given specification from a pool of data. How to do it... The grep command is the magic Unix utility for searching in text. It accepts regular expressions, and can produce output in various formats. Additionally, it has numerous interesting options. Let's see how to use them: To search for lines of text that contain the given pattern: $ grep pattern filenamethis is the line containing pattern Or: $ grep "pattern" filenamethis is the line containing pattern We can also read from stdin as follows: $ echo -e "this is a word\nnext line" | grep wordthis is a word Perform a search in multiple files by using a single grep invocation, as follows: $ grep "match_text" file1 file2 file3 ... We can highlight the word in the line by using the --color option as follows: $ grep word filename --color=autothis is the line containing word Usually, the grep command only interprets some of the special characters in match_text. To use the full set of regular expressions as input arguments, the -E option should be added, which means an extended regular expression. Or, we can use an extended regular expression enabled grep command, egrep. For example: $ grep -E "[a-z]+" filename Or: $ egrep "[a-z]+" filename In order to output only the matching portion of a text in a file, use the -o option as follows: $ echo this is a line. | egrep -o "[a-z]+\." line. In order to print all of the lines, except the line containing match_pattern, use: $ grep -v match_pattern file The -v option added to grep inverts the match results. Count the number of lines in which a matching string or regex match appears in a file or text, as follows: $ grep -c "text" filename 10 It should be noted that -c counts only the number of matching lines, not the number of times a match is made. For example: $ echo -e "1 2 3 4\nhello\n5 6" | egrep -c "[0-9]" 2 Even though there are six matching items, it prints 2, since there are only two matching lines. Multiple matches in a single line are counted only once. To count the number of matching items in a file, use the following trick: $ echo -e "1 2 3 4\nhello\n5 6" | egrep -o "[0-9]" | wc -l 6 Print the line number of the match string as follows: $ cat sample1.txt gnu is not unix linux is fun bash is art $ cat sample2.txt planetlinux $ grep linux -n sample1.txt 2:linux is fun or $ cat sample1.txt | grep linux -n If multiple files are used, it will also print the filename with the result as follows: $ grep linux -n sample1.txt sample2.txt sample1.txt:2:linux is fun sample2.txt:2:planetlinux Print the character or byte offset at which a pattern matches, as follows: $ echo gnu is not unix | grep -b -o "not" 7:not The character offset for a string in a line is a counter from 0, starting with the first character. In the preceding example, not is at the seventh offset position (that is, not starts from the seventh character in the line; that is, gnu is not unix). The -b option is always used with -o. To search over multiple files, and list which files contain the pattern, we use the following: $ grep -l linux sample1.txt sample2.txt sample1.txt sample2.txt The inverse of the -l argument is -L. The -L argument returns a list of non-matching files. There's more... We have seen the basic usages of the grep command, but that's not it; the grep command comes with even more features. Let's go through those. Recursively search many files To recursively search for a text over many directories of descendants, use the following command: $ grep "text" . -R -n In this command, "." specifies the current directory. The options -R and -r mean the same thing when used with grep. For example: $ cd src_dir $ grep "test_function()" . -R -n ./miscutils/test.c:16:test_function(); test_function() exists in line number 16 of miscutils/test.c. This is one of the most frequently used commands by developers. It is used to find files in the source code where a certain text exists. Ignoring case of pattern The -i argument helps match patterns to be evaluated, without considering the uppercase or lowercase. For example: $ echo hello world | grep -i "HELLO" hello grep by matching multiple patterns Usually, we specify single patterns for matching. However, we can use an argument -e to specify multiple patterns for matching, as follows: $ grep -e "pattern1" -e "pattern" This will print the lines that contain either of the patterns and output one line for each match. For example: $ echo this is a line of text | grep -e "this" -e "line" -o this line There is also another way to specify multiple patterns. We can use a pattern file for reading patterns. Write patterns to match line-by-line, and execute grep with a -f argument as follows: $ grep -f pattern_filesource_filename For example: $ cat pat_file hello cool $ echo hello this is cool | grep -f pat_file hello this is cool Including and excluding files in a grep search grep can include or exclude files in which to search. We can specify include files or exclude files by using wild card patterns. To search only for .c and .cpp files recursively in a directory by excluding all other file types, use the following command: $ grep "main()" . -r --include *.{c,cpp} Note, that some{string1,string2,string3} expands as somestring1 somestring2 somestring3. Exclude all README files in the search, as follows: $ grep "main()" . -r --exclude "README" To exclude directories, use the --exclude-dir option. To read a list of files to exclude from a file, use --exclude-from FILE. Using grep with xargs with zero-byte suffix The xargs command is often used to provide a list of file names as a command-line argument to another command. When filenames are used as command-line arguments, it is recommended to use a zero-byte terminator for the filenames instead of a space terminator. Some of the filenames can contain a space character, and it will be misinterpreted as a terminator, and a single filename may be broken into two file names (for example, New file.txt can be interpreted as two filenames New and file.txt). This problem can be avoided by using a zero-byte suffix. We use xargs so as to accept a stdin text from commands such as grep and find. Such commands can output text to stdout with a zero-byte suffix. In order to specify that the input terminator for filenames is zero byte (\0), we should use -0 with xargs. Create some test files as follows: $ echo "test" > file1 $ echo "cool" > file2 $ echo "test" > file3 In the following command sequence, grep outputs filenames with a zero-byte terminator (\0), because of the -Z option with grep. xargs -0 reads the input and separates filenames with a zero-byte terminator: $ grep "test" file* -lZ | xargs -0 rm Usually, -Z is used along with -l. Silent output for grep Sometimes, instead of actually looking at the matched strings, we are only interested in whether there was a match or not. For this, we can use the quiet option (-q), where the grep command does not write any output to the standard output. Instead, it runs the command and returns an exit status based on success or failure. We know that a command returns 0 on success, and non-zero on failure. Let's go through a script that makes use of grep in a quiet mode, for testing whether a match text appears in a file or not. #!/bin/bash #Filename: silent_grep.sh #Desc: Testing whether a file contain a text or not if [ $# -ne 2 ]; then echo "Usage: $0 match_text filename" exit 1 fi match_text=$1 filename=$2 grep -q "$match_text" $filename if [ $? -eq 0 ]; then echo "The text exists in the file" else echo "Text does not exist in the file" fi The silent_grep.sh script can be run as follows, by providing a match word (Student) and a file name (student_data.txt) as the command argument: $ ./silent_grep.sh Student student_data.txt The text exists in the file Printing lines before and after text matches Context-based printing is one of the nice features of grep. Suppose a matching line for a given match text is found, grep usually prints only the matching lines. But, we may need "n" lines after the matching line, or "n" lines before the matching line, or both. This can be performed by using context-line control in grep. Let's see how to do it. In order to print three lines after a match, use the -A option: $ seq 10 | grep 5 -A 3 5 6 7 8 In order to print three lines before the match, use the -B option: $ seq 10 | grep 5 -B 3 2 3 4 5 Print three lines after and before the match, and use the -C option as follows: $ seq 10 | grep 5 -C 3 2 3 4 5 6 7 8 If there are multiple matches, then each section is delimited by a line "--": $ echo -e "a\nb\nc\na\nb\nc" | grep a -A 1 a b -- a b Cutting a file column-wise with cut We may need to cut the text by a column rather than a row. Let's assume that we have a text file containing student reports with columns, such as Roll, Name, Mark, and Percentage. We need to extract only the name of the students to another file or any nth column in the file, or extract two or more columns. This recipe will illustrate how to perform this task. How to do it... cut is a small utility that often comes to our help for cutting in column fashion. It can also specify the delimiter that separates each column. In cut terminology, each column is known as a field . To extract particular fields or columns, use the following syntax: cut -f FIELD_LIST filename FIELD_LIST is a list of columns that are to be displayed. The list consists of column numbers delimited by commas. For example: $ cut -f 2,3 filename Here, the second and the third columns are displayed. cut can also read input text from stdin. Tab is the default delimiter for fields or columns. If lines without delimiters are found, they are also printed. To avoid printing lines that do not have delimiter characters, attach the -s option along with cut. An example of using the cut command for columns is as follows: $ cat student_data.txt No Name Mark Percent 1 Sarath 45 90 2 Alex 49 98 3 Anu 45 90 $ cut -f1 student_data.txt No 1 2 3 Extract multiple fields as follows: $ cut -f2,4 student_data.txt Name Percent Sarath 90 Alex 98 Anu 90 To print multiple columns, provide a list of column numbers separated by commas as arguments to -f. We can also complement the extracted fields by using the --complement option. Suppose you have many fields and you want to print all the columns except the third column, then use the following command: $ cut -f3 --complement student_data.txt No Name Percent 1 Sarath 90 2 Alex 98 3 Anu 90 To specify the delimiter character for the fields, use the -d option as follows: $ cat delimited_data.txt No;Name;Mark;Percent 1;Sarath;45;90 2;Alex;49;98 3;Anu;45;90 $ cut -f2 -d";" delimited_data.txt Name Sarath Alex Anu There's more The cut command has more options to specify the character sequences to be displayed as columns. Let's go through the additional options available with cut. Specifying the range of characters or bytes as fields Suppose that we don't rely on delimiters, but we need to extract fields in such a way that we need to define a range of characters (counting from 0 as the start of line) as a field. Such extractions are possible with cut. Let's see what notations are possible: N- from the Nth byte, character, or field, to the end of line N-M from the Nth to Mth (included) byte, character, or field -M from first to Mth (included) byte, character, or field We use the preceding notations to specify fields as a range of bytes or characters with the following options: -b for bytes -c for characters -f for defining fields For example: $ cat range_fields.txt abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxyz abcdefghijklmnopqrstuvwxy You can print the first to fifth characters as follows: $ cut -c1-5 range_fields.txt abcde abcde abcde abcde The first two characters can be printed as follows: $ cut range_fields.txt -c -2 ab ab ab ab Replace -c with -b to count in bytes. We can specify the output delimiter while using with -c, -f, and -b, as follows: --output-delimiter "delimiter string" When multiple fields are extracted with -b or -c, the --output-delimiter is a must. Otherwise, you cannot distinguish between fields if it is not provided. For example: $ cut range_fields.txt -c1-3,6-9 --output-delimiter "," abc,fghi abc,fghi abc,fghi abc,fghi
Read more
  • 0
  • 0
  • 2567

article-image-seam-data-validation
Packt
09 Oct 2009
8 min read
Save for later

Seam Data Validation

Packt
09 Oct 2009
8 min read
Data validation In order to perform consistent data validation, we would ideally want to perform all data validation within our data model. We want to perform data validation in our data model so that we can then keep all of the validation code in one place, which should then make it easier to keep it up-to-date if we ever change our minds about allowable data values. Seam makes extensive use of the Hibernate validation tools to perform validation of our domain model. The Hibernate validation tools grew from the Hibernate project (http://www.hibernate.org) to allow the validation of entities before they are persisted to the database. To use the Hibernate validation tools in an application, we need to add hibernate-validator.jar into the application's class path, after which we can use annotations to define the validation that we want to use for our data model. Let's look at a few validations that we can add to our sample Seam Calculator application. In order to implement data validation with Seam, we need to apply annotations either to the member variables in a class or to the getter of the member variables. It's good practice to always apply these annotations to the same place in a class. Hence, throughout this article, we will always apply our annotation to the getter methods within classes. In our sample application, we are allowing numeric values to be entered via edit boxes on a JSF form. To perform data validation against these inputs, there are a few annotations that can help us. Annotation Description @Min The @Min annotation allows a minimum value for a numeric variable to be specified. An error message to be displayed if the variable's value is less than the specified minimum can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be greater than or equal to ...). @Min(value=0, message="...") @Max The @Max annotation allows a maximum value for a numeric variable to be specified. An error message to be displayed if the variable's value is greater than the specified maximum can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be less than or equal to ...). @Max(Value=100, message="...") @Range The @Range annotation allows a numeric range-that is, both minimum and maximum values-to be specified for a variable. An error message to be displayed if the variable's value is outside the specified range can also be specified. The message parameter is optional. If it is not specified, then a sensible error message will be generated (similar to must be between ... and ...). @Range(min=0, max=10, message="...") At this point, you may be wondering why we need to have an @Range validator, when by combining the @Min and @Max validators, we can get a similar effect. If you want a different error message to be displayed when a variable is set above its maximum value as compared to the error message that is displayed when it is set below its minimum value, then the @Min and @Max annotations should be used. If you are happy with the same error message being displayed when a variable is set outside its minimum or maximum values, then the @Range validator should be used. Effectively, the @Min and @Max validators are providing a finer level of error message provision than the @Range validator. The following code sample shows how these annotations can be applied to a sample application, to add basic data validation to our user inputs. package com.davidsalter.seamcalculator; import java.io.Serializable; import org.jboss.seam.annotations.Name; import org.jboss.seam.faces.FacesMessages; import org.hibernate.validator.Max;import org.hibernate.validator.Min;import org.hibernate.validator.Range; @Name("calculator") public class Calculator implements Serializable { private double value1; private double value2; private double answer; @Min(value=0) @Max(value=100) public double getValue1() { return value1; } public void setValue1(double value1) { this.value1 = value1; } @Range(min=0, max=100) public double getValue2() { return value2; } public void setValue2(double value2) { this.value2 = value2; } public double getAnswer() { return answer; } ... } Displaying errors to the user In the previous section, we saw how to add data validation to our source code to stop invalid data from being entered into our domain model. Now that we have reached a level of data validation, we need to provide feedback to the user to inform them of any invalid data that they have entered. JSF applications have the concept of messages that can be displayed associated with different components. For example, if we have a form asking for a date of birth to be entered, we could display a message next to the entry edit box if an invalid date were entered. JSF maintains a collection of these error messages, and the simplest way of providing feedback to the user is to display a list of all of the error messages that were generated as a part of the previous operation. In order to obtain error messages within the JSF page, we need to tell JSF which components we want to be validated against the domain model. This is achieved by using the <s:validate/> or <s:validateAll/> tags. These are Seam-specific tags and are not a part of the standard JSF runtime. In order to use these tags, we need to add the following taglib reference to the top of the JSF page. <%@ taglib uri="http://jboss.com/products/seam/taglib" prefix="s" %> In order to use this tag library, we need to add a few additional JAR files into the WEB-INF/lib directory of our web application, namely: jboss-el.jar jboss-seam-ui.jar jsf-api.jar jsf-impl.jar This tag library allows us to validate all of the components (<s:validateAll/>) within a block of JSF code, or individual components (<s:validate/>) within a JSF page. To validate all components within a particular scope, wrap them all with the <s:validateAll/> tag as shown here: <h:form> <s:validateAll> <h:inputText value="..." /> <h:inputText value="..." /> </s:validateAll> </h:form> To validate individual components, embed the <s:validate/> tag within the component, as shown in the following code fragment. <h:form> <h:inputText value="..." > <s:validate/> </h:inputText> <h:inputText value="..." > <s:validate/> </h:inputText> </h:form> After specifying that we wish validation to occur against a specified set of controls, we can display error messages to the user. JSF maintains a collection of errors on a page, which can be displayed in its entirety to a user via the <h:messages/> tag. It can sometimes be useful to show a list of all of the errors on a page, but it isn't very useful to the user as it is impossible for them to say which error relates to which control on the form. Seam provides some additional support at this point to allow us to specify the formatting of a control to indicate error or warning messages to users. Seam provides three different JSF facets (<f:facet/>) to allow HTML to be specified both before and after the offending input, along with a CSS style for the HTML. Within these facets, the <s:message/> tag can be used to output the message itself. This tag could be applied either before or after the input box, as per requirements. Facet Description beforeInvalidField This facet allows HTML to be displayed before the input that is in error. This HTML could contain either text or images to notify the user that an error has occurred. <f:facet name="beforeInvalidField"> ... </f:facet> afterInvalidField This facet allows HTML to be displayed after the input that is in error. This HTML could contain either text or images to notify the user that an error has occurred. <f:facet name="afterInvalidField"> ... </f:facet> aroundInvalidField This facet allows the CSS style of the text surrounding the input that is in error to be specified. <f:facet name="aroundInvalidField"> ... </f:facet> In order to specify these facets for a particular field, the <s:decorate/>  tag must be specified outside the facet scope. <s:decorate> <f:facet name="aroundInvalidField"> <s:span styleClass="invalidInput"/> </f:facet> <f:facet name="beforeInvalidField"> <f:verbatim>**</f:verbatim> </f:facet> <f:facet name="afterInvalidField"> <s:message/> </f:facet> <h:inputText value="#{calculator.value1}" required="true" > <s:validate/> </h:inputText> </s:decorate> In the preceding code snippet, we can see that a CSS style called invalidInput is being applied to any error or warning information that is to be displayed regarding the <inputText/> field. An erroneous input field is being adorned with a double asterisk (**) preceding the edit box, and the error message specific to the inputText field after is displayed in the edit box.
Read more
  • 0
  • 0
  • 2566

article-image-gamified-websites-framework
Packt
07 Oct 2013
15 min read
Save for later

Gamified Websites: The Framework

Packt
07 Oct 2013
15 min read
(For more resources related to this topic, see here.) Business objectives Before we can go too far down the road on any journey, we first have to be clear about where we are trying to go. This is where business objectives come into the picture. Although games are about fun, and gamification is about generating positive emotion without losing sight of the business objectives, gamification is a serious business. Organizations spend millions of dollars every year on information technology. Consistent and steady investment in information technology is expected to bring a return on that investment in the way of improved business process flow. It's meant to help the organization run smoother and easier. Gamification is all about "improving" business processes. Organizations try to improve the process itself, wherever possible, whereas technology only facilitates the process. Therefore, gamification efforts will be scrutinized under similar microscope and success metrics that information technology efforts will. The fact that customers, employees, or stakeholders are having more fun with the organization's offering is not enough. It will have to meet a business objective. The place to start with defining business objectives is with the business process that the organization is looking to improve. In our case, the process we are planning to improve is e-learning. We are looking at the process of K-12 aged persons learning "thinking". How does that process look right now? Image source: http://www.moddb.com/groups/critical-thinkers-of-moddb/images/critical-thinking-skills-explained In a full-blown e-learning situation, we would be looking to gamify as much of this process as possible. For our purpose, we will focus on the areas of negotiation and cooperation. According to the Negotiate and Cooperate phase of the Critical Thinking Process, learners consider different perspectives and engage in discussions with others. This gives us a clear picture of what some of our objectives might be. They might be, among others: Increasing engagement in discussion with others Increasing the level of consideration of different perspectives Note that these objectives are measurable. We will be able to test whether the increases/improvements we are looking for are actually happening over time. With a set of measurable objectives, we can turn our attention to the next step, that is target behaviors, in our Gamification Design Framework. Target behaviors Now that we are clear about what we are trying to accomplish with our system, we will focus on the actions we are hoping to incentivize: our target behaviors. One of the big questions around gamification efforts is can it really cause behavioral change. Will employees, customers, and stakeholders simply go back to doing things the way they are used to once the game is over? Will they figure out a way to "cheat" the system? The only way to meet long-term organizational objectives in a systematic way is the application to not only cause change for the moment, but lasting change over time. Many gamification applications fail in long-term behavior change, and here's why. Psychologists have studied the behavior change life cycle at length. . The study revealed that people go through five distinct phases when changing a behavior. Each phase presents a different set of challenges. The five phases of the behavioral life cycle are as follows: Awareness: Before a person will take any action to change a behavior, he/she must first be aware of their current behavior and how it might need to change. Buy in: After a person becomes aware that they need to change, they must agree that they actually need to change and make the necessary commitment to do so. Learn: But what actually does a person need to do to change? It cannot be assumed that he/she knows how to change. They must learn the new behavior. Adopt: Now that he/she has learned the necessary skills, they have to actually implement them. They need to take the new action. Maintain: Finally, after adopting a new behavior, it can only become a lasting change with constant practice. Image source: http://www.accenture.com/us-en/blogs/technology-labs-blog/archive/2012/03/28/gamification-and-the-behavior-change-lifecycle.aspx) How can we use this understanding to establish our target behaviors? Keep in mind that our objectives are to increase interaction through discussion and increase consideration for other perspectives. According to our understanding of changing behavior around our objectives, we need our users to: Become aware of their discussion frequency with other users Become aware that other perspectives exist Commit to more discussions with other users Commit to considering other users' perspectives Learn how to have more discussions with other users Learn about other users' perspectives Have more discussions with other users Actually consider other users' perspectives Continue to have more discussions with other users on a consistent basis Continue to consider other users' perspectives over time This outlines the list of activities that needs to be performed for our systems to meet our objectives. Of course, some of our target behaviors will be clear. In other cases, it will require some creativity on our part to get users to take these actions. So what are some possible actions that we can have our users take to move them along the behavior change life cycle? Check their discussion thread count Review the Differing Point of View section Set a target discussion amount for a particular time period Set a target number of Differing Points of View to review Watch a video (or some instructional material) on how to use the discussion area Watch a video (or some instructional material) on the value of viewing other perspectives Participate in the discussion groups Read through other users' discussions posts Participate in the discussion groups over time Read through other users' perspectives over time Some of these target behaviors are relatively straightforward to implement. Others will require more thought. More importantly, we have now identified the target behaviors we want our users to take. This will guide the rest of our development efforts. Players Although the last few sections have been about the serious side of things, such as objectives and target behaviors, we still have gamification as the focal point. Hence, from this point on we will refer to our users as players. We must keep in mind that although we have defined the actions that we want our players to take, the strategies to motivate them to take that action vary from player to player. Gamification is definitely not a one-size-fits-all process. We will have to look at each of our target behaviors from the perspective of our players. We must take their motivations into consideration, unless our mechanics are pretty much trial and error. We will need an approach that's a little more structured. According to the Bartle's Player Motivations theory, players of any game system fall into one of the following four categories: Killers: These are people motivated to participate in a gaming scenario with the primary purpose of winning the game by "acting on" other players. This might include killing them, beating, and directly competing with other players in the game. Achievers: These, on the other hand, are motivated by taking clear actions against the system itself to win. They are less motivated by beating an opponent than by achieving things to win. Socializers: These have very different motivations for participating in a game. They are motivated more by interacting and engaging with other players. Explorers: Like socializers, explorers enjoy interaction and engagement, but less with other players than with the system itself. The following diagram outlines each player motivation type and what game mechanic might best keep them engaged. Image source: http://frankcaron.com/Flogger/?p=1732 As we define our activity loops, we need to make sure that we include each of the four types of players and their motivations. Activity loops Gamified systems, like other systems, are simply a series of actions. The player acts on the system and the system responds. We refer to how the user interacts with the system as activity loops. We will talk about two types of activity loops, engagement loops and progression loops, to describe our player interactions. Engagement loops describe how a player engages the system. They outline what a player does and how the system responds. Activity will be different for players depending on their motivations, so we must also take into consideration why the player is taking the action he is taking. A progression loop describes how the player engages the system as a whole. It outlines how he/she might progress through the game itself. Whereas engagement loops discuss what the player does on a detailed level, progression loops outline the movement of the player through the system. For example, when a person drives a car, he/she is interacting with the car almost constantly. This interaction is a set of engagement loops. All the while, the car is going somewhere. Where the car is going describes its progression loops. Activity loops tend to follow the Motivation, Action, Feedback pattern. The players are sufficiently motivated to take an action. When the players take the action and they get a feedback from the system, the feedback hopefully motivates the players enough to take another action. They take that action and get more feedback. In a perfect world, this cycle would continue indefinitely and the players would never stop playing our gamified system. Our goal is to get as close to this continuous activity loop as we possibly can. Progression loops We have spent the last few pages looking at the detailed interactions that a player will have with the system in our engagement loops. Now it's time to turn our attention to the other type of activity loop, the progression loop. Progression loops look at the system at a macro level. They describe the player's journey through the system. We usually think about levels, badges, and/or modes when we are thinking about progression loops We answer questions such as: where have you been, where are you now, and where are you going. This can all be summed up into codifying the player's mastery level. In our application, we will look at the journey from the vantage point of a novice, an expert, and a master. Upon joining the game, players will begin at novice level. At novice level we will focus on: Welcome On-boarding and getting the user acclimated to using the system Achievable goals In the Welcome stage, we will simply introduce the user to the game and encourage him/her to try it out. Upon on-boarding, we need to make the process as easy as possible and give back positive feedback as soon as possible. Once the user is on board, we will outline the easiest way to get involved and begin the journey. At the expert level, the player is engaging regularly in the game. However, other players would not consider this player a leader in the game. Our goal at this level is to present more difficult challenges. When the player reaches a challenge that is appearing too difficult, we can include surprise alternatives along the way to keep him/her motivated until they can break through the expert barrier to master level. The game and other players recognize masters. They should be prominently displayed within the game and might tend to want to help others at novice and expert levels. These options should become available at later stages in the game. Fun After we have done the work of identifying our objectives, defining target behaviors, scoping our players, and laying out the activities of our system, we can finally think about the area of the system where many novice game designers start: the fun. Other gamification practitioners will avoid, or at least disguise, the fun aspect of the gamification design process. It is important that we don't over or under emphasize the fun in the process. For example, chefs prepare an entire meal with spices, but they don't add all spices together. They use the spices in a balanced amount in their cooking to bring flavor to their dishes. Think of fun as an array of spices that we can apply to our activity loops. Marc Leblanc has categorized fun into eight distinct categories. We will attempt to sprinkle just enough of each, where appropriate, to accomplish the desired amount of fun. Keep in mind that what one player will experience as fun will not be the same for another. One size definitely does not fit all in this case. Sensation: A pleasurable experience Narrative: An unfolding story Challenge: An obstacle course Fantasy: Make believe Fellowship: A social framework Discovery: Exploring uncharted territory Expression: Player is given a platform Submission: Mindless activity So how can we sparingly introduce the above dimensions of fun in our system? Action to take Dimension of fun Check their discussion thread count Challenge Review a differing point of the View section Discovery Set a target discussion  amount for a particular time period Challenge Set a target number of "Differing Points of View" to review Challenge Watch a video (or some instructional material) on the how to use the discussion area Challenge Watch a video (or some instructional material) on the value of viewing other perspectives Challenge Participate in the discussion groups Fellowship Expression Read through other users' discussions posts Discovery Participate in the discussion groups over time Fellowship Expression Read through other users' perspectives over time Discovery Tools We are finally at the stage from where we can begin implementation. At this point, we can look at the various game elements (tools) to implement our gamified system. If we have followed the framework upto this point, the mechanics and elements should become apparent. We are not simply adding leader boards or a point system for the sake of it. We can tie all the tools we use back to our previous work. This will result in a Gamification Design Matrix for our application. But before we go there, let's stop and take a look at some tools we have at our disposal. There are a myriad of tools, mechanics, and strategies at our disposal. New ones are being designed everyday. Here are a few of the most common mechanics that we will encounter when designing our gamified system: Achievements: These are specific objectives that a player meets. Avatars: These are visual representations of a player's role, persona, or character in a game. Badges: These are visual elements used to recognize a particular accomplishment. They give players a sense of pride that they can show off to others. Boss fight: This is an exceptionally difficult challenge in a game scenario, usually at the end of a level to demonstrate enough skill level to move up to the next level. Leaderboards: These show rankings of players publicly. They recognize an accomplishment like a badge, but they are visible for all to see. We see this almost every day, in every way from sports team rankings to sales rep monthly results. Points: These are rather straightforward. Players accumulate points and take various actions in the system. Quests/Mission: These are specialized challenges in a game scenario having narrative and objective as characteristics. Reward: This is anything used to extrinsically motivate the user to take a particular action. Team: This is a group of players playing as a single unit. Virtual assets: These are elements in the game that have some value and can be acquired or used to acquire other assets, whether tangible or virtual. Now it's time to turn and take off our gamification design hat and put on our developer hat. Let's start by developing some initial mockups of what our final site might look like using the design we have outlined previously. Many people develop mockups using graphics tools such as Photoshop or Gimp. At this stage, we will be less detailed in our mockups and simply use pencil sketches or a mockup tool such as Balsamiq. Login screen This is a mock-up of the basic login screen in our application. Players are accustomed to a basic login and password scenario we provide here. Account creation screen First time players will have to create an account initially. This is the mock-up of our signup page. Main Player Screen This captures the main elements of our system when a player is fully engaged with the system. Main Player Post Response Screen We have outlined the key functionality of our gamified system via mock-ups. Mock-ups are a means of visually communicating to our team what we are building and why we are building it. Visual mock-ups also give us an opportunity to uncover issues in our design early in the process. Summary Most gamified applications will fail due to a poorly designed system. Hence, we have introduced a Gamification Design Framework to guide our development process. We know that our chances of developing a successful system increase tremendously if we: Define clear business objectives Establish target behaviors Understand our players Work through the activity loops Remember the fun Optimize the tools Resources for Article: Further resources on this subject: An Introduction to PHP-Nuke [Article] Installing phpMyAdmin [Article] Getting Started with jQuery [Article]
Read more
  • 0
  • 0
  • 2565

article-image-article-iclone-4-31-3d-using-personas-iprops-helpers
Packt
31 Oct 2011
7 min read
Save for later

iClone 4.31 3D: Using Personas, iProps, and Helpers

Packt
31 Oct 2011
7 min read
(For more resources on animation, see here.) Understanding AML The best way to describe AML is from the iClone Wiki, which this author originally set up for, and under the direction and guidance of the team at Reallusion: The DramaScript Markup Language (AML) is a general-purpose specification for creating performance interaction between characters and props. It is classified as an XML (Extensible Markup Language) because it allows its users to write individual DramaScripts for either characters or props in iClone4 to interact. Its primary purpose is to create script animations to allow characters and props to interact with each other smoothly. AML Script Editor can be used when modifying DramaScripts. At the time of writing, version 1.0 of AML Script Editor was having issues on Windows 7 systems with the latest version of Direct X. Where to find and store Motion Files for the Characters? C:Documents and SettingsAll UsersDocumentsReallusionTemplateiClone 4 TemplateiClone TemplateMotion What's the difference between Prop's Animation Clips and Character's Animation Clips? For Prop's Animation Clips, there are two ways to produce the motion clips. One is using the collect clip method in iClone and the other method is to use 3Ds Max and export it through our Plug-in converter. 3Ds Max can produce both the prop and the animation, but when you produce the motion clips for the props, the animation is embedded within the prop itself. For the creation of the character's motion, the character and the character's motion are always exported separately. The following table is also from iCloneWiki:   Character iProps Where is AML Stored? Persona AML is embedded within the iProp. Where to access the motion files. Animation > Motion files in iClone Template. in the iProp's right-click menu under Perform How to export the AML scripts? Export Persona from the right-click menu. Export DramaScript from the right-click menu. How to generate motion files? In the timeline or Motion Editor in iClone3 Pro or above 3DS Max 8.0 or above In the timeline or Motion Editor in iClone3 Pro or above 3DS Max 8.0 or above Exploring personas to animate a character A Persona is an editable AML file that is based on the XML specification. A Persona can hold many different motions such as waving, walking, and so forth. These actions are Perform actions that are available from the right-click Perform menu when a Persona has been loaded into a character. Default characters such as Dylan and Jana already have a Persona loaded into them which will differ from character to character. The motions the Persona invokes can also be used as regular motions and are accessed by the Animation tab, Motion button interface when a character is selected. Personas can be exported, saved, then imported into another character with the right-click menu under the Persona menu choice. Personas can be edited with an XML editor such as the free XML Notepad from Microsoft. XML Notepad was originally released in 2006 then updated in 2007. There may be other updated versions available. http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=7973 The following image shows the right-click menu with the Perform sub-menu highlighted. Notice the three actions available: Hey You, Listen Music, Puzzle, and there are additional commands under the Move sub-menu to Walk Forward or Run Forward.   Some Personas will have more commands available than others. It depends on what the Persona author had in mind. Remember that all of these motions are available in the motion library also. To demonstrate a different Persona we will use the Dylan character to load with a different Persona. Time for action – loading a Persona Since Personas can have different motions available, we will add a different Persona to the Dylan character to demonstrate this: Start a new blank project. Make sure the time scrubber is at the start of the Timeline. Load the Dylan character into the workspace. Right-click on Dylan and hold your mouse cursor over the Persona menu item until the sub-menu appears. With the Dylan character selected, click on the Actor tab. Select the Persona button. Double-click on the Benny Persona in the Content Manager on the left side menu to load the Benny Persona into Dylan. There will be no visible change when the Persona is loaded. The following image shows the choices available when the Benny Persona is loaded versus the few choices that were available with the Dylan Persona:   Select the Perform motion Angry. Select the Can't Help It choice when the previous action has stopped running. Select the Talk 01 choice when the Can't Help It motion stops running. Move the time scrubber to the beginning and playback the scene. The following is an image depicting the three motions strung together in the Perform timeline. Notice the linear designation. Remember our curves? We can change from linear to ease out or any of the available curve choices. In most cases, the curves are slight differences from the default linear curve:   What just happened? We loaded a character, explored its built in motion based on the characters default Persona file. We then loaded a different Persona to see the difference some Personas have. After loading the Benny Persona file we then proceeded to add three distinct motions with the simple right click menu system by adding a new perform action when the previous actions stopped playing. Have a go hero – experimenting with perform motions Experiment by loading the various Personas into different characters and see how they react. Use different curve settings and blending with the handles. This exercise is for you to become acquainted with the various Personas and their effect on characters. Female-based Personas will have female characteristics just as male-based Personas will have a male-oriented body language. Mixing these up can produce some unique results. Using AML templates In the Content Manager, you may have noticed a folder named AML Templates. These are helper props that contain AML scripting to help perform a task or function such as sitting down. The AML can be built into props but the helpers can work with regular props such as furniture, downloaded from the web or created in another 3D application. Implementing character interaction The following image shows the AML templates available from the Character_Interaction sub- folder located in the Props folder:   Time for action – placing and using character interaction dummies Once again we will use a new blank project for this action section: Create a new blank project. Load the Jana character into the workspace. Load the Dylan character into the workspace. Load the Hello_Dummy prop located in the Character_Interaction sub-folder of the AML Templates folder. Place the characters near each other, in facing the same general direction. Place the Hello_Dummy prop, as in the following image: Click on the Jana character, then right-click on the Hello prop and select the Operate menu then Hello from the sub-menu: Select the character you wish to interact with the prop, then use the Hello template perform action to have this character initiate the motion. What just happened? We used the Hello AML template to initiate a waving from the Jana character without having to key frame the event. The last character selected will be the character whose action is triggered by the AML templates.
Read more
  • 0
  • 0
  • 2565
article-image-microsoft-dynamics-nav-2009-development-tools
Packt
17 Sep 2010
7 min read
Save for later

Microsoft Dynamics NAV 2009 Development Tools

Packt
17 Sep 2010
7 min read
(For more resources on Microsoft Dynamics, see here.) NAV process flow Primary data such as sales orders, purchase orders, production orders, financial transactions, job transactions, and so on flow through the NAV system as follows: Initial Setup: Entry of essential Master data, reference data, control and setup data. Much of this preparation is done when the system (or a new application) is first set up for production use. Transaction Entry: Transactions are entered into a Journal table; data is preliminarily validated as it is entered, master and auxiliary data tables are referenced as appropriate. Entry can be manual keying, an automated transaction generation process, or an import function which brings transaction data in from another system. Validate: Provide for additional test validations of data prior to submitting the batch to Posting. Post: Post the Journal Batch, completing transaction data validation, adding entries as appropriate to one or more Ledgers, including perhaps a register and a document history. Utilize: Access the data via Forms and/or Reports of various types as appropriate. At this point, total flexibility exists. Whatever tools are available and are appropriate for users' needs should be used. There are some very good tools built into NAV for data manipulation, extraction, and presentation. In the past, these capabilities were considered good enough to be widely accepted as full Online Analytical Processing (OLAP) tools. Maintenance: Continue maintenance of Master data, reference data, and setup and control data, as appropriate. The loop returns to the beginning of this data flow sequence. The preceding image provides a simplified picture of the flow of application data through a NAV system. Many of the transactions types have additional reporting, more ledgers to update, or even auxiliary processing. However, this is the basic data flow followed whenever a Journal and Ledger table are involved. Data preparation Prepare all the Master data, reference data, and control and setup data. Much of this preparation is done initially, when an application is first set up for production usage. Naturally, this data must be maintained as new Master data becomes available, as various system operating parameters change, and so on. The standard approach for NAV data entry allows records to be entered that have just enough information to define the primary key fields, but not necessarily enough to support processing. This allows a great deal of flexibility in the timing and responsibility for entry and completeness of new data. This system design philosophy allows initial and incomplete data entry by one person, with validation and completion to be handled later by someone else. For example, a sales person might initialize a new customer entry with name, address, and phone number, saving the entry with just the data entered to which they have access. At this point, there is not enough information recorded to process orders for this new customer. At a later time, someone in the accounting department can set up posting groups, payment terms, and other control data that should not be controlled by the sales department. This additional data may make the new customer record ready for production use. As in many instances data comes into an organization on a piecemeal basis, the NAV approach allows the system to be updated on an equally piecemeal basis providing a flexible user friendliness many accounting-oriented systems lack. Transactions entry Transactions are entered into a Journal table; data is preliminarily validated as it is entered, master and auxiliary data tables are referenced as appropriate. NAV uses a relational database design approach that could be referred to as a "rational normalization". NAV resists being constrained by the concept of a normalized data structure, where any data element appears only once. The NAV data structure is normalized so long as that principle doesn't get in the way of processing speed. Where processing speed or ease of use for the user is improved by duplicating data across tables, NAV does so. At the point where Journal transactions are entered, a considerable amount of data validation takes place. Most, if not all, of the validation that can be done is done when a Journal entry is made. These validations are based on the combination of the individual transaction data plus the related Master records and associated reference tables (for example lookups, application or system setup parameters, and so on). Here also you find the philosophy of allowing entries, which are incomplete and not totally ready for processing, to be made. Testing and Posting the Journal batch Any additional validations that need to be done to ensure the integrity and completeness of the transaction data prior to being Posted are done either in pre-Post routines or directly in the course of the Posting processes. The actual Posting of the Journal batch occurs when the transaction data has been completely validated. Depending on the specific application function, when Journal transactions don't pass muster during this final validation stage, either the individual transaction is bypassed while acceptable transactions are Posted, or the entire Journal Batch is rejected until the identified problem is resolved. The Posting process adds entries as appropriate to one or more Ledgers and sometimes a document history. When a Journal Entry is Posted to a Ledger, it becomes a part of the permanent accounting record. Most data cannot be changed or deleted once it is resident in a Ledger except by a subsequent Posting process. During the Posting process, Register tables are also updated showing what transaction entries (by ID number) were posted when and in what batches. This adds to the transparency of the NAV application system for audits and analysis. In general, NAV follows the standard accounting practice of requiring Ledger corrections to be made by Posting reversing entries, rather than deletion of problem entries. The overall result is that NAV is a very auditable system, a key requirement for a variety of government, legal, and certification requirements for information systems. Accessing the data The data in a NAV system can be accessed via Pages and/or Reports of various types as appropriate, providing total flexibility. Whatever tools are available to the developer or the user, and are appropriate, should be used. There are some very good tools in NAV for data manipulation, extraction, and presentation. Among other things, these include the SIFT/Flowfield functionality, the pervasive filtering capability (including the ability to apply filters to subordinate data structures), and the Navigate function. NAV 2009 added the ability to create page parts for graphing,with a wide variety of predefined graph page parts included as part of the standard distribution. You can create your own chart parts as well, but that discussion is outside the scope of this book. There is an extended discussion and some tools available in the NAV Blog community. There are a number of methods by which data can be pushed or pulled from an NAV database for processing and presentation outside NAV. These allow use of more sophisticated graphical displays, or the use of other specialized data analysis tools such as Microsoft Excel or various Business Intelligence (BI) tools. Ongoing maintenance As with any database-oriented application software, ongoing maintenance of Master data, reference data, and setup and control data is required, as appropriate. Of course at this point, the cycle of processing returns to the first step of the data flow sequence, Data Preparation.
Read more
  • 0
  • 0
  • 2563

article-image-drupal-and-ubercart-2x-install-ready-made-drupal-theme
Packt
31 Mar 2010
5 min read
Save for later

Drupal and Ubercart 2.x: Install a Ready-made Drupal Theme

Packt
31 Mar 2010
5 min read
Install a ready-made Drupal theme We have to admit that Drupal was not famous for its plethora of available themes. Until recently, the Drupal community was focused on developing the backend, debugging the code, and creating new modules. The release of Drupal 6 made theming much easier and helped the theming community to grow. Now, there are not only thousands of Drupal themes, but also dozens of themes designed and customized especially for Ubercart. Basic principles when choosing a theme Choosing a theme for your online shop is not an easy task. Moreover, it can be even harder considering that you want to promote specific items from your catalog, you need to change first page items often, and you need to rapidly communicate offers and loyalty policies and other business-related stuff. Ubercart-specific themes mostly target the following special areas: Product catalog Shopping cart Product-specific views You should keep these layout regions in mind, while going through the following section on theme selection. Before you search for any kind of theme layout, provide your neurons with enough input to inspire you and help you decide. Perform a quick Google search for online shops in your target market to get some inspiration and track down sites that make you, as a customer, feel comfortable during product searching and navigation. If you decide to search for professional help, a list of existing sites will help you to communicate your preferences much more directly. What better place to search for inspiration and successful practices than Ubercart's live site repository! You will find good practices and see how mostly people like you (without any development background) have solved all the problems that might occur during your search for themes.http://www.ubercart.org/site Next we describe the main user interface components that you should keep in mind when deciding for your online shop: Number of columns: The number of columns depends on the block information you want to provide to your end customers. If you need widgets that display on every page, information about who bought what, and product or kit suggestions, go with three columns. You will find a plethora of two-column Drupal themes and many three-column Drupal themes, while some of them can alternate between two and three columns. Color scheme: From a design perspective, you should choose a color scheme that matches your company logo and business profile. For instance, if your store sells wooden toys, go with something more comic such as rounded corners, but if you are a consulting firm, you should go with something more professional. Many themes let you choose color schemes dynamically; however, always keep in mind that color is a rather easy modification from the CSS. You can get great color combination ideas from COLOURlovers online service (http://www.colourlovers.com/) that match your logo and business colors. Be careful though. If you choose a complex theme with rounded corners, lots of images, and multiple backgrounds, it may be difficult to modify it. Drupal version: Make sure the Drupal theme you choose is compatible with the version of Drupal you are running. Before using a Drupal theme, look up notes on the theme to see if there are any known bugs or problems with it. If you are not a programmer, you do not want a Drupal theme that has open issues. Extra features: Many Drupal themes expose a large set of configuration options to the end users. Various functionality such as post author's visibility or color scheme selection are welcome for managing the initial setup. Moreover, you can change appearance in non-invasive ways for your online marque. Regions available: We have discussed column layouts, but for the Drupal template engine to show its full capabilities and customization, you definitely need multiple regions. The more regions, the more choices you have for where to put blocks of content. Therefore, you can have space for customizing new affiliate ads for instance, or provide information about some special deals, or even configure your main online shop page, as we will see in the next section. Further customization and updates: When you choose your theme, don't just keep the functionality of version 1.0 in mind, but consider all of the future business plans for approaching your target market and raising sales figures. Make a three-year plan and try to visualize any future actions that should be taken into account from day one. Although you can change themes easily, you are better off choosing a more flexible theme ahead of time than having to change the theme as your website grows. Always bear in mind that the famous razor of Occam also applies to online shop theme design. Keep it simple and professional by choosing simple layouts, which allow ease of use for the end user and ease further customize designs and themes (changing colors, adding a custom image header, and so on). Before you start, clearly define your timeline, risks, total theme budget, and skills. Theming is usually 25-40% of the budget of an entire online shop project. Drupal's theming engine closely integrates with actual functionality and many features are encapsulated inside the theme itself. There are a number of different ways in which you can get yourself the best theme for your online store. We will go through all these approaches with useful comments on what options best suits your needs.
Read more
  • 0
  • 0
  • 2562

article-image-database-interaction-codeigniter-17
Packt
26 Apr 2010
4 min read
Save for later

Database Interaction with Codeigniter 1.7

Packt
26 Apr 2010
4 min read
(Read more interesting articles on CodeIgniter 1.7 Professional Development here.) Loading the library Loading the Database library is slightly different from loading other libraries. This is because it is large and resides in a different folder, unlike the other libraries. $this->load->database(); Performing simple queries Let's dive straight in by starting with the simple stuff. CodeIgniter gives us a function that we can pass a SQL Query to, and the query will be run on the database. Here's how it works: $this->db->query('PUT YOUR SQL HERE'); This function is incredibly simple to use; you simply use this function in place of any native PHP functions you would use to run queries. This function will return TRUE or FALSE for write queries, and will return a dataset for read queries. There is another function that you can use for very simple queries; this will only return TRUE or FALSE. It won't let you cache your query or run the query timer. In most cases you won't want to use this function. $this->db->simple_query('PUT YOUR SQL HERE'); The SQL code that you pass to these functions are database-dependent. Only Active Record queries are independent of any type of Database SQL. Returning values You can assign the function $this->db->query() to a variable. You can then run a number of helper functions on the variable in order to return the data in different formats. Take the following example: $query = $this->db->query('SELECT * FROM 'users''); Return a result object In this case, returning the result will return an array of objects, or an empty array if the query failed. You would usually use this function in a foreach loop. foreach($query->result() as $row){ echo $row->username; echo $row->email;} If your query does not return a result, the CodeIgniter User Guide encourages you to check for a failure before using this function. if($query->num_rows > 0){ foreach($query->result() as $row) { echo $row->username; echo $row->email; }} Returning a result array You are also able to return the result dataset as an array. Typically, you would use this function inside a foreach loop as well. foreach($query->result_array() as $row){ echo $row['username']; echo $row['email'];} Returning a row object If your query is only expected to return a single result, you should return the row by using the following function. The row is returned as an object. if($query->num_rows() > 0){$row = $query->row();echo $row->username;echo $row->email;} You can return a specific row by passing the row number as a digit in the first parameter. $query->row(2); Returning a row array You can return a row as an array, if you prefer. The function is used in the same way as the previous example. if($query->num_rows() > 0){ $row = $query->row_array(); echo $row['username']; echo $row['email'];} You can return a numbered row by passing the digit to the first parameter, also. $query->row_array(2); Result helper functions Besides the helper function that helps to return the dataset in different ways, there are some other more generalized helper functions. Number of rows returned Used in the same way as the other helper functions, this will return the total number of rows returned from a query. Take the following example: echo $query->num_rows(); Number of fields returned Just like the previous function, this will return the number of fields returned by your query. echo $query->num_fields(); Free result This function will remove the resource ID associated with your query, and free the associated memory. PHP will usually do this by default, although when using many queries you may wish to use this to free up memory space. $query->free_result();
Read more
  • 0
  • 0
  • 2561
article-image-cms-made-simple-16-learning-smarty-basics
Packt
04 Mar 2010
8 min read
Save for later

CMS Made Simple 1.6: Learning Smarty Basics

Packt
04 Mar 2010
8 min read
Working with Smarty Variables Smarty variables are much simpler than complex Smarty plugins. They are placeholders that contain plain information about the actual page ID, page alias, or position of the page in the hierarchy. Some Smarty variables that you are not aware of, are already defined in your template. You do not need to know or remember all of them if you know how you can figure out their names and values. Time for action – getting Smarty variables We are going to get the number of the page in the page hierarchy to integrate this information into the design of the page title. How do we figure out the name of the Smarty variable that contains this information? We can get it from the template as follows: In the admin console, click on Layout | Templates. Open the Business World template for edit and add the plugin {get_template_vars} just before the last tag, as shown in the following code snippet: <!DOCTYPE html> <html> <head> <title>{title} - {sitename}</title> {stylesheet} {metadata} <meta name="description" content="" /> </head> <body> ........... {get_template_vars} </div> </body> </html> Click on Apply and then click on the magnifying glass icon on the top-right corner of the admin console to see the result. It should now look like the following screenshot: What just happened? With the Smarty {get_template_vars} plugin, you displayed all Smarty variables available in your template. In the list of variables on each line, one variable is displayed with its name and its value separated by an equals sign. These values change from page to page. For example, the variable with the name friendly_position contains the position of the page in the page hierarchy. If you navigate to other pages, you will see that the value of this variable is different on every page. How do you add a variable in your template? Smarty variables are enclosed in curly brackets as well, but unlike the Smarty plugins, they have a dollar sign at the beginning. To use the variable friendly_position, you just need to add the following Smarty tag to your template: {$friendly_position} You can delete the {get_template_vars} plugin now. It is helpful for you to see which Smarty variables exist and what values are stored there. You can add this plugin again, when you need to look for another variable. Let us use the information we have learned about Smarty plugins and Smarty variables by combining them both to create a title of the page. Open the template Business World (Layout | Templates)for editing and change the title of the page between the body tags and before the tag {content} shown as follows: <h1><span>{$friendly_position}</span> {title}</h1> Then open Business World Style Sheet for editing (Layout | Stylesheets), and add a CSS style to format the title of the page: h1 span { color: #ffffff; background: #cccccc; padding: 0 5px;} The result of the above formating should look as shown in the following screenshot: You  can use any Smarty variable from the template, except for variables with the value Array(). We will look at these special variables in the following section. Controlling output with the IF function You can create numerous templates for your website and assign different templates to different pages. This is useful if you use layouts with a different number of columns. However, sometimes there is only a tiny difference between the templates, and it is not efficient to create a new template each time you need only slight changes. For example, imagine you would like to display the last editor of the page, as we did with the {last_modified_by}tag. It is a useful piece of information on most pages but we would like to hide it on the contact page. You do not need to create a new template where this tag is not added. For such slight changes, it is better to know how to control the output in the same template with an IF structure. Time for action – displaying tags in dependence of the page We  are going to hide the {last_modified_by} tag on the page Contact Us. However, it has to be still displayed on all other pages. Open the template Business World for editing (Layout | Templates). Add the Smarty IF code around the {last_modified_by…} tag, as shown in the following code snippet: <!DOCTYPE html> <html> <head> <title>{title} - {sitename}</title> {stylesheet} {metadata} <meta name="description" content="" /> </head> <body> <div id="container"> <div id="header"> businessWorld </div> <div id="top-navi"> {menu number_of_levels="1" template="minimal_menu.tpl"} </div> <div id="content"> <h1>{title}</h1> {content} {if $page_alias neq "contact-us"} <p>Last modified by {last_modified_by format= "fullname"}</p> {/if} </div> <div id="sidebar"> {menu start_level="2" template="minimal_menu.tpl"} </div> <div id="footer"> 2009 businessWorld </div> </div> </body> </html> Click on Apply and then click on the magnifying glass icon in the top-right corner of the admin console to see the result. What just happened? The IF code that you have added around the paragraph containing the last modification causes CMS to check the page alias of the displayed page. If the page alias is equal to "contact-us", then everything between the IF structure is not shown, otherwise the information about the last modification is displayed. You have seen from the previous section that CMS knows what page of our website is currently being displayed. This information is stored in the Smarty variable {$page_alias}. With the built-in IF function, you can compare the page alias of the actual page with the page alias of the page Contact Us. If the value of the variable {$page_alias} is NOT equal to contact-us, then everything between the IF tags is displayed. If the page alias is equal to contact-us, then nothing is displayed. In this way, you can control the output of the template depending on the page alias.   The abbreviation neq (meaning not equal) between the variable {$page_alias} and the value contact-us is called a Qualifier. Qualifiers are used to build a logical condition in the IF code. The result of the logical condition can be true or false. If the result of the IF condition is true (and it is true if the page alias IS NOT EQUAL to contact-us), then everything placed in between the IF tags is displayed. If the result of the IF condition is false (and it is only false if the page alias IS EQUAL to contact-us), then everything between the IF tags is suppressed. There are more qualifiers that can be used to build logical conditions in Smarty. Some of them are listed in the following table: The IF structure is a useful tool for handling slight changes in one template depending on the page name or the position in the hierarchy. In the preceding example, you saw that you can use every variable from the template to build a logical condition. Creating navigation template with Smarty loop You can also change the HTML markup of the navigation. Before you can learn this principle, you have to understand some Smarty basics. When we added the top navigation to the website, we used a standard template for the navigation. It displays the navigation as an unordered HTML list. Imagine that you need a kind of footer navigation where all the links from the top navigation are shown. You do not need an unordered HTML list in this case. You just would like to show all links in one line separated by a pipe (|) shown as follows: Our Company | Announcements | History | Team | Photo gallery …… This means that you need a completely different HTML markup for this kind of navigation. The great advantage of CMS Made Simple is the ability to display a template in template. While you can use the main template to define the whole layout for the page, the  HTML markup of the navigation is saved in its own template. This navigation template is just a piece of the HTML code that is added to the main template at the place where the tag {menu} is placed.
Read more
  • 0
  • 0
  • 2561

article-image-mastering-blender-25-basics
Packt
17 Jun 2011
13 min read
Save for later

Mastering the Blender 2.5 Basics

Packt
17 Jun 2011
13 min read
Blender 2.5 Character Animation Cookbook 50 great recipes for giving soul to your characters by building high-quality rigs Adjusting and tracking the timing Timing, by itself, is a subject that goes well beyond the scope of a simple recipe. It is, in fact, the main subject of a number of animation-related books. Strictly speaking, Timing in animation is how long it takes (in frames or seconds) between two Extreme poses. You can have your character in great poses, but if the timing between them is not right, your shot may be ruined. Maybe it is a difficult thing to master because there are no definite rules for it: everyone is born with a particular sense of timing. Despite that, it's enormously important to look at video and real life references to understand the timing for different actions. Imagine a tennis ball falling to the ground and bouncing. Think of the time between its first and second contact with the ground. Now replace it with a bowling ball and think of the time required for this bounce. You know, from your life experience, that the tennis ball bounces slower than the bowling ball. The timing between these two balls is different. The timing here (along with spacing, subject of the next recipe) is the main factor that makes us perceive the different nature and weight of each ball. The "rules" of timing can also be broken for comedic effect: something that purposely moves faster or slower than usual may get a laugh from the audience. We're going to see how different timings can change how we perceive a shot with the same poses. How to do it... Open the file 007-Timing.blend (Go to Support to get the code). It has our character Otto with three poses, making him look from one side to the other: (Move the mouse over the image to enlarge it.) Press Alt + A to play the animation. You may think the timing is acceptable for this head turn, but this method of checking the timing is not ideal. When you tell Blender to play the animation through Alt + A, you're relying in your computer's power to process all the information of your scene in real time. You'd probably end up seeing something slower than what you'll actually get after rendering the frames. When playing the animation inside the 3D view, you can see the actual playback frame rate on the top left corner of the window. If it's slower than the scene frame rate (in this case, 24 fps), it means that the rendered animation will be faster than what you're seeing. When adjusting the timing, we must be sure of the exact results of every keyframe set. Even a one-frame change can make a huge impact on the scene, but rendering a complex scene just to test the timing is out of the question, because it just takes too long to see the results. We need a quick way to check the timing precisely. Fortunately, Blender allows us to make a quick "render" of our 3D view, with only the OpenGL information. This is also called "playblast", and is exactly what we need. Take a look at the header of our 3D view and find the button with a clapperboard icon, as seen in the next screenshot: OpenGL stands for Open Graphics Library, and is a free cross-platform specification and API for writing 2D and 3D computer graphics. Not only are the objects inside Blender's 3D view made using this library, but also the user interface with all its buttons, icons, and text are drawn on the screen with OpenGL. From OpenGL version 2.0 it's possible to use GLSL, a high level shading language heavily used to create games and supported by Blender to enhance the way objects are displayed on the screen in real time. From Blender 2.5, GLSL is the default real time rendering method when the user selects the Textured viewport shading mode, but that option has to be supported by your graphics card. Click on that clapperboard button, and the active 3D view will be used for a quick OpenGL render of your scene. This preview rendering shares the Render panel settings in the Properties window, so the picture size, frame rate, output folder, file format, duration, and stamp will be the same. If you can't see the button in your 3D View header (it is available only in the header) it may be an issue of lack of space; you can click with the middle button (or the scroll wheel) of your mouse over the header and drag it to the sides to find it. After the OpenGL rendering is complete, press Esc to go back to your scene and press Ctrl + F11 to preview the animation with the correct frame rate to check the timing. Starting with the Blender 2.5 series, there's no built-in player in the program, so you have to specify one in the User Preferences window (Ctrl + Alt + U), on the File tab. This player can even be a previous version of Blender in the 2.4 series or any player you wish, such as DJV or Mplayer. With any of these options you must tell Blender the file path where the player is installed. Now that you can watch the animation with the correct frame rate, you'll notice that the head turns quite fast, since it only takes five frames to complete. This fast timing makes our action seem to happen after the character listens to an abrupt and loud noise coming from his left, so he has to turn his head quickly and look to see what happened. Let's suppose our character is watching a tennis match in Wimbledon, and his seat is in line with the net, at the middle of the court (yep, lucky guy). Watching the ball from the serve until it reaches the other side of the court should take longer than what we have just set up, so let's adjust our keyframes now. In the DopeSheet window, leave the first keyframe at frame 1. Select the last column of keyframes by holding Alt and right-clicking on any keyframe set at frame 5. Move (G) the column to frame 15 (hold Ctrl for snapping to the frames), so our action takes three times longer than the original. Another way of selecting a column of keyframes is through the DopeSheet Summary option on the window header. It creates an extra line above all channels. If you select the diamond on this line, all keyframes on that column will be selected. You can even collapse all channels and use only the DopeSheet Summary to move the keys along the timeline to make timing adjustments easily. Now, the Breakdown, or intermediate position between two Extreme poses. It doesn't have to be at the exact middle of our action. Actually, it's good to avoid symmetry not only in our models and poses, but in our motions too. Move (G) the Breakdown to frame 6, and you'll have something similar to the next screenshot: Now you can make another OpenGL render to preview the action with the new timing. You can choose to disable the layer where the armature is located, the second, by holding Shift and clicking over it, so you don't have the bones on the preview. Of course this is far from a finished shot: it's a good idea to make the character blink during the head turn, add some moving holds, animate the eyeballs, add some facial expressions, and so on. This rough example is only to show how drastically the timing can change the feel of an action. If you set the timing between the positions even higher, our character may seem like he's looking at something slower (someone on a bike, maybe?) moving in front of him. How it works... Along with good posing, the timing is crucial to make our actions vivid, believable, and with a sense of weight. The timing also is very important to help your audience understand what is happening in the scene, so it must be carefully adjusted. To have a precise view of how the timing is working in an action within Blender, it's best to use the OpenGL preview mode, since the usual Alt + A shortcut to preview the animation inside the 3D View can be misleading. There's more... Depending on the complexity of your scene, you can achieve the correct frame rate within the 3D view with Alt + A. You can disable the visibility of irrelevant objects or some modifiers to help speed up this real time processing, like lowering (or disabling) the Subdivision Surface modifier and hiding the armature and background layers. Spacing: favoring and easing poses The previous recipe shows us how to adjust the timing of our character's actions, which is something extremely important to make our audience not only understand what is happening on the screen, but also know the weight and forces involved in the motion. Since timing is closely related to spacing, there is often confusion between the two concepts. Timing in animation is the number of frames between two Extreme poses. Spacing is how the animated subject moves and shows variations of speed along these frames. Actions with the same timing and different spacing are perceived differently by the audience, and these principles combined are responsible for the feeling of weight of our actions. We're going to see how the spacing works and how we can create eases and favoring poses to enhance movements. How to do it... Open the file 007-Spacing.blend. It has our character Otto turning his head from right to left, just like in the timing recipe. We don't have a Breakdown position defined yet, and this action has a timing set to 15 frames. First, let's understand the most elementary type of spacing: linear, or even spacing. This is when the calculated intermediate positions between two keyframes have the same distance among them, without any kind of acceleration. This isn't something we're used to seeing in nature, thus it's not the default interpolation mode in Blender. To use it, select the desired keyframes in a DopeSheet or a Graph Editor window, press Shift + T, and choose the Linear interpolation mode. The curves between the keyframes will turn into straight lines, as you can see in the next screenshot showing the channels for the Head bone. If you preview the animation with Alt + A, you'll see that the movement is very mechanical and unappealing, something we don't see in nature. That's why this interpolation mode isn't the default one. Movements in nature all have some variation in speed, going from a resting state, accelerating to a peak velocity, then slowing down until another resting state. These variations of speed are called eases, and are represented with curved lines on the Graph Editor. When there is an increase in speed we have an ease out. When the movement slows down to a resting state, we have an ease in. This variation in speed is the default interpolation method in Blender, and you can enable it by selecting the desired keyframes in a DopeSheet or Graph Editor window, press Shift + T and select the Bezier interpolation mode. The next screenshot shows the same keyframes with easing: When we adjust the curve handles on the Graph Editor, we're actually defining the eases of that movement. When you insert keyframes in Blender, it automatically creates both eases: out and in (with same speeds). Since not all movements have the same variation of speed at their beginning and end, it's a good idea to change the handles on the Graph Editor. This difference of speed between the start and end keyframes is called favoring. When the Spacing between two poses have different eases, we say the movement "favors" one of the poses, notably the one which has the bigger ease. In the next screenshot, the curves for the Head bone were adjusted so the movement favors the second pose. Note that there is a softer curve near the second pose, while the first has sharper lines near it. This will make the head leave the first pose very quick and slowly settle into the second one. In order to create sharp angles with the handles in the Graph Editor window, you need to select the desired curve channels, press V and choose the Free handle type. Open the video file 007-Spacing.mov in a video player, which enables navigating through the frames (such as DJV), to watch the three actions at the same time. Although the timing of the action is unchanged, you can clearly notice how the interpolation changes the motion. In the next screenshot, you can see that at frame 8, the Favoring version has the face closer to the second pose: Now that you understand what spacing is, know the difference between the interpolation types, and can use eases to favor poses, let's add a Breakdown position. This action is pretty boring, since the head turn happens without any arcs. It's a good idea to tilt the head down a little during the turn, making an imaginary arc with the eyes. Especially during quick head turns, it's a good idea to make your character blink during the turn. Unless your character is following something with the eyes—such as in a tennis court in our example—a quick blink is useful to make a "scene cut" in our minds from one subject to the other. On the DopeSheet window, in the Action Editor, select the Favoring action. Go to frame 6, where the character looks to the camera. Select and rotate (R) the Head and Neck bones to front on their local X axis, as seen in the next screenshot, and insert a keyframe (I) for its rotation: Since Blender automatically creates symmetrical eases on each new keyframe, it's time to adjust our spacing for the Head and Neck bones on the Graph Editor window. If you play the animation with Alt + A, you'll notice that the motion goes very weird because of that automatic ease. The F-Curves on the X axis of each bone for this motion are not soft. Ideally, since this is a Breakdown position, the curves between it and its surrounding Extreme poses should be smooth, regardless of the favoring. Select the curve handles on frames 1 and 6, and move (G) them in order to soften the curve peak in that Breakdown position. The next screenshot shows the curves before and after editing. Notice how the peak curves at the Breakdown in the middle get smoother after editing: Now the action looks more natural, with a nice Breakdown and favoring created using the F-Curves. The file 007-Spacing-complete.blend has this finished example for your reference, in which you can play the animation with Alt + A to see the results. How it works... By understanding the principle of Spacing, you can create eases and favoring in order to create snappy and interesting motions. Just like visible shapes, the pace of motion in nature is often asymmetrical. To make your motions not only more interesting but also more believable and with accents to reinforce the purpose behind the movements, you should master Spacing. Be sure to check out the interpolation curves in your animations: interesting movements normally have different eases between two Extreme positions.
Read more
  • 0
  • 0
  • 2556
Modal Close icon
Modal Close icon