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

How-To Tutorials

7019 Articles
article-image-article-working-with-microsoft-dynamics-ax-forms
Packt
16 May 2012
9 min read
Save for later

Working with Microsoft Dynamics AX Forms

Packt
16 May 2012
9 min read
Building a dynamic form A standard approach for creating forms in Dynamics AX is to create and store form objects in the AOT. Using this approach, it is possible to achieve a high level of complexity. However, in a number of cases, it is required to have forms created dynamically. In the standard Dynamics AX application we can see that application objects, such as the Table browser form, various lookups, or dialogs, are built dynamically. In this recipe, we will create a dynamic form. In order to show how flexible it can be, we will replicate the layout of the existing Customer groups form located in the Accounts receivable module. It can be opened from Accounts receivable | Setup | Customers. How to do it... Carry out the following steps in order to complete this recipe: In the AOT, create a new class called CustGroupDynamic with the following code: code 7 In order to test the form, run the class. Notice that the form is similar to the one in Accounts receivable | Setup | Customers | Customer groups: How it works... We start the code by declaring some variables. Note that most of them begin with FormBuild, which is part of a set of the application classes used for building dynamic forms. Each of these types correspond to the control types manually used when building forms in the AOT. Right after the variable declaration, we create a dictTable object based on the CustGroup table. We will use this object several times later in the code. Then we create a new form object and set its AOT name by calling the following code: code 8 The name is not important as this is a dynamic form, unless we are planning to save it in the AOT. The form should have a data source, so we add one by calling the addDataSource() method on the form object and providing the previously created dictTable object. code 9 Every form has a design, so we add a new design, define its style as a simple list, and set its title data source: code Once the design is ready, we can start adding controls from the code as if we were doing this from the AOT. The first thing to do is to add a strip action pane with its buttons: code 10 Right after the action pane, we add an automatically expanding Grid control pointing to the previously mentioned data source. Just to follow best practice, we place the grid inside of a Group control: code 11 Next, we add a number of grid controls pointing to the relevant data source fields by calling addDataField() on the grid object. The last thing is to initialize and run the form. Here we use a recommended approach to create and run forms using the globally available classFactory object. Adding a form splitter In Dynamics AX, more complex forms consist of one or more sections. Each section may contain grids, groups or any other element. In order to maintain section sizes while resizing the form, the sections are normally separated by so-called splitters. Splitters are not special Dynamics AX controls; they are group controls with the properties modified so they look like splitters. Most of the multisection forms in Dynamics AX already contain splitters. In this recipe, to demonstrate the usage of splitters, we will modify one of the existing forms that does not have a splitter. We will modify the Account reconciliation form in the Cash and bank management module, which can be opened from Cash and bank management | Bank accounts list page, by clicking on the Reconcile | Account reconciliation button in the action pane, and then selecting any of the existing records and hitting the Transactions button. In the following screenshot, you can see that it is not possible to control the sizes of each grid individually, and they are resized automatically using a fixed ratio when resizing the form: In this recipe, we will demonstrate the usage of splitters by resolving this situation. We will add a form splitter in the middle of the two grids in the mentioned form. It will allow users to define the size of both grids to make sure the data is optimally displayed. How to do it... Carry out the following steps in order to complete this recipe: Open the BankReconciliation form in the AOT, and in the form's design add a new Group control right after the ActionPane control with the following properties: table 1 Move the AllReconciled, Balances, and Tab controls into the newly created group. Add a new Group control right below the Top group with the following properties: table 2 Add the following line of code to the bottom of the form's class declaration: code 12 Add the following line of code to the bottom of the form's init() method: code 13 Override three methods in the Splitter group with the following code: code 14 Change the following properties of the existing BankTransTypeGroup group: table 3 Change the following property of the exiting TypeSums grid located inside the BankTransTypeGroup group: table 4 In the AOT, the modified BankReconciliation form should look similar to the following screenshot: Now, to test the results, open Cash and bank management | Bank accounts, select any bank account, click Reconcile | Account reconciliation, choose an existing one or create a new bank statement, and click on the Transactions button. Notice that the form now has a nice splitter in the middle, which makes the form look better and allows resizing of both grids: Open the SalesCreateOrder form in the AOT, and set its Design property: table 5 In order to test, open Sales and marketing | Sales orders | All sales orders, and start creating a new order. Notice that now the sales order creation form always stays on top: < How it works... Normally, a splitter has to be placed between two form groups. In this recipe, to follow that rule, we need to adjust the BankReconciliation form's design. The AllReconciled, Balances and Tab controls are moved to a new group called Top. We do not want this new group to be visible to the user, so we FrameType to None. Setting AutoDeclaration to Yes allows us to access this object from the code. Finally, we make this group automatically expanding in the horizontal direction by setting its Width to Column width. At this stage, visual form layout does not change, but now we have the upper group ready. The BankTransTypeGroup group could be used as a bottom group with slight changes. We change its Top behavior to Auto and make it fully expandable in the horizontal and vertical directions. The Height of the grid inside this group also has to be changed to Column height in order to fill all the vertical space. In the middle of those two groups, we add a splitter. The splitter is nothing but another group, which looks like a splitter. In order to achieve that, we set the Height to 5, FrameType to Raised 3D, and BackgroundColor to Windows background. This group does not hold any other controls inside, therefore, in order to make it visible we have to set the HideIfEmpty property to No. The Column width value of the property Width forces the splitter to automatically fill the form's width. Mouse events are handled by the SysFormSplitter_Y application class. After it has been declared in the form's class declaration, we instantiate it in the object in the form's init() method. We pass the name of the splitter control, the name of the top group, and the form itself as arguments when creating it. A fully working splitter requires three mouse event handlers. It is implemented by overriding the mouseMove(), mouseDown(), and mouseUp()event methods in the splitter group control. All arguments are passed to the respective member methods of the SysFormSplitter_Y class, which does all the work. In this way, horizontal splitters can easily be added to any form. The Dynamics AX application also contains nice examples about splitters, which can be found in the AOT in the Tutorial_ Form_Split form. Vertical splitters can also be added to forms using a very similar approach. For this, we need to use another application class called SysFormSplitter_X.     Creating a modal form Quite often people who are not familiar with computers and software tend to get lost among open application windows. The same could be applied to Dynamics AX. Often a user opens one form, clicks a button to open another one, and then goes back to the first one without closing the second one. Sometimes this happens intentionally, sometimes not, but the result is that the second form is hidden behind the first one and the user starts wondering why it is not possible to close or edit the first form. Such issues can be easily solved by making the child form a modal window. In other words, the second form always stays on top of the first one until closed. In this recipe, we will do exactly that. As an example, we will make the Create sales order form a modal window. How to do it... Carry out the following steps in order to complete this recipe: How it works... The design of the form has a WindowType property, which is set Standard by default. In order to make a form behave as a modal window, we have to change it to Popup. Such forms will always stay on top of the parent form. There's more We already know that some of the Dynamics AX forms are created dynamically using the Dialog class. If we look deeper into the code, we could find that the Dialog class actually creates a runtime form. This means that we can apply the same principle—change the relevant form's design property. The following code could be added to the Dialog object and would do the job. The format is given as follows: code 15 Here we get a reference to the form's design, by first using the dialogForm() method of the dialog object to get a reference to the DialogForm object, and then we call buildDesign() on the latter object. Finally, we set the design property by calling its windowType() with an argument FormWindowType::Popup. Summary In this article, we looked at various aspects of building forms in Dynamics AX. We looked at dialogs and their events. We learned how to create a dialog and how to handle it. We also learned how to build a dyamic form, as well as learned how to create a modal form. We also looked at splitter, which is an important feature of Microsoft Dynamics AX 2012.   Installing Microsoft Dynamics NAV [Article] Integrating BizTalk Server and Microsoft Dynamics CRM [Article] Installing the Dynamics AX Base Server Components for Microsoft [Article] Fine-tuning the SQL Server database for fcDynamics NAV [Article]
Read more
  • 0
  • 0
  • 5130

article-image-core-sql-server-2008-r2-technologies-deploying-master-data-services
Packt
27 May 2011
8 min read
Save for later

Core SQL Server 2008 R2 Technologies: Deploying Master Data Services

Packt
27 May 2011
8 min read
Microsoft SQL Server 2008 R2 Administration Cookbook Over 70 practical recipes for administering a high-performance SQL Server 2008 R2 system       Installing and configuring a Master Data Services Solution The administrative control of data is a primary task in any line of business management; as long as the data-flow is intended to meet enterprise level business needs, it serves the purpose. The essence of Master Data Management (MDM) is identified when the data is used for operational and analytical processes; however, those management processes must be able to clearly define the business concepts, identify different ways the data sets represent commonly understood concepts, and integrate the data into a consistent view that is available across the organization. SQL Server 2008 R2 introduces Master Data Services (MDS), which is designed to provide hierarchies that can be customized to group and summarize the master data. This kind of hierarchical representation helps to change the reporting structures and incorporate new aspects of the business rules by reducing the data-duplication. The best usage of MDS will help us to maintain a central database of master data, which is managed for reporting and analysis. In this recipe, we will go through the important steps to install and configure an MDS solution on an existing data platform. The core components of MDS are MDS configuration manager, MDS manager, and MDS web service. Getting ready There are certain pre-installation tasks required to install Master Data Services (MDS) and the setup must meet minimum requirements. The installation requirement is divided into MDS setup, MDM web application services, and MDS database. The MDS setup prerequisites are as follows: The MDS setup is possible only on the 64-bit versions of SQL Server 2008 R2 Datacenter, SQL Server 2008 R2 Enterprise, and SQL Server 2008 R2 Developer editions The supported operating systems are Enterprise Editions of Windows Server 2008 R2, Windows Server 2008, and Ultimate editions of Windows 7, and Windows Vista Ultimate. Also, Windows 7 or Vista Professional edition support this feature Microsoft .NET framework 3.5 Service Pack1 is required, to download refer to http://go.microsoft.com/fwlink/?LinkId=128220 The user account used to install MDS must be a member of the Administrators group on the local server The MDM web application and web services prerequisites are as follows: MDM is a web application hosted by IIS On a Windows Server 2008 or Windows Server 2008 R2 machine, use Server Manager to install Web Server (IIS) role and refer to http://msdn.microsoft.com/en-us/library/ee633744.aspx for the required role services The MDS database prerequisites are as follows: MDS requires a database to support MDM web applications and web services In this recipe, the machine that hosts an MDS database is using an instance of SQL Server 2008 R2 database engine How to do it... To implement the Master Data Management solution, MDS must be installed, which has two main components, an MDS database component and an MDS web component. Ensure that all of the prerequisites (mentioned in the earlier sections) are in place and by default the MDS is not installed as a part of the regular SQL Server 2008 R2 installation. We need to install the MDS separately as follows: On the SQL Server 2008 R2 installation media, navigate to the MasterDataServicesX641033_ENU folder and double-click on masterdataservices.msi file that will present a welcome screen Similar to the SQL Server installation screens, the MDS setup requires default information on the remaining steps that are self-explanatory The presented screens are License Agreement, Registration Information, Feature selection, and Ready to install to complete the Master Data Services installation Now that we have installed the Master Data Services components on the server, we need to configure the MDS to make it available for use. The MDM configuration is implemented as a two-fold phase: Databases and Web Configuration. To launch the MDS configuration manager, go to Start | All Programs | SQL Server 2008 R2 | Master Data Services | Configuration Manager. The tabs on the left-hand side represent Databases and Web configuration. Databases configure and store MDS configuration, web configuration for MDS, and web service for application integration. Make sure you click on the Databases page to create an MDS database to configure and store MDS objects. The database that is used or created must be on SQL Server 2008 R2. To ensure that the supplied configuration is working, click on the Test Connection button. Click Next to create a new Master Data Services database. On the Create Database screen, provide the database name and collation (choose SQL Server default collation or Windows collation). The collation is a single-selection, when we choose the SQL Server default collation, the Windows collation and other options (binary/case-sensitive) are disabled. The Collation is an important step to plan when Unicode data is stored and managed within the database. It is essential to plan proper collation settings during the SQL Server installation. The remaining two options Service Account and Administrator Account are self-explanatory. The username specified in the Service Account screen is added as member of dbo role for DBIASSQA_MDS_DB database. The user name specified in the Administrator Account screen will be the site administrator (super user) and will also have permissions to log on and add users to MDM applications. The account must be a domain account that is required to use application pools to connect to a database. Access the database using MDS manager site and web services based on the permissions. The Summary screen is an informative window that will help to review the details, click Next to start the configuration. The status for the MDS database creation and configuration will be shown as a Success. Click Finish to complete the Create Database wizard. To hold the metadata for the MDS repository, proceed to Metadata Services configuration manager. It is ideal to leave all the System Settings to default except Master Data Manager URL for notifications value. The MDS configuration manager for Databases is complete, so we will now proceed to the Web Configuration tab. Click on the Web Configuration option, which will present the following screenshot. The configuration will provide you with various options such as: Select the required website (from Web site drop-down) and web applications that hold MDS and can be configured Select required websites that do not have MDS and click on Create Application Create a new website by clicking on Create Site–that is specific to MDS only–that automatically creates a web application To choose an existing SQL server instance and database for MDS web application to access, click on the Select button. For this recipe, we will use an existing website: DBIASSQA-MDS, so select an existing SQL Server instance: DBIA-SSQASQL2K8R2 and database: DBIASSQA_MDS_DB. To configure the web services to enable programmatic access to MDS, click on the Enable Web services for this Web application option. Click on Apply to complete the MDS configuration. This completes the configuration and presents a popup indicating that the MDS configuration is complete. On the Configuration Complete screen, choose the Launch Web application in browser option and click OK to open the MDS Getting Started page in the browser. This completes the configuration of the Master Data Services databases and web configuration that will enable you to feature the MDS solution on an existing data platform. How it works... The Master Data Services setup will host the MDS web application and installs relevant MDS folders and files at the location and assigns permission to the objects. The setup will register MDS assemblies in the Global Assembly Cache (GAC). The MDS snap-in for Windows PowerShell is registered and installs the MDS configuration manager. A new windows group called MDS_ServiceAccount is created to contain the MDS service accounts for application pools. The MDS installation path creates a folder MDSTempDir where temporary compilation files are compiled for the MDM web application, and permissions are assigned for the MDS_ServiceAccount group. The web application configuration section follows a different workflow method, by including an option to Create Site followed by specifying settings for the new site and the MDS web application configured as the root web application in the site. This process will not allow you to configure the MDS web application under any virtual paths or specify an alias for the application. The Create New Application process enables you to select a website to create an MDS application in and the Create Application screen allows you to specify settings for the new application. The MDS application will be configured as an application in the selected site at the virtual path and at a specified alias.
Read more
  • 0
  • 0
  • 5130

article-image-working-large-data-sources
Packt
08 Jul 2015
20 min read
Save for later

Working with large data sources

Packt
08 Jul 2015
20 min read
In this article, by Duncan M. McGreggor, author of the book Mastering matplotlib, we come across the use of NumPy in the world of matplotlib and big data, problems with large data sources, and the possible solutions to these problems. (For more resources related to this topic, see here.) Most of the data that users feed into matplotlib when generating plots is from NumPy. NumPy is one of the fastest ways of processing numerical and array-based data in Python (if not the fastest), so this makes sense. However by default, NumPy works on in-memory database. If the dataset that you want to plot is larger than the total RAM available on your system, performance is going to plummet. In the following section, we're going to take a look at an example that illustrates this limitation. But first, let's get our notebook set up, as follows: In [1]: import matplotlib        matplotlib.use('nbagg')        %matplotlib inline Here are the modules that we are going to use: In [2]: import glob, io, math, os         import psutil        import numpy as np        import pandas as pd        import tables as tb        from scipy import interpolate        from scipy.stats import burr, norm        import matplotlib as mpl        import matplotlib.pyplot as plt        from IPython.display import Image We'll use the custom style sheet that we created earlier, as follows: In [3]: plt.style.use("../styles/superheroine-2.mplstyle") An example problem To keep things manageable for an in-memory example, we're going to limit our generated dataset to 100 million points by using one of SciPy's many statistical distributions, as follows: In [4]: (c, d) = (10.8, 4.2)        (mean, var, skew, kurt) = burr.stats(c, d, moments='mvsk') The Burr distribution, also known as the Singh–Maddala distribution, is commonly used to model household income. Next, we'll use the burr object's method to generate a random population with our desired count, as follows: In [5]: r = burr.rvs(c, d, size=100000000) Creating 100 million data points in the last call took about 10 seconds on a moderately recent workstation, with the RAM usage peaking at about 2.25 GB (before the garbage collection kicked in). Let's make sure that it's the size we expect, as follows: In [6]: len(r) Out[6]: 100000000 If we save this to a file, it weighs in at about three-fourths of a gigabyte: In [7]: r.tofile("../data/points.bin") In [8]: ls -alh ../data/points.bin        -rw-r--r-- 1 oubiwann staff 763M Mar 20 11:35 points.bin This actually does fit in the memory on a machine with a RAM of 8 GB, but generating much larger files tends to be problematic. We can reuse it multiple times though, to reach a size that is larger than what can fit in the system RAM. Before we do this, let's take a look at what we've got by generating a smooth curve for the probability distribution, as follows: In [9]: x = np.linspace(burr.ppf(0.0001, c, d),                          burr.ppf(0.9999, c, d), 100)          y = burr.pdf(x, c, d) In [10]: (figure, axes) = plt.subplots(figsize=(20, 10))          axes.plot(x, y, linewidth=5, alpha=0.7)          axes.hist(r, bins=100, normed=True)          plt.show() The following plot is the result of the preceding code: Our plot of the Burr probability distribution function, along with the 100-bin histogram with a sample size of 100 million points, took about 7 seconds to render. This is due to the fact that NumPy handles most of the work, and we only displayed a limited number of visual elements. What would happen if we did try to plot all the 100 million points? This can be checked by the following code: In [11]: (figure, axes) = plt.subplots()          axes.plot(r)          plt.show() formatters.py:239: FormatterWarning: Exception in image/png formatter: Allocated too many blocks After about 30 seconds of crunching, the preceding error was thrown—the Agg backend (a shared library) simply couldn't handle the number of artists required to render all the points. But for now, this case clarifies the point that we stated a while back—our first plot rendered relatively quickly because we were selective about the data we chose to present, given the large number of points with which we are working. However, let's say we have data from the files that are too large to fit into the memory. What do we do about this? Possible ways to address this include the following: Moving the data out of the memory and into the filesystem Moving the data off the filesystem and into the databases We will explore examples of these in the following section. Big data on the filesystem The first of the two proposed solutions for large datasets involves not burdening the system memory with data, but rather leaving it on the filesystem. There are several ways to accomplish this, but the following two methods in particular are the most common in the world of NumPy and matplotlib: NumPy's memmap function: This function creates memory-mapped files that are useful if you wish to access small segments of large files on the disk without having to read the whole file into the memory. PyTables: This is a package that is used to manage hierarchical datasets. It is built on the top of the HDF5 and NumPy libraries and is designed to efficiently and easily cope with extremely large amounts of data. We will examine each in turn. NumPy's memmap function Let's restart the IPython kernel by going to the IPython menu at the top of notebook page, selecting Kernel, and then clicking on Restart. When the dialog box pops up, click on Restart. Then, re-execute the first few lines of the notebook by importing the required libraries and getting our style sheet set up. Once the kernel is restarted, take a look at the RAM utilization on your system for a fresh Python process for the notebook: In [4]: Image("memory-before.png") Out[4]: The following screenshot shows the RAM utilization for a fresh Python process: Now, let's load the array data that we previously saved to disk and recheck the memory utilization, as follows: In [5]: data = np.fromfile("../data/points.bin")        data_shape = data.shape        data_len = len(data)        data_len Out[5]: 100000000 In [6]: Image("memory-after.png") Out[6]: The following screenshot shows the memory utilization after loading the array data: This took about five seconds to load, with the memory consumption equivalent to the file size of the data. This means that if we wanted to build some sample data that was too large to fit in the memory, we'd need about 11 of those files concatenated, as follows: In [7]: 8 * 1024 Out[7]: 8192 In [8]: filesize = 763        8192 / filesize Out[8]: 10.73656618610747 However, this is only if the entire memory was available. Let's see how much memory is available right now, as follows: In [9]: del data In [10]: psutil.virtual_memory().available / 1024**2 Out[10]: 2449.1796875 That's 2.5 GB. So, to overrun our RAM, we'll just need a fraction of the total. This is done in the following way: In [11]: 2449 / filesize Out[11]: 3.2096985583224114 The preceding output means that we only need four of our original files to create a file that won't fit in memory. However, in the following section, we will still use 11 files to ensure that data, if loaded into the memory, will be much larger than the memory. How do we create this large file for demonstration purposes (knowing that in a real-life situation, the data would already be created and potentially quite large)? We can try to use numpy.tile to create a file of the desired size (larger than memory), but this can make our system unusable for a significant period of time. Instead, let's use numpy.memmap, which will treat a file on the disk as an array, thus letting us work with data that is too large to fit into the memory. Let's load the data file again, but this time as a memory-mapped array, as follows: In [12]: data = np.memmap(            "../data/points.bin", mode="r", shape=data_shape) The loading of the array to a memmap object was very quick (compared to the process of bringing the contents of the file into the memory), taking less than a second to complete. Now, let's create a new file to write the data to. This file must be larger in size as compared to our total system memory (if held on in-memory database, it will be smaller on the disk): In [13]: big_data_shape = (data_len * 11,)          big_data = np.memmap(              "../data/many-points.bin", dtype="uint8",              mode="w+", shape=big_data_shape) The preceding code creates a 1 GB file, which is mapped to an array that has the shape we requested and just contains zeros: In [14]: ls -alh ../data/many-points.bin          -rw-r--r-- 1 oubiwann staff 1.0G Apr 2 11:35 many-points.bin In [15]: big_data.shape Out[15]: (1100000000,) In [16]: big_data Out[16]: memmap([0, 0, 0, ..., 0, 0, 0], dtype=uint8) Now, let's fill the empty data structure with copies of the data we saved to the 763 MB file, as follows: In [17]: for x in range(11):              start = x * data_len              end = (x * data_len) + data_len              big_data[start:end] = data          big_data Out[17]: memmap([ 90, 71, 15, ..., 33, 244, 63], dtype=uint8) If you check your system memory before and after, you will only see minimal changes, which confirms that we are not creating an 8 GB data structure on in-memory. Furthermore, checking your system only takes a few seconds. Now, we can do some sanity checks on the resulting data and ensure that we have what we were trying to get, as follows: In [18]: big_data_len = len(big_data)          big_data_len Out[18]: 1100000000 In [19]: data[100000000 – 1] Out[19]: 63 In [20]: big_data[100000000 – 1] Out[20]: 63 Attempting to get the next index from our original dataset will throw an error (as shown in the following code), since it didn't have that index: In [21]: data[100000000] ----------------------------------------------------------- IndexError               Traceback (most recent call last) ... IndexError: index 100000000 is out of bounds ... But our new data does have an index, as shown in the following code: In [22]: big_data[100000000 Out[22]: 90 And then some: In [23]: big_data[1100000000 – 1] Out[23]: 63 We can also plot data from a memmaped array without having a significant lag time. However, note that in the following code, we will create a histogram from 1.1 million points of data, so the plotting won't be instantaneous: In [24]: (figure, axes) = plt.subplots(figsize=(20, 10))          axes.hist(big_data, bins=100)          plt.show() The following plot is the result of the preceding code: The plotting took about 40 seconds to generate. The odd shape of the histogram is due to the fact that, with our data file-hacking, we have radically changed the nature of our data since we've increased the sample size linearly without regard for the distribution. The purpose of this demonstration wasn't to preserve a sample distribution, but rather to show how one can work with large datasets. What we have seen is not too shabby. Thanks to NumPy, matplotlib can work with data that is too large for memory, even if it is a bit slow iterating over hundreds of millions of data points from the disk. Can matplotlib do better? HDF5 and PyTables A commonly used file format in the scientific computing community is Hierarchical Data Format (HDF). HDF is a set of file formats (namely HDF4 and HDF5) that were originally developed at the National Center for Supercomputing Applications (NCSA), a unit of the University of Illinois at Urbana-Champaign, to store and organize large amounts of numerical data. The NCSA is a great source of technical innovation in the computing industry—a Telnet client, the first graphical web browser, a web server that evolved into the Apache HTTP server, and HDF, which is of particular interest to us, were all developed here. It is a little known fact that NCSA's web browser code was the ancestor to both the Netscape web browser as well as a prototype of Internet Explorer that was provided to Microsoft by a third party. HDF is supported by Python, R, Julia, Java, Octave, IDL, and MATLAB, to name a few. HDF5 offers significant improvements and useful simplifications over HDF4. It uses B-trees to index table objects and, as such, works well for write-once/read-many time series data. Common use cases span fields such as meteorological studies, biosciences, finance, and aviation. The HDF5 files of multiterabyte sizes are common in these applications. Its typically constructed from the analyses of multiple HDF5 source files, thus providing a single (and often extensive) source of grouped data for a particular application. The PyTables library is built on the top of the Python HDF5 library and NumPy. As such, it not only provides access to one of the most widely used large data file formats in the scientific computing community, but also links data extracted from these files with the data types and objects provided by the fast Python numerical processing library. PyTables is also used in other projects. Pandas wraps PyTables, thus extending its convenient in-memory data structures, functions, and objects to large on-disk files. To use HDF data with Pandas, you'll want to create pandas.HDFStore, read from the HDF data sources with pandas.read_hdf, or write to one with pandas.to_hdf. Files that are too large to fit in the memory may be read and written by utilizing chunking techniques. Pandas does support the disk-based DataFrame operations, but these are not very efficient due to the required assembly on columns of data upon reading back into the memory. One project to keep an eye on under the PyData umbrella of projects is Blaze. It's an open wrapper and a utility framework that can be used when you wish to work with large datasets and generalize actions such as the creation, access, updates, and migration. Blaze supports not only HDF, but also SQL, CSV, and JSON. The API usage between Pandas and Blaze is very similar, and it offers a nice tool for developers who need to support multiple backends. In the following example, we will use PyTables directly to create an HDF5 file that is too large to fit in the memory (for an 8GB RAM machine). We will follow the following steps: Create a series of CSV source data files that take up approximately 14 GB of disk space Create an empty HDF5 file Create a table in the HDF5 file and provide the schema metadata and compression options Load the CSV source data into the HDF5 table Query the new data source once the data has been migrated Remember the temperature precipitation data for St. Francis, in Kansas, USA, from a previous notebook? We are going to generate random data with similar columns for the purposes of the HDF5 example. This data will be generated from a normal distribution, which will be used in the guise of the temperature and precipitation data for hundreds of thousands of fictitious towns across the globe for the last century, as follows: In [25]: head = "country,town,year,month,precip,tempn"          row = "{},{},{},{},{},{}n"          filename = "../data/{}.csv"          town_count = 1000          (start_year, end_year) = (1894, 2014)          (start_month, end_month) = (1, 13)          sample_size = (1 + 2                        * town_count * (end_year – start_year)                        * (end_month - start_month))          countries = range(200)          towns = range(town_count)          years = range(start_year, end_year)          months = range(start_month, end_month)          for country in countries:             with open(filename.format(country), "w") as csvfile:                  csvfile.write(head)                  csvdata = ""                  weather_data = norm.rvs(size=sample_size)                  weather_index = 0                  for town in towns:                    for year in years:                          for month in months:                              csvdata += row.format(                                  country, town, year, month,                                  weather_data[weather_index],                                  weather_data[weather_index + 1])                              weather_index += 2                  csvfile.write(csvdata) Note that we generated a sample data population that was twice as large as the expected size in order to pull both the simulated temperature and precipitation data at the same time (from the same set). This will take about 30 minutes to run. When complete, you will see the following files: In [26]: ls -rtm ../data/*.csv          ../data/0.csv, ../data/1.csv, ../data/2.csv,          ../data/3.csv, ../data/4.csv, ../data/5.csv,          ...          ../data/194.csv, ../data/195.csv, ../data/196.csv,          ../data/197.csv, ../data/198.csv, ../data/199.csv A quick look at just one of the files reveals the size of each, as follows: In [27]: ls -lh ../data/0.csv          -rw-r--r-- 1 oubiwann staff 72M Mar 21 19:02 ../data/0.csv With each file that is 72 MB in size, we have data that takes up 14 GB of disk space, which exceeds the size of the RAM of the system in question. Furthermore, running queries against so much data in the .csv files isn't going to be very efficient. It's going to take a long time. So what are our options? Well, to read this data, HDF5 is a very good fit. In fact, it is designed for jobs like this. We will use PyTables to convert the .csv files to a single HDF5. We'll start by creating an empty table file, as follows: In [28]: tb_name = "../data/weather.h5t"          h5 = tb.open_file(tb_name, "w")          h5 Out[28]: File(filename=../data/weather.h5t, title='', mode='w',              root_uep='/', filters=Filters(                  complevel=0, shuffle=False, fletcher32=False,                  least_significant_digit=None))          / (RootGroup) '' Next, we'll provide some assistance to PyTables by indicating the data types of each column in our table, as follows: In [29]: data_types = np.dtype(              [("country", "<i8"),              ("town", "<i8"),              ("year", "<i8"),              ("month", "<i8"),               ("precip", "<f8"),              ("temp", "<f8")]) Also, let's define a compression filter that can be used by PyTables when saving our data, as follows: In [30]: filters = tb.Filters(complevel=5, complib='blosc') Now, we can create a table inside our new HDF5 file, as follows: In [31]: tab = h5.create_table(              "/", "weather",              description=data_types,              filters=filters) With that done, let's load each CSV file, read it in chunks so that we don't overload the memory, and then append it to our new HDF5 table, as follows: In [32]: for filename in glob.glob("../data/*.csv"):          it = pd.read_csv(filename, iterator=True, chunksize=10000)          for chunk in it:              tab.append(chunk.to_records(index=False))            tab.flush() Depending on your machine, the entire process of loading the CSV file, reading it in chunks, and appending to a new HDF5 table can take anywhere from 5 to 10 minutes. However, what started out as a collection of the .csv files that weigh in at 14 GB is now a single compressed 4.8 GB HDF5 file, as shown in the following code: In [33]: h5.get_filesize() Out[33]: 4758762819 Here's the metadata for the PyTables-wrapped HDF5 table after the data insertion: In [34]: tab Out[34]: /weather (Table(288000000,), shuffle, blosc(5)) '' description := { "country": Int64Col(shape=(), dflt=0, pos=0), "town": Int64Col(shape=(), dflt=0, pos=1), "year": Int64Col(shape=(), dflt=0, pos=2), "month": Int64Col(shape=(), dflt=0, pos=3), "precip": Float64Col(shape=(), dflt=0.0, pos=4), "temp": Float64Col(shape=(), dflt=0.0, pos=5)} byteorder := 'little' chunkshape := (1365,) Now that we've created our file, let's use it. Let's excerpt a few lines with an array slice, as follows: In [35]: tab[100000:100010] Out[35]: array([(0, 69, 1947, 5, -0.2328834718674, 0.06810312195695),          (0, 69, 1947, 6, 0.4724989007889, 1.9529216219569),          (0, 69, 1947, 7, -1.0757216683235, 1.0415374480545),          (0, 69, 1947, 8, -1.3700249968748, 3.0971874991576),          (0, 69, 1947, 9, 0.27279758311253, 0.8263207523831),          (0, 69, 1947, 10, -0.0475253104621, 1.4530808932953),          (0, 69, 1947, 11, -0.7555493935762, -1.2665440609117),          (0, 69, 1947, 12, 1.540049376928, 1.2338186532516),          (0, 69, 1948, 1, 0.829743501445, -0.1562732708511),          (0, 69, 1948, 2, 0.06924900463163, 1.187193711598)],          dtype=[('country', '<i8'), ('town', '<i8'),                ('year', '<i8'), ('month', '<i8'),                ('precip', '<f8'), ('temp', '<f8')]) In [36]: tab[100000:100010]["precip"] Out[36]: array([-0.23288347, 0.4724989 , -1.07572167,                -1.370025 , 0.27279758, -0.04752531,                -0.75554939, 1.54004938, 0.8297435 ,                0.069249 ]) When we're done with the file, we do the same thing that we would do with any other file-like object: In [37]: h5.close() If we want to work with it again, simply load it, as follows: In [38]: h5 = tb.open_file(tb_name, "r")          tab = h5.root.weather Let's try plotting the data from our HDF5 file: In [39]: (figure, axes) = plt.subplots(figsize=(20, 10))          axes.hist(tab[:1000000]["temp"], bins=100)          plt.show() Here's a plot for the first million data points: This histogram was rendered quickly, with a much better response time than what we've seen before. Hence, the process of accessing the HDF5 data is very fast. The next question might be "What about executing calculations against this data?" Unfortunately, running the following will consume an enormous amount of RAM: tab[:]["temp"].mean() We've just asked for all of the data—all of its 288 million rows. We are going to end up loading everything into the RAM, grinding the average workstation to a halt. Ideally though, when you iterate through the source data and create the HDF5 file, you also crunch the numbers that you will need, adding supplemental columns or groups to the HDF5 file that can be used later by you and your peers. If we have data that we will mostly be selecting (extracting portions) and which has already been crunched and grouped as needed, HDF5 is a very good fit. This is why one of the most common use cases that you see for HDF5 is the sharing and distribution of the processed data. However, if we have data that we need to process repeatedly, then we will either need to use another method besides the one that will cause all the data to be loaded into the memory, or find a better match for our data processing needs. We saw in the previous section that the selection of data is very fast in HDF5. What about calculating the mean for a small section of data? If we've got a total of 288 million rows, let's select a divisor of the number that gives us several hundred thousand rows at a time—2,81,250 rows, to be more precise. Let's get the mean for the first slice, as follows: In [40]: tab[0:281250]["temp"].mean() Out[40]: 0.0030696632864265312 This took about 1 second to calculate. What about iterating through the records in a similar fashion? Let's break up the 288 million records into chunks of the same size; this will result in 1024 chunks. We'll start by getting the ranges needed for an increment of 281,250 and then, we'll examine the first and the last row as a sanity check, as follows: In [41]: limit = 281250          ranges = [(x * limit, x * limit + limit)              for x in range(2 ** 10)]          (ranges[0], ranges[-1]) Out[41]: ((0, 281250), (287718750, 288000000)) Now, we can use these ranges to generate the mean for each chunk of 281,250 rows of temperature data and print the total number of means that we generated to make sure that we're getting our counts right, as follows: In [42]: means = [tab[x * limit:x * limit + limit]["temp"].mean()              for x in range(2 ** 10)]          len(means) Out[42]: 1024 Depending on your machine, that should take between 30 and 60 seconds. With this work done, it's now easy to calculate the mean for all of the 288 million points of temperature data: In [43]: sum(means) / len(means) Out[43]: -5.3051780413782918e-05 Through HDF5's efficient file format and implementation, combined with the splitting of our operations into tasks that would not copy the HDF5 data into memory, we were able to perform calculations across a significant fraction of a billion records in less than a minute. HDF5 even supports parallelization. So, this can be improved upon with a little more time and effort. However, there are many cases where HDF5 is not a practical choice. You may have some free-form data, and preprocessing it will be too expensive. Alternatively, the datasets may be actually too large to fit on a single machine. This is when you may consider using matplotlib with distributed data. Summary In this article, we covered the role of NumPy in the world of big data and matplotlib as well as the process and problems in working with large data sources. Also, we discussed the possible solutions to these problems using NumPy's memmap function and HDF5 and PyTables. Resources for Article: Further resources on this subject: First Steps [article] Introducing Interactive Plotting [article] The plot function [article]
Read more
  • 0
  • 0
  • 5127

article-image-what-is-ensemble-learning
Ankit Dixit
26 Feb 2018
6 min read
Save for later

What is ensemble learning?

Ankit Dixit
26 Feb 2018
6 min read
Ensemble learning explained There are many instances when a single machine learning model simply isn't good enough - you need to use multiple models. Here is what an ensemble framework looks like: In everyday life we use a form of ensemble learning for our daily decision making.  For example, suppose you are applying to a university to enrol on an ensemble machine learning course. How do you decide whether it is the right choice or not? There are always multiple things that will inform your decision: Other students' reviews: Students may provide information such as whether this course is useful for improving skill sets, information about the course curriculum, the practical sessions, and so on. But as the students are not fully aware of the course's details (obviously, that's why they are taking that course) and also because they cannot suggest any other competitive course, you cannot rely on their suggestion solely. However, you know that their suggestions helped you in the past to choose previous courses. Let's say they are correct 60% of the time. Study counselors: You can get information regarding other competitive courses. They also know which universities have experts for the domain, so they can help you out to choose one course over other ML courses. Let's assume that these counselors are correct 60% of the time. Career counselors: Why do you want to take this course? Of course, for a better job, so a career counselor can tell you about the current requirements related to this skill set. They can tell you whether this course will help you enhance your career. Keep in mind that career counselors are right most of the time, say 40%. Social media: Yes it helps! Here, you can join many discussion forums, find many suggestions, and pros and cons of the course. You can get suggestions from a large audience and they can perform a very critical role in your decision. This can show you in which region of the country there is more demand for a certain course, or where it is not considered an important skill. It may be correct, say, 40% of the time. Placement officer: A placement officer is a person who takes care of job placements; so they better know which specific companies need employees for this domain. Also they will give you assurance of getting a decent job after completion of this course. And trust me, 70% of the time you will go with their review, because they will help you in getting a job! None of these things alone are going to help you come to a final answer. But by combining each of these different components, you’ll probably come to a decision. Let's take a look at how you can make a decision on whether you should go with this course or not. Let's quickly analyze the scenario. As all the experts are from an independent system, we can get a very high accuracy rate as follows: 1-60%*60%*40%*40%*70% 1-0.040 96% Can you see what we have got by the combined decision? I think it is more than you think. Can we further improve it? Yes we can; for that, we have to take suggestions from more sources, such as course faculties, a company's workers, and so on. The preceding example is based on an assumption that the suggestions from all the sources are independent. Well, in a practical scenario, this is not possible. If we are talking about the same domain, more or less there will be a correlation between the suggestions. Suppose we choose six sources but all are students of that course. Then we cannot reach the correct decision with high confidence; this is where the power of ensembles comes into the picture, where you have multiple predictions and you combine all of them to get a high-confidence prediction. Let's enter the world of ensembles. When to use ensemble learning There are many reasons to go for ensembles, as each model of the group is usually based on algorithms, some of which are very simple and less computation intensive, but some may be quite complex and more computation intensive. For any production environment, accuracy and computation time are equally important. A system with higher accuracy but one that is unimplementable for real-time applications is of no use. However, a simple algorithm may lack in accuracy and may not fit onto the data properly; in those cases, we have to make a compromise between accuracy and computation time. This compromise can be minimized if we use many weak learners to get a combined confidence index out of them, which may help us to implement such a system for real-time applications with very high accuracy. These are the main instanced when you should use ensemble learning: The dataset is too large or too small: When a dataset is too large and so it cannot be trained by a single model, we can create a small subset of data to train different models. At the end, we can choose the average of all as the final prediction. Similarly, when a dataset is too small to train a single model, we can use bootstrap methods to create random subsamples of data to train the models. Complex (nonlinear) data: Most of the time, a real-world dataset is a nonlinear dataset, where a single model cannot define the class boundary clearly. This is known as underfitting of the model. In such cases, we can use more than one model to train different subsets of the data and average out the result at the end to predict distinct boundaries. High confidence: When we train multiple classifiers on the training dataset and get mostly correlated output, it ensures a high prediction rate. Consider a case of classification where most of our classifiers predict the same class for an instance; in such cases, interprets ensemble system having high confidence on its decision. As with just about everything in the machine learning world, the key thing is to select the right model for the data you have at your disposal and the questions you're trying to answer. If you want to learn more about ensemble learning, explore it in depth in Ensemble Machine Learning from which this post has been taken. Find more machine learning eBooks and videos. Explore deep learning eBooks and videos.
Read more
  • 0
  • 0
  • 5127

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

Paths and curves in Raphael JS Vector Graphics

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

article-image-differences-style-between-java-and-scala-code
Packt
22 Apr 2014
6 min read
Save for later

Differences in style between Java and Scala code

Packt
22 Apr 2014
6 min read
(For more resources related to this topic, see here.) Writing an algorithm in Java follows an imperative style, that is, a sequence of statements that change a program state. Scala, focusing primarily on functional programming, adopts a more declarative approach, where everything is an expression rather than a statement. Let's illustrate this in an example. In Java, you would commonly find the following code snippet: ... String customerLevel = null; if(amountBought > 3000) { customerLevel = "Gold"; } else { customerLevel = "Silver"; } ... The Scala equivalent consists of the following code snippet: scala> val amountBought = 5000 amountBought: Int = 5000 scala> val customerLevel = if (amountBought> 3000) "Gold" else "Silver" customerLevel: String = Gold Note that unlike the Java statements, if is now embedded as part of the resulting evaluated expression. In general, working where everything is evaluated as an expression (and here an immutable expression) will make it much easier for reuse as well as composition. Being able to chain the result of one expression to the next will give you a concise way of expressing fairly complicated transformations that would require much more code in Java. Adjusting the code layout As the intent of functional programming is to minimize state behavior, it often consists of short lambda expressions so that you can visualize a fairly complicated transformation in an elegant and concise way, in many cases even as one-liners. For this reason, general formatting in Scala recommends that you use only two-space indentations instead of the four-space indentation that is generally admitted in Java code, as shown in the following code snippet: scala> class Customer( val firstName: String, val lastName: String, val age: Int, val address: String, val country: String, valhasAGoodRating: Boolean ) { override def toString() = s" $firstName $lastName" } defined class Customer If you have many constructor/method parameters, having them aligned as previously illustrated makes it easier to change them without the need to reformat the whole indentation. It is also the case if you want to refactor the class with a longer name, for example, VeryImportantCustomer instead of Customer; it will make smaller and more precise differences against your version control management system (Git, subversion, and so on). Naming conventions Conventions for naming packages, classes, fields, and methods in the camel case generally follow the Java conventions. Note that you should avoid the underscore (_) in variable names (such as first_name or _first_name) as the underscore has a special meaning in Scala (self or this in anonymous functions). However, constants, most likely declared as private static final myConstant in Java, are normally declared in Scala in the upper camel case, such as in the following enclosing object: scala> object Constants { | val MyNeverChangingAge = 20 | } defined module Constants Choosing a meaningful name for variables and methods should always be a priority in Java, and it is often recommended to use rather long variable names to precisely describe what a variable or method represents. In Scala, things are a little bit different; meaningful names are, of course, a good way to make code more readable. However, as we are at the same time aiming at making behavior transformations concise through the use of functions and lambda expressions, short variable names can be an advantage if you can capture a whole piece of functionality in a short block of code. For example, incrementing a list of integers in Scala can simply be expressed as follows: scala> val amounts = List(3,6,7,10) map ( x => x +1 ) amounts: List[Int] = List(4, 7, 8, 11) Although using x as a variable name is often discouraged in Java, here it does not matter that much as the variable is not reused and we can capture the transformation it does at once. There are many short or long alternatives to the previous lambda syntax that will produce the same result. So, which one to choose? Some of the alternatives are as follows: scala> val amounts = List(3,6,7,10) map ( myCurrentAmount => myCurrentAmount +1 ) amounts: List[Int] = List(4, 7, 8, 11) In this case, a long variable name breaks a clear and concise one-liner into two lines of code, thereby, making it difficult to understand. Meaningful names make more sense here if we start expressing logic on several lines as shown in the following code snippet: scala> val amounts = List(3,6,7,10) map { myCurrentAmount => val result = myCurrentAmount + 1 println("Result: " + result) result } Result: 4 Result: 7 Result: 8 Result: 11 amounts: List[Int] = List(4, 7, 8, 11) A shorter but still expressive name is sometimes a good compromise to indicate to the reader that this is an amount we are currently manipulating in our lambda expression, as follows: scala> val amounts = List(3,6,7,10) map( amt => amt + 1 ) amounts: List[Int] = List(4, 7, 8, 11) Finally, the shortest syntax of all that is well accepted by fluent Scala programmers for such a simple increment function is as follows: scala> val amounts = List(3,6,7,10) map( _ + 1 ) amounts: List[Int] = List(4, 7, 8, 11) Underscores are also encountered in Scala for expressing more complicated operations in an elegant but more awkward way, as is the following sum operation using the foldLeft method that accumulates the state from one element to the other: scala> val sumOfAmounts = List(3,6,7,10).foldLeft(0)( _ + _ ) sumOfAmounts: Int = 26 Instead of explicitly having 0 as the initial value for the sum, we can write this summation a bit more elegantly by using the reduce method that is similar to foldLeft. However, we take the first element of the collection as the initial value (here, 3 will be the initial value), as shown in the following command: scala> val sumOfAmounts = List(3,6,7,10) reduce ( _ + _ ) sumOfAmounts: Int = 26 As far as style is concerned, fluent Scala programmers will not have any problem reading this code. However, if the state accumulation operation is more complicated than just a simple + operation, it might be wise to write it more explicitly as shown in the following command: scala> val sumOfAmounts = List(3,6,7,10) reduce ( (total,element) => total + element ) sumOfAmounts: Int = 26 Summary In this article, we discussed about the style differences and the naming conventions that we must be aware of, to write easier-to-read and more maintainable code. Resources for Article: Further resources on this subject: The Business Layer (Java EE 7 First Look) [article] Getting Started with JavaFX [article] Enterprise JavaBeans [article]
Read more
  • 0
  • 0
  • 5118
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-introduction-applicationcfc-object-and-application-variables-coldfusion-9
Packt
26 Jul 2010
9 min read
Save for later

Introduction to the Application.cfc Object and Application Variables in ColdFusion 9

Packt
26 Jul 2010
9 min read
(For more resources on ColdFusion, see here.) Life span Each of our shared scopes has a life span. They come into existence at a given point, and cease to exist at a predictable point. Learning to recognize these points is very important. It is also the first aspect of "Scope". The request scope is created when a request is made to your ColdFusion server from any source. This could either be a web browser, or any type of web application that can make an HTTP request to your server. Any variable placed into the request structure persists until the request processing is complete. Variable persistence is the property of data remaining available for a set period of time. Without persistence, we would have to make information last by passing all the information from one web page to another, in all forms and in all links. You may have heard people say that web pages are stateless. If you have passed all the information into the browser, they would be closer to stateful applications, but would be difficult to manage. In this article, we will learn how to create a stateful web application. Here is a chart of the "life spans" of the key scopes: Scope Begins Ends Request Begins when a server receives a request from any source.Created before any session or an application is created. Ends when the processing for this request is complete.Ending has nothing to do with the end of applications or sessions. Application Begins before a session but after the request.Begins only when an Application.cfc file is first run with the current unique application name, or when the <cfapplication> tag is called in older code CF applications. Ends when the amount of time since a request is greater than the expiration time set for the application. Session Begins after an application is created.Created inside the same sources as the application. Ends when the amount of time since a request is greater than the expiration time set for the session. Client Begins when a unique visitor first visits the server. If you want them to expire, you can store client variables in encrypted cookies. Cookies have limited storage space and are not always available. We will be discussing the scopes in more detail later in this article series. All the scopes, except the client scope, expire if you shut down your server. When we close our browser window or reboot the client side, a session does not come to an end, but our connectivity to that particular session scope ends. The information and resources for storing that session are held until the session expires. Then, when connecting the server starts a new session and we are unable to reconnect to the former session. Introducing the Application.cfc object The first thing we need to do is to understand how this application page is called. When a .cfm or .cfc file is called, the server looks for an Application.cfc file in the current directory where the web page is being called from. It also looks for an Application.cfm file. We do not create an application or session scope with the .cfm version because .cfc provides many advantages and is much more powerful than the .cfm version. It provides better encapsulation and code reuse. If the application file is found, ColdFusion runs it. If the file is not found, then it moves up one directory towards the sever root directory in order to search for an Application.cfc file. The search stops either when a file is found, or once it reaches the root directory and a file is not found. There are several methods in the Application.cfc file. It is worth noting that this file does not exist by default, the developer must create it. The following table gives the method names and the details as to when those methods are called: Method name When a method is called onApplicationEnd The application ends; the application times out. onApplicationStart The application first starts: the first request for a page is processed or the first CFC method is invoked by an event gateway instance, a web service, or Macromedia Flash Remoting CFC. onCFCRequest HTTP or AMF (remote special Flash) calls. onError An exception occurs that is not caught by a try or catch block. onMissingTemplate ColdFusion receives a request for a non-existent page. onRequest The onRequestStart() method finishes(this method can filter request contents). onRequestEnd All pages in the request have been processed. onRequestStart A request starts. onSessionEnd A session ends. onSessionStart A session starts. onServerStart A ColdFusion server starts. When the Application.cfc file runs for the first time, these methods are called in the order as shown in the following diagram. The request variable scope is available at all times. Yet, to make the code flow right, the designers of this object made sure of the order in which the server runs the code. You will also find that for technical reasons, there are some issues that arise when we use the onRequest() method. Therefore, we will not be using this method. The steps in the previous screenshot are explained as follows: Browser Request: The browser sends a request to the server. The server passes the processing to the Application.cfc file, if it exists. It skips the step if it does not exist. The Application.cfc file has methods that execute if they exist too. The first method is onApplicationStart(). This executes on the basis of the application name. If the unique named application is not currently running on the server, then this method is called. Application Start: The next thing that Application.cfc does is to check if the request to the server is a pre-existing application. If the request is to an application which has not started, then it calls the onApplicationStart() method, if the method exists. Session Start: On every request to the server, if the onSessionStart() method exists, then it is called at this particular point in the processing. Request Start: On every request to the server, if the onRequestStart() method exists, then it is called at this particular point in the processing. OnRequest: This step normally occurs after the onRequestStart() method. If the onRequest() method was used, then by default it prevented the calling of CFCs. We do not say that it is always wrong to use this method. However, we will avoid it as much as possible. Requested Page: Now, the actual page requested is called and processed. Request End: After the requested page is processed, the control is passed back to the onRequestEnd() method, if it exists in Application.cfc. return response to browser: This is the point when ColdFusion has completed its work of processing information to respond to the browser request. At this point, you could either send HTML to the browser, a redirect, or any other response. Session End: The onSessionEnd() method is called if the method exists but only when the time since the user has last made a request to the server is less than the time for the session timeout. Application End: The onApplicationEnd() method is called if it exists when the time since the last request was received by the server is greater than the timeout for the application. The application and session scopes have already been created on the server and they do not need to be reinitialized. Once the application is created and other requests are made to the server, the following methods are called with each request: onRequestStart() onRequest() onRequestEnd() In previous versions of ColdFusion, when the onRequest() method of the Application.cfc was called, it blocked CFCs from operating correctly. You may see some fancy code in older frameworks that check if the current request is calling a CFC. They would then delete the onRequest() method for that request. Now there is a new method called onCFCRequest(). If you need backwards capability to previous versions of ColdFusion, then you would delete the onRequest() method. You can use either of these approaches depending on whether you need the code to run on prior versions of ColdFusion. The onCFCRequest() method will execute at the same point as the onRequest() method in the previous examples. You can add this code in or not depending on your own preferences. The previous example still operates as expected if you leave the method out. The OnRequestEnd.cfm side of using Application.cfm based page calls does not execute if the page runs a <cflocation> tag before the OnRequestEnd.cfm is run. It is also not a part of Application.cfc based applications and was intended for use with Application.cfm in older versions of ColdFusion. Here is a representation of the complete process that is less granular. We can see that the application behaves just as it did in the earlier illustration; we just do not go into explicit detail about every method that is called internally. We also see that the requested page can call additional code segments. These code segments can be a CFC, a custom tag, or any included page. Those pages can also include other pages, so that they create a proper hierarchy of functionality. Always try to make sure that functionality is layered, so the separation of layers provides a structured and simpler approach to creation, maintenance, and long-term support for your web applications. The variables set in Application.cfc can be modified before the requested page is called, and even later. Let us say for example, you want to record the time at which the session was last hit. You could choose to set a variable, <cfset session._stat.lasthit = now()>. This could be set either at the beginning of a request, or at the end. Here, the question is where you would put this function. At first, you might think that you would add this function to the OnSessionStart() method or OnSessionEnd() method. This would cause an issue because these two methods are only called when a session has begun or when it has come to an end. You would actually put the code into the OnRequestStart() or OnRequestEnd() code segment of the Application.cfc file for the function to work properly. The request methods are called with every server request. We will have a complete Application.cfc to use as a model for creating our own variations in future projects. Remember to place the code in the right place and test your code using CFDump or by some other means to make sure it works when creating changes.
Read more
  • 0
  • 0
  • 5113

article-image-different-types-mapping-nhibernate-2
Packt
19 May 2010
8 min read
Save for later

Different types of Mapping in Nhibernate 2

Packt
19 May 2010
8 min read
(Read more interesting articles on Nhibernate 2 Beginner's Guide here.) What is mapping? Simply put, we need to tell NHibernate about the database that we created and how the fields and tables match up to the properties and classes we created. We need to tell NHibernate how we will be assigning Primary Keys, the data types that we will be using to represent data, what variables we will store them in, and so on. You could say this is one of the most important exercises we will perform in our pursuit of NHibernate. Don't worry though, it's pretty easy. Types of mapping There are two basic ways to map data for NHibernate: the traditional XML mapping in an hbm.xml file, or the newer "Fluent NHibernate" style, which is similar to the interface pattern introduced with the .NET 3.5 framework (see http://www.martinfowler.com/bliki/FluentInterface.html). In both cases, we will create a document for each of our tables. We will map each field from our database to the property we created to display it in our class. XML mapping XML mapping is undoubtedly the most common method of mapping entities with NHibernate. Basically, we create an XML document that contains all of the information about our classes and how it maps to our database tables. These documents have several advantages: They are text files, so they are small They are very readable They use a very small number of tags to describe the data The two biggest complaints about XML mapping is the verbosity of the text and that it is not compiled. We can handle some of the verbosity by limiting the amount of data we put into the document. There are a number of optional parameters that do not absolutely need to be mapped, but that provide additional information about the database that can be included. We'll discuss more about that in the Properties section. You should copy the nhibernate-mapping.xsd and nhibernate-configuration.xsd files from the NHibernate ZIP file into your Visual Studio schemas directory (that is C:Program FilesMicrosoft Visual Studio 9.0Common7Packagesschemasxml). This will give you IntelliSense and validation in the .NET XML editor when editing NHibernate mapping and configuration files. Without compilation, when the database changes or the classes change, it's difficult to detect mismatches until the application is actually executed and NHibernate tries to reconcile the database structure with the mapping classes. While this can be an issue there are a number of ways to mitigate it, such as careful monitoring of changes, writing tests for our persistence layer, using a Visual Studio plugin, or using a code generation tool. Getting started The XML mapping document begins like any XML document, with an XML declaration. No magic here, just a simple xml tag, and two attributes, version and encoding. <?xml version="1.0" encoding="utf-8" ?> The next tag we are going to see in our document is the hibernate-mapping tag. This tag has an attribute named ><hibernate-mapping namespace="BasicWebApplication.Common.DataObjects" assembly="BasicWebApplication"> </hibernate-mapping> These three properties within the hibernate-mapping tag make up the basic XML mapping document. Classes The next tag we need to define in our document is the class tag. This is a KEY tag, because it tells NHibernate two things—the class this mapping document is meant to represent and which table in the database that class should map to. The class tag has two attributes we need to be concerned with—name and table <class name="" table=""> </class> The name attribute contains the fully-qualified POCO (or VB.NET) class that we want to map to, including the assembly name. While this can be specified in the standard fully-qualified dotted class name, a comma, and then the assembly name, the preferred method is to define the namespace and assembly in the <hibernate-mapping> tag, as shown in the previous code. The table attribute specifies the table in the database that this mapping file represents. It can be as simple as the name of the table Address or as complex as needed to adequately describe the table. If you need to include the owner of the table, such as dbo.Address, then you can add the schema attribute as follows: schema="dbo" If we were going to map the Address class in our application to the Address table in the database, then we would use a tag as follows: <class name="Address" table="Address"> </class> Technically, as the table name is the same as our class name, we could leave out the table attribute. Properties We can map properties from our class to fields in the database using the id tag and the property tag. These tags are for the standard fields in the database, not the Foreign Key fields. We'll get to those in a minute. The id and property tags follow a standard pattern and have a number of optional parameters. They follow the basic format of defining the property on the class that they are mapping to and the data type that is used to represent that data. This will generally look as follows: <property name="Address1" type="String"> <column name="Address1" length="255" sql-type="varchar" not-null="true"/> </property> This is the fully-verbose method of mapping the properties, and the one I personally use. If something happens to your database, you can re-generate the database from this information. It's also very helpful when you are troubleshooting because all of the information about the data is right there. Alternately, you can map the property as follows: <property name="Address1" /> Both methods will provide the same mapping to NHibernate, but as I stated earlier, the more verbose method gives you a lot more flexibility. One of the optional attributes that I generally use on the id and property tags is the type attribute. With this attribute I can tell NHibernate that I am using a particular type of data to store that information in my class. Adding this data type, our property tag would look as follows: <property name="Address1" type="String" /> I also like to use the column tag, just to explicitly link the field with the property in the class, but that again is just preference. The previous code is completely adequate. ID columns The first property from our class that we want to map is the Id property. This tag has a number of attributes we can optionally set, but the simplest way we can map the Id property is as follows: <id name="Id"> <generator class="hilo"/> </id> This tells NHibernate that we have a property in our class named Id which maps to a field in the database called Id and also that we use the hilo method to automatically generate a value for this field. Simple enough! An optional attribute that I generally use on the id tag is the unsaved-value attribute. This attribute specifies what value should be returned in a new object before it is persisted (saved) to the database. Adding this attribute, as well as the type attribute we talked about, the code would look as follows: <id name="Id" type="Int32" unsaved-value="null"> <generator class="hilo"/> </id> As long as our field is named Id in the database, we are good to go. But what if it was named id or address_id? This simply wouldn't handle it. In that case, we would have to add the optional column tag to identify it: <id name="Id"> <column name="address_id"/> <generator class="hilo"/> </id> Now we have mapped our address_id field from the database into a more standard Id property on our class. Some of the additional attributes that are commonly used on the column tag are as follows: name: Define the name of the column in the database length: The length of the field, as defined in the database sql-type: The database definition of the column type not-null: Whether or not the database column allows nulls. not-null="true" specifies a required field Again, these optional attributes simply allow you to further define how your database is created. Some people don't even define the database. They just define the hbm.xml files and use the NHibernate.Tool.hbm2ddl to create a SQL script to do this work!
Read more
  • 0
  • 0
  • 5109

article-image-creating-themes-report-using-birt
Packt
17 Jul 2010
3 min read
Save for later

Creating Themes for a Report using BIRT

Packt
17 Jul 2010
3 min read
Creating themes Using the power of stylesheets and libraries, one has the ability to apply general formatting to an entire report design using themes and reuse these among different reports. Themes provide a simple mechanism to apply a wide range of styles to an entire report design without the need to manually apply them. The following example will move the styles that we have created in our library and will show how to apply them to our report using a theme. For each of the styles we have created, select them under the Outline tab and choose Export to Library…. Choose the ClassicCarsLibrary.rptLibrary file. All of the styles will reside under the defaultTheme themes section, so select this from the drop-down list that appears next to the Theme option. Repeat these steps for all styles we have created in Customer Orders.rptDesign. Delete all of the styles stored in the Customer Orders.rptDesign file. You will notice all the styles disappear from the report designer. In the Outline tab, under the Customer Orders.rptDesign file, select the root element titled Customer Orders.rptDesign. Right-click the element and select Refresh Library. The library should already be shared since we built the report using the library's data source and datasets. If it is not, open the Resource Explorer, choose ClassicCarsLibrary.rptLibrary, right-click and choose Use Library. Under the Property Editor, change the Themes drop down to ClassicCarsLibrarydefaultTheme. When we apply the theme, we will see the detail table header automatically apply the style for table-header. Apply the remaining custom styles to the two columns in the customer information section and the order detail row. Now, we know that we can create several different themes by grouping styles together in libraries. So, when developing reports, you can create several different looks that can be applied to reports, simply by applying themes to reports with the help of libraries. Using external CSS stylesheets Another stylesheet feature is the ability to use external stylesheets and simply link to them. This works out very well when report documents are embedded into existing web portals by using the portals stylesheets to keep a consistent look and feel. This creates a sense of uniformity in the overall site. Imagine that our graphics designer gives us a CSS file and asks us to design our reports around it. There are two ways one can use CSS files in BIRT: Importing CSS files Using CSS as a resource In the following examples we are going to illustrate both scenarios. I have a CSS file containing six styles—five styles that are for predefined elements in reports and one style that is a custom style. The following is the CSS stylesheet for the given report: .page { background-color: #FFFFFF; font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 24px; color: #336699;}.table-group-footer-1 { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 12px; line-height: 24px; color: #333333; background-color: #FFFFCC;}.title { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 24px; line-height: 40px; background-color: #99CC00; color: #003333; font-weight: bolder;}.table-header { font-family: Verdana, Arial, Helvetica, sans-serif; font-size: 20px; background-color: #669900; color: #FFFF33;}.table-footer { font-family: Arial, Helvetica, sans-serif; font-size: 14px; font-weight: bold; line-height: 22px; color: #333333; background-color: #CCFF99;}
Read more
  • 0
  • 0
  • 5108

article-image-setting-oracle-order-management
Packt
21 Feb 2011
4 min read
Save for later

How to set up Oracle Order Management

Packt
21 Feb 2011
4 min read
In order to set up Oracle Order Management, there are some mandatory and optional steps. Most of the information that is required while setting up Oracle Order Management is shared through other modules. Some common features include the following: Inventory organization Key and descriptive Flexfields Unit Of Measure (UOM) Price list Customer Picking rules System options System options are the key values that are used for setting up Oracle Order Management Suite. These parameters contain a list of values that should be used as per our business requirement. We can see some common parameter values in the following figure: Profile options Profile options are the system profiles that we assign as per our requirement. These profiles fulfill critical business requirements. We can use these profiles on four different levels, as follows: Site Application Responsibility User Document sequence Document sequence is used for generating sequential number for orders. Using the document sequence an automatic document sequence number will be generated. These document numbers are user defined. We can identify from where new document sequencing should take place and where it is going to end. Also, we can have a unique number sequence for a particular time period. Using the document sequence, we differentiate our document sequencing for sales order documents. We can assign these document sequences to particular transaction types. Each transaction type has its own document sequence numbering. In the Name field, we will give a unique name for the number sequence. Select the application for which the document sequence will be working, and enter start and finish dates from when to when this sequence will be applicable. If we want to keep this document sequence for an unspecified period, then we will keep the To field blank. For automatic number generation, select the Type as Automatic. For the assignment of the document sequence, we will again select Order Management in Application field, which we have selected at the time of defining the new sequence. In the Category field, we will select the order type for which we require the document sequence. In the Ledger field, select the ledger and select Automatic in the Method Type field. Under the Assignment tab, we will again select the sequence that should be used for the transaction type and the Start Date from when this template would be applicable. Transaction type We use transaction types to manage different types of sales order. These transaction types can be according to business requirements (how we want to differentiate our orders). There are various options for which we can classify a new transaction type, as follows: Export sales Local sales Territory-based Price-based Workflows are assigned to transaction types. We can assign price lists, payment terms, invoicing rules, and the inventory organization from where the items against the order would be picked and shipped. To create a new transaction type in Oracle Order Management, navigate to Setup | Transaction Types. Here we will give the name of the new transaction type such as Standard Order Type and so on. Now we will attach the Fulfillment Flow and Negotiation Flow to this transaction type. We will also assign an effective date to this transaction type in order to start working from that date. Also, we can assign the price list and the picking rule to this transaction type. Now under the Shipping tab, we will provide the information for the Warehouse from where the inventory should be picked. We can also leave that blank if we have specified that at the picking-rule level or we can specify that at the order-entry level. We can specify the FOB field. We can attach the transaction type freight terms, as well as specify the shipping method at Transaction Type level. Under the Finance tab, we enter information that would be required in Oracle Accounts Receivable at the time of invoice creation. We can also specify the account for Cost of Goods Sold (COGS) at the Transaction Type level; else we have the option to pick from the Inventory Organization. Invoice Source type will be the source type used for invoices interfaced to Accounts Receivable. We can also specify a particular invoicing rule for the transaction type.
Read more
  • 0
  • 0
  • 5105
article-image-deep-learning-and-regression-analysis
Packt
09 Jan 2017
6 min read
Save for later

Deep learning and regression analysis

Packt
09 Jan 2017
6 min read
In this article by Richard M. Reese and Jennifer L. Reese, authors of the book, Java for Data Science, We will discuss neural networks can be used to perform regression analysis. However, other techniques may offer a more effective solution. With regression analysis, we want to predict a result based on several input variables (For more resources related to this topic, see here.) We can perform regression analysis using an output layer that consists of a single neuron that sums the weighted input plus bias of the previous hidden layer. Thus, the result is a single value representing the regression. Preparing the data We will use a car evaluation database to demonstrate how to predict the acceptability of a car based on a series of attributes. The file containing the data we will be using can be downloaded from: http://archive.ics.uci.edu/ml/machine-learning-databases/car/car.data. It consists of car data such as price, number of passengers, and safety information, and an assessment of its overall quality. It is this latter element that we will try to predict. The comma-delimited values in each attribute are shown next, along with substitutions. The substitutions are needed because the model expects numeric data: Attribute Original value Substituted value Buying price vhigh, high, med, low 3,2,1,0 Maintenance price vhigh, high, med, low 3,2,1,0 Number of doors 2, 3, 4, 5-more 2,3,4,5 Seating 2, 4, more 2,4,5 Cargo space small, med, big 0,1,2 Safety low, med, high 0,1,2 There are 1,728 instances in the file. The cars are marked with four classes: Class Number of instances Percentage of instances Original value Substituted value Unacceptable 1210 70.023% unacc 0 Acceptable 384 22.222% acc 1 Good 69 3.99% good 2 Very good 65 3.76% v-good 3 Setting up the class We start with the definition of a CarRegressionExample class, as shown next: public class CarRegressionExample { public CarRegressionExample() { try { ... } catch (IOException | InterruptedException ex) { // Handle exceptions } } public static void main(String[] args) { new CarRegressionExample(); } } Reading and preparing the data The first task is to read in the data. We will use the CSVRecordReader class to get the data: RecordReader recordReader = new CSVRecordReader(0, ","); recordReader.initialize(new FileSplit(new File("car.txt"))); DataSetIterator iterator = new RecordReaderDataSetIterator(recordReader, 1728, 6, 4); With this dataset, we will split the data into two sets. Sixty five percent of the data is used for training and the rest for testing: DataSet dataset = iterator.next(); dataset.shuffle(); SplitTestAndTrain testAndTrain = dataset.splitTestAndTrain(0.65); DataSet trainingData = testAndTrain.getTrain(); DataSet testData = testAndTrain.getTest(); The data now needs to be normalized: DataNormalization normalizer = new NormalizerStandardize(); normalizer.fit(trainingData); normalizer.transform(trainingData); normalizer.transform(testData); We are now ready to build the model. Building the model A MultiLayerConfiguration instance is created using a series of NeuralNetConfiguration.Builder methods. The following is the dice used. We will discuss the individual methods following the code. Note that this configuration uses two layers. The last layer uses the softmax activation function, which is used for regression analysis: MultiLayerConfiguration conf = new NeuralNetConfiguration.Builder() .iterations(1000) .activation("relu") .weightInit(WeightInit.XAVIER) .learningRate(0.4) .list() .layer(0, new DenseLayer.Builder() .nIn(6).nOut(3) .build()) .layer(1, new OutputLayer .Builder(LossFunctions.LossFunction .NEGATIVELOGLIKELIHOOD) .activation("softmax") .nIn(3).nOut(4).build()) .backprop(true).pretrain(false) .build(); Two layers are created. The first is the input layer. The DenseLayer.Builder class is used to create this layer. The DenseLayer class is a feed-forward and fully connected layer. The created layer uses the six car attributes as input. The output consists of three neurons that are fed into the output layer and is duplicated here for your convenience: .layer(0, new DenseLayer.Builder() .nIn(6).nOut(3) .build()) The second layer is the output layer created with the OutputLayer.Builder class. It uses a loss function as the argument of its constructor. The softmax activation function is used since we are performing regression as shown here: .layer(1, new OutputLayer .Builder(LossFunctions.LossFunction .NEGATIVELOGLIKELIHOOD) .activation("softmax") .nIn(3).nOut(4).build()) Next, a MultiLayerNetwork instance is created using the configuration. The model is initialized, its listeners are set, and then the fit method is invoked to perform the actual training. The ScoreIterationListener instance will display information as the model trains which we will see shortly in the output of this example. Its constructor argument specifies the frequency that information is displayed: MultiLayerNetwork model = new MultiLayerNetwork(conf); model.init(); model.setListeners(new ScoreIterationListener(100)); model.fit(trainingData); We are now ready to evaluate the model. Evaluating the model In the next sequence of code, we evaluate the model against the training dataset. An Evaluation instance is created using an argument specifying that there are four classes. The test data is fed into the model using the output method. The eval method takes the output of the model and compares it against the test data classes to generate statistics. The getLabels method returns the expected values: Evaluation evaluation = new Evaluation(4); INDArray output = model.output(testData.getFeatureMatrix()); evaluation.eval(testData.getLabels(), output); out.println(evaluation.stats()); The output of the training follows, which is produced by the ScoreIterationListener class. However, the values you get may differ due to how the data is selected and analyzed. Notice that the score improves with the iterations but levels out after about 500 iterations: 12:43:35.685 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 0 is 1.443480901811554 12:43:36.094 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 100 is 0.3259061845624861 12:43:36.390 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 200 is 0.2630572026049783 12:43:36.676 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 300 is 0.24061281470878784 12:43:36.977 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 400 is 0.22955121170274934 12:43:37.292 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 500 is 0.22249920540161677 12:43:37.575 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 600 is 0.2169898450109222 12:43:37.872 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 700 is 0.21271599814600958 12:43:38.161 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 800 is 0.2075677126088741 12:43:38.451 [main] INFO o.d.o.l.ScoreIterationListener - Score at iteration 900 is 0.20047317735870715 This is followed by the results of the stats method as shown next. The first part reports on how examples are classified and the second part displays various statistics: Examples labeled as 0 classified by model as 0: 397 times Examples labeled as 0 classified by model as 1: 10 times Examples labeled as 0 classified by model as 2: 1 times Examples labeled as 1 classified by model as 0: 8 times Examples labeled as 1 classified by model as 1: 113 times Examples labeled as 1 classified by model as 2: 1 times Examples labeled as 1 classified by model as 3: 1 times Examples labeled as 2 classified by model as 1: 7 times Examples labeled as 2 classified by model as 2: 21 times Examples labeled as 2 classified by model as 3: 14 times Examples labeled as 3 classified by model as 1: 2 times Examples labeled as 3 classified by model as 3: 30 times ==========================Scores======================================== Accuracy: 0.9273 Precision: 0.854 Recall: 0.8323 F1 Score: 0.843 ======================================================================== The regression model does a reasonable job with this dataset. Summary In this article, we examined deep learning and regression analysis. We showed how to prepare the data and class, build the model, and evaluate the model. We used sample data and displayed output statistics to demonstrate the relative effectiveness of our model. Resources for Article: Further resources on this subject: KnockoutJS Templates [article] The Heart of It All [article] Bringing DevOps to Network Operations [article]
Read more
  • 0
  • 0
  • 5104

article-image-models-and-animations-away3d-36
Packt
28 Jan 2011
7 min read
Save for later

Models and Animations with Away3D 3.6

Packt
28 Jan 2011
7 min read
Away3D 3.6 Essentials Take Flash to the next dimension by creating detailed, animated, and interactive 3D worlds with Away3D Create stunning 3D environments with highly detailed textures Animate and transform all types of 3D objects, including 3D Text Eliminate the need for expensive hardware with proven Away3D optimization techniques, without compromising on visual appeal Written in a practical and illustrative style, which will appeal to Away3D beginners and Flash developers alike Models and Animations It is possible to create a 3D object from the ground up using basic elements like vertices, triangle faces, Sprite3D objects, and segments. However, creating each element manually in code is not practical for more complex models. While the classes from the away3d.primitives package offer a solution by providing a way to quickly create some standard shapes, advanced applications will need to display more complex shapes. For those situations where these standard primitive shapes do not provide enough fexibility, Away3D can load and display 3D models created by external 3D modeling applications. 3D modeling applications are specifcally designed to provide a visual environment in which 3D models can be manipulated. It is certainly much more convenient to create or edit a 3D mesh in one of these applications than it is to build up a mesh in code using ActionScript. Away3D can directly load a wide range of 3D formats. The process of exporting a 3D mesh into a fle that can be used with Away3D will be covered for the following 3D modeling applications: 3ds Max: A popular commercial modeling, animation, and rendering application which runs on Windows. Blender: A free and open source modeling application, which is available on a number of platforms, including Windows, Linux, and MacOS. Milkshape: A commercial low-polygon modeler which runs on Windows that was originally designed for the game Half-Life. Sketch-up: A free 3D modeling application provided by Google. A commercial version is also available that includes a number of additional features. Sketch-up runs on Windows and MacOS. Actually creating a model in these 3D modeling applications is outside the scope of this article. However, 3D models are provided that can be loaded and then exported from these applications, which will allow you run through the procedure without having to know how to make a 3D model from scratch. 3D formats supported by Away3D Away3D includes classes that can load a wide range of 3D model fle formats. All the supported formats can be used to load a static 3D model, while a smaller number can be used to load animated models. The following table lists the 3D model formats supported by Away3D, their common extensions, whether they can load animated 3D models, and the Away3D class that is used to load and parse them. Exporting 3D models The following instructions show you how to export a Collada fle from a number of different 3D modeling applications. Collada is an open, XML-based format that has been designed to provide a way to exchange data between 3D applications. Away3D supports loading both static and animated 3D models from the Collada format. Exporting from 3ds Max 3ds Max is a commercial 3D modeling application. At the time of writing, the latest version of the ColladaMax plugin, which is the plugin that we will use to export the 3D model, was 3.05C. This version supports 3ds Max 2008, 3ds Max 9, 3ds Max 8 SP3, or 3ds Max 7 SP1. Note that this version does not support 3ds Max 2010 or 2011. A trial version of 3ds Max 9 is available, although it can be diffcult to fnd. You should be able to fnd a copy if you search the Internet for Autodesk3dsMax2009_ENU_TrialDownload.exe, which is the name of fle that will install the trial version of 3ds Max 9. Download and install the ColladaMax plugin from http://sourceforge.net/projects/colladamaya/files/. Open 3ds Max. Click File | Open. Select the MAX file you wish to open and click on the Open button. Click File | Export from within 3ds Max. Select COLLADA (*.DAE) from the Save as type drop-down list. Select the same directory where the original MAX fle was located. Type a fle name for the exported fle in the File name textbox, and click on the Save button. In the ColladaMax Export dialog box make sure the following checkboxes are enabled: Relative Paths Normals Triangulate If you want to export animations, enable the Enable export checkbox. If you want to export a specifc range of frames, enable the Sample animation checkbox and enter the required values in the Start and End textboxes. Click on the OK button to export the fle. Exporting from MilkShape The Collada exporter supplied with MilkShape does not export animations. So even if the MilkShape MS3D file we are loading contains an animated model, the exported Collada DAE file will be a static mesh. A trial version of MilkShape can be downloaded and installed from its website at http://chumbalum.swissquake.ch/. Click File | Open. Select the MS3D file you wish to open and click on the Open button. Click File | Export | COLLADA…. Select the same directory where the original MS3D file was located. Type a flename for the exported fle in the File name textbox and click the Save button. Exporting from Sketch-Up Like Milkshape, Sketch-up does not support exporting animated Collada fles. Sketch-Up can be downloaded for free from http://sketchup.google.com/. Click File | Open. Select the SKP file you wish to open and click on the Open button. Click File | Export | 3D Model…. Select Collada File (*.dae) from the Export type combobox. Select an appropriate directory, and type a filename for the exported file in the File name textbox. Click on the Options... button. Make sure the Triangulate All Faces checkbox is enabled. If the Export Texture Maps option is enabled, Sketch-Up will export the textures along with the DAE file. Click on the OK button to save the options. Click on the Export button to export the file. Exporting from Blender The latest version of the Collada exporter for Blender, which is version 0.3.162 at the time of writing, does support exporting animations. However, in most cases Away3D will not load these animations correctly. It is recommended that only static meshes be exported from Blender to a Collada fle. Click File | Open.... Select the BLEND file you wish to open and click on the Open button. Click File | Export | COLLADA1.4 (*.dae) .... Type a flename for the exported fle in the directory where the original BLEND fle was located in the Export File textbox. Make sure the Triangles and Use Relative Paths buttons are pressed. Click on the Export and Close button. A note about the Collada exporters Despite being free and open standard, exporting to a Collada fle that can be correctly parsed by Away3D can be a hit-and-miss affair. The Collada exporters for 3ds Max are a good example. During testing, neither the built-in Collada exporter included with 3ds Max, nor the third-party OpenCollada exporter from http://opencollada.org (version 1.2.5 was the latest version at the time of writing) would export an animated Collada fle that Away3D could read. At best Away3D would display a static mesh, and at worst it would throw an exception when reading the DAE fle. Likewise, neither of the Collada exporters that come with Blender (which was at version 2.49b at the time of writing) would consistently export an animated Collada mesh that was compatible with Away3D. It is important to be aware that just because a 3D modeling application says that it can export to a Collada fle, this is no guarantee that the resulting fle can be read correctly by Away3D.
Read more
  • 0
  • 0
  • 5101

article-image-article-getting-started-with-html5-modernizer-url
Packt
31 Jan 2013
4 min read
Save for later

Getting Started with Modernizr

Packt
31 Jan 2013
4 min read
(For more resources on this subject, see here.) Detect and design with features, not User agents (browsers) What if you could build your website based on features instead of for the individual browser idiosyncrasies by manufacturer and version, making your website not just backward compatible but also forward compatible? You could quite potentially build a fully backward and forward compatible experience using a single code base across the entire UA spectrum. What I mean by this is instead of baking in an MSIE 7.0 version, an MSIE 8.0 version , a Firefox version, and so on of your website, and then using JavaScript to listen for, or sniff out, the browser version in play, it would be much simpler to instead build a single version of your website that supports all of the older generation, latest generation, and in many cases even future generation technologies, such as a video API,box-shadow,and first-of-type. Think of your website as a full-fledged cable television network broadcasting over 130 channels, and your users as customers that sign up for only the most basic package available, of only 15 channels. Any time that they upgrade their cable (browser) package to one offering additional channels (features), they can begin enjoying them immediately because you have already been broadcasting to each one of those channels the entire time. What happens now is that a proverbial line is drawn in the sand, and the site is built on the assumption that a particular set of features will exist and are thus supported. If not, fallbacks are in place to allow a smooth degradation of the experience as usual, but more importantly the site is built to adopt features that the browser will eventually have. Modernizr can detect CSS features, such as @font-face , box-shadow , and CSS gradients. It can also detect HTML5 elements, such as canvas , localstorage, and application cache. In all it can detect over 40 features for you, the developer. Another term commonly used to describe this technique is "progressive enhancement ". When the time fi nally comes that the user decides to upgrade their browser, the new features that the more recent browser version brings with it, for example text-shadow , will automatically be detected and picked up by your website, to be leveraged by your site with no extra work or code from you when they do. Without any additional work on your part, any text that is assigned text-shadow attributes will turn on at the fl ick of a switch so that user's experience will smoothly, and progressively be enhanced. What is Modernizr? More importantly, why should you use it? At its foundation, Modernizr is a feature-detection library powered by none other than JavaScript. Here is an example of conditionally adding CSS classes based on the browser, also known as the User Agent . When the browser parses this HTML document and fi nds a match, that class will be conditionally added to the page. Now that the browser version has been found, the developer can use CSS to alter the page based on the version of the browser that is used to parse the page. In the following example, IE 7, IE 8, and IE 9 all use a different method for a drop shadow attribute on an anchor element: /* IE7 Conditional class using UA sniffing */ .lt-ie7 a{ display: block; float: left; background: url( drop-shadow. gif ); } .lt-ie8 a{ display: inline-block; background: url( drop-shadow.png ); } .lt-ie9 a{ display: inline-block; box-shadow: 10px 5px 5px rgba(0,0,0,0.5); } The problem with the conditional method of applying styles is that not only does it require more code, but it also leaves a burden on the developer to know what browser version is capable of a given feature, in this case box-shadow . Here is the same example using Modernizr . Note how Modernizr has done the heavy lifting for you, irrespective of whether or not the box-shadow feature is supported by the browser: /* Box shadow using Modernizr CSS feature detected classes */ .box-shadow a{ box-shadow: 10px 5px 5px rgba(0,0,0,0.5); } .no-box-shadow a{ background: url( drop-shadow.gif ); }   The Modernizr namespace The Modernizr JavaScript library in your web page's header is a lightweight feature library that will test your browser for the features that it may or may not support, and store those results in a JavaScript namespace aptly named Modernizr. You can then use those test results as you build your website. From this point on everything you need to know about what features your user's browser can and cannot support can be checked for in two separate places. Going back to the cable television analogy, you now know what channels (features) your user does and does not have, and can act accordingly.
Read more
  • 0
  • 0
  • 5100
article-image-use-iso-image-installation-windows8-virtual-machine
Packt
29 Oct 2013
5 min read
Save for later

Use Of ISO Image for Installation of Windows8 Virtual Machine

Packt
29 Oct 2013
5 min read
(For more resources related to this topic, see here.) In the past, the only way that a Windows consumer could acquire the Windows OS was to purchase the installation media on a CD-ROM, floppy disk, or physical computer accessory, which had to be ordered online or bought from a local bricks and mortar store. Now with the recent release of Windows 8, Microsoft is continuing to extend its installation platform to digital media on a large scale. Windows 8 simplifies the process by using a web platform installer called Windows 8 Upgrade Assistant, which makes it easier to download, burn physical copies, and create a backup copy of the installation media. This form of digital distribution allows Microsoft to deploy products at a faster speed to the market, and increase its capacity to meet consumer demands. Getting ready To proceed with this recipe you will need to download Windows 8, so go to http://www.windows.com/buy. How to do it... In the first part of this section we will look into downloading the Windows 8 ISO file. Skip these steps if you have already downloaded the Windows 8 ISO file in advance. Visit the Microsoft website to purchase Windows 8 and then select the option to download the Windows 8 Upgrade Assistant file. Launch the Windows 8 Upgrade Assistant file and proceed with purchasing Windows 8. After completing the transaction, wait while the Windows 8 setup files are downloaded. The estimated download time varies, based on your Internet connection.speed. In addition, you have the option to pause the download and resume it later. Once the download is complete, the Windows 8 Upgrade Assistant will verify the integrity of the download by checking for file corruption and missing files. Wait while the Windows 8 setup gets the files ready to begin the installation. You will see a prompt that says Install Windows 8. Select the Install by creating media radio button. Select ISO file, then click on the Save button. When prompted to select a location to save the ISO file, choose a folder location and type Windows 8 as the filename. Then click on the Save button. When the product key is revealed, write it down and store it somewhere secure. Then click on the Finish button. The following set of instructions explains the details of installing Windows 8 on a newly created virtual machine using VMware Player. These steps are similar to the installation procedures encountered when installing Windows 8 on a physical computer: Open the VMware application by going to Start | All Programs| VMware. Then click on the VMware Player menu item. If you are opening VMware Player for the first time, the VMware Player License Agreement prompt will be displayed. Read the terms and conditions. Select Yes, I accept the terms in the license agreement to proceed to open the VMware Player application. If you select No, I do not accept the terms in the license agreement, you will not be permitted to continue. The Welcome to the New Virtual Machine Wizard screen will be visible. Click on Create a New Virtual Machine on the right side of the window. Select the Installer disc image file (iso): radio button. Then click on the Browse button. Browse to the directory of the Windows 8 ISO image and click on Open. You will see an information icon that says Windows 8 detected. This operating system will use Easy Install. Click on the Next button to continue. Under Easy Install Information, type in the Windows product information and click on Next to continue. You now have the options to: Enter the Windows product key Select the version of Windows to install (Windows 8 or Windows 8 Pro) Enter the full name of the computer Enter a password, which is optional If you do not enter a product key, you will receive a message saying that it can be manually entered later. Enter a new virtual machine name and directory location to install the virtual machine. For example, type Windows 8 VM and then click on the Next button to continue. Enter 16 as the Maximum disk size (GB) and store the virtual disk as a single file. Then click on the Finish button. This is because Windows 8 requires a minimum of 16 GB of free hard drive space. The Windows 8 virtual machine will power on automatically for the first time. At the Ready to Create Virtual Machine prompt, click on the Finish button. Remember that Windows 8 requires a minimum of 16 GB hard disk free space for the 32 bit installation and 20 GB space for the 64 bit installation. VMware will prompt you to install VMware Tools for Windows 2000 and later, click on the Remind Me Later button. The virtual machine will automatically boot up to the Windows 8 setup wizard. Wait until the Windows installation is complete. The virtual machine will reboot several times during this process. You will see various Windows 8 pictorials during the installation; please be patient. Once the installation is complete, your virtual machine will be immediately directed to the Windows 8 home screen. Summary This article introduced you to downloading of the Windows 8 operating system as an ISO, creating a new virtual machine, and installing Window 8 as a virtual machine. Resources for Article: Further resources on this subject: VMware View 5 Desktop Virtualization [Article] Windows 8 with VMware View [Article] Cloning and Snapshots in VMware Workstation [Article]    
Read more
  • 0
  • 0
  • 5098

article-image-creating-poi-listview-layout
Packt
04 Sep 2015
27 min read
Save for later

Creating the POI ListView layout

Packt
04 Sep 2015
27 min read
In this article by Nilanchala Panigrahy, author of the book Xamarin Mobile Application Development for Android Second Edition, will walk you through the activities related to creating and populating a ListView, which includes the following topics: Creating the POIApp activity layout Creating a custom list row item layout The ListView and ListAdapter classes (For more resources related to this topic, see here.) It is technically "possible to create and attach the user interface elements to your activity using C# code. However, it is a bit of a mess. We will go with the most common approach by declaring the XML-based layout. Rather than deleting these files, let's give them more appropriate names and remove unnecessary content as follows: Select the Main.axml file in Resources | Layout and rename it to "POIList.axml. Double-click on the POIList.axml file to open it in a layout "designer window.Currently, the POIList.axml file contains the layout that was created as part of the default Xamarin Studio template. As per our requirement, we need to add a ListView widget that takes the complete screen width and a ProgressBar in the middle of the screen. The indeterminate progress "bar will be displayed to the user while the data is being downloaded "from the server. Once the download is complete and the data is ready, "the indeterminate progress bar will be hidden before the POI data is rendered on the list view. Now, open the "Document Outline tab in the designer window and delete both the button and LinearLayout. Now, in the designer Toolbox, search for RelativeLayout and drag it onto the designer layout preview window. Search for ListView in the Toolbox search field and drag it over the layout designer preview window. Alternatively, you can drag and drop it over RelativeLayout in the Document Outline tab. We have just added a ListView widget to POIList.axml. Let's now open the Properties pad view in the designer window and edit some of its attributes: There are five buttons at the top of the pad that switch the set of properties being edited. The @+id notation notifies the compiler that a new resource ID needs to be created to identify the widget in API calls, and listView1 identifies the name of the constant. Now, perform the following steps: Change the ID name to poiListView and save the changes. Switch back to the Document Outline pad and notice that the ListView ID is updated. Again, switch back to the Properties pad and click on the Layout button. Under the View Group section of the layout properties, set both the Width and Height properties to match_parent. The match_parent value "for the Height and Width properties tells us that the ListView can use the entire content area provided by the parent, excluding any margins specified. In our case, the parent would be the top-level RelativeLayout. Prior to API level 8, fill_parent was used instead of match_parent to accomplish the same effect. In API level 8, fill_parent was deprecated and replaced with match_parent for clarity. Currently, both the constants are defined as the same value, so they have exactly the same effect. However, fill_ parent may be removed from the future releases of the API; so, going forward, match_parent should be used. So far, we have added a ListView to RelativeLayout, let's now add a Progress Bar to the center of the screen. Search for Progress Bar in the Toolbox search field. You will notice that several types of progress bars will be listed, including horizontal, large, normal, and small. Drag the normal progress bar onto RelativeLayout.By default, the Progress Bar widget is aligned to the top left of its parent layout. To align it to the center of the screen, select the progress bar in the Document Outline tab, switch to the Properties view, and click on the Layout tab. Now select the Center In Parent checkbox, and you will notice that the progress bar is aligned to the center of the screen and will appear at the top of the list view. Currently, the progress bar is visible in the center of the screen. By default, this could be hidden in the layout and will be made visible only while the data is being downloaded. Change the Progress Bar ID to progressBar and save the changes. To hide the Progress Bar from the layout, click on the Behavior tab in the Properties view. From Visibility, select Box, and then select gone.This behavior can also be controlled by calling setVisibility() on any view by passing any of the following behaviors. The View.Visibility property" allows you to control whether a view is visible or not. It is based on the ViewStates enum, which defines the following values: Value Description Gone This value tells the parent ViewGroup to treat the View as though it does not exist, so no space will be allocated in the layout Invisible This value tells the parent ViewGroup to hide the content for the View; however, it occupies the layout space Visible This value tells the parent ViewGroup to display the content of the View Click on the Source tab to switch the IDE context from visual designer to code, and see what we have built so far. Notice that the following code is generated for the POIList.axml layout: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout p1_layout_width="match_parent" p1_layout_height="match_parent" p1_id="@+id/relativeLayout1"> <ListView p1_minWidth="25px" p1_minHeight="25px" p1_layout_width="match_parent" p1_layout_height="match_parent" p1_id="@+id/poiListView" /> <ProgressBar p1_layout_width="wrap_content" p1_layout_height="wrap_content" p1_id="@+id/progressBar" p1_layout_centerInParent="true" p1_visibility="gone" /> </RelativeLayout> Creating POIListActivity When we created the" POIApp solution, along with the default layout, a default activity (MainActivity.cs) was created. Let's rename the MainActivity.cs file "to POIListActivity.cs: Select the MainActivity.cs file from Solution Explorer and rename to POIListActivity.cs. Open the POIListActivity.cs file in the code editor and rename the "class to POIListActivity. The POIListActivity class currently contains the code that was "created automatically while creating the solution using Xamarin Studio. We will write our own activity code, so let's remove all the code from the POIListActivity class. Override the OnCreate() activity life cycle callback method. This method will be used to attach the activity layout, instantiate the views, and write other activity initialization logic. Add the following code blocks to the POIListActivity class: namespace POIApp { [Activity (Label = "POIApp", MainLauncher = true, Icon = "@ drawable/icon")] public class POIListActivity : Activity { protected override void OnCreate (Bundle savedInstanceState) { base.OnCreate (savedInstanceState); } } } Now let's set the activity content layout by calling the SetContentView(layoutId) method. This method places the layout content directly into the activity's view hierarchy. Let's provide the reference to the POIList layout created in previous steps. At this point, the POIListActivity class looks as follows: namespace POIApp { [Activity (Label = "POIApp", MainLauncher = true, Icon = "@drawable/icon")] public class POIListActivity : Activity { protected override void OnCreate (Bundle savedInstanceState) { base.OnCreate (savedInstanceState); SetContentView (Resource.Layout.POIList); } } } Notice that in the preceding code snippet, the POIListActivity class uses some of the [Activity] attributes such as Label, MainLauncher, and Icon. During the build process, Xamarin.Android uses these attributes to create an entry in the AndroidManifest.xml file. Xamarin makes it easier by allowing all of the Manifest properties to set using attributes so that you never have to modify them manually in AndroidManifest.xml. So far, we have "declared an activity and attached the layout to it. At this point, if you run the app on your Android device or emulator, you will notice that a blank screen will be displayed. Creating the POI list row layout We now turn our attention to the" layout for each row in the ListView widget. "The" Android platform provides a number of default layouts out of the box that "can be used with a ListView widget: Layout Description SimpleListItem1 A "single line with a single caption field SimpleListItem2 A "two-line layout with a larger font and a brighter text color for the first field TwoLineListItem A "two-line layout with an equal sized font for both lines and a brighter text color for the first line ActivityListItem A "single line of text with an image view All of the preceding three layouts provide a pretty standard design, but for more control over content layout, a custom layout can also be created, which is what is needed for poiListView. To create a new layout, perform the following steps: In the Solution pad, navigate to Resources | Layout, right-click on it, and navigate to Add | New File. Select Android from the list on the left-hand side, Android Layout from the template list, enter POIListItem in the name column, and click on New. Before we proceed to lay out the design for each of the row items in the list, we must draw on a piece of paper and analyze how the UI will look like. In our example, the POI data will be organized as follows: There are a "number of ways to achieve this layout, but we will use RelativeLayout to achieve the same result. There is a lot going on in this diagram. Let's break it down as follows: A RelativeLayout view group is used as the top-level container; it provides a number of flexible options for positioning relative content, its edges, or other content. An ImageView widget is used to display a photo of the POI, and it is anchored to the left-hand side of the RelativeLayout utility. Two TextView widgets are used to display the POI name and address information. They need to be anchored to the right-hand side of the ImageView widget and centered within the parent RelativeLayout "utility. The easiest way to accomplish this is to place both the TextView classes inside another layout; in this case, a LinearLayout widget with "the orientation set to vertical. An additional TextView widget is used to display the distance, and it is anchored on the right-hand side of the RelativeLayout view group and centered vertically. Now, our task is to get this definition into POIListItem.axml. The next few sections describe how to "accomplish this using the Content view of the designer when feasible and the Source view when required. Adding a RelativeLayout view group The RelativeLayout layout "manager allows its child views to be positioned relative to each other or relative to the container or another container. In our case, for building the row layout, as shown in the preceding diagram, we can use RelativeLayout as a top-level view group. When the POIListItem.axml layout file was created, by default a top-level LinearLayout was added. First, we need to change the top-level ViewGroup to RelativeLayout. The following section will take you through the steps to complete the layout design for the POI list row: With POIListItem.axml opened in the content mode, select the entire layout by clicking on the content area. You should see a blue outline going around the edge. Press Delete. The LinearLayout view group will be deleted, and you will see a message indicating that the layout is empty. Alternatively, you can also select the LinearLayout view group from the Document Outline tab and press Delete. Locate the RelativeLayout view group in the toolbox and drag it onto the layout. Select the RelativeLayout view group from Document Outline. Open the Properties pad and change the following properties: The Padding option to 5dp The Layout Height option to wrap_content The Layout Width option to match_parent The padding property controls how much space will be placed around each item as a margin, and the height determines the height of each list row. Setting the Layout Width option to match_ parent will cause the POIListItem content to consume the entire width of the screen, while setting the Layout Height option to wrap_content will cause each row to be equal to the longest control. Switch to the Code view to see what has been added to the layout. Notice that the following lines of code have been added to RelativeLayout: <RelativeLayout p1_minWidth="25px" p1_minHeight="25px" p1_layout_width="match_parent" p1_layout_height="wrap_content" p1_id="@+id/relativeLayout1" p1_padding="5dp"/> Android runs on a "variety of devices that offer different screen sizes and densities. When specifying dimensions, you can use a number of different units, including pixels (px), inches (in), and density-independent pixels (dp). Density-independent pixels are abstract units based on 1 dp being 1 pixel on a 160 dpi screen. At runtime, Android will scale the actual size up or down based on the actual screen density. It is a best practice to specify dimensions using density-independent pixels. Adding an ImageView widget The ImageView widget in "Android is used to display the arbitrary image for different sources. In our case, we will download the images from the server and display them in the list. Let's add an ImageView widget to the left-hand side of the layout and set the following configurations: Locate the ImageView widget in the toolbox and drag it onto RelativeLayout. With the ImageView widget selected, use the Properties pad to set the ID to poiImageView. Now, click on the Layout tab in the Properties pad and set the Height and Width values to 65 dp. In the property grouping named RelativeLayout, set Center Vertical to true. Simply clicking on the checkbox does not seem to work, but you can click on the small icon that looks like an edit box, which is to the right-hand side, and just enter true. If everything else fails, just switch to the Source view and enter the following code: p1:layout_centerVertical="true" In the property grouping named ViewGroup, set the Margin Right to 5dp. This brings some space between the POI image and the POI name. Switch to the Code view to see what has been added to the layout. Notice the following lines of code added to ImageView: <ImageView p1_src="@android:drawable/ic_menu_gallery" p1_layout_width="65dp" p1_layout_height="65dp" p1_layout_marginRight="5dp" p1_id="@+id/poiImageView" /> Adding a LinearLayout widget LinearLayout is one of the "most basic layout managers that organizes its child "views either horizontally or vertically based on the value of its orientation property. Let's add a LinearLayout view group that will be used to lay out "the POI name and address data as follows: Locate the LinearLayout (vertical) view group in the toolbox. Adding this widget is a little trickier because we want it anchored to the right-hand side of the ImageView widget. Drag the LinearLayout view group to the right-hand side of the ImageView widget until the edge turns to a blue dashed line, and then drop the LinearLayout view group. It will be aligned with the right-hand side of the ImageView widget. In the property grouping named RelativeLayout of the Layout section, set Center Vertical to true. As before, you will need to enter true in the edit box or manually add it to the Source view. Switch to the Code view to see what has been added to the layout. Notice "the following lines of code added to LinearLayout: <LinearLayout p1_orientation="vertical" p1_minWidth="25px" p1_minHeight="25px" p1_layout_width="wrap_content" p1_layout_height="wrap_content" p1_layout_toRightOf="@id/poiImageView" p1_id="@+id/linearLayout1" p1_layout_centerVertical="true" /> Adding the name and address TextView classes Add the TextView classes to display the POI name and address: Locate TextView in" the Toolbox and add a TextView class to the layout. "This TextView needs to be added within the LinearLayout view group we just added, so drag TextView over the LinearLayout view group until it turns blue and then drop it. Name the TextView ID as nameTextView and set the text size to 20sp. "The text size can be set in the Style section of the Properties pad; you will need to expand the Text Appearance group by clicking on the ellipsis (...) button on the right-hand side. Scale-independent pixels (sp) "are like dp units, but they are also scaled by the user's font size preference. Android allows users to select a font size in the Accessibility section of Settings. When font sizes are specified using sp, Android will not only take into account the screen density when scaling text, but will also consider the user's accessibility settings. It is recommended that you specify font sizes using sp. Add "another TextView to the LinearLayout view group using the same technique except dragging the new widget to the bottom edge of the nameTextView until it changes to a blue dashed line and then drop it. This will cause the second TextView to be added below nameTextView. Set the font size to 14sp. Change the ID of the newly added TextView to addrTextView. Now change the sample text for both nameTextView and addrTextView to POI Name and City, State, Postal Code. To edit the text shown in TextView, just double tap the widget on the content panel. This enables a small editor that allows you to enter the text directly. Alternately, you can change the text by entering a value for the Text property in the Widget section of the Properties pad. It is a design practice to declare all your static strings in the Resources/values/string.xml file. By declaring the strings in the strings.xml file, you can easily translate your whole app to support other languages. Let's add the following strings to string.xml: <string name="poi_name_hint">POI Name</string> <string name="address_hint">City, State, Postal Code.</string> You can now change the Text property of both nameTextView and addrTextView by selecting the ellipsis (…) button, which is next to the Text property in the Widget section of the Properties pad. Notice that this will open a dialog window that lists all the strings declared in the string.xml file. Select the appropriate strings for both TextView objects. Now let's switch to the Code view to see what has been added to the layout. Notice the following lines of code added inside LinearLayout: <TextView p1_layout_width="match_parent" p1_layout_height="wrap_content" p1_id="@+id/nameTextView " p1_textSize="20sp" p1_text="@string/app_name" /> <TextView p1_text="@string/address_hint" p1_layout_width="match_parent" p1_layout_height="wrap_content" p1_id="@+id/addrTextView " p1_textSize="14sp" /> Adding the distance TextView Add a TextView to show "the distance from POI: Locate the TextView in the toolbox and add a TextView to the layout. This TextView needs to be anchored to the right-hand side of the RelativeLayout view group, but there is no way to visually accomplish this; so, we will use a multistep process. Initially, align the TextView with the right-hand edge of the LinearLayout view group by dragging it to the left-hand side until the edge changes to a dashed blue line and drop it. In the Widget section of the Properties pad, name the widget as distanceTextView and set the font size to 14sp. In the Layout section of the Properties pad, set Align Parent Right to true, Center Vertical to true, and clear out the linearLayout1 view group name in the To Right Of layout property. Change the sample text to 204 miles. To do this, let's add a new string entry to string.xml and set the Text property from the Properties pad.The following screenshot depicts what should be seen from the Content view "at this point: Switch back to the "Source tab in the layout designer, and notice the following code generated for the POIListItem.axml layout: <?xml version="1.0" encoding="utf-8"?> <RelativeLayout p1_minWidth="25px" p1_minHeight="25px" p1_layout_width="match_parent" p1_layout_height="wrap_content" p1_id="@+id/relativeLayout1" p1_padding="5dp"> <ImageView p1_src="@android:drawable/ic_menu_gallery" p1_layout_width="65dp" p1_layout_height="65dp" p1_layout_marginRight="5dp" p1_id="@+id/poiImageView" /> <LinearLayout p1_orientation="vertical" p1_layout_width="wrap_content" p1_layout_height="wrap_content" p1_layout_toRightOf="@id/poiImageView" p1_id="@+id/linearLayout1" p1_layout_centerVertical="true"> <TextView p1_layout_width="match_parent" p1_layout_height="wrap_content" p1_id="@+id/nameTextView " p1_textSize="20sp" p1_text="@string/app_name" /> <TextView p1_text="@string/address_hint" p1_layout_width="match_parent" p1_layout_height="wrap_content" p1_id="@+id/addrTextView " p1_textSize="14sp" /> </LinearLayout> <TextView p1_text="@string/distance_hint" p1_layout_width="wrap_content" p1_layout_height="wrap_content" p1_id="@+id/textView1" p1_layout_centerVertical="true" p1_layout_alignParentRight="true" /> </RelativeLayout> Creating the PointOfInterest apps entity class The first class that is needed is the one that represents the primary focus of the application, a PointofInterest class. POIApp will allow the following attributes "to be captured for the Point Of Interest app: Id Name Description Address Latitude Longitude Image The POI entity class can be nothing more than a simple .NET class, which houses these attributes. To create a POI entity class, perform the following steps: Select the POIApp project from the Solution Explorer in Xamarin Studio. Select the POIApp project and not the solution, which is the top-level node in the Solution pad. Right-click on it and select New File. On the left-hand side of the New File dialog box, select General. At the top of the template list, in the middle of the dialog box, select Empty Class (C#). Enter the name PointOfInterest and click on OK. The class will be created in the POIApp project folder. Change the "visibility of the class to public and fill in the attributes based on the list previously identified. The following code snippet is from POIAppPOIAppPointOfInterest.cs from the code bundle available for this article: public class PointOfInterest { public int Id { get; set;} public string Name { get; set; } public string Description { get; set; } public string Address { get; set; } public string Image { get; set; } public double? Latitude { get; set; } public double? Longitude { get; set; } } Note that the Latitude and Longitude attributes are all marked as nullable. In the case of latitude and longitude, (0, 0) is actually a valid location so a null value indicates that the attributes have never been set. Populating the ListView item All the adapter "views such as ListView and GridView use an Adapter that acts as a bridge between the data and views. The Adapter iterates through the content and generates Views for each data item in the list. The Android SDK provides three different adapter implementations such as ArrayAdapter, CursorAdapter, and SimpleAdapter. An ArrayAdapter expects an array or a list as input, while CursorAdapter accepts the instance of the Cursor, and SimpleAdapter maps the static data defined in the resources. The type of adapter that suits your app need is purely based on the input data type. The BaseAdapter is the generic implementation for all of the three adapter types, and it implements the IListAdapter, ISpinnerAdapter, and IDisposable interfaces. This means that the BaseAdapter can be used for ListView, GridView, "or Spinners. For POIApp, we will create a subtype of BaseAdapter<T> as it meets our specific needs, works well in many scenarios, and allows the use of our custom layout. Creating POIListViewAdapter In order to create "POIListViewAdapter, we will start by creating a custom adapter "as follows: Create a new class named POIListViewAdapter. Open the POIListViewAdapter class file, make the class a public class, "and specify that it inherits from BaseAdapter<PointOfInterest>. Now that the adapter class has been created, we need to provide a constructor "and implement four abstract methods. Implementing a constructor Let's implement a "constructor that accepts all the information we will need to work with to populate the list. Typically, you need to pass at least two parameters: an instance of an activity because we need the activity context while accessing the standard common "resources and an input data list that can be enumerated to populate the ListView. The following code shows the constructor from the code bundle: private readonly Activity context; private List<PointOfInterest> poiListData; public POIListViewAdapter (Activity _context, List<PointOfInterest> _poiListData) :base() { this.context = _context; this.poiListData = _poiListData; } Implementing Count { get } The BaseAdapter<T> class "provides an abstract definition for a read-only Count property. In our case, we simply need to provide the count of POIs as provided in poiListData. The following code example demonstrates the implementation from the code bundle: public override int Count { get { return poiListData.Count; } } Implementing GetItemId() The BaseAdapter<T> class "provides an abstract definition for a method that returns a long ID for a row in the data source. We can use the position parameter to access a POI object in the list and return the corresponding ID. The following code example demonstrates the implementation from the code bundle: public override long GetItemId (int position) { return position; } Implementing the index getter method The BaseAdapter<T> class "provides an abstract definition for an index getter method that returns a typed object based on a position parameter passed in as an index. We can use the position parameter to access the POI object from poiListData and return an instance. The following code example demonstrates the implementation from the code bundle: public override PointOfInterest this[int index] { get{ return poiListData [index]; } } Implementing GetView() The BaseAdapter<T> class "provides an abstract definition for GetView(), which returns a view instance that represents a single row in the ListView item. As in other scenarios, you can choose to construct the view entirely in code or to inflate it from a layout file. We will use the layout file we previously created. The following code example demonstrates inflating a view from a layout file: view = context.LayoutInflater.Inflate (Resource.Layout.POIListItem, null, false); The first parameter of Inflate is a resource ID and the second is a root ViewGroup, which in this case can be left null since the view will be added to the ListView item when it is returned. Reusing row Views The GetView() method is called" for each row in the source dataset. For datasets with large numbers of rows, hundreds, or even thousands, it would require a great deal of resources to create a separate view for each row, and it would seem wasteful since only a few rows are visible at any given time. The AdapterView architecture addresses this need by placing row Views into a queue that can be reused as they" scroll out of view of the user. The GetView() method accepts a parameter named convertView, which is of type view. When a view is available for reuse, convertView will contain a reference to the view; otherwise, it will be null and a new view should be created. The following code example depicts the use of convertView to facilitate the reuse of row Views: var view = convertView; if (view == null){ view = context.LayoutInflater.Inflate (Resource.Layout.POIListItem, null); } Populating row Views Now that we have an instance of the "view, we need to populate the fields. The View class defines a named FindViewById<T> method, which returns a typed instance of a widget contained in the view. You pass in the resource ID defined in the layout file to specify the control you wish to access. The following code returns access to nameTextView and sets the Text property: PointOfInterest poi = this [position]; view.FindViewById<TextView>(Resource.Id.nameTextView).Text = poi.Name; Populating addrTextView is slightly more complicated because we only want to use the portions of the address we have, and we want to hide the TextView if none of the address components are present. The View.Visibility property allows you to control the visibility property "of a view. In our case, we want to use the ViewState.Gone value if none of "the components of the address are present. The following code shows the "logic in GetView: if (String.IsNullOrEmpty (poi.Address)) { view.FindViewById<TextView> (Resource.Id.addrTextView).Visibility = ViewStates.Gone; } else{ view.FindViewById<TextView>(Resource.Id.addrTextView).Text = poi.Address; } Populating the value for the distance text view requires an understanding of the location services. We need to do some calculation, by considering the user's current location with the POI latitude and longitude. Populating the list thumbnail image Image downloading and" processing is a complex task. You need to consider the various aspects, such as network logic, to download images from the server, caching downloaded images for performance, and image resizing for avoiding the memory out conditions. Instead of writing our own logic for doing all the earlier mentioned tasks, we can use UrlImageViewHelper, which is a free component available in the Xamarin Component Store. The Xamarin Component Store provides a set of reusable components, "including both free and premium components, that can be easily plugged into "any Xamarin-based application. Using UrlImageViewHelper The following steps will walk you "through the process of adding a component from the Xamarin Component Store: To include the UrlImageViewHelper component in POIApp, you can either double-click on the Components folder in the Solution pad, or right-click and select Edit Components. Notice that the component manager will be loaded with the already downloaded components and a Get More Components button that allows you to open the Components store from the window. Note that to access the component manager, you need to log in to your Xamarin account: Search for UrlImageViewHelper in the components search box available in the left-hand side pane. Now click on the download button to add your Xamarin Studio solution. Now that we have added the UrlImageViewHelper component, let's go back to the GetView() method in the POIListViewAdapter class. Let's take a look at the following section of the code: var imageView = view.FindViewById<ImageView> (Resource.Id.poiImageView); if (!String.IsNullOrEmpty (poi.Address)) { Koush.UrlImageViewHelper.SetUrlDrawable (imageView, poi.Image, Resource.Drawable.ic_placeholder); } Let us examine how the preceding code snippet works: The SetUrlDrawable() method defined in the UrlImageViewHelper "component provides a logic to download an image using a single line of code. It accepts three parameters: an instance of imageView, where the image is to be displayed after the download, the image source URL, and the placeholder image. Add a new image ic_placeholder.png to the drawable Resources directory. While the image is being downloaded, the placeholder image will be displayed on imageView. Downloading the image over the network requires Internet permissions. The following section will walk you through the steps involved in defining permissions in your AndroidManifest.xml file. Adding Internet permissions Android apps must be "granted permissions while accessing certain features, such as downloading data from the Internet, saving an image in storage, and so on. You must specify the permissions that an app requires in the AndroidManifest.xml file. This allows the installer to show potential users the set of permissions an app requires at the time of installation. To set the appropriate permissions, perform the following steps: Double-click on AndroidManifest.xml in the Properties directory in the Solution pad. The file will open in the manifest editor. There are two tabs: Application and Source, at the bottom of the screen, that can be used to toggle between viewing a form for editing the file and the raw XML, as shown in the following screenshot: In the" Required permissions list, check Internet and navigate to File | Save. Switch to the Source view to view the XML as follows: Summary In this article, we covered a lot about how to create user interface elements using different layout managers and widgets such as TextView, ImageView, ProgressBar, and ListView. Resources for Article: Further resources on this subject: Code Sharing Between iOS and Android[article] XamChat – a Cross-platform App[article] Heads up to MvvmCross [article]
Read more
  • 0
  • 0
  • 5098
Modal Close icon
Modal Close icon