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-getting-started-mudbox-2013
Packt
18 Sep 2012
12 min read
Save for later

Getting Started with Mudbox 2013

Packt
18 Sep 2012
12 min read
(For more resources on Web Graphics and Videos, see here.) Introduction This article will help you get your preferences set up so that you can work in a way that is most intuitive and efficient for you. Whether you are a veteran or a newbie, it is always a good idea to establish a good workflow. It will speed up your production time, allowing you to get ideas out of your head before you forget them. This will also greatly aid you in meeting deadlines and producing more iterations of your work. Installing Mudbox 2013 documentation In addition to the recipes in this book, you may find yourself wanting to look through the Mudbox 2013 documentation for additional help. By default, when you navigate to Help through Mudbox 2013's interface, you will be sent to an online help page. If you have a slow Internet connection or lack a connection altogether, you may want to install a local copy of the documentation. After downloading and installing the local copy, it is a good idea to have Mudbox 2013 point you to the right location when you navigate to Helpfrom the menus. This will eliminate the need to navigate through your files in order to find the documentation. The following recipe will guide you through this process. How to do it... First thing you will want to do is download the documentation from Autodesk's website. You can find the documentation for this version as well as the previous versions from the following link: http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=17765502. Once you're on this page you can scroll down and click on 2013 for the language and operating system that you are using. The following screenshot is what you should see: Next you will navigate to the location that you downloaded the file to, and run it. Now follow the prompts by clicking Next until the installation is complete. This file will install the documentation into your AutodeskMudbox 2013 folder by default. You can change this location during the installation process if you like but I recommend leaving this as the default location. After the local version of the Help files are installed, we need to point Mudbox 2013's Help menu to the local copy of the documentation. To do this, open the Mudbox 2013 folder, click on Windows in the top menu bar, and click on Preferences. The following screenshot shows how it should look: Next, click on the small arrow next to Help so that more options open up. You will notice that next to Help Location it says Autodesk Web Site. We are going to change that to Installed Local Help by clicking on the small arrow next to (or directly on the text) Autodesk Web Site and choose Installed Local Help from the drop-down menu. Then click on OK. Take note that if you did install your documentation to a different directory, then you will need to choose Custom instead of Installed Local Help. Then you will need to copy and paste the directory location into the Help Path textbox. Setting up hotkeys The first thing you will want to do when you start using a new piece of software is, either set up your own hotkeys or familiarize yourself with the default hotkeys. This is very important for speeding up your workflow. If you do not use hotkeys, you will have to constantly go through menus and scroll through windows to find the tools that you need, which will undoubtedly slow you down. How to do it... First you will need to go into the Windows menu item on the top menu bar. Next, you will click on Hotkeys to bring up the hotkey window as shown in the next screenshot. You will notice a drop-down menu that reads Use keyboard shortcuts from with a Restore Mudbox Defaults button next to it. Within this menu you can set your default hotkeys to resemble a 3D software that you are accustomed to using. This will help you transition smoothly into using Mudbox. If you are new to all 3D software, or use a software package that is not on this list, then using Mudbox hotkeys should suffice. The following screenshot shows the options available in Mudbox 2013: After choosing a default set of keys, you can now go in and change any hotkeys that you would like to customize. Let's say, I would like Eyedropper to activate when I press the E key and the left mouse button together. What you will do is change the current letter that is in the box next to Eyedropper to E and you will make sure there is a check in the box next to LMB (Left Mouse Button). It should look like the following screenshot: How it works... Once all your hotkeys are set up as desired, you will be able to use quick keystrokes to access a large number of tools without ever taking your eyes off your project. The more you get comfortable with your hotkeys, the faster you will get at switching between tools. There's more... When you first start using a particular software, you probably won't know exactly which tools you will be using most often. With that in mind, you will want to revisit your hotkey customization after getting a feel for your workflow and which tools you use the most. Another thing you want to think about, when setting up your hotkeys, is how easy it is to use the hotkey. For example, I tend to make hotkeys that relate to the tool in some way in order to make it easier to remember. For example, the Create Curve tool has a good hotkey already set for it, Ctrl+ C, for the reasons mentioned as follows: One reason it is a good hotkey is that the first letter of the tool is also the letter of the key being used for the hotkey. I can relate Cto curve. Another reason this could be a good hotkey is because if creating curves is something that I find myself doing often, then all I have to do is use my pinky finger on the Ctrl key and my pointer finger on the C key. You may think "Yeah? So what?" but if I were to set the hotkey to Ctrl+ Alt+ U it's a bit more of a stretch on my fingers and I would not want to do that frequently. The point is, key location and frequency of use are things you want to think about to speed up your workflow and stay comfortable while using your hotkeys. Increasing the resolution on your model Before you can get any fine details, or details that you would see while viewing from close up, into the surface of your model you will need to subdivide your mesh to increase its resolution. In the same way that a computer monitor displays more pixels when its resolution is increased, a model will have more points on its surface when the resolution is increased. How to do it... The hotkey for subdividing your surface is Shift + D or you can alternatively go into the menus as shown in the following screenshot: How it works... What this does is it adds more polygons which can be manipulated to add more detail. You will not want to subdivide your model too many times, otherwise, your computer will begin to slow down. The extent to which your computer will slow down is exponential. For example, if you have a six-sided cube and you subdivide it once, it will become 24-sided. If you subdivide it one more time, it will become 96-sided and so on. The following screenshot from Maya shows you what the wireframe looks like from one level to the next: The reason this image was created in Maya is because Mudbox will only show the proper wireframe when your model reaches 1000 polygons or more. The more powerful your computer, the more smoothly Mudbox 2013 will run. More specifically, it's the RAM and the video memory that are important. The following are some explanations on how RAM and video memory will affect your machines performance. RAM is the most important of all. The more RAM you have, the more polygons Mudbox will be able to handle, without taking a performance hit. The video memory increases the performance of your video card and allows high resolution, high speed, and color graphics. Basically, it allows the Graphical User Interface (GUI) to have better performance. So, now that you know RAM is important, how do you decide how much will be needed to run Mudbox 2013 smoothly? Well, one thing to consider is your operating system and the version of Mudbox 2013 you are running. If you have a 32-bit operating system and you are running the 32-bit Mudbox 2013, then the maximum RAM you can get is 4 GB. But, in reality you are only getting about 3 GB of RAM as the operating system needs to use around 1 GB of that memory. On the other hand, if you are using a 64-bit operating system and the 64-bit Mudbox 2013 version then you are capped at about 8 TB (yes, I said TB not GB). You will not need anywhere near that amount of RAM to run Mudbox 2013 smoothly. My recommendation is to have a minimum of 8 GB of RAM and 1 GB of video memory. With this amount of RAM and video memory you should be able to work with around 10 million triangles on the top level of your sculpt . There's more... Notice the little white box next to Add New Subdivision Level in the following screenshot: By clicking on this box, you will be given a few options for how Mudbox will handle the subdivision, as shown in the following screenshot: The options shown in the previous screenshot are explained as follows: Smooth Positions: This option will smooth out the edges by averaging out the vertices that are added. The following screenshot shows the progression from Level 0 to Level 2 on a cube: Subdivide UVs: If this option is unchecked when you create a new subdivision level, then you will lose your UVs on the object. To get your UVs back you will need to recreate the UVs for that level. If the Subdivide UVs option is turned on then it will just add subdivisions to your existing UVs. Smooth UVs: If this option is turned on, the UVs will be smoothed within the UV Borders as shown in the next screenshot: If you want your borders to smooth along with the interior parts of the shell, as shown in the next screenshot, then you will need to take a few extra steps to allow this: This is the method Mudbox used in the 2009 and earlier versions. In Mudbox 2010, they switched the way they handle this operation so that the borders do not smooth. Here is an excerpt from the Service Pack notes from 2010: "A new environment variable now exists to alter how the Smooth UVs property works when subdividing a model: MUDBOX2009_SUBDIVIDE_SMOOTH_UV. When this environment variable is set, the Smooth UVs property works as it did in Mudbox 2009. That is, the entire UV shell, including its UV borders, are smoothed when subdividing a model whenever the Smooth UVs property is turned on. If this environment variable is not set, the default Mudbox 2010 UV smoothing behavior occurs. That is, smoothing only occurs for the interior UVs in a UV shell, leaving the UV shell border edges unsmoothed. Which UV smoothing method you choose to use is entirely dependent on your individual rendering pipeline requirements and render application used." This has not changed since Mudbox 2010. So, basically what you need to do on a PC is add an environment variable MUDBOX2009_SUBDIVIDE_SMOOTH_UV that has a value of 1. To do this you will need to right-click on My Computer and click on Properties. Then, choose Advanced system settings and under the Advanced tab click on Environment Variables.... Under System Variables click on New.... In the blank where it says Variable Name enter MUDBOX2009_SUBDIVIDE_SMOOTH_UV and under Variable Value input a 1. Hit OK and it's all ready to go. Moving up and down subdivision levels Once you create subdivision levels using Shift + D, or through the menus, you can move up and down the levels you have created by using the Page Up key to move up in levels, or the Page Down key to move down in levels. But keep in mind, you will not be able to go any higher than the highest level you created using Add New Subdivision Level and you will never be able to go below Level 0. Another thing to take into account is which model you are subdividing. If you have multiple objects in your scene, you need to make sure the correct mesh is active when subdividing. The following are a couple of ways to make sure you are subdividing the correct mesh: One way is to select the object in the Object List before hitting Shift + D. Another way is to hover your mouse cursor over the mesh that you want to subdivide and then hit Shift + D. This will subdivide the mesh that is directly underneath your cursor.
Read more
  • 0
  • 0
  • 3326

article-image-graphical-capabilities-r
Packt
29 Oct 2010
8 min read
Save for later

Graphical Capabilities of R

Packt
29 Oct 2010
8 min read
Statistical Analysis with R Take control of your data and produce superior statistical analysis with R. An easy introduction for people who are new to R, with plenty of strong examples for you to work through This book will take you on a journey to learn R as the strategist for an ancient Chinese kingdom! A step by step guide to understand R, its benefits, and how to use it to maximize the impact of your data analysis A practical guide to conduct and communicate your data analysis with R in the most effective manner           Read more about this book       (For more resources on R, see here.) Time for action — creating a line chart The ever popular line chart, or line graph, depicts relationships as continuous series of connected data points. Line charts are particularly useful for visualizing specific values and trends over time. Just as a line chart is an extension of a scatterplot in the non-digital realm, a line chart is created using an extended form of the plot(...) function in R. Let us explore how to extend the plot(...) function to create line charts in R: Use the type argument within the plot(...) function to create a line chart that depicts a single relationship between two variables: > #create a line chart that depicts the durations of past fire attacks> #get the data to be used in the chart> lineFireDurationDataX <- c(1:30)> lineFireDurationDataY <- subsetFire$DurationInDays> #customize the chart> lineFireDurationMain <- "Duration of Past Fire Attacks"> lineFireDurationLabX <- "Battle Number"> lineFireDurationLabY <- "Duration in Days"> #use the type argument to connect the data points with a line> lineFireDurationType <- "o"> #use plot(...) to create and display the line chart> plot(x = lineFireDurationDataX, y = lineFireDurationDataY,main = lineFireDurationMain, xlab = lineFireDurationLabX,ylab = lineFireDurationLabY, type = lineFireDurationType) Your chart will be displayed in the graphic window, as follows: What just happened? We expanded our use of the plot(...) function to generate a line chart and encountered a new data notation in the process. Let us review these features. type In the plot(...) function, the type argument determines what kind of line, if any, should be used to connect a chart's data points. The type argument receives one of several character values, all of which are listed as follows: p: only points are plotted; this is the default value when type is undefined l: only lines are drawn, without any points o: both lines and points are drawn, with the lines overlapping the points b: both lines and points are drawn, with the lines broken where they intersect with points c: only lines are drawn, but they are broken where points would occur s: only the lines are drawn in step formation; the initial step begins at zero S: (uppercase) only the lines are drawn in step formation; the final step tails off at the last point h: vertical lines are drawn to represent each point n: no points nor lines are drawn Our chart, which represented the duration of past fire attacks, featured a line that overlapped the plotted points. First, we defined our desired line type in an R variable: > lineFireDurationType <- "o" Then the type argument was placed within our plot(...) function to generate the line chart: > plot(lineFireDurationDataX, lineFireDurationDataY,main = lineFireDurationMain, xlab = lineFireDurationLabX,ylab = lineFireDurationLabY,type = lineFireDurationType) Number-colon-number notation You may have noticed that we specified a vector for the x-axis data in our plot(...) function. > lineFireDurationDataX <- c(1:30) This vector used number-colon-number notation. Essentially, this notation has the effect of enumerating a range of values that lie between the number that precedes the colon and the number that follows it. To do so, it adds one to the beginning value until it reaches a final value that is equal to or less than the number that comes after the colon. For example, the code > 14:21 would yield eight whole numbers, beginning with 14 and ending with 21, as follows: [1] 14 15 16 17 18 19 20 21 Furthermore, the code > 14.2:21 would yield seven values, beginning with 14.2 and ending with 20.2, as follows: [1] 14.2 15.2 16.2 17.2 18.2 19.2 20.2 Number-colon-number notation is a useful way to enumerate a series of values without having to type each one individually. It can be used in any circumstance where a series of values is acceptable input into an R function. Number-colon-number notation can also enumerate values from high to low. For instance, 21:14 would yield a list of values beginning with 21 and ending with 14. Since we do not have exact dates or other identifying information for our 30 past battles, we simply enumerated the numbers 1 through 30 on the x-axis. This had the effect of assigning a generic identification number to each of our past battles, which in turn allowed us to plot the duration of each battle on the y axis. Pop quiz Which of the following is the type argument capable of? Drawing a line to connect or replace the points on a scatterplot. Drawing vertical or step lines. Drawing no points or lines. All of the above. What would the following line of code yield in the R console? > 1:50 A sequence of 50 whole numbers, in order from 1 to 50. A sequence of 50 whole numbers, in order from 50 to 1. A sequence of 50 random numbers, in order from 1 to 50. A sequence of 50 random numbers, in order from 50 to 1. Time for action — creating a box plot A useful way to convey a collection of summary statistics in a dataset is through the use of a box plot. This type of graph depicts a dataset's minimum and maximum, as well as its lower, median, and upper quartiles in a single diagram. Let us look at how box plots are created in R: Use the boxplot(...) function to create a box plot. > #create a box plot that depicts the number of soldiers required to launch a fire attack> #get the data to be used in the plot> boxplotFireShuSoldiersData <- subsetFire$ShuSoldiers> #customize the plot> boxPlotFireShuSoldiersLabelMain <- "Number of Soldiers Required to Launch a Fire Attack"> boxPlotFireShuSoldiersLabelX <- "Fire Attack Method"> boxPlotFireShuSoldiersLabelY <- "Number of Soldiers"> #use boxplot(...) to create and display the box plot> boxplot(x = boxplotFireShuSoldiersData,main = boxPlotFireShuSoldiersLabelMain,xlab = boxPlotFireShuSoldiersLabelX,ylab = boxPlotFireShuSoldiersLabelY) Your plot will be displayed in the graphic window, as shown in the following: Use the boxplot(...) function to create a box plot that compares multiple datasets. > #create a box plot that compares the number of soldiers required across the battle methods> #get the data formula to be used in the plot> boxplotAllMethodsShuSoldiersData <- battleHistory$ShuSoldiers ~ battleHistory$Method> #customize the plot> boxPlotAllMethodsShuSoldiersLabelMain <- "Number of Soldiers Required by Battle Method"> boxPlotAllMethodsShuSoldiersLabelX <- "Battle Method"> boxPlotAllMethodsShuSoldiersLabelY <- "Number of Soldiers"> #use boxplot(...) to create and display the box plot> boxplot(formula = boxplotAllMethodsShuSoldiersData,main = boxPlotAllMethodsShuSoldiersLabelMain,xlab = boxPlotAllMethodsShuSoldiersLabelX,ylab = boxPlotAllMethodsShuSoldiersLabelY) Your plot will be displayed in the graphic window, as shown in the following: What just happened? We just created two box plots using R's boxplot(...) function, one with a single box and one with multiple boxes. boxplot(...) We started by generating a single box plot that was composed of a dataset, main title, and x and y labels. The basic format for a single box plot is as follows: boxplot(x = dataset) The x argument contains the data to be plotted. Technically, only x is required to create a box plot, although you will often include additional arguments. Our boxplot(...) function used the main, xlab, and ylab arguments to display text on the plot, as shown: > boxplot(x = boxplotFireShuSoldiersData,main = boxPlotFireShuSoldiersLabelMain,xlab = boxPlotFireShuSoldiersLabelX,ylab = boxPlotFireShuSoldiersLabelY) Next, we created a multiple box plot that compared the number of Shu soldiers deployed by each battle method. The main, xlab, and ylab arguments remained from our single box plot, however our multiple box plot used the formula argument instead of x. Here, a formula allows us to break a dataset down into separate groups, thus yielding multiple boxes. The basic format for a multiple box plot is as follows: boxplot(formula = dataset ~ group) In our case, we took our entire Shu soldier dataset (battleHistory$ShuSoldiers) and separated it by battle method (battleHistory$Method): > boxplotAllMethodsShuSoldiersData <- battleHistory$ShuSoldiers ~ battleHistory$Method Once incorporated into the boxplot(...) function, this formula resulted in a plot that contained four distinct boxes—ambush, fire, head to head, and surround: > boxplot(formula = boxplotAllMethodsShuSoldiersData,main = boxPlotAllMethodsShuSoldiersLabelMain,xlab = boxPlotAllMethodsShuSoldiersLabelX,ylab = boxPlotAllMethodsShuSoldiersLabelY) Pop quiz Which of the following best describes the result of the following code? > boxplot(x = a) A single box plot of the a dataset. A single box plot of the x dataset. A multiple box plot of the a dataset that is grouped by x. A multiple box plot of the x dataset that is grouped by a. Which of the following best describes the result of the following code? > boxplot(formula = a ~ b) A single box plot of the a dataset. A single box plot of the b dataset. A multiple box plot of the a dataset that is grouped by b. A multiple box plot of the b dataset that is grouped by a.
Read more
  • 0
  • 0
  • 3325

article-image-elastic-stack-overview
Packt
10 Jan 2017
9 min read
Save for later

Elastic Stack Overview

Packt
10 Jan 2017
9 min read
In this article by Ravi Kumar Gupta and Yuvraj Gupta, from the book, Mastering Elastic Stack, we will have an overview of Elastic Stack, it's very easy to read a log file of a few MBs or hundreds, so is it to keep data of this size in databases or files and still get sense out of it. But then a day comes when this data takes terabytes and petabytes, and even notepad++ would refuse to open a data file of a few hundred MBs. Then we start to find something for huge log management, or something that can index the data properly and make sense out of it. If you Google this, you would stumble upon ELK Stack. Elasticsearch manages your data, Logstash reads the data from different sources, and Kibana makes a fine visualization of it. Recently, ELK Stack has evolved as Elastic Stack. We will get to know about it in this article. The following are the points that will be covered in this article: Introduction to ELK Stack The birth of Elastic Stack Who uses the Stack (For more resources related to this topic, see here.) Introduction to ELK Stack It all began with Shay Banon, who started it as an open source project, Elasticsearch, successor of Compass, which gained popularity to become one of the top open source database engines. Later, based on the distributed model of working, Kibana was introduced to visualize the data present in Elasticsearch. Earlier, to put data into Elasticsearch we had rivers, which provided us with a specific input via which we inserted data into Elasticsearch. However, with growing popularity this setup required a tool via which we can insert data into Elasticsearch and have flexibility to perform various transformations on data to make unstructured data structured to have full control on how to process the data. Based on this premise, Logstash was born, which was then incorporated into the Stack, and together these three tools, Elasticsearch, Logstash, and Kibana were named ELK Stack. The following diagram is a simple data pipeline using ELK Stack: As we can see from the preceding figure, data is read using Logstash and indexed to Elasticsearch. Later we can use Kibana to read the indices from Elasticsearch and visualize it using charts and lists. Let's understand these components separately and the role they play in the making of the Stack. Logstash As we got to know that rivers were used initially to put data into Elasticsearch before ELK Stack. For ELK Stack, Logstash is the entry point for all types of data. Logstash has so many plugins to read data from a number of sources and so many output plugins to submit data to a variety of destinations and one of those is the Elasticsearch plugin, which helps to send data to Elasticsearch. After Logstash became popular, eventually rivers got deprecated as they made the cluster unstable and also performance issues were observed. Logstash does not ship data from one end to another; it helps us with collecting raw data and modifying/filtering it to convert it to something meaningful, formatted, and organized. The updated data is then sent to Elasticsearch. If there is no plugin available to support reading data from a specific source, or writing the data to a location, or modifying it in your way, Logstash is flexible enough to allow you to write your own plugins. Simply put, Logstash is open source, highly flexible, rich with plugins, can read your data from your choice of location, normalizes it as per your defined configurations, and sends it to a particular destination as per the requirements. Elasticsearch All of the data read by Logstash is sent to Elasticsearch for indexing. There is a lot more than just indexing. Elasticsearch is not only used to index data, but it is a full-text search engine, highly scalable, distributed, and offers many more things. Elasticsearch manages and maintains your data in the form of indices, offers you to query, access, and aggregate the data using its APIs. Elasticsearch is based on Lucene, thus providing you all of the features that Lucene does. Kibana Kibana uses Elasticsearch APIs to read/query data from Elasticsearch indices to visualize and analyze in the form of charts, graphs and tables. Kibana is in the form of a web application, providing you a highly configurable user interface that lets you query the data, create a number of charts to visualize, and make actual sense out of the data stored. After a robust ELK Stack, as time passed, a few important and complex demands took place, such as authentication, security, notifications, and so on. This demand led for few other tools such as Watcher (providing alerting and notification based on changes in data), Shield (authentication and authorization for securing clusters), Marvel (monitoring statistics of the cluster), ES-Hadoop, Curator, and Graph as requirement arose. The birth of Elastic Stack All the jobs of reading data were done using Logstash, but that's resource consuming. Since Logstash runs on JVM, it consumes a good amount of memory. The community realized the need of improvement and to make the pipelining process resource friendly and lightweight. Back in 2015, Packetbeat was born, a project which was an effort to make a network packet analyzer that could read from different protocols, parse the data, and ship to Elasticsearch. Being lightweight in nature did the trick and a new concept of Beats was formed. Beats are written in Go programming language. The project evolved a lot, and now ELK stack was no more than just Elasticsearch, Logstash, and Kibana, but Beats also became a significant component. The pipeline now looked as follows: Beat A Beat reads data, parses it, and can ship to either Elasticsearch or Logstash. The difference is that they are lightweight, serve a specific purpose, and are installed as agents. There are few beats available such as Topbeat, Filebeat, Packetbeat, and so on, which are supported and provided by the Elastic.co and a good number of Beats already written by the community. If you have a specific requirement, you can write your own Beat using the libbeat library. In simple words, Beats can be treated as very light weight agents to ship data to either Logstash or Elasticsearch and offer you an infrastructure using the libbeat library to create your own Beats. Together Elasticsearch, Logstash, Kibana, and Beats become Elastic Stack, formally known as ELK Stack. Elastic Stack did not just add Beats to its team, but they will be using the same version always. The starting version of the Elastic Stack will be 5.0.0 and the same version will apply to all the components. This version and release method is not only for Elastic Stack, but for other tools of the Elastic family as well. Due to so many tools, there was a problem of unification, wherein each tool had their own version and every version was not compatible with each other, hence leading to a problem. To solve this, now all of the tools will be built, tested, and released together. All of these components play a significant role in creating a pipeline. While Beats and Logstash are used to collect the data, parse it, and ship it, Elasticsearch creates indices, which is finally used by Kibana to make visualizations. While Elastic Stack helps with a pipeline, other tools add security, notifications, monitoring, and other such capabilities to the setup. Who uses Elastic Stack? In the past few years, implementations of Elastic Stack have been increasing very rapidly. In this section, we will consider a few case studies to understand how Elastic Stack has helped this development. Salesforce Salesforce developed a new plugin named ELF (Event Log Files) to collect Salesforce logged data to enable auditing of user activities. The purpose was to analyze the data to understand user behavior and trends in Salesforce. The plugin is available on GitHub at https://github.com/developerforce/elf_elk_docker. This plugin simplifies the Stack configuration and allows us to download ELF to get indexed and finally sensible data that can be visualized using Kibana. This implementation utilizes Elasticsearch, Logstash, and Kibana. CERN There is not just one use case that Elastic Stack helped CERN (European Organization for Nuclear Research), but five. At CERN, Elastic Stack is used for the following: Messaging Data monitoring Cloud benchmarking Infrastructure monitoring Job monitoring Multiple Kibana dashboards are used by CERN for a number of visualizations. Green Man Gaming This is an online gaming platform where game providers publish their games. The website wanted to make a difference by proving better gameplay. They started using Elastic Stack to do log analysis, search, and analysis of gameplay data. They began with setting up Kibana dashboards to gain insights about the counts of gamers by the country and currency used by gamers. That helped them to understand and streamline the support and help in order to provide an improved response. Apart from these case studies, Elastic Stack is used by a number of other companies to gain insights of the data they own. Sometimes, not all of the components are used, that is, not all of the times a Beat would be used and Logstash would be configured. Sometimes, only an Elasticsearch and Kibana combination is used. If we look at the users within the organization, all of the titles who are expected to do big data analysis, business intelligence, data visualizations, log analysis, and so on, can utilize Elastic Stack for their technical forte. A few of these titles are data scientists, DevOps, and so on. Stack competitors Well, it would be wrong to call for Elastic Stack competitors because Elastic Stack has been emerged as a strong competitor to many other tools in the market in recent years and is growing rapidly. A few of these are: Open source: Graylog: Visit https://www.graylog.org/ for more information InfluxDB: Visit https://influxdata.com/ for more information Others: Logscape: Visit http://logscape.com/ for more information Logscene: Visit http://sematext.com/logsene/ for more information Splunk: Visit http://www.splunk.com/ for more information Sumo Logic: Visit https://www.sumologic.com/ for more information Kibana competitors: Grafana: Visit http://grafana.org/ for more information Graphite: Visit https://graphiteapp.org/ for more information Elasticsearch competitors: Lucene/Solr: Visit http://lucene.apache.org/solr/ or https://lucene.apache.org/ for more information Sphinx: Visit http://sphinxsearch.com/ for more information Most of these compare with respect to log management, while Elastic Stack is much more than that. It offers you the ability to analyze any type of data and not just logs. Resources for Article: Further resources on this subject: AIO setup of OpenStack – preparing the infrastructure code environment [article] Our App and Tool Stack [article] Using the OpenStack Dashboard [article]
Read more
  • 0
  • 0
  • 3325

article-image-enhancing-user-experience-php-5-ecommerce-part-1
Packt
29 Jan 2010
7 min read
Save for later

Enhancing the User Experience with PHP 5 Ecommerce: Part 1

Packt
29 Jan 2010
7 min read
Juniper Theatricals Juniper Theatricals want to have a lot of products on their online store, and as a result they fear that some products may get lost within the website, or not be as obvious to their customers. To help prevent this problem, we will integrate product searching to make products easy to find, and we will add filters to product lists allowing customers to see products that match what they are looking for (for example, ones within their price range). As some products could still be lost, they want to be able to recommend related products to customers when they view particular products. If a customer wants a product, and it happens to be out of stock, then they want to prevent the customer from purchasing it elsewhere; so we will look at stock notifications too. The importance of user experience Our customers' experience on the stores powered by our framework is veryimportant. A good user experience will leave them feeling wanted and valued, whereas a poor user experience will leave them feeling unwanted, unvalued, and may leave a bad taste in their mouths. Search The ability for customers to be able to search, find, and filter products is vital, as if they cannot find what they are looking for they will be frustrated by our site and go somewhere where they can find what they are looking for much more easily. There are two methods that can make it much easier for customers to find what they are looking for: Keyword search: This method allows customers to search the product catalog based on a series of keywords. Filtering: This method allows customers to filter down lists of products based on attributes, refining larger lists of products into ones that better match their requirements. Finding products The simplest way for us to implement a search feature is to search the product name and product description fields. To make the results more relevant, we can place different priorities on where matches were found; for instance, if a word or phrase is found in both the name and description then that would be of the highest importance; next would be products with the word or phrase in the name; and finally, we would have products that just have the word or phrase contained within the product description itself. So, what is involved in adding search features to our framework? We need the following: Search box: We need a search box for our customers to type in words or phrases. Search feature in the controller: We need to add some code to search the products database for matching products. Search results: Finally, we need to display the matching products to the customer. Search box We need a search box where our customers can type in words or phrases to search our stores. This should be a simple POST form pointing to the path products/search with a search field of product_search. The best place for this would be in our website's header, so customers can perform their search from anywhere on the site or store. <div id="search"><form action="products/search" method="post"><label for="product_search">Search for a product</label><input type="text" id="product_search" name="product_search" /><input type="submit" id="search" name="search" value="Search" /></form></div> We now have a search box on the store: Controlling searches with the products controller A simple modification to our products controller will allow customers to search products. We need to make a small change to the constructor, to ensure that it knows when to deal with search requests. Then we need to create a search function to search products, store the results, and display them in a view. Constructor changes A simple switch statement can be used to detect if we are viewing a product, performing a search, or viewing all of the products in the database as a list. $urlBits = $this->registry->getURLBits();if( !isset( $urlBits[1] ) ){$this->listProducts();}else{switch( $urlBits[1] ){case 'view':$this->viewProduct();break;case 'search':$this->searchProducts();break;default:$this->listProducts();break;}} This works by breaking down the URL and, depending on certain aspects of the URL, different methods are called from within the controller. Search function We now need a function to actually search our products database, such as the following: private function searchProducts(){// check to see if the user has actually submitted the search formif( isset( $_POST['product_search'] ) &&$_POST['product_search'] != '' ){ Assuming the customer has actually entered something to search, we need to clean the search phrase, so it is suitable to run in our database query, and then we perform the query. The phrase is checked against the name and description of the product, with the name taking priority within the results. The highlighted code illustrates the query with prioritization. // clean up the search phrase$searchPhrase = $this->registry->getObject('db')->sanitizeData( $_POST['product_search'] );$this->registry->getObject('template')->getPage()->addTag( 'query', $_POST['product_search'] );// perform the search, and cache the results, ready for the// results template$sql = "SELECT v.name, c.path,IF(v.name LIKE '%{$searchPhrase}%', 0, 1) AS priority,IF(v.content LIKE '%{$searchPhrase}%', 0, 1)AS prioritybFROM content c, content_versions v, content_types tWHERE v.ID=c.current_revision AND c.type=t.IDAND t.reference='product' AND c.active=1AND ( v.name LIKE '%{$searchPhrase}%' OR v.contentLIKE '%{$searchPhrase}%' )ORDER BY priority, priorityb ";$cache = $this->registry->getObject('db')->cacheQuery( $sql );if( $this->registry->getObject('db')->numRowsFromCache( $cache ) == 0 ){// no results from the cached query, display the no results// template} If there are some products matching the search, then we display the results to the customer. else{// some results were found, display them on the results page// IMPROVEMENT: paginated results$this->registry->getObject('template')->getPage()->addTag( 'results', array( 'SQL', $cache ) );$this->registry->getObject('template')->buildFromTemplates('header.tpl.php','products-searchresults.tpl.php', 'footer.tpl.php');}}else{// search form not submitted, so just display the search box page$this->registry->getObject('template')->buildFromTemplates('header.tpl.php','products-searchform.tpl.php', 'footer.tpl.php');}} As the results from the query are stored in a cache, we can simply assign this cache to a template tag variable, and the results will be displayed. Of course, as we need to account for the fact that there may be no results, we must check to ensure there are some results, and if there are none, we must display the relevant template. Search results Finally, we need a results page to display these results on. <h2>Products found...</h2><p>The following products were found, matching your search for{query}.</p><ul><!-- START results --><li><a href="products/view/{path}">{ name}</a></li><!-- END results --></ul> Our search results page looks like this: Improving searches We could improve this search function by making it applicable for all types of content managed by the framework. Obviously if we were going to do this, it would need to be taken out of the products controller, perhaps either as a controller itself, or as a core registry function, or as part of the main content/pages controller. The results could either be entirely in a main list, with a note of their type of content, or tabbed, with each type of content being displayed in a different tab. The following diagrams represent these potential Search Results pages.   And, of course, the tab-separated search results.
Read more
  • 0
  • 0
  • 3324

Packt
19 Jun 2010
5 min read
Save for later

Getting Started with Blender’s Particle System- A Sequel

Packt
19 Jun 2010
5 min read
Creating Fire Taking from the same setup we had for the creating the smoke, making a fire is almost a similar process except for a few changes: the halo shader settings and force field strengths. Let’s go ahead and start changing the halo shader such that we change the color, hardness, add, and to disable the texture option. Then, we change the Force Field from Texture to Force with Strength of -6.7. Halo Settings for Fire   Force Field Settings   Fire Test Render   Furthermore, we can achieve even more believable results when we plug these image renders over to our compositor for some contrast boosting and other cool 2d effects. Creating Bubbles Let’s start a new Blender file, delete the default Cube, and replace it with a Plane primitive. Then let’s position the camera such that our plane is just below our view. Preparing the View   Next, let’s add a new particle system to the Plane and name it “Bubble”. Check the screenshots below for the settings. Bubble Cache Settings   Bubble Emission Settings   Bubble Velocity Settings   Bubble Physics Settings   Bubble Display Settings Bubble Field Weights Settings Now that we’ve got those settings in (remember though to play around because your settings might be way better than mine), let’s add a UV Sphere with the default divisions to our scene and name it “Bubble”. Then place it somewhere that the camera view won’t see. Adding, Moving, and Renaming the UV Sphere   What we’ll be doing next is to “instance” the UV Sphere (“Bubble”) we just added into the emitter plane, thus obeying the Particle Settings that we’ve set awhile back. To do this, select the Emitter plane and edit the Render and Display settings under Particle Settings (as seen below). Emitter Render and Display Settings Now if we play the animation in our 3D Viewport, you’ll now notice that the UV Sphere is now instanced to where the particle points are before, replacing them with a mesh object. Often, the instanced Bubble object would look small in our view, if this happens, simply scale the Bubble object and it will propagate accordingly in our Particle System. Instanced Bubble Objects   And that’s about it! Coupled with some nice shaders and compositing effects, you can definitely achieve impressive and seamless results. Bubbles with Sample Shaders and Image Background   Bubble Particles Composited Over a Photograph Bubbles and Butterflies   Creating Rockslides Similar to the concept of creating bubbles via Particle Systems, let’s derive the steps and create something different. This time, we’ll take advantage of Blender’s physics systems to automate natural motion and collision interaction. We won’t be using the Blender Game Engine for this matter (which should do almost the same thing), but instead we’re still going to use the particle system that is present in Blender. Like how we started the other topics, this time again, we’ll start by refreshing Blender’s view and starting a new session. Delete the default cube and add a plane mesh or a grid and start modeling a mountain-like terrain. This will be our slope from which our rock particles will fall and slide later on. You can use whichever technique you have on your disposal. Fast forward into time, here’s closely what we should have: Terrain Model for Rock Sliding   Next step is to create the actual rocks that are going to be falling and sliding on our terrain mesh. It’s optimal to start with an Icosphere and model from there. Be sure to move the models out of the camera’s view since we don’t want to see the original meshes, only the instances that are going to be generated. Model five (5) variations of the rocks and create a group for them named “RockGroup”. Rock Group Add an emitter plane across the top of the mountain terrain, this will be our particle rock emitter. Rock Particle Emitter   Next, create a Particle System on the emitter mesh and call it “RockSystem”. And this time, we’ll use the default gravity settings to simulate falling rock. Check the screenshots below for the particle setup.           Additionally, we must set the terrain mesh as a collision object such that the particles react to it whenever they collide. Play around with the settings until you’re satisfied with the behavior of your particles. Press ALT+A or click the play button in the Timeline Window to preview the animation. Setting Terrain as Collision   Single Frame from the Animation   Single Frame Rendered  
Read more
  • 0
  • 0
  • 3324

article-image-faq-web-services-and-apache-axis2
Packt
28 Feb 2011
12 min read
Save for later

FAQ on Web Services and Apache Axis2

Packt
28 Feb 2011
12 min read
Apache Axis2 Web Services, 2nd Edition Create secure, reliable, and easy-to-use web services using Apache Axis2. Extensive and detailed coverage of the enterprise ready Apache Axis2 Web Services / SOAP / WSDL engine. Attain a more flexible and extensible framework with the world class Axis2 architecture. Learn all about AXIOM - the complete XML processing framework, which you also can use outside Axis2. Covers advanced topics like security, messaging, REST and asynchronous web services. Written by Deepal Jayasinghe, a key architect and developer of the Apache Axis2 Web Service project; and Afkham Azeez, an elected ASF and PMC member.      Q: How did SOA change the world view? A: The era of isolated computers is over. Now "connected we stand, isolated we fall" is becoming the motto of computing. Networking and communication facilities have connected the world in a way as never before. The world has hardware that could support the systems that connect thousands of computers, and these systems have the capacity to wield power that was once only dreamed of. Yet, computer science lacked the technologies and abstraction to utilize the established communication networks. The goal of distributed computing is to provide such abstractions. RPC, RMI, IIOP, and CORBA are a few proposals that provide abstractions over the network for the developers to build upon. These proposals fail to consider one critical nature of the problem. The systems are a composition of numerous heterogeneous subsystems, but these proposals require all the participants to share a programming language or a few languages. Service Oriented Architecture (SOA) provides the answer by defining a set of concepts and patterns to integrate homogenous and heterogeneous components together. SOA provides a better way to achieve loosely coupled systems, and hence more extensibility and flexibility. In addition, similar to object-oriented programming (OOP), SOA enables a high degree of reusability. There are three main ways one can enable SOA capabilities in their systems and applications: Existing messaging systems: for example, JMS, IBM MQSeries, Tibco, and so on Plain Old XML (POX): for example, REST, XML/HTTP and so on Web services: for example, SOAP, WSDL, WS-* Q: What are the shortcomings of Java Messaging Service (JMS)? A: Among the commonly used messaging systems, Java Messaging Service (JMS) plays a major role in the industry and has become a common API for messaging systems. We can find a number of different message types of JMS, such as Text, Bytes, Name-Value pair, Stream, and Object. One of the main disadvantages of these types of messaging systems is that they do not have a single wire format (serialization format). As a result, interoperability is a big issue: if two applications are using JMS to communicate, then they must be on the same implementation. Sonic, Tibco, and IBM are the leaders in the commercial markets, and JBoss, Manta, and ActiveMQ are the commonly used open source implementations. Q: What is POX and how does it serve the web? A: Plain Old XML or POX is another way of exposing functionality and enabling SOA in the system. With the widespread use of the Web, the POX approach has become more popular. Most of the web applications expose the XML APIs, where we can develop components and communicate with them. Google Maps, Auto complete, and Amazon services are a few examples of applications that heavily use XML APIs to expose the functionality. In most cases, POX is used in combination with REST (Representational State Transfer). REST is a model of an underlying architecture of the Web, and it is based on the concept that every URL identifies resources. GET, PUT, POST, and DELETE are the verbs that are used in the REST architecture. REST is often associated with the theoretical standpoints, and for this reason, REST is generally not used for complex interactions. Q: What are web services? A: The fundamental concept behind web services is the SOA where an application is no longer a large monolithic program, but it is divided into smaller, loosely coupled programs. The provided services are loosely coupled together with standardized and well-defined interfaces. These loosely coupled programs make the architecture very extensible due to the possibility to add or remove services with limited costs. Therefore, new services can be created by combining existing services. To understand loose coupling clearly, it is better to understand the opposite, which is tight coupling, and its problems: Errors, delays, and downtime spread through the system The resilience of the whole system is based on the weakest part Cost of upgrading or migrating spreads It's hard to evaluate the useful parts from the dead weight The benefits a web service provides are listed below: Increased interoperability, resulting in lower maintenance costs Increased reusability and composablity (for example, use publicly available services and reuse them or integrate them to provide new services) Increased competition among vendors, resulting in lower product costs Easy transition from one product to another, resulting in lower training costs Greater degree of adoption and longevity for a standard, a large degree of usage from vendors and users leading to a higher degree of acceptance Q: What contributes to the popularity of web services? A: Among the three commonly used methods to enable SOA, a web service can be considered as the most standard and flexible way. Web services extend the idea of POX and add additional standards to make the communication more organized and standardized. There are several reasons behind the web services being the most popular SOA-enabled mechanism, as stated here: Web services are described using WSDL, and WSDL can capture any complex application and the required quality of services. Web services use SOAP as the message transmission mechanism, as SOAP is a special type of XML. It gains all the extensibility features from XML. There are a number of standard bodies to create and enforce the standards for web services. There are multiple open source and commercial web service implementations. By using the standards and procedures, web services provide application and programming language-independent mechanism to integrate and communicate. Different programming languages may define different implementations for web services, yet they interoperate because they all agree on the format of the information they share. Q: What are the standard bodies for web services? A: In web services, there are three main standard bodies that helped to improve the interoperability, quality of service, and base standards: WS-I OASIS W3C Q: How do organizations move into web services? A: There are three ways in which an organization could possibly use to move into the web services, listed next: Create a new web service from scratch. The developer creates the functionalities of the services as well as the description (i.e., WSDL). Expose the existing functionality through a web service. Here the functionalities of the service already exist. Only the service description needs to be implemented. Integrate web services from other vendors or business partners. There are occasions when using a service implemented by another is more cost effective than building from the scratch. On these occasions, the organization will need to integrate others' or even business partners' web services. The real usage of web service concepts is for the second and third methods, which enables other web services and applications to use the existing applications. Web services describe a new model for using the web; the model allows publication of business functions to the Web and provides universal access to those business functions. Both developers and end users benefit from web services. The web service model simplifies business application development and interoperation. Q: How does a Web services model look like? A: Web service model consists of a set of basic functionalities such as describe, publish, discover, bind, invoke, update, and unpublish. In the meantime, the model also consists of three actors—service provider, service broker, and service requester. Both the functionalities as well as actors are shown in the next figure. Service provider is the individual (organization) that provides the service. The service provider's job is to create, publish, maintain, and unpublish their services. From a business point of view, a service provider is the owner of the service. From an architectural view, a service provider is the platform that holds the implementation of the service. Google API, Yahoo! Financial services, Amazon Services, and Weather services are some examples of service providers. Service broker provides a repository of service descriptions (WSDL). These descriptions are published by the service provider. Service requesters will search the repository to identify the required service and obtain the binding information for these services. Service broker can be either public, where the services are universally accessible, or private, where only a specified set of service requesters are able to access the service. Service requester is the party that is looking for a service to fulfill its requirements. A requester could be a human accessing the service or an application program (a program could also be a service). From a business view, this is the business that wants to fulfill a particular service. From an architectural view, this is the application that is looking for and invoking a service. Q: What are web services standards? A: So far we have discussed SOA, standard bodies of web services, and the web service model. Here, we are going to discuss more about standards, which make web services more usable and flexible. In the past few years, there has been a significant growth in the usage of web services as application integration mechanism. As mentioned earlier, a web service is different from other SOA exposing mechanisms because it consists of various standards to address issues encountered in the other two mechanisms. The growing collection of WS-* (for example, Web Service security, Web Service reliable messaging, Web Service addressing, and others) standards, supervised by the web services governing bodies, define the web service protocol stack shown in the following figure. Here we will be looking at the standards that have been specified in the most basic layers: messaging and description, and discovery. The messaging standards are intended to give the framework for exchanging information in a distributed environment. These standards have to be reliable so that the message will be sent only once and only the intended receiver will receive it. This is one of the primary areas where research is being conducted, as everything depends on the messaging ability. Q: Describe the web services standards, XML-RPC and SOAP? A: The web services standards; XML-RPC and SOAP are described below. XML-RPC: The XML-RPC standard was created by Dave Winer in 1998 with Microsoft. That time the existing RPC systems were very bulky. Therefore, to create a light-weight system, the developer simplified it by specifying only the essentials and defined only a handful of data types and commands. This protocol uses XML to encode its calls to HTTP as a transport mechanism. The message is sent as a POST request in which the body of the request is in XML. A procedure is executed on the server and the value it returns is also formatted into XML. The parameters can be scalars, numbers, strings, dates, as well as complex record and list structures. As new functionalities were introduced, XML-RPC evolved into what is now known as SOAP, which is discussed next. Still, some people prefer using XML-RPC because of its simplicity, minimalism, and the ease of use. SOAP: The concept of SOAP is a stateless, one-way message exchange. However, applications can create more complex interaction patterns—such as request-response, request-multiple responses, and so on—by combining such one-way exchanges with features provided by an underlying protocol and application-specific information. SOAP is silent on the semantics of any application-specific data it conveys as it is on issues such as routing of SOAP messages, reliable data transfer, firewall traversal, and so on. However, SOAP provides the framework by which application-specific information may be conveyed in an extensible manner. The developers had chosen XML as the standard message format because of its widespread use by major organizations and open source initiatives. Also, there is a wide variety of freely available tools that ease the transition to a SOAP-based implementation. Q: Define the scope of Web Services Addressing (WS-Addressing)? A: The standard provides transport independent mechanisms to address messages and identifies web services, corresponding to the concepts of address and message correlation described in the web services architecture. The standard defines XML elements to identify web services endpoints and to secure end-to-end endpoint identification in messages. This enables messaging systems to support message transmission through networks that include processing nodes such as endpoint managers, firewalls, and gateways in a transport-neutral manner. Thus, WS-Addressing enables organizations to build reliable and interoperable web service applications by defining a standard mechanism for identifying and exchanging Web Services messages between multiple end points. Q: What is Web Services Description Language (WSDL)? A: WSDL developed by IBM, Ariba, and Microsoft is an XML-based language that provides a model for describing web services. The standard defines services as network endpoints or ports. WSDL is normally used in combination with SOAP and XML schema to provide web services over networks. A service requester who connects to a web service can read the WSDL to determine what functions are available in the web service. Special data types are embedded in the WSDL file in the form of XML Schema. The client can then use SOAP to call functions listed in the WSDL. The standard enables one to separate the description of the abstract functionality offered by a service from the concrete details of a service description such as how and where that functionality is offered. This specification defines a language for describing the abstract functionality of a service as well as a framework for describing the concrete details of a service description. The abstract definition of ports and messages is separated from their concrete use, allowing the reuse of these definitions.
Read more
  • 0
  • 0
  • 3323
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
article-image-building-custom-version-jquery
Packt
04 Apr 2013
9 min read
Save for later

Building a Custom Version of jQuery

Packt
04 Apr 2013
9 min read
(For more resources related to this topic, see here.) Why Is It Awesome? While it's fairly common for someone to say that they use jQuery in every site they build (this is usually the case for me), I would expect it much rarer for someone to say that they use the exact same jQuery methods in every project, or that they use a very large selection of the available methods and functionality that it offers. The need to reduce file size as aggressively as possible to cater for the mobile space, and the rise of micro-frameworks such as Zepto for example, which delivers a lot of jQuery functionality at a much-reduced size, have pushed jQuery to provide a way of slimming down. As of jQuery 1.8, we can now use the official jQuery build tool to build our own custom version of the library, allowing us to minimize the size of the library by choosing only the functionality we require. For more information on Zepto, see http://zeptojs.com/. Your Hotshot Objectives To successfully conclude this project we'll need to complete the following tasks: Installing Git and Make Installing Node.js Installing Grunt.js Configuring the environment Building a custom jQuery Running unit tests with QUnit Mission Checklist We'll be using Node.js to run the build tool, so you should download a copy of this now. The Node website (http://nodejs.org/download/) has an installer for both 64 and 32-bit versions of Windows, as well as a Mac OS X installer. It also features binaries for Mac OS X, Linux, and SunOS. Download and install the appropriate version for your operating system. The official build tool for jQuery (although it can do much more besides build jQuery) is Grunt.js, written by Ben Alman. We don't need to download this as it's installed via the Node Package Manager (NPM). We'll look at this process in detail later in the project. For more information on Grunt.js, visit the official site at http://gruntjs.com. First of all we need to set up a local working area. We can create a folder in our root project folder called jquery-source. This is where we'll store the jQuery source when we clone the jQuery Github repository, and also where Grunt will build the final version of jQuery. Installing Git and Make The first thing we need to install is Git, which we'll need in order to clone the jQuery source from the Github repository to our own computer so that we can work with the source files. We also need something called Make, but we only need to actually install this on Mac platforms because it gets installed automatically on Windows when Git is installed. As the file we'll create will be for our own use only and we don't want to contribute to jQuery by pushing code back to the repository, we don't need to worry about having an account set up on Github. Prepare for Lift Off First we'll need to download the relevant installers for both Git and Make. Different applications are required depending on whether you are developing on Mac or Windows platforms. Mac developers Mac users can visit http://git-scm.com/download/mac for Git. Next we can install Make. Mac developers can get this by installing XCode. This can be downloaded from https://developer.apple.com/xcode/. Windows developers Windows users can install msysgit, which can be obtained by visiting https://code.google.com/p/msysgit/downloads/detail?name=msysGit-fullinstall-1.8.0-preview20121022.exe. Engage Thrusters Once the installers have downloaded, run them to install the applications. The defaults selected by the installers should be fine for the purposes of this mission. First we should install Git (or msysgit on Windows). Mac developers Mac developers simply need to run the installer for Git to install it to the system. Once this is complete we can then install XCode. All we need to do is run the installer and Make, along with some other tools, will be installed and ready. Windows developers Once the full installer for msysgit has finished, you should be left with a Command Line Interface (CLI) window (entitled MINGW32) indicating that everything is ready for you to hack. However, before we can hack, we need to compile Git. To do this we need to run a file called initialize.sh. In the MINGW32 window, cd into the msysgit directory. If you allowed this to install to the default location, you can use the following command: cd C:msysgitmsysgitsharemsysGit Once we are in the correct directory, we can then run initialize.sh in the CLI. Like the installation, this process can take some time, so be patient and wait for the CLI to return a flashing cursor at the $ character. An Internet connection is required to compile Git in this way. Windows developers will need to ensure that the Git.exe and MINGW resources can be reached via the system's PATH variable. This can be updated by going to Control Panel | System | Advanced system settings | Environment variables. In the bottom section of the dialog box, double-click on Path and add the following two paths to the git.exe file in the bin folder, which is itself in a directory inside the msysgit folder wherever you chose to install it: ;C:msysgitmsysgitbin; C:msysgitmsysgitmingwbin; Update the path with caution! You must ensure that the path to Git.exe is separated from the rest of the Path variables with a semicolon. If the path does not end with a semicolon before adding the path to Git.exe, make sure you add one. Incorrectly updating your path variables can result in system instability and/or loss of data. I have shown a semicolon at the start of the previous code sample to illustrate this. Once the path has been updated, we should then be able to use a regular command prompt to run Git commands. Post-installation tasks In a terminal or Windows Command Prompt (I'll refer to both simply as the CLI from this point on for conciseness) window, we should first cd into the jquery-source folder we created at the start of the project. Depending on where your local development folder is, this command will look something like the following: cd c:jquery-hotshotsjquery-source To clone the jQuery repository, enter the following command in the CLI: git clone git://github.com/jquery/jquery.git Again, we should see some activity on the CLI before it returns to a flashing cursor to indicate that the process is complete. Depending on the platform you are developing on, you should see something like the following screenshot: Objective Complete — Mini Debriefing We installed Git and then used it to clone the jQuery Github repository in to this directory in order to get a fresh version of the jQuery source. If you're used to SVN, cloning a repository is conceptually the same as checking out a repository. Again, the syntax of these commands is very similar on Mac and Windows systems, but notice how we need to escape the backslashes in the path when using Windows. Once this is complete, we should end up with a new directory inside our jquery-source directory called jquery. If we go into this directory, there are some more directories including: build: This directory is used by the build tool to build jQuery speed: This directory contains benchmarking tests src: This directory contains all of the individual source files that are compiled together to make jQuery Test: This directory contains all of the unit tests for jQuery It also has a range of various files, including: Licensing and documentation, including jQuery's authors and a guide to contributing to the project Git-specific files such as .gitignore and .gitmodules Grunt-specific files such as Gruntfile.js JSHint for testing and code-quality purposes Make is not something we need to use directly, but Grunt will use it when we build the jQuery source, so it needs to be present on our system. Installing Node.js Node.js is a platform for running server-side applications built with JavaScript. It is trivial to create a web-server instance, for example, that receives and responds to HTTP requests using callback functions. Server-side JS isn't exactly the same as its more familiar client-side counterpart, but you'll find a lot of similarities in the same comfortable syntax that you know and love. We won't actually be writing any server-side JavaScript in this project – all we need Node for is to run the Grunt.js build tool. Prepare for Lift Off To get the appropriate installer for your platform, visit the Node.js website at http://nodejs.org and hit the download button. The correct installer for your platform, if supported, should be auto-detected. Engage Thrusters Installing Node is a straightforward procedure on either the Windows or Mac platforms as there are installers for both. This task will include running the installer, which is obviously simple, and testing the installation using a CLI. Installing Node is a straightforward procedure on either the Windows or Mac platforms as there are installers for both. This task will include running the installer, which is obviously simple, and testing the installation using a CLI. On Windows or Mac platforms, run the installer and it will guide you through the installation process. I have found that the default options are fine in most cases. As before, we also need to update the Path variable to include Node and Node's package manager NPM. The paths to these directories will differ between platforms. Mac Mac developers should check that the $PATH variable contains a reference to usr/local/bin. I found that this was already in my $PATH, but if you do find that it's not present, you should add it. For more information on updating your $PATH variable, see http://www.tech-recipes.com/rx/2621/os_x_change_path_environment_variable/. Windows Windows developers will need to update the Path variable, in the same way as before, with the following paths: C:Program Filesnodejs; C:UsersDesktopAppDataRoamingnpm; Windows developers may find that the Path variable already contains an entry for Node so may just need to add the path to NPM. Objective Complete — Mini Debriefing Once Node is installed, we will need to use a CLI to interact with it. To verify Node has installed correctly, type the following command into the CLI: node -v The CLI should report the version in use, as follows: We can test NPM in the same way by running the following command: npm -v
Read more
  • 0
  • 0
  • 3322

article-image-using-third-party-plugins-non-native-plugins
Packt
30 Aug 2013
4 min read
Save for later

Using third-party plugins (non-native plugins)

Packt
30 Aug 2013
4 min read
(For more resources related to this topic, see here.) We want to focus on a particular case here, because we have already seen how to add a new property, and for some components, we can easily add the plugins or features property, and then add the plugin configuration. But the components that have native plugins supported by the API do not allow us to do so, like for instance, the grid panel from Ext JS: We can only use the plugins and features that are available within Sencha Architect. What if we want to use a third-party plugin or feature such as the Filter Plugin? It is possible, but we need to use an advanced feature from Sencha Architect, which is "creating overrides". A disclaimer about overrides: this has to be avoided. Whenever you can use a set method to change a property, use it. Overrides should be your last resource and they should be used very carefully, because if you do not use them carefully, you can change the behavior of a component and something may stop working. But we will demonstrate how to do it in a safe way! We will use the BooksGrid as an example in this topic. Let's say we need to use the Filter Plugin on it, so we need to create an override first. To do it, select the BooksGrid from the project inspector, open the code editor, and click on the Create Override button (Step 1). Sencha Architect will display a warning (Step 2). We can click on Yes to continue: The code editor will open (Step 3) the override class so we can enter our code. In this case, we will have complete freedom to do whatever we need to on this file. So let's add the features() function with the declaration of the plugin and also the initComponent()function as shown in the following screenshot (Step 4): One thing that is very important is that we must call the callParent()function (callOverriden()is deprecated already in Ext JS 4.1 and later versions) to make sure we will continue to have all the original behavior of the component (in this case the BooksGridclass). The only thing we want to do is to add a new feature to it. And we are done with the override! To go back to the original class we can use the navigator as shown in the following screenshot: Notice that requires was added to the class Packt.view.override. BooksGrid, which is the class we just wrote. The next step is to add the plugin on the class requires. To do so, we need to select the BooksGrid, go to the config panel, and add the requires with the name of the plugin (Ext.ux.grid.FiltersFeature): Some developers like to add the plugin file directly as a JavaScript file on app.html/index.html. Sencha provides the dynamic loading feature so let's take advantage of it and use it! First, we cannot forget to add the uxfolder with the plugin on the project root folder as shown in the following screenshot: Next, we need to set the application loader. Select the Application from the project inspector (Step 5), then go to the config panel, locate the Loader Config property, click on the +icon (Step 6), then click on the arrow icon (Step 7). The details of the loader will be available on the config panel. Locate the paths property and click on it (Step 8). The code editor will be opened with the loader path's default value, which is {"Ext": "."}(Step 9). Do not remove it; simply add the path of the Ext.uxnamespace which is the uxfolder (Step 10): And we are almost done! We need to add the filterable option in each column we want to allow the user to filter its values (Step 11): we can use the config panel to add a new property (we need to select the desired column from the project inspector first—always remember to do this). And then, we can choose what type of property we want to add (Step 12 and Step 14). For example, we can add filterable: true(Step 13) for the id column and filterable: {type: 'string'}(Step 15 and Step 16) to the Name column as shown in the following screenshot: And the plugin is ready to be used! Summary In this article we learned some useful tricks that can help in our everyday tasks while working with Sencha projects using Sencha Architect. Also we covered advanced topics such as creating overrides to use third party plugins and features and implement multilingual apps. Resources for Article: Further resources on this subject: Sencha Touch: Layouts Revisited [Article] Sencha Touch: Catering Form Related Needs [Article] Creating a Simple Application in Sencha Touch [Article]
Read more
  • 0
  • 0
  • 3320

article-image-polygon-modeling-handgun-using-blender-3d-249-part-1
Packt
30 Nov 2009
3 min read
Save for later

Polygon Modeling of a Handgun using Blender 3D 2.49: Part 1

Packt
30 Nov 2009
3 min read
With the base model created, we will be able to analyze the shape of our model and evaluate the next steps of the project. We can even decide to make changes to the project because new ideas may appear when we see the object in 3D rather than in 2D. Starting with a background image The first step to start the modeling is to add the reference image as the background of the Blender 3D view. To do that, we can go to the View menu in the 3D view and choose Background Image. The background image in Blender appears only when we are at an orthogonal or Camera view. The background image is a simple black and white drawing of the weapon, but it will be a great reference for modeling. Before we go any further, it's important to point out a few things about the Background Image menu. We can make some adjustments to the image if it doesn't fit our Blender view: Use: With this button turned on, we will use the image as a background. If you want to hide the image, just turn it off and the image will disappear. Blend: The blend slider will control the transparency of the image. If you feel that the image is actually blocking your view of the whole model, making it a bit transparent may help. Size: As the name says, we can control the scale of the image. X and Y offset: With this option, we will be able to move the image in the X or Y axis to place it in a specific location. After clicking on the Use button, just hit the load button and choose the image to be used as a reference. Since you don't have the image used in this example, visit the Packt web site and download the project files from Support. If you've never used a reference image in Blender, it is important to note that the reference images appear only in 3D view when we are using the orthographic view or the camera view mode. It works only in the top, right, left, front, and other orthographic views. If you hit 5 and change the view to perspective, the image will disappear. By using the middle mouse button or the scroll to rotate the view, the image disappears. However, it's still there and we can see the image again by changing the view to an orthogonal or camera view. Make the image more transparent by using the Blend control. It will help in focusing on the model instead of the image. A value of 0.25 will be enough to help in the modeling without causing confusion.
Read more
  • 0
  • 0
  • 3319

article-image-php-magic-features
Packt
12 Oct 2009
5 min read
Save for later

PHP Magic Features

Packt
12 Oct 2009
5 min read
In this article by Jani Hartikainen, we'll look at PHP's "magic" features: Magic methods, which are class methods with specific names, are used to perform various specialized tasks. They are grouped into two: overloading methods and non-overloading methods. Overloading magic methods are used when your code attempts to access a method or a property which does not exist. Non-overloading methods perform other tasks. Magic functions, which are similar to magic methods, but are just plain functions outside any class. Currently there is only one magic function in PHP. Magic constants, which are similar to constants in notation, but act more like "dynamic" constants - their value depends on where you use them. We'll also look at some practical examples of using some of these, and lastly we'll check out what new features PHP 5.3 is going to add. Magic methods For starters, let's take a look at the magic methods PHP provides. We will first go over the non-overloading methods. __construct and __destruct class SomeClass { public function __construct() { } public function __destruct() { }} The most common magic method in PHP is __construct. In fact, you might not even have thought of it as a magic method at all, as it's so common.  __construct is the class constructor method, which gets called when you instantiate a new object using the new keyword, and any parameters used will get passed to __construct. $obj = new SomeClass(); __destruct is __construct's "pair". It is a class destructor, which is rarely used in PHP, but still it is good to know about  its existence. It gets called when your object falls out of scope or is garbage collected. function someFunc() { $obj = new SomeClass(); //when the function ends, $obj falls out of scope and SomeClass __destruct is called } someFunc(); If you make the constructor private or protected, it means that the class cannot be instantiated, except inside a method of the same class. You can use this to your advantage, for example to create a singleton. __clone class SomeClass { public $someValue; public function __clone() { $clone = new SomeClass(); $clone->someValue = $this->someValue; return $clone; }} The __clone method is called when you use PHP's clone keyword, and is used to create a clone of the object. The purpose is that by implementing __clone, you can define a way to copy objects. $obj1 = new SomeClass();$obj1->someValue = 1;$obj2 = clone $obj1;echo $obj2->someValue;//echos 1 Important: __clone is not the same as =. If you use = to assign an object to another variable, the other variable will still refer to the same object as the first one! If you use the clone keyword, the purpose is to return a new object with similar state as the original. Consider the following: $obj1 = new SomeClass();$obj1->someValue = 1;$obj2 = $obj1;$obj3 = clone $obj1;$obj1->someValue = 2; What are the values of the someValue property in $obj2 and $obj3 now? As we have used the assign operator to create $obj2, it refers to the same object as $obj1, thus $obj2->someValue is 2. When creating $obj3, we have used the clone keyword, so the __clone method was called. As __clone creates a new instance, $obj3->someValue is still the same as it was when we cloned $obj1: 1. If you want to disable cloning, you can make __clone private or protected. __toString class SomeClass { public function __toString() { return 'someclass'; }} The __toString method is called when PHP needs to convert class instances into strings, for example when echoing: $obj = new SomeClass();echo $obj;//will output 'someclass' This can be a useful example to help you identify objects or when creating lists. If we have a user object, we could define a __toString method which outputs the user's first and last names, and when we want to create a list of users, we could simply echo the objects themselves. __sleep and __wakeup class SomeClass { private $_someVar; public function __sleep() { return array('_someVar'); } public function __wakeup() { }} These two methods are used with PHP's serializer: __sleep is called with serialize(), __wakeup is called with unserialize(). Note that you will need to return an array of the class variables you want to save from __sleep. That's why the example class returns an array with _someVar in it: Without it, the variable will not get serialized. $obj = new SomeClass();$serialized = serialize($obj);//__sleep was calledunserialize($serialized);//__wakeup was called You typically won't need to implement __sleep and __wakeup, as the default implementation will serialize classes correctly. However, in some special cases it can be useful. For example, if your class stores a reference to a PDO object, you will need to implement __sleep, as PDO objects cannot be serialized. As with most other methods, you can make __sleep private or protected to stop serialization. Alternatively, you can throw an exception, which may be a better idea as you can provide a more meaningful error message. An alternative to __sleep and __wakeup is the Serializable interface. However, as its behavior is different from these two methods, the interface is outside the scope of this article. You can find info on it in the PHP manual. __set_state class SomeClass { public $someVar; public static function __set_state($state) { $obj = new SomeClass(); $obj->someVar = $state['someVar']; return $obj; }} This method is called in code created by var_export. It gets an array as its parameter, which contains a key and value for each of the class variables, and it must return an instance of the class. $obj = new SomeClass();$obj->someVar = 'my value';var_export($obj); This code will output something along the lines of: SomeClass::__set_state(array('someVar'=>'my value')); Note that var_export will also export private and protected variables of the class, so they too will be in the array.
Read more
  • 0
  • 0
  • 3314
article-image-learning-data-analytics-r-and-hadoop
Packt
20 Nov 2013
6 min read
Save for later

Learning Data Analytics with R and Hadoop

Packt
20 Nov 2013
6 min read
(For more resources related to this topic, see here.) Understanding the data analytics project life cycle While dealing with the data analytics projects, there are some fixed tasks that should be followed to get the expected output. So here we are going to build a data analytics project cycle, which will be a set of standard data-driven processes to lead data to insights effectively. The defined data analytics processes of a project life cycle should be followed by sequences for effectively achieving the goal using input datasets. This data analytics process may include identifying the data analytics problems, designing, and collecting datasets, data analytics, and data visualization. The data analytics project life cycle stages are seen in the following diagram: Let's get some perspective on these stages for performing data analytics. Identifying the problem Today, business analytics trends change by performing data analytics over web datasets for growing business. Since their data size is increasing gradually day by day, their analytical application needs to be scalable for collecting insights from their datasets. With the help of web analytics; we can solve the business analytics problems. Let's assume that we have a large e-commerce website, and we want to know how to increase the business. We can identify the important pages of our website by categorizing them as per popularity into high, medium, and low. Based on these popular pages, their types, their traffic sources, and their content, we will be able to decide the roadmap to improve business by improving web traffic, as well as content. Designing data requirement To perform the data analytics for a specific problem, it needs datasets from related domains. Based on the domain and problem specification, the data source can be decided and based on the problem definition; the data attributes of these datasets can be defined. For example, if we are going to perform social media analytics (problem specification), we use the data source as Facebook or Twitter. For identifying the user characteristics, we need user profile information, likes, and posts as data attributes. Preprocessing data In data analytics, we do not use the same data sources, data attributes, data tools, and algorithms all the time as all of them will not use data in the same format. This leads to the performance of data operations, such as data cleansing, data aggregation, data augmentation, data sorting, and data formatting, to provide the data in a supported format to all the data tools as well as algorithms that will be used in the data analytics. In simple terms, preprocessing is used to perform data operation to translate data into a fixed data format before providing data to algorithms or tools. The data analytics process will then be initiated with this formatted data as the input. In case of Big Data, the datasets need to be formatted and uploaded to Hadoop Distributed File System (HDFS) and used further by various nodes with Mappers and Reducers in Hadoop clusters. Performing analytics over data After data is available in the required format for data analytics algorithms, data analytics operations will be performed. The data analytics operations are performed for discovering meaningful information from data to take better decisions towards business with data mining concepts. It may either use descriptive or predictive analytics for business intelligence. Analytics can be performed with various machine learning as well as custom algorithmic concepts, such as regression, classification, clustering, and model-based recommendation. For Big Data, the same algorithms can be translated to MapReduce algorithms for running them on Hadoop clusters by translating their data analytics logic to theMapReduce job which is to be run over Hadoop clusters. These models need to be further evaluated as well as improved by various evaluation stages of machine learning concepts. Improved or optimized algorithms can provide better insights. Visualizing data Data visualization is used for displaying the output of data analytics. Visualization is an interactive way to represent the data insights. This can be done with various data visualization softwares as well as R packages. R has a variety of packages for the visualization of datasets. They are as follows: ggplot2: This is an implementation of the Grammar of Graphics by Dr. Hadley Wickham (http://had.co.nz/). For more information refer http://cran.r-project.org/web/packages/ggplot2/. rCharts: This is an R package to create, customize, and publish interactive JavaScript visualizations from R by using a familiar lattice-style plotting interface by Markus Gesmann and Diego de Castillo. For more information refer http://ramnathv.github.io/rCharts/. Some popular examples of visualization with R are as follows: Plots for facet scales (ggplot): The following figure shows the comparison of males and females with different measures; namely, education, income, life expectancy, and literacy, using ggplot: Dashboard charts: This is an rCharts type. Using this we can build interactive animated dashboards with R. Understanding data analytics problems In this section, we have included three practical data analytics problems with various stages of data-driven activity with R and Hadoop technologies. These data analytics problem definitions are designed such that readers can understand how Big Data analytics can be done with the analytical power of functions, packages of R, and the computational powers of Hadoop. The data analytics problem definitions are as follows: Exploring the categorization of web pages Computing the frequency of changes in the stock market Predicting the sale price of a blue book for bulldozers (case study) Exploring web pages categorization This data analytics problem is designed to identify the category of a web page of a website, which may categorized popularity wise as high, medium, or low (regular), based on the visit count of the pages. While designing the data requirement stage of the data analytics life cycle, we will see how to collect these types of data from Google Analytics. Identifying the problem As this is a web analytics problem, the goal of the problem is to identify the importance of web pages designed for websites. Based on this information, the content, design, or visits of the lower popular pages can be improved or increased. Designing data requirement In this section, we will be working with data requirement as well as data collection for this data analytics problem. First let's see how the requirement for data can be achieved for this problem. Since this is a web analytics problem, we will use Google Analytics data source. To retrieve this data from Google Analytics, we need to have an existent Google Analytics account with web traffic data stored on it. To increase the popularity, we will require the visits information of all of the web pages. Also, there are many other attributes available in Google Analytics with respect to dimensions and metrics.
Read more
  • 0
  • 0
  • 3311

article-image-jboss-jbpm-concepts-and-jbpm-process-definition-language-jpdl
Packt
22 Oct 2009
6 min read
Save for later

JBoss jBPM Concepts and jBPM Process Definition Language (jPDL)

Packt
22 Oct 2009
6 min read
JBoss jBPM Concepts JBoss jBPM is built around the concept of waiting. That may sound strange given that software is usually about getting things done, but in this case there is a very good reason for waiting. Real-life business processes cut across an organization, involve numerous humans and multiple systems, and happen over a period of time. In regular software, the code that makes up the system is normally built to "do all these tasks as soon as possible". This wouldn't work for a business process, as the people who need to take part in the process won't always want or be able to "do their task now". The software needs some way of waiting, until the process actor is ready to do their activity. Then once they have done their activity, the software needs to know what is the next activity in the chain and then wait for the next process actor to get round to doing their bit. The orchestration of this sequence of "wait, work, wait, work" is handled by the JBoss jBPM engine. The jBPM engine looks up our process definition and works out which way it should direct us through the process. We know the "process definition" better as our graphical process map. jBPM Process Definition Language—jPDL We will introduce the key terms and concepts here to get the ball rolling. We won't linger too long over the definitions, as the best way to fix the terminology in the brain is to see it used in context. At this point, we will introduce some core terminologies for a better understanding. The visual process map in the Designer is an example of what the JBoss jBPM project calls "Graph Oriented Programming". Instead of programming our software in code, we are programming our software using a visual process map: referred to as a "directed graph". This directed graph is also defined in the XML representation of the process we saw in the Source view. The graph plus the XML is a notation set, which is properly called jPDL, the "jBPM Process Definition Language". A process definition specified in jPDL is composed of "nodes", "transitions", and "actions", which together describe how an "instance" of the process should traverse the directed graph. During execution of the process, as the instance moves through the directed graph, it carries through a "token", which is a pointer to the node of the graph at which the instance is currently waiting. A "signal" tells the token which "transition" it should take from the node: signals specify which path to take through the process. Let's break this down a little bit with some more detail. Nodes A node in jPDL is modeled visually as a box, and hence looks very similar to the activity box we are used to from our workflow and activity flow diagrams. The concept of "nodes" does subtly differ from that of activities, however. In designing jPDL, the jBPM team have logically separated the idea of waiting for the result of an action from that of doing an action. They believe that the term "activity" blurs the line between these two ideas, which causes problems when trying to implement the logic behind a business process management system. For example, both "Seek approval" and "Record approval" would be modeled as activities on an activity flow diagram, but the former would be described as a "state" and the latter as an "action" in jPDL: the state element represents the concept of waiting for the action to happen, moving the graph to the next state. "Node" is therefore synonymous with "state" in jPDL. "Actions" are bits of code that can be added by a developer to tell the business process management system to perform an action that needs to be done by the system: for example, recording the approval of a holiday request in a database. Actions aren't mapped visually, but are recorded in the XML view of the process definition. We'll cover actions a bit later. There are different types of node, and they are used to accomplish different things. Let's quickly go through them so we know how they are used. Tasks A task node represents a task that is to be performed by humans. If we model a task node on our graph, it will result in a task being added to the task list of the person assigned to that task, when the process is executed. The process instance will wait for the person to complete that task and hand back the outcome of the task to the node. State A state node simply tells the process instance to wait, and in contrast to a task node, it doesn't create a task in anybody's task list. A state node would normally be used to model the behavior of waiting for an external system to provide a response. This would typically be done in combination with an Action, which we'll talk about soon. The process instance will resume execution when a signal comes back from the external system. Forks and Joins We can model concurrent paths of execution in jPDL using forks and joins. For example, the changes we made to our model to design our To Be process can be modeled using forks and joins to represent the parallel running of activities. We use a Fork to split the path of execution up, and then join it back together using a Join: the process instance will wait at the Join until the parallel tasks on both sides are completed. The instance can't move on until both chains of activities are finished. jBPM creates multiple child tokens related to the parent token for each path of execution. Decision In modeling our process in jBPM, there are two distinct types of decision with which we need to concern ourselves. Firstly, there is the case where the process definition itself needs to make a decision, based on data at its disposal, and secondly, where a decision made by a human or an external system is an input to the process definition. Where the process definition itself will make the decision, we can use a decision node in the model. Where the outcome of the decision is simply input into the process definition at run time, we should use a state node with multiple exiting transitions representing the possible outcomes of the decision.
Read more
  • 0
  • 1
  • 3308

article-image-installing-rhev-manager
Packt
23 Sep 2014
15 min read
Save for later

Installing RHEV Manager

Packt
23 Sep 2014
15 min read
This article by Pradeep Subramanian, author of Getting Started with Red Hat Enterprise Virtualization, describes setting up RHEV-M, including the installation, initial configuration, and connection to the administrator and user portal of the manager web interface. (For more resources related to this topic, see here.) Setting up the RHEL operating system for the manager Prior to starting the installation of RHEV-M, please make sure all the prerequisite are met to set up RHEV environment. Consider the following when setting up RHEL OS for RHEV-M: Install Red Hat Enterprise Linux 6 with latest minor update of 5, and during package selection step, select minimal or basic server as an option. Don't select any custom package. The hostname should be set to FQDN. Set up basic networking; use of static IP is recommended for your manager with a default gateway and primary and secondary DNS client configured. SELinux and iptables are enabled by default as part of the operating system installation. For more security, it's highly recommended to keep it on. To disable SELinux on Red Hat Enterprise Linux, please run the following command as the root user: # setenforce Permissive This command will switch off SELinux enforcement temporarily until the machine is rebooted. If you would like to permanently disable it, edit /etc/sysconfig/selinux and enter SELINUX=disabled. Registering with Red Hat Network To install RHEV-M, you need to first register your manager machine with Red Hat Network and subscribe to the relevant channels. You need to connect your machine to the Red Hat Network with a valid account with access to the relevant software channels to register your machine and deploy RHEV-M packages. If your environment does not have access to the Red Hat Network, you can perform an offline installation of RHEV-M. For more information, please refer to https://access.redhat.com/site/articles/216983. To register your machine with the Red Hat Network using RHN Classic, please run the following command from the shell and follow the onscreen instructions: # rhn_register This command will register your manager machine to the parent channel of your operating system version. It's strongly recommended to use Red Hat Subscription Manager to register and subscribe to the relevant channel. To use Red Hat Subscription Manager, please refer to the Subscribing to the Red Hat Enterprise Virtualization Manager Channels using Subscription Manager section from the RHEV 3.3 installation guide at https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Virtualization/3.3/html/Installation_Guide/index.html. After successful registration of your manager machine to the Red Hat Network, subscribe the manager machine using the following command to subscribe to the relevant channels. Then download and install the manager-related software packages. The following command will prompt you to enter your Red Hat Network login credentials: # rhn-channel -a -c rhel-x86_64-server-6-rhevm-3.3 -c rhel-x86_64-server-supplementary-6 -c jbappplatform-6-x86_64-server-6-rpm Username: "yourrhnlogin" Password: XXXX To cross-check whether your manager machine is registered with Red Hat Network and subscribed to the relevant channels, please run the following command. This will return all the channels mentioned earlier plus the base channel of your operating system version, as shown in the following yum command output: # yum repolist repo id repo name status jbappplatform-6-x86_64-server-6-rpm Red Hat JBoss EAP (v 6) for 6Server x86_64 1,415 rhel-x86_64-server-6 Red Hat Enterprise Linux Server (v. 6 for 64-bit x86_64) 12,662 rhel-x86_64-server-6-rhevm-3.3 Red Hat Enterprise Virtualization Manager (v.3.3 x86_64) 164 rhel-x86_64-server-supplementary-6 RHEL Server Supplementary (v. 6 64-bit x86_64) 370 You are now ready to start downloading and installing the software required to set up and run your RHEV-M. Installing the RHEV-Manager packages Update your base Red Hat Enterprise Linux operating system to the latest up-to-date version by running the following command: # yum -y upgrade Reboot the machine if the upgrade installed the latest version of the kernel. After a successful upgrade, run the following command to install RHEV-M and its dependent packages: # yum -y install rhevm There are a few conditions you need to consider before configuring RHEV-M: We need a working DNS for forward and reverse lookup of FQDN. We are going to use the Red Hat IdM server configured with the DNS role in the rest of the article for domain name resolution of the entire virtualization infrastructure. Refer to the Red Hat Identity Management Guide for more information on how to add forward and reverse zone records to the configured IdM DNS at https://access.redhat.com/documentation/en- US/Red_Hat_Enterprise_Linux/6/html/Identity_Management_Guide/Working_with_DNS.html. You can't install Identity Management software on the same box where the manager is going to be deployed due to some package conflicts. To store ISO images of operating systems in order to create a virtual machine, you need Network File Server (NFS) with a planned NFS export path. If your manager machine has sufficient storage space to host all your ISOs, you can set up the ISO domain while configuring the manager to set up the NFS share automatically through the installer to store all your ISO images. If you have an existing NFS server, it's recommended to use a dedicated export for the ISO domain to store the ISO images instead of using the manager server to serve the NFS service. Here we are going to use a dedicated local mount point named /rhev-iso-library on the RHEV Manager box to store our ISO images to provision the virtual machine. Note that the mount point should be empty and only contain the user and group ownership and permission sets before running the installer: # chown -R 36:36 /rhev-iso-library ; chmod 0755 /rhev-iso-library It will also be useful to have the following information at hand: Ports to be used for HTTP and HTTPS communication. FQDN of the manager. A reverse lookup is performed on your hostname. At the time of writing this article, RHEV supported only the PostgreSQL database for use with RHEV-M. You can use a local database or remote database setup. Here we are going to use the local database. In the case of a remote database setup, keep all database login credentials ready. Please refer to the Preparing a PostgreSQL Database for Use with Red Hat Enterprise Virtualization Manager section for detailed information on setting up a remote database to use with manager at https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Virtualization/3.3/html-single/Installation_Guide/index.html#Preparing_a_Postgres_Database_Server_for_use_with_Red_Hat_Enterprise_Virtualization_Manager. Password for internal admin account of RHEV-M. Organization name for the RHEV-M SSL certificate. Leave the default storage type to NFS for the initial default data center. We will create a new data center in the latter stage of our setup. Provide the file system path and display name for NFS ISO library configuration, so that the manager will configure NFS of the supplied filesystem path, and make it visible by the display name under the Storage tab section on administration portal of RHEV-M. Running the initial engine setup Once you're prepared with all the answers to the questions we discussed in the previous section, it's time to run the initial configuration script called engine-setup to perform the initial configuration and setting up of RHEV-M. The installer will ask you several questions, which have been discussed above, and based on your input, it will configure your RHEV-M. Leave the default settings as they are and press Enter if you feel the installer's default answers are appropriate to your setup. Once the installer takes in all your input, it will ask you for the final confirmation of your supplied configuration setting; type in OK and press Enter to continue the setup. For better understanding, please refer to the following output of the engine-setup installer while setting up a lab for this article. Log in to manager as the root user, and from the shell of your Manager machine, run the following engine-setup command: # engine-setup Once you execute this command, engine-setup performs the following set of tasks on the system: First check whether any updates are available for this system. Accept the default Yes and proceed further: Checking for product updates and update if available. Enter Default Yes. Set the hostname of the RHEV-M system. The administration portal web access will get bound to the FQDN entered here: Host fully qualified DNS name of this server [rhevmanager.example.com]: Set up the firewall rule on the manager system, and this will backup your existing firewall rule configured on the manager system if any: Do you want Setup to configure the firewall? (Yes, No) [Yes]: No Local will set up the PostgreSQL database instance on the manager system; optionally, you can choose Remote to use the existing remote PostgreSQL database instance to use with manager: Where is the database located? (Local, Remote) [Local]: If you selected Local, you will get an option to customize the PostgreSQL database setup by choosing the relevant option: Would you like Setup to automatically configure PostgreSQL, or prefer to perform that manually? (Automatic, Manual) [Automatic]: Set up the internal admin user password to access the manager web interface for initial setup of the virtualization infrastructure: Engine admin password: Confirm engine admin password: RHEV supports the use of clusters to manage Gluster storage bricks in addition to virtualization hosts. Choosing both will give the flexibility to use hypervisor hosts to host virtual machines as well as other sets of hypervisor hosts to manage Gluster storage bricks in your RHEV environment: Application mode (Both, Virt, Gluster) [Both]: Engine installer creates a data center named Default as part of the initial setup. The following step will ask you to select the type of storage to be used with the data center. Mixing storage domains of different types is not supported in the 3.3 release, but it is supported in the latest 3.4 release. Choose the default NFS option and proceed further. We are going to create a new data center, using the administration portal, from scratch after the engine setup and then select the storage type as ISCSI for the rest of this article: Default storage type: (NFS, FC, ISCSI, POSIXFS) [NFS]: The manager uses certificates to communicate securely with its hosts. Provide your organization's name for the certificate: Organization name for certificate [example.com]: The manager uses the Apache web server to present a landing page to users. The engine-setup script can make the landing page of the manager the default page presented by Apache: Do you wish to set the application as the default page of the web server? (Yes, No) [Yes]: By default, external SSL (HTTPS) communications with the manager are secured with the self-signed certificate created in the PKI configuration stage for secure communication with hosts. Another certificate may be chosen for external HTTPS connections without affecting how the manager communicates with hosts: Setup can configure apache to use SSL using a certificate issued from the internal CA. Do you wish Setup to configure that, or prefer to perform that manually? (Automatic, Manual) [Automatic]: Choose Yes to set up an NFS share on the manager system and provide the export path to be used to dump the ISO images in a later part. Finally, label the ISO domain with a name that will be unique and easily identifiable on the Storage tab of the administration portal: Configure an NFS share on this server to be used as an ISO Domain? (Yes, No) [Yes]: Local ISO domain path [/var/lib/exports/iso]: /rhev-iso-library Local ISO domain name [ISO_DOMAIN]: ISO_Datastore The engine-setup script can optionally configure a WebSocket proxy server in order to allow users to connect with virtual machines via the noVNC or HTML 5 consoles: Configure WebSocket Proxy on this machine? (Yes, No) [Yes]: The final step will ask you to provide proxy server credentials if the manager system is hosted behind the proxy server to access the Internet. RHEV supports vRed Hat Access Plugin, which will help you collect the logs and open a service request with Red Hat Global Support Services from the administration portal of the manager: Would you like transactions from the Red Hat Access Plugin sent from the RHEV Manager to be brokered through a proxy server? (Yes, No) [No]: Finally, if you feel all the input and configurations are satisfactory, press Enter to complete the engine setup. It will show you the configuration preview, and if you feel satisfied, press OK: Please confirm installation settings (OK, Cancel) [OK]: After the successful setup of RHEV-M, you can see the summary, which will show various bits of information such as how to access the admin portal of RHEV-M, the installed logs, the configured iptables firewall, the required ports, and so on. Connecting to the admin and user portal 006C Now access the admin portal, as shown in the following screenshot, using the following URLs: http://rhevmanager.example.com:80/ovirt-engine https://rhevmanager.example.com:443/ovirt-engine Use the user admin and password specified during the setup to log in to the oVirt engine (also called RHEV-M). Click on Administration Portal and log in using the credentials you set up for the admin account during the engine setup. Then click on User Portal and log in using the credentials you set up for the admin account during the engine setup. You will see a difference in the portal with a very trimmed-down user interface that is useful for self-service. We will see how to integrate the manager with other active directory services and efficiently use the user portal for self-service consumption later in the article. RHEV reporting RHEV bundles two optional components. The first is the history management database, which holds the historical information of various virtualization resources such as data centers, clusters, hosts, virtual machines, and others so that any other external application can consume them for reporting. The second optional component is the customized JasperServer and JasperReports. JasperServer is an open source reporting tool capable of generating and exporting reports in various formats such as PDF, Word, and CSV for end user consumption. To enable the reporting functionality, you need to install the specific components that we discussed. For simplicity, we are installing both the components at one go using the command described in the following section. Installing the RHEV history database and report server To install the history database and report servers, execute the following command: # yum install rhevm-dwh rhevm-reports Once you have installed the reporting components, you need to start with setting up the RHEV history database by using the following command: # rhevm-dwh-setup This will momentarily stop and start the oVirt engine service during the setup. Further, it will ask you to create a read-only user account to access the history database. Create it if you want to allow remote access to the history database and follow the onscreen instructions and finish the setup. Once the oVirt engine history database (also known as the RHEV Manager history database) is created, move on to setting up the report server. From the RHEV-M server, run the following command to set up the reporting server: # rhevm-reports-setup #setup will prompt to restart ovirt-engine service. In order to proceed the installer must stop the ovirt-engine service Would you like to stop the ovirt-engine service? (yes|no): #The command then performs a number of actions before prompting you to set the password for the Red Hat Enterprise Virtualization Manager Reports administrative users (rhevm-admin and superuser) Please choose a password for the reports admin user(s) (rhevm-admin and superuser): Downloading the example code You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you. Follow the onscreen instructions and enter Yes to stop the oVirt-engine and set up a password for the default internal super user account called rhevm-admin to access and manage the report portal and proceed further with the setup. Note that this user is different from the internal admin account we set up during the engine setup of RHEV-M. The rhevm-admin user is used only for accessing and managing the report portal, not for the admin or user portal. Accessing the RHEV report portal After the successful installation and initial configuration setup of the report portal, you can access it by https://rhevmanager.example.com/rhevm-reports/login.html from your client machine. You can also access the report portal from the manager web interface by clicking on the Reports Portal hyperlink, which will redirect you to the report portal. Log in with rhevm-admin and the password credentials we set while running the RHEV-M report setup script in the previous section to generate reports and create and manage users to access the report portal. Initially, most of the report portal is empty since we are yet to set up and create the virtual infrastructure. It will take at least a day or two after the complete virtualization infrastructure setup to view various resources and generate reports. To learn more about using and gathering reports using the report portal, please refer to Reports, History Database Reports, and Dashboards at https://access.redhat.com/documentation/en-US/Red_Hat_Enterprise_Virtualization/3.3/html/Administration_Guide/chap-Reports_History_Database_Reports_and_Dashboards.html. Summary In this article, we discussed setting up our basic virtualization infrastructure, which includes installing RHEV-M and report server and connecting to various portals such as admin, user, and report portal. Resources for Article: Further resources on this subject: Designing a XenDesktop® Site [article] XenMobile™ Solutions Bundle [article] Installing Virtual Desktop Agent – server OS and desktop OS [article]
Read more
  • 0
  • 0
  • 3307
article-image-jquery-mobile-collapsible-blocks-and-theming-content
Packt
18 Jul 2011
4 min read
Save for later

jQuery Mobile: Collapsible Blocks and Theming Content

Packt
18 Jul 2011
4 min read
jQuery Mobile First Look Discover the endless possibilities offered by jQuery Mobile for rapid Mobile Web Development          The reader would benefit by referring the previous article on How to Use jQuery Mobile Grid and Columns Layout. A note on collapsible blocks On a completely different note, jQuery Mobile provides an easy-to-use and visually-appealing solution to hide and show content, namely, the so-called collapsible blocks. Collapsible blocks should be already well-known to the web designers out there, and they have gained in popularity especially after the advent of JavaScript libraries and frameworks like jQuery, which have made writing the necessary code a matter of minutes to obtain a pane which shows its content once a button (or any kind of element, actually) is clicked. The following screenshot shows how jQuery Mobile renders, by default, any collapsible block we include into our web page: So, how do we create a (set of) collapsible block(s)? Collapsible blocks are obtained by assigning a container the data-role="collapsible" attribute. As easy as that. <div data-role="collapsible"> <!-- this is a collapsible block --> </div> The jQuery Mobile framework needs a heading element to be present inside the container. The heading (which can be from h1 through h6) will be styled like a clickable button, and a plus (+) symbol will be added to its left to indicate it's expandable. Once we click the header/button and the content shows, a minus (-) symbol will replace the plus to indicate it's collapsible. Where do I put the heading? The heading can be placed anywhere inside the container. Remember that jQuery Mobile will use as a header the very first h-element it finds inside the container, and remove it from its original position. Once the required header is provided, you can add any other h-element to the container and it will not be processed (that is, it will behave like a normal heading would). <div data-role="collapsible"> <h3>Collapsible block header</h3> <p>Lorem ipsum dolor sit amet etc....</p> </div> We used an h3 heading in this example, but any other heading would have looked just the same: jQuery Mobile changes completely the style of the heading to match a button's style. We can specify whether we want a collapsible block to be expanded on page load or not by adding the data-collapsed="true" attribute to the container: <div data-role="collapsible" data-collapsed="true"> <h3>This block will be collapsed (does not show content)</h3> <p>Lorem ipsum dolor sit amet etc....</p> </div> <div data-role="collapsible"> <h3>This block will expand on page load</h3> <p>This text is visible right away!</p> </div> Nested collapsible blocks Collapsible blocks can also be nested, resulting in a series of blocks which control various paragraphs and content: To create a set of nested collapsible blocks, we only need to insert a block into another block, which will be its container: <!-- Top level collapsible block --> <div data-role="collapsible"> <h3>Collapsible block header</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> <!-- nested collapsible block --> <div data-role="collapsible"> <h3>Nested collapsible block</h3> <p>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p> </div> </div> We may have any number of collapsible blocks nested; for example, here is another one: <!-- Top level collapsible block --> <div data-role="collapsible"> <h3>Collapsible block header</h3> <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</p> <!-- nested collapsible block --> <div data-role="collapsible"> <h3>Nested collapsible block</h3> <p>Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos.</p> <!-- nested into a nested block --> <div data-role="collapsible"> <h3>Nested into a nested collapsible block</h3> <p>Integer lectus eros, accumsan eget ultrices vel, sagittis volutpat odio.</p> </div> </div> </div>  
Read more
  • 0
  • 0
  • 3305

article-image-python-unit-testing-doctest
Packt
15 Sep 2010
12 min read
Save for later

Python: Unit Testing with Doctest

Packt
15 Sep 2010
12 min read
What is Unit testing and what it is not? The title of this section, begs another question: "Why do I care?" One answer is that Unit testing is a best practice that has been evolving toward its current form over most of the time that programming has existed. Another answer is that the core principles of Unit testing are just good sense; it might actually be a little embarrassing to our community as a whole that it took us so long to recognize them. Alright, so what is Unit testing? In its most fundamental form, Unit testing can be defined as testing the smallest meaningful pieces of code (such pieces are called units), in such a way that each piece's success or failure depends only on itself. For the most part, we've been following this principle already. There's a reason for each part of this definition: we test the smallest meaningful pieces of code because, when a test fails, we want that failure to tell where the problem is us as specifically as possible. We make each test independent because we don't want a test to make any other test succeed, when it should have failed; or fail when it should have succeeded. When tests aren't independent, you can't trust them to tell you what you need to know. Traditionally, automated testing is associated with Unit testing. Automated testing makes it fast and easy to run unit tests, which tend to be amenable to automation. We'll certainly make heavy use of automated testing with doctest and later with tools such as unittest and Nose as well. Any test that involves more than one unit is automatically not a unit test. That matters because the results of such tests tend to be confusing. The effects of the different units get tangled together, with the end result that not only do you not know where the problem is (is the mistake in this piece of code, or is it just responding correctly to bad input from some other piece of code?), you're also often unsure exactly what the problem is this output is wrong, but how does each unit contribute to the error? Empirical scientists must perform experiments that check only one hypothesis at a time, whether the subject at hand is chemistry, physics, or the behavior of a body of program code. Time for action – identifying units Imagine that you're responsible for testing the following code: class testable: def method1(self, number): number += 4 number **= 0.5 number *= 7 return number def method2(self, number): return ((number * 2) ** 1.27) * 0.3 def method3(self, number): return self.method1(number) + self.method2(number) def method4(self): return 1.713 * self.method3(id(self)) In this example, what are the units? Is the whole class a single unit, or is each method a separate unit. How about each statement, or each expression? Keep in mind that the definition of a unit is somewhat subjective (although never bigger than a single class), and make your own decision. Think about what you chose. What would the consequences have been if you chose otherwise? For example, if you chose to think of each method as a unit, what would be different if you chose to treat the whole class as a unit? Consider method4. Its result depends on all of the other methods working correctly. On top of that, it depends on something that changes from one test run to another, the unique ID of the self object. Is it even possible to treat method4 as a unit in a self-contained test? If we could change anything except method4, what would we have to change to enable method4 to run in a self-contained test and produce a predictable result? What just happened? By answering those three questions, you thought about some of the deeper aspects of unit testing. The question of what constitutes a unit, is fundamental to how you organize your tests. The capabilities of the language affects this choice. C++ and Java make it difficult or impossible to treat methods as units, for example, so in those languages each class is usually treated as a single unit. C, on the other hand, doesn't support classes as language features at all, so the obvious choice of unit is the function. Python is flexible enough that either classes or methods could be considered units, and of course it has stand-alone functions as well, which are also natural to think of as units. Python can't easily handle individual statements within a function or method as units, because they don't exist as separate objects when the test runs. They're all lumped together into a single code object that's part of the function. The consequences of your choice of unit are far-reaching. The smaller the units are, the more useful the tests tend to be, because they narrow down the location and nature of bugs more quickly. For example, one of the consequences of choosing to treat the testable class as a single unit is that tests of the class will fail if there is a mistake in any of the methods. That tells you that there's a mistake in testable, but not (for example) that it's in method2. On the other hand, there is a certain amount of rigmarole involved in treating method4 and its like as units. Even so, I recommend using methods and functions as units most of the time, because it pays off in the long run. In answering the third question, you probably discovered that the functions id and self.method3 would need to have different definitions, definitions that produced a predictable result, and did so without invoking code in any of the other units. In Python, replacing the real function with such stand-ins is fairly easy to do in an ad hoc manner. Unit testing throughout the development process We'll walk through the development of a single class, treating it with all the dignity of a real project. We'll be strictly careful to integrate unit testing into every phase of the project. This may seem silly at times, but just play along. There's a lot to learn from the experience. The example we'll be working with is a PID controller. The basic idea is that a PID controller is a feedback loop for controlling some piece of real-world hardware. It takes input from a sensor that can measure some property of the hardware, and generates a control signal that adjusts that property toward some desired state. The position of a robot arm in a factory might be controlled by a PID controller. If you want to know more about PID controllers, the Internet is rife with information. The Wikipedia entry is a good place to start: http://en.wikipedia.org/wiki/PID_controller. Design phase Our notional client comes to us with the following (rather sparse) specification: We want a class that implements a PID controller for a single variable. The measurement, setpoint, and output should all be real numbers. We need to be able to adjust the setpoint at runtime, but we want it to have a memory, so that we can easily return to the previous setpoint. Time for action - unit testing during design Time to make that specification a bit more formal—and complete—by writing unit tests that describe the desired behavior. We need to write a test that describes the PID constructor. After checking our references, we determine that a PID controller is defined by three gains, and a setpoint. The controller has three components: proportional, integral and derivative (hence the name PID). Each gain is a number that determines how much one of the three parts of the controller has on the final result. The setpoint determines what the goal of the controller is; in other words, to where it's trying to move the controlled variable. Looking at all that, we decide that the constructor should just store the gains and the setpoint, along with initializing some internal state that we know we'll need due to reading up on the workings of a PID controller: >>> import pid>>> controller = pid.PID(P=0.5, I=0.5, D=0.5, setpoint=0)>>> controller.gains(0.5, 0.5, 0.5)>>> controller.setpoint[0.0]>>> controller.previous_time is NoneTrue>>> controller.previous_error0.0>>> controller.integrated_error0.0 We need to write tests that describe measurement processing. This is the controller in action, taking a measured value as its input and producing a control signal that should smoothly move the measured variable to the setpoint. For this to work correctly, we need to be able to control what the controller sees as the current time. After that, we plug our test input values into the math that defines a PID controller, along with the gains, to figure out what the correct outputs would be: >>> import time>>> real_time = time.time>>> time.time = (float(x) for x in xrange(1, 1000)).next>>> pid = reload(pid)>>> controller = pid.PID(P=0.5, I=0.5, D=0.5, setpoint=0)>>> controller.measure(12)-6.0>>> controller.measure(6)-3.0>>> controller.measure(3)-4.5>>> controller.measure(-1.5)-0.75>>> controller.measure(-2.25)-1.125>>> time.time = real_time We need to write tests that describe setpoint handling. Our client asked for a setpoint stack, so we write tests that check such stack behavior. Writing code that uses this stack behavior brings to our attention that fact that a PID controller with no setpoint is not a meaningful entity, so we add a test that checks that the PID class rejects that situation by raising an exception. >>> pid = reload(pid)>>> controller = pid.PID(P = 0.5, I = 0.5, D = 0.5, setpoint = 0)>>> controller.push_setpoint(7)>>> controller.setpoint[0.0, 7.0]>>> controller.push_setpoint(8.5)>>> controller.setpoint[0.0, 7.0, 8.5]>>> controller.pop_setpoint()8.5>>> controller.setpoint[0.0, 7.0]>>> controller.pop_setpoint()7.0>>> controller.setpoint[0.0]>>> controller.pop_setpoint()Traceback (most recent call last):ValueError: PID controller must have a setpoint What just happened? Our clients gave us a pretty good initial specification, but it left a lot of details to assumption. By writing these tests, we've codified exactly what our goal is. Writing the tests forced us to make our assumptions explicit. Additionally, we've gotten a chance to use the object, which gives us an understanding of it that would otherwise be hard to get at this stage. Normally we'd place the doctests in the same file as the specification, and in fact that's what you'll find in the book's code archive. In the book format, we used the specification text as the description for each step of the example. You could ask how many tests we should write for each piece of the specification. After all, each test is for certain specific input values, so when code passes it, all it proves is that the code produces the right results for that specific input. The code could conceivably do something entirely wrong, and still pass the test. The fact is that it's usually a safe assumption that the code you'll be testing was supposed to do the right thing, and so a single test for each specified property fairly well distinguishes between working and non-working code. Add to that tests for any boundaries specified—for "The X input may be between the values 1 and 7, inclusive" you might add tests for X values of 0.9 and 7.1 to make sure they weren't accepted—and you're doing fine. There were a couple of tricks we pulled to make the tests repeatable and independent. In every test after the first, we called the reload function on the pid module, to reload it from the disk. That has the effect of resetting anything that might have changed in the module, and causes it to re-import any modules that it depends on. That latter effect is particularly important, since in the tests of measure, we replaced time.time with a dummy function. We want to be sure that the pid module uses the dummy time function, so we reload the pid module. If the real time function is used instead of the dummy, the test won't be useful, because there will be only one time in all of history at which it would succeed. Tests need to be repeatable. The dummy time function is created by making an iterator that counts through the integers from 1 to 999 (as floating point values), and binding time.time to that iterator's next method. Once we were done with the time-dependent tests, we replaced the original time.time. Right now, we have tests for a module that doesn't exist. That's good! Writing the tests was easier than writing the module will be, and it gives us a stepping stone toward getting the module right, quickly and easily. As a general rule, you always want to have tests ready before the code that they test is written. Have a go hero Try this a few times on your own: Describe some program or module that you'd enjoy having access to in real life, using normal language. Then go back through it and try writing tests, describing the program or module. Keep an eye out for places where writing the test makes you aware of ambiguities in your prior description, or makes you realize that there's a better way to do something.
Read more
  • 0
  • 0
  • 3305
Modal Close icon
Modal Close icon