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-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-how-add-static-material-course-moodle
Packt
06 Sep 2011
7 min read
Save for later

How to Add Static Material to a Course in Moodle

Packt
06 Sep 2011
7 min read
  (For more resources on Moodle, see here.)   Kinds of static course material that can be added Static course material is added from the Add a resource drop-down menu. Using this menu, you can create: Web pages Links to anything on the Web Files A label that displays any text or image Multimedia   Adding links On your Moodle site, you can show content from anywhere on the Web by using a link. You can also link to files that you've uploaded into your course. By default, this content appears in a frame within your course. You can also choose to display it in a new window. When using content from outside sites, you need to consider the legality and reliability of using the link. Is it legal to display the material on your Moodle site? Will the material still be there when your course is running? In this example, I've linked to an online resource from the BBC, which is a fairly reliable source: Remember that the bottom of the window displays Window Settings, so you can choose to display this resource in its own window. You can also set the size of the window. You may want to make it appear in a smaller window, so that it does not completely obscure the window of your Moodle site. This will make it clearer to the student that he or she has opened a new window. To add a link to a resource on the Web: Log in to your course as a Teacher or Site Administrator. In the upper-right corner of the page, if you see a button that reads, Turn editing on, click on this button. If it reads Turn editing off, then you do not need to click on this button. (You will also find this button in the Settings menu on the leftmost side of the page.) From the Add a resource... drop-down menu, select URL. Moodle displays the Adding a new URL page. Enter a Name for the link. This is the name that people will see on the home page of your course. Enter a Description for the link. When the student sees the course's home page, they will see the Name and not the Description. However, whenever this resource is selected from the Navigation bar, the Description will be displayed. Here is a link as it appears on the home page of a course: Here is the same link, as it appears when selected from the Navigation bar: In the External URL field, enter the Web address for this link. From the Display drop-down menu, select the method that you want Moodle to use when displaying the linked page. Embed will insert the linked page into a Moodle page. Your students will see the Navigation bar, any blocks that you have added to the course and navigation links across the top of the page, just like when they view any other page in Moodle. The center of the page will be occupied by the linked page. Open will take the student away from your site, and open the linked page in the window that was occupied by Moodle. In pop-up will launch a new window, containing the linked page on top of the Moodle page. Automatic will make Moodle choose the best method for displaying the linked page. The checkboxes for Display URL name and Display URL description will affect the display of the page, only if Embed is chosen as the display method. If selected, the Name of the link will be displayed above the embedded page, and the Description will be displayed below the embedded page. Under Options, the ShowAdvanced button will display fields that allow you to set the size of the popup window. If you don't select In pop-up as the display method, these fields have no effect. Under Parameters, you can add parameters to the link. In a Web link, a parameter would add information about the course or student to the link. If you have Web programming experience, you might take advantage of this feature. For more about passing parameters in URLs, see http://en.wikipedia.org/wiki/Query_string. Under Common Module Settings, the Visible setting determines if this resource is visible to students. Teachers and site Administrators can always see the resource. Setting this to Hide will completely hide the resource. Teachers can hide some resources and activities at the beginning of a course, and reveal them as the course progresses. Show/Hide versus Restrict availability If you want a resource to be visible, but not available, then use the Restrict Availability settings further down on the page. Those settings enable you to have a resource's name and its description appear, but still make the resource unavailable. You might want to do this for resources that will be used later in a course, when you don't want the student to work ahead of the syllabus. The ID number field allows you to enter an identifier for this resource, which will appear in the Gradebook. If you export grades from the Gradebook and then import them into an external database, you might want the course ID number here to match the ID number that you use in that database. The Restrict Availability settings allow you to set two kinds of conditions that will control whether this resource is available to the student. The Accessible from and Accessible until settings enable you to set dates for when this resource will be available. The Grade condition setting allows you to specify the grade that a student must achieve in another Activity in this course, before being able to access this Resource. The setting for Before activity is available determines if the Resource will be visible while it is unavailable. If it is visible but unavailable, Moodle will display the conditions needed to make it available (achieve a grade, wait for a date, and so on.). Click on one of the Save buttons at the bottom of the page to save your work.   Adding pages Under the Add a resource drop-down menu, select Page to add a Web page to a course. A link to the page that you create will appear on the course's home page. Moodle's HTML editor When you add a Page to your course, Moodle displays a Web page editor. This editor is based on an open source web page editor called TinyMCE. You can use this editor to compose a web page for your course. This page can contain almost anything that a web page outside of Moodle can contain. Pasting text into a Moodle page Many times, we prefer to write text in our favorite word processor instead of writing it in Moodle. Or we may find text that we can legally copy and paste into a Moodle page, somewhere else. Moodle's text editor does allow you to do this. To paste text into a page, you can just use the appropriate keyboard shortcut. Try Ctrl + V for Windows PCs and Apple + V for Macintoshes. If you use this method, the format of the text will be preserved. To paste plain text, without the format of the original text, click on the Paste as Plain Text icon, as shown below: When you paste text from a Microsoft Word document into a web page, it usually includes a lot of non-standard HTML code. This code doesn't work well in all browsers, and makes it more difficult to edit the HTML code in your page. Many advanced web page editors, such as AdobeDreamWeaver, have the ability to clean up Word HTML code. Moodle's web page editor can also clean up Word HTML code. When pasting text that was copied from Word, use the Paste from Word icon, as shown in the image below. This will strip out most of Word's non-standard HTML code.  
Read more
  • 0
  • 0
  • 5097

article-image-detecting-fake-reviews
Janu Verma
10 Feb 2017
6 min read
Save for later

Detecting Fake Reviews

Janu Verma
10 Feb 2017
6 min read
Product and service reviews play an important role in making purchase decisions. In current times, when we are faced with many choices, the opinion-based reviews help us narrow down the options and make decisions based on our needs. This is especially true online, where the reviews are easily accessible. Some companies where review-based decisions are very prominent are Amazon, TripAdviser, Yelp, and AirBnB, to name a few. From a business point of view, positive reviews can result in significant financial benefits. This also provides opportunities for deception, where fake reviews can be generated to garner positive opinion about a product, or to disrepute some business. To ensure credibility of the reviews posted on a platform, it is important to use a strong detecting model. In this post, we’ll talk about some methods for detecting fake reviews. The models discussed here fall into three categories: Textbased, Sentimentbased, and Userbased. Text-based Model This approach to classify fake and non-fake reviews is very similar to the ideas used in spam—classification. By creating the linguistic n-gram features and using a supervised learning algorithm such as Naive Bayes or SVM, one can construct the classification model. This approach, of course, relies on the assumption that the fake and non-fake reviews consist of words with significantly different frequencies. In case the spammers had a little knowledge of the product, or they didn’t have a genuine interest in writing the reviews (for example, the cheaply paid spammers), there are more chances of them creating reviews linguistically different from the non-fake ones. We don’t have any reason to believe that the spammer won’t be careful enough to create reviews linguistically similar to the genuine ones, or have strong inclinations to write fake opinions. In that case, the pure text-based models won’t be successful. We will need to incorporate more information. Other features from the review Length of the review: Even if a spammer tried to use words similar to real reviews, he probably didn’t spend much time in writing the review. Thus, length of the fake-review is smaller than the other reviews of the same product. Lack of domain knowledge also increases the chances of a shorter review. Also, it could have happened that the spammer tried to overdo his job and wrote a longer review. Deviation from the average rating: There is a high probability for the spamming review to deviate from the general consensus rating for the product or the service. Sentiment-based Model Because the fake reviews are created to enhance the positive opinion or tarnish the image, these reviews should have a strong positive or negative sentiment. Therefore, sentiment analysis of the reviews can be an important tool to separate the spam reviews. Though more sophisticated sentiment analysis methods can be employed, the static AFINN model should give high accuracy as it contains the sentiment scores for the terms, which project very high and low sentiment, and such words are going to be very prominent in the fake reviews. Some of these words include 'nice', 'great', 'awesome', 'amazing', 'bad', 'awful', 'helpful', 'shitty', and so on. In AFINN model, the authors have computed sentiment scores for a list of words. Compute the sentiment of a review based on the sentiment scores of the terms in the review. The sentiment of the review is defined to be equal to the sum of the sentiment scores for each term in the review. The AFINN is a list of English words rated for valence with an integer value between -5 and 5. The words have been manually labelled by Finn Arup Neilsen in 2009-2010. If the spammer made an attempt to sound convincing by using words that have high positive or negative sentiment, this model can be very successful. Even if the numeric rating of the spammer does not deviate much from the general consensus, the text reviews are going to be overwhelmingly positive. In such cases, sentiment scores of the reviews can shed light on the problem of detecting fake reviews, for example, you can compute the sentiment scores of all the 5-star reviews and see if some reviews have extremely high sentiment scores. User-based Model The user-based model asserts that a spamming user displays an abnormal behavior, and it is possible to classify users as spammers and non-spammers. The user information can be extracted from their public profiles. The relevant features include: Number of reviews: A spammer is likely to create a lot of reviews, and this can be used to identify fake reviewers. Most of the users create not more than 1 review per day. Average review length: As mentioned earlier, a spammer is not going to invest much time in creating his reviews (especially when you are being paid by number of the reviews you write) and is more likely to create shorter reviews. Number of positive votes: Most of the fake reviews tend to be extremely positive. A high percent of strong positive votes indicated abnormal behavior. Non-fake reviewers have varying rating levels. Deviation from other users: One can compute the deviation of the spammer from the rest of the users by averaging over all of his reviews the deviation from the other ratings for the same product. A standard learning algorithm,such as SVM or Random Forests, on these features can create a classification model for fake reviewers and non-fake reviewers. Other than these important features, there are some other features that can be extracted from the user’s profile, which can be used in detecting fake reviews. Geographical Information: A user who is reviewing location-based products (for example, businesses on Yelp) at two or more locations in a day is surely exhibiting suspicious behavior. The credit card companies use this kind of information to track down scams. Activity: On social sites (for example, Yelp, Foursquare, and more), the account activity can also be an indicator of abnormal behavior. Users with a friend base and who post share check-ins on Facebook and Twitter are mostly genuine. In fact, linking your other accounts is a positive indicator. Useful votes: Yelp also allows its users to vote on a review, and the number of people of ’useful’ votes for a review can also be used to classify spammers and non-spammers. Conclusions In this post, we discussed three different categories of models for detecting online fake reviews. Though the basic text-mining approach should detect spam reviews with reasonable accuracy, a smart spammer can make it harder for this model to classify. The sentiment-based model and user behavior can help achieve better accuracy in filtering false opinions. We propose that a combination of these models can be very effective in detecting fake reviews. References [1] Paul Graham "A plan for spam" [2] More information and a link to download the AFINN wordlist is available here [3] Finn Arup Nielsen Evaluation of a word list for sentiment analysis in microblogs Proceedings of the ESWC2011 Workshop on "Making Sense of Microposts: Big things come in small packages" 718 in CEUR Workshop Proceedings - 93-98. 2011 May
Read more
  • 0
  • 0
  • 5089

article-image-making-the-most-of-chatgpt-code-interpreter-plugin
Julian Melanson
22 Jun 2023
5 min read
Save for later

Making the Most of ChatGPT Code Interpreter Plugin

Julian Melanson
22 Jun 2023
5 min read
As we stand on the threshold of a new age in Artificial Intelligence,, OpenAI recently announced the rollout of its ChatGPT Code Interpreter plugin for ChatGPT Plus subscribers, marking a significant evolution in the capabilities of AI. This groundbreaking technology is not merely another link in the AI chain but rather an exemplar of the transformative capabilities AI can bring to the table, particularly in programming and data analysis.The ChatGPT Code Interpreter plugin positions itself as an invaluable tool for developers, promising to significantly augment and streamline their workflows. Among its multiple functionalities, three stand out due to their potential impact on the programming landscape and data analysis, which work in tandem to extract valuable insights.Data VisualizationAt its core, the ChatGPT Code Interpreter excels in the domain of data visualization. In a world increasingly reliant on data, the ability to transform complex datasets into visually comprehensible and comprehensive formats is priceless. The plugin simplifies the arduous task of crunching through complex numbers and data sets, producing insightful visualizations without the need for prompt engineering. This proficiency in creatively rendering data echoes the power of platforms like Wolfram, introducing a new era of ease and efficiency in data comprehension.Here’s an example from Justin Fineberg’s TikTok: Click hereFile ConversionThe ChatGPT Code Interpreter extends its versatility into the realm of file conversion. This feature provides a simple solution to the often cumbersome task of converting files from one format to another. Its impressive functionality ranges from changing audio file formats, like MP3 to WAV, to converting an image into a text file. This capability paves the way for more accessible content transformation, such as easily convert PDF documents into editable text files.Here’s an example from Twitter user Riley Goodside: Click herePython Code ExecutionWhat sets the ChatGPT Code Interpreter plugin apart is its prowess in executing Python code within a sandboxed, firewalled execution environment. This essentially means that all the data visualizations are generated using Python, thereby lending the plugin an additional layer of power and versatility.As the plugin is still in its alpha stage, gaining access currently involves joining a waitlist, and  OpenAI has not publicly stated when a large-scale rollout will take place. However, those eager to explore its features have an alternative route via Discord's GPT Assistant bot, which already incorporates the Code Interpreter plugin to enhance its features and functionalities.This revolutionary plugin is not merely an advanced code interpreter; it's a complete tool that uses Python to generate code from natural language input and run it. The results are then presented within the dialogue box. The chatbot’s functionality extends to solving mathematical problems, data analysis and visualization, and file conversion, with an adeptness in these domains that rivals experienced coders.Beyond its immediate capabilities, the ChatGPT Code Interpreter plugin has broader implications for the programming and data analysis industry. It is reminiscent of Github Copilot X in its design, aimed at making workflows more creative and efficient. For instance, when asked to plot a function, the plugin not only generates the graph but also offers the option to 'show work', revealing the exact code it created and executed to generate the graph.The accessibility and user-friendliness of the plugin are expected to democratize the coding landscape, opening up the world of programming to a wider audience. This feature holds tremendous potential to accelerate collaborations, allowing technical and non-technical team members to work together more effectively on data analysis projects.Practical use cases for the ChatGPT Code Interpreter extend beyond the realm of programming, spanning various industries. Marketing teams, for instance, can leverage their capabilities to analyze customer data, segment audiences, and create targeted campaigns. Finance teams can utilize the plugin for tasks like financial modeling, forecasting, and risk analysis. Similarly, human resource teams can use it to analyze employee data, identify performance trends, and make data-driven hiring decisions. Even the healthcare sector stands to benefit, as the tool can analyze patient data, identify patterns in health outcomes, and thus enhance patient care.Accessing ChatGPT Code InterpreterIf you’re selected from the waitlist, here’s a step-by-step guide on how to install the plugin:Ensure you're a ChatGPT Plus subscriber, paying the $20 monthly fee.Log into ChatGPT on the OpenAI website.Click on 'Settings', then the three-dot menu next to your login name.In the 'Beta features' menu, enable 'Plug-ins'. For web browsing access, enable that too.Close the menu, find the language model selector, and choose 'Plugin Store' from the drop-down.Click 'All plug-ins', find 'Code Interpreter' in the list and install it.Now, you can interact with ChatGPT using the Code Interpreter plug-in.SummaryThe ChatGPT Code Interpreter plugin presents a transformative approach to programming and data analysis, automating code generation, facilitating data exploration, and improving code quality. This plugin empowers users to derive more value from their data, aiding in the formulation of strategic insights. As AI continues to evolve, tools like the ChatGPT Code Interpreter will undoubtedly play an instrumental role in shaping the future of data interaction and understanding, ultimately revolutionizing the landscape of data analysis.Author BioJulian Melanson is one of the founders of Leap Year Learning. Leap Year Learning is a cutting-edge online school that specializes in teaching creative disciplines and integrating AI tools. We believe that creativity and AI are the keys to a successful future and our courses help equip students with the skills they need to succeed in a continuously evolving world. Our seasoned instructors bring real-world experience to the virtual classroom and our interactive lessons help students reinforce their learning with hands-on activities.No matter your background, from beginners to experts, hobbyists to professionals, Leap Year Learning is here to bring in the future of creativity, productivity, and learning!
Read more
  • 0
  • 0
  • 5087

article-image-application-session-and-request-scope-coldfusion-9
Packt
27 Jul 2010
8 min read
Save for later

Application, Session, and Request Scope in ColdFusion 9

Packt
27 Jul 2010
8 min read
(For more resources on ColdFusion, see here.) The start methods We will have a look at the start methods and make some observations now. Each method has its own set of arguments. All Application.cfc methods return a Boolean value of true or false to declare if they completed correctly or not. Any code you place inside a method will execute when the start event occurs. These are the events that match with the name of the method. We will also include some basic code that will help you build an application core that is good for reuse and discuss what those features provide. Application start method—onApplicationStart() The following is the code structure of the application start method. You could actually place these methods in any order in the CFC, as the order does not matter. Code that uses CFCs only require the methods to exist. If they exist, then it will call them. We place them in our code so that it helps us to read and understand the structure from a human perspective. <cffunction name="onApplicationStart" output="false"> <cfscript> // create default stat structure and pre-request values application._stat = structNew(); application._stat.started = now(); application._stat.thisHit = now(); application._stat.hits = 0; application._stat.sessions = 0; </cfscript></cffunction> There are no arguments for the onApplicationStart() method. We have included some extra code to show you an example of what can be done in this function. Please note that if we change the code in this method, it will only run at the very first time when an application running in ColdFusion is hit. To hit it again, we need to either change the application name or restart the ColdFusion server. The Application variables section that was previously explained shows how to change the application's name. From the start methods, we can see that we can access the variable scopes that allow persistence of key information. To understand the power of this object, we will be creating some statistics that can be used in most situations. We could use them for debugging, logging, or in any other appropriate use case. Again, we have to be aware that this only gets hit the first time a request is made to a ColdFusion server for that application. We will be updating many of our statistics in the request methods. We will also be updating one of our variables in the session end method. Session start method—onSessionStart() The session start method only gets called when a request is made for a new session. It is good that ColdFusion can keep track of these things. The following is example code that allows us to keep a record of the session-based statistics that is similar to the application-based statistics: <cffunction name="onSessionStart" output="false"> <cfscript> // create default session stat structure and pre-request values session._stat.started = now(); session._stat.thisHit = now(); session._stat.hits = 0; // at start of each session update count for application stat application._stat.sessions += 1; </cfscript></cffunction> You might have noticed that in the previous code we used +=. In ColdFusion prior to version 8, you had to type that particular line in a different way. The following two examples are the same in functionality (example one works in all versions and two works only in version 8 and higher): Example 1: myTotal = myTotal +3 Example 2: myTotal += 3 This is common in JavaScript, ActionScript, and many other languages. This syntax was added in ColdFusion version 8. We change the application-based setting because sessions are hidden from one another and cannot see each other. Therefore, we use the application CFC to either count or add a count every time a new session starts. Request start method—onRequestStart() This is one of the longest methods in the article. The first thing you will notice is that the script that is called is passed to the onRequestStart() method by ColdFusion. In this example, we will instruct ColdFusion to block any scripts from execution that begin with an underscore when called remotely. This means that you can call the server and request any .cfm page or .cfc page with an underscore at the start, and this protects it from being called outside the local server. The files can still be run if called from pages inside the server. This makes all these files locally accessible: <cffunction name="onRequestStart" output="false"> <cfargument name="thePage" type="string" required="true"> <cfscript> var myReturn = true; //fancy code to block pages that start with underscore if(left(listLast(arguments.thePage,"/"),1) EQ "_") { myReturn = false; } // update application stat on each request application._stat.lastHit = application._stat.thisHit; application._stat.thisHit = now(); application._stat.hits += 1; // update session stat on each request session._stat.lastHit = session._stat.thisHit; session._stat.thisHit = now(); session._stat.hits += 1; </cfscript> <cfreturn myReturn></cffunction> The methods in the following sections are used to update all the application and session statistics variables that need to be updated with each request. You should also notice that we are recording the last time the application or session was requested. The end methods Previously, some of the methods in this object were impossible to achieve with the earlier versions of ColdFusion. It was possible to code an end request function, but only a few programmers made use of it. We find that by using this object many more people are taking advantage of these features. The new methods that are added have the ability to run code specifically when a session ends, and when an application ends. This allows us to do things that we could not do previously. We can keep a record of how long a user is online without having to access the database with each request. When the session starts, you can store it in the session scope. When the session ends, you can take all that information and store it in the session log table if logging is desired in your site. Request end method—onRequestEnd() We are not going to use every method that is available to us. As we have the concept from the other sections, this would be redundant. The concepts of this method are very similar to the onRequestStart() method with the exception that it occurs after the requested page has been called. If you create content in this method and set the output attribute to true, then it will be sent back to browser requests. Here you can place the code that logs information about our requests: <cffunction name="onRequestEnd" returnType="void" output="false"> <cfargument name="thePage" type="string" required="true"></cffunction> Session end method—onSessionEnd() In the session end method, we can perform logging functions for analytical statistics that are specific to the end of a session if desired for your site. You need to use the argument's scope variables to read both the application and session variables. If you are changing application variables as in our example code, then you must use the argument's scope for that. <cffunction name="onSessionEnd" returnType="void" output="false"> <cfargument name="SessionScope" type="struct" required="true"> <cfargument name="ApplicationScope" type="struct" required="false"> <cfscript> // NOTE: You must use the variable scope below to access the // application structure inside this method. arguments.ApplicationScope._stat.sessions -= 1; </cfscript></cffunction> Application end method—onApplicationEnd This is our end method for applications. Here is where you can do the logging activity. As in the session method, you need to use the argument's scope in order to read variables for the application. It is also good to note that at this point, you can no longer access the session scope. <cffunction name="onApplicationEnd" returnType="void" output="false"> <cfargument name="applicationScope" required="true"></cffunction> On Error method—onError() The following code demonstrates how we can be flexible in managing errors sent to this method. If the error comes from Application.cfc, then the event (or method that had an issue) will be contained in the value of the arguments.eventname variable. Otherwise, it will be an empty string. In our code, we change the label on our dump statement, so that it is a bit more obvious where it was generated. <cffunction name="onError" returnType="void" output="true"> <cfargument name="exception" required="true"> <cfargument name="eventname" type="string" required="true"> <cfif arguments.eventName NEQ ""> <cfdump var="#arguments.exception#" label="Application core exception"> <cfelse> <cfdump var="#arguments.exception#" label="Application exception"> </cfif></cffunction>
Read more
  • 0
  • 0
  • 5086

article-image-did-unfettered-growth-kill-maker-media-financial-crisis-leads-company-to-shutdown-maker-faire-and-lay-off-all-staff
Savia Lobo
10 Jun 2019
5 min read
Save for later

Did unfettered growth kill Maker Media? Financial crisis leads company to shutdown Maker Faire and lay off all staff

Savia Lobo
10 Jun 2019
5 min read
Updated: On July 10, 2019, Dougherty announced the relaunch of Maker Faire and Maker Media with the new name “Make Community“. Maker Media Inc., the company behind Maker Faire, the popular event that hosts arts, science, and engineering DIY projects for children and their parents, has laid off all its employees--22 employees--and have decided to shut down due to financial troubles. In January 2005, the company first started off with MAKE, an American bimonthly magazine focused on do it yourself and/or DIWO projects involving computers, electronics, robotics, metalworking, woodworking, etc. for both adults and children. In 2006, the company first held its Maker Faire event, that lets attendees wander amidst giant, inspiring art and engineering installations. Maker Faire now includes 200 owned and licensed events per year in over 40 countries. The Maker movement gained momentum and popularity when MAKE magazine first started publishing 15 years ago.  The movement emerged as a dominant source of livelihood as individuals found ways to build small businesses using their creative activity. In 2014, The WhiteHouse blog posted an article stating, “Maker Faires and similar events can inspire more people to become entrepreneurs and to pursue careers in design, advanced manufacturing, and the related fields of science, technology, engineering and mathematics (STEM).” With funding from the Department of Labor, “the AFL-CIO and Carnegie Mellon University are partnering with TechShop Pittsburgh to create an apprenticeship program for 21st-century manufacturing and encourage startups to manufacture domestically.” Recently, researchers from Baylor University and the University of North Carolina, in their research paper, have highlighted opportunities for studying the conditions under which the Maker movement might foster entrepreneurship outcomes. Dale Dougherty, Maker Media Inc.’s founder and CEO, told TechCrunch, “I started this 15 years ago and it’s always been a struggle as a business to make this work. Print publishing is not a great business for anybody, but it works…barely. Events are hard . . . there was a drop off in corporate sponsorship”. “Microsoft and Autodesk failed to sponsor this year’s flagship Bay Area Maker Faire”, TechCrunch reports. Dougherty further told that the company is trying to keep the servers running. “I hope to be able to get control of the assets of the company and restart it. We’re not necessarily going to do everything we did in the past but I’m committed to keeping the print magazine going and the Maker Faire licensing program”, he further added. In 2016, the company laid off 17 of its employees, followed by 8 employees recently in March. “They’ve been paid their owed wages and PTO, but did not receive any severance or two-week notice”, TechCrunch reports. These layoffs may have hinted the staff of the financial crisis affecting the company. Maker Media Inc. had raised $10 million from Obvious Ventures, Raine Ventures, and Floodgate. Dougherty says, “It started as a venture-backed company but we realized it wasn’t a venture-backed opportunity. The company wasn’t that interesting to its investors anymore. It was failing as a business but not as a mission. Should it be a non-profit or something like that? Some of our best successes, for instance, are in education.” The company has a huge public following for its products. Dougherty told TechCrunch that despite the rain, Maker Faire’s big Bay Area event last week met its ticket sales target. Also, about 1.45 million people attended its events in 2016. “MAKE: magazine had 125,000 paid subscribers and the company had racked up over one million YouTube subscribers. But high production costs in expensive cities and a proliferation of free DIY project content online had strained Maker Media”, writes TechCrunch. Dougherty told TechCrunch he has been overwhelmed by the support shown by the Maker community. As of now, licensed Maker Faire events around the world will proceed as planned. “Dougherty also says he’s aware of Oculus co-founder Palmer Luckey’s interest in funding the company, and a GoFundMe page started for it”, TechCrunch reports. Mike Senese, Executive Editor, MAKE magazine, tweeted, “Nothing but love and admiration for the team that I got to spend the last six years with, and the incredible community that made this amazing part of my life a reality.” https://twitter.com/donttrythis/status/1137374732733493248 https://twitter.com/xeni/status/1137395288262373376 https://twitter.com/chr1sa/status/1137518221232238592 Former Mythbusters co-host Adam Savage, who was a regular presence at the Maker Faire, told The Verge, “Make Media has created so many important new connections between people across the world. It showed the power from the act of creation. We are the better for its existence and I am sad. I also believe that something new will grow from what they built. The ground they laid is too fertile to lie fallow for long.” On July 10, 2019, Dougherty announced he’ll relaunch Maker Faire and Maker Media with the new name “Make Community“. The official launch of Make Community will supposedly be next week. The company is also working on a new issue of Make Magazine that is planned to be published quarterly and the online archives of its do-it-yourself project guides will remain available. Dougherty told TechCrunch “with the goal that we can get back up to speed as a business, and start generating revenue and a magazine again. This is where the community support needs to come in because I can’t fund it for very long.” GitHub introduces ‘Template repository’ for easy boilerplate code management and distribution 12 Visual Studio Code extensions that Node.js developers will love [Sponsored by Microsoft] Shoshana Zuboff on 21st century solutions for tackling the unique complexities of surveillance capitalism
Read more
  • 0
  • 0
  • 5086
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-disaster-recovery-hyper-v
Packt
29 Jan 2013
9 min read
Save for later

Disaster Recovery for Hyper-V

Packt
29 Jan 2013
9 min read
(For more resources related to this topic, see here.) Hyper-V and Windows Server 2012 come with tools and solutions to make sure that your virtual machines will be up, running, and highly available. Components such as Failover Cluster can ensure that your servers are accessible, even in case of failures. However, disasters can occur and bring all the servers and services offline. Natural disasters, viruses, data corruption, human errors, and many other factors can make your entire system unavailable. People think that High Available (HA) is a solution for Disaster Recovery (DR) and that they can use it to replace DR. Actually HA is a component of a DR plan, which consists of process, policies, procedures, backup and recovery plan, documentation, tests, Service Level Agreements (SLA), best practices, and so on. The objective of a DR is simply to have business continuity in case of any disaster. In a Hyper-V environment, we have options to utilize the core components, such as Hyper-V Replica, for a DR plan, which replicates your virtual machines to another host or cluster and makes them available if the first host is offline, or even backs up and restores to bring VMs back, in case you lose everything. This module will walk you through the most important processes for setting up disaster recovery for your virtual machines running on Hyper-V. Backing up Hyper-V and virtual machines using Windows Server Backup Previous versions of Hyper-V had complications and incompatibilities with the built-in backup tool, forcing the administrators to acquire other solutions for backing up and restoring. Windows Server 2012 comes with a tool known as Windows Server Backup (WSB), which has full Hyper-V integration, allowing you to back up and restore your server, applications, Hyper-V, and virtual machines. WSB is easy and provides for a low cost scenario for small and medium companies. This recipe will guide you through the steps to back up your virtual machines using the Windows Server Backup tool. Getting ready Windows Server Backup does not support tapes. Make sure that you have a disk, external storage, network share, and free space to back up your virtual machines before you start. How to do it... The following steps will show you how to install the Windows Server Backup feature and how to schedule a task to back up your Hyper-V settings and virtual machines: To install the Windows Server Backup feature, open Server Manager from the taskbar. In the Server Manager Dashboard, click on Manage and select Add Roles and Features. On the Before you begin page, click on Next four times. Under the Add Roles and Features Wizard, select Windows Server Backup from the Features section, as shown in the following screenshot: Click on Next and then click on Install. Wait for the installation to be completed. After the installation, open the Start menu and type wbadmin.msc to open the Windows Server Backup tool. To change the backup performance options, click on Configure Performance from the pane on the right-hand side in the Windows Server Backup console. In the Optimize Backup Performance window, we have three options to select from—Normal backup performance, Faster backup performance, and Custom, as shown in the following screenshot: In the Windows Server Backup console, in the pane on the right-hand side, select the backup that you want to perform. The two available options are Backup Schedule to schedule an automatic backup and Backup Once for a single backup. The next steps will show how to schedule an automatic backup. In the Backup Schedule Wizard, in the Getting Started page, click on Next. In the Select Backup Configuration page, select Full Server to back up all the server data or click on Custom to select specific items to back up. If you want to backup only Hyper-V and virtual machines, click on Custom and then Next. In Select Items for Backup, click on Add Items. In the Select Items window, select Hyper-V to back up all the virtual machines and the host component, as shown in the following screenshot. You can also expand Hyper-V and select the virtual machines that you want to back up. When finished, click on OK. Back to the Select Items for Backup, click on Advanced Settings to change Exclusions and VSS Settings. In the Advanced Settings window, in the Exclusions tab, click on Add Exclusion to add any necessary exclusions. Click on the VSS Settings tab to select either VSS full Backup or VSS copy Backup as shown in the following screenshot. Click on OK. In the Select Items for Backup window, confirm the items that will be backed up and click on Next. In the Specify Backup Time page, select Once a day and the time for a daily backup or select More than once a day and the time and click on Next. In the Specify Destination Type page, select the option Back up to a hard disk that is dedicated for backups (recommended), back up to a volume, or back up to a shared network folder, as shown in the following screenshot and click on Next. If you select the first option, the disk you choose will be formatted and dedicated to storing the backup data only. In Select Destination Disk, click on Show All Available Disks to list the disks, select the one you want to use to store your backup, and click on OK. Click on Next twice. If you have selected the Back up to a hard disk that is dedicated for backups (recommended) option, you will see a warning message saying that the disk will be formatted. Click on Yes to confirm. In the Confirmation window, double-check the options you selected and click on Finish, as shown in the following screenshot: After that, the schedule will be created. Wait until the scheduled time to begin and check whether the backup has been finished successfully. How it works... Many Windows administrators used to miss the NTBackup tool from the old Windows Server 2003 times because of its capabilities and features. The Windows Server Backup tool, introduced in Windows Server 2008, has many limitations such as no tape support, no advanced schedule options, fewer backup options, and so on. When we talk about Hyper-V in this regards, the problem is even worse. Windows Server 2008 has minimal support and features for it. In Windows Server 2012, the same tool is available with some limitations; however, it provides at least the core components to back up, schedule, and restore Hyper-V and your virtual machines. By default, WSB is not installed. The feature installation is made by Server Manager. After its installation, the tool can be accessed via console or command lines. Before you start the backup of your servers, it is good to configure the backup performance options you want to use. By default, all the backups are created as normal. It creates a full backup of all the selected data. This is an interesting option when low amounts of data are backed up. You can also select the Faster backup performance option. This backs up the changes between the last and the current backup, increasing the backup time and decreasing the stored data. This is a good option to save storage space and backup time for large amounts of data. A backup schedule can be created to automate your backup operations. In the Backup Schedule Wizard, you can back up your entire server or a custom selection of volumes, applications, or files. For backing up Hyper-V and its virtual machines, the best option is the customized backup, so that you don't have to back up the whole physical server. When Hyper-V is present on the host, the system shows Hyper-V, and you will be able to select all the virtual machines and the host component configuration to be backed up. During the wizard, you can also change the advanced options such as exclusions and Volume Shadow Copy Services (VSS) settings. WSB has two VSS backup options—VSS full backup and VSS copy backup. When you opt for VSS full backup, everything is backed up and after that, the application may truncate log files. If you are using other backup solutions that integrate with WSB, these logs are essential to be used in future backups such as incremental ones. To preserve the log files you can use VSS copy backup so that other applications will not have problems with the incremental backups. After selecting the items for backup, you have to select the backup time. This is another limitation from the previous version—only two schedule options, namely Once a day or More than once a day. If you prefer to create different backup schedule such as weekly backups, you can use the WSB commandlets in PowerShell. Moving forward, in the backup destination type, you can select between a dedicated hard disk, a volume, or a network folder to save your backups in. When confirming all the items, the backup schedule will be ready to back up your system. You can also use the option Backup once to create a single backup of your system. There's more... To check whether previous backups were successful or not, you can use the details option in the WSB console. These details can be used as logs to get more information about the last (previous), next, and all the backups. To access these logs, open Windows Server Backup, under Status select View details. The following screenshot shows an example of the Last backup. To see which files where backed up, click on the View list of all backed up files link. Checking the Windows Server Backup commandlets Some options such as advanced schedule, policies, jobs, and other configurations can only be created through commandlets on PowerShell. To see all the available Windows Server Backup commandlets, type the following command: Get-Command –Module WindowsServerBackup See also The Restoring Hyper-V and virtual machines using Windows Server Backup recipe in this article
Read more
  • 0
  • 0
  • 5082

article-image-how-to-develop-for-wearable-tech-with-pebblejs
Eugene Safronov
09 Oct 2015
7 min read
Save for later

How to Develop for Today's Wearable Tech with Pebble.js

Eugene Safronov
09 Oct 2015
7 min read
Pebble is a smartwatch that pairs with both Android and iPhone devices via Bluetooth. It has an e-paper display with LED backlight, accelerometer and compass sensors. On top of that battery lasts up to a week between charges. From the beginning Pebble team embraced the Developer community which resulted in powerful SDK. Although a primary language for apps development is C, there is a room for JavaScript developers as well. PebbleKit JS The PebbleKit JavaScript framework expands the ability of Pebble app to run JavaScript logic on the phone. It allows fast access to data location from the phone and has API for getting data from the web. Unfortunately app development still requires programming in C. I could recommend some great articles on how to get started. Pebble.js Pebble.js, in contrast to PebbleKit JS, allows developers to create watchapp using only JavaScript code. It is simple yet powerful enough for creating watch apps that fetch and display data from various web services or remotely control other smartdevices. The downside of that approach is connected to the way how Pebble.js works. It is built on top of the standard Pebble SDK and PebbleKit JS. It consists of a C app that runs on the watch and interacts with the phone in order to process user actions. The Pebble.js library provides an API to build user interface and then remotely controls the C app to display it. As a consequence of the described approach watchapp couldn't function without a connection to the phone. On a side note, I would mention that library is open source and still in beta, so breaking API changes are possible. First steps There are 2 options getting started with Pebble.js: Install Pebble SDK on your local machine. This option allows you to customize Pebble.js. Create a CloudPebble account and work with your appwatch projects online. It is the easiest way to begin Pebble development. CloudPebble The CloudPebble environment allows you to write, build and deploy your appwatch applications both on a simulator and a physical device. Everything is stored in the cloud so no headache with compilers, virtual machines or python dependencies (in my case installation of boost-python end up with errors on MacOS). Hello world As an introduction let's build the Hello World application with Pebble.js. Create a new project in CloudPebble: Then write the following code in the app.js file: // Import the UI elements var UI = require('ui'); // Create a simple Card var card = new UI.Card({ title: 'Hello World', body: 'This is your first Pebble app!' }); // Display to the user card.show(); Start the code on Pebble watch or simulator and you will get the same screen as below: StackExchange profile Getting some data from web services like weather or news is easy with an Ajax library call. For example let's construct an app view of your StackExchange profile: var UI = require('ui'); var ajax = require('ajax'); // Create a Card with title and subtitle var card = new UI.Card({ title:'Profile', subtitle:'Fetching...' }); // Display the Card card.show(); // Construct URL // https://api.stackexchange.com/docs/me#order=desc&sort=reputation&filter=default&site=stackoverflow&run=true var API_TOKEN = 'put api token here'; var API_KEY = 'secret key'; var URL = 'https://api.stackexchange.com/2.2/me?key=' + API_KEY + '&order=desc&sort=reputation&access_token=' + API_TOKEN + '&filter=default'; // Make the request ajax( { url: URL, type: 'json' }, function(data) { // Success! console.log('Successfully fetched StackOverflow profile'); var profile = data.items[0]; var badges = 'Badges: ' + profile.badge_counts.gold + ' ' + profile.badge_counts.silver + ' ' + profile.badge_counts.bronze; // Show to user card.subtitle('Rep: ' + profile.reputation); card.body(badges + 'nDaily change:' + profile.reputation_change_day + 'nWeekly change:' + profile.reputation_change_week + 'nMonthly change:' + profile.reputation_change_month); }, function(error) { // Failure! console.log('Failed fetching Stackoverflow data: ' + JSON.stringify(error)); } ); Egg timer Lastly I would like to create a small real life watchapp. I will demonstrate how to compose a Timer app for boiling eggs. Let's start with the building blocks that we need: Window is the basic building block in Pebble application. It allows you to add different elements and specify a position and size for them. A menu is a type of Window that displays a standard Pebble menu. Vibe allows you to trigger vibration on the wrist. It will signal that eggs are boiled. Egg size screen Users are able to select eggs size from options: Medium Large Extra-large var UI = require('ui'); var menu = new UI.Menu({ sections: [{ title: 'Egg size', items: [{ title: 'Medium', }, { title: 'Large' }, { title: 'Extra-large' }] }] }); menu.show(); Timer selection screen On the next step user selects timer duration. It depends whether he wants soft-boiled or hard-boiled eggs. The second level menu for medium size looks like: var mdMenu = new UI.Menu({ sections: [{ title: 'Egg timer', items: [{ title: 'Runny', subtitle: '2m' }, { title: 'Soft', subtitle: '3m' }, { title: 'Firm', subtitle: '4m' }, { title: 'Hard', subtitle: '5m' }] }] }); // open second level menu from the main menu.on('select', function(e) { if (e.itemIndex === 0){ mdMenu.show(); } else if (e.itemIndex === 1){ lgMenu.show(); } else { xlMenu.show(); } }); Timer screen When timer duration is selected we start a countdown. mdMenu.on('select', onTimerSelect); lgMenu.on('select', onTimerSelect); xlMenu.on('select', onTimerSelect); // timeouts mapping from header to seconds var timeouts = { '2m': 120, '3m': 180, '4m': 240, '5m': 300, '6m': 360, '7m': 420 }; function onTimerSelect(e){ var timeout = timeouts[e.item.subtitle]; timer(timeout); } The final bit of the watchapp is to display a timer, show a message and notify the user with vibration on the wrist when time is elapsed. var readyMessage = new UI.Card({ title: 'Done', body: 'Your eggs are ready!' }); function timer(timerInSec){ var intervalId = setInterval(function(){ timerInSec--; // notify with double vibration if (timerInSec == 1){ Vibe.vibrate('double'); } if (timerInSec > 0){ timerText.text(getTimeString(timerInSec)); } else { readyMessage.show(); timerWindow.hide(); clearInterval(intervalId); // notify with long vibration Vibe.vibrate('long'); } }, 1000); var timerWindow = new UI.Window(); var timerText = new UI.Text({ position: new Vector2(0, 50), size: new Vector2(144, 30), font: 'bitham-42-light', text: getTimeString(timerInSec), textAlign: 'center' }); timerWindow.add(timerText); timerWindow.show(); timerWindow.on('hide', function(){ clearInterval(intervalId); }); } // format remaining time into 00:00 string function getTimeString(timeInSec){ var minutes = parseInt(timeInSec / 60); var seconds = timeInSec % 60; return minutes + ':' + (seconds < 10 ? ('0' + seconds) : seconds); } Conclusion You can do much more with Pebble.js: Get accelerometer values Display complex UI mixing geometric elements, text and images Animate elements on the screen Use the GPS and LocalStorage on the phone Timeline API is coming Pebble.js is best suited for quick prototyping and applications that require access to the Internet. The unfortunate part of the JavaScript written applications is the requirement of a constant connection to the phone. Usually Pebble.js apps need more power and respond slower than a similar native app. Useful links Pebble.js tutorial Pebble blog Pebble.js docs Egg timer code About the author Eugene Safronov is a software engineer with a proven record of delivering high quality software. He has an extensive experience building successful teams and adjusting development processes to the project’s needs. His primary focuses are Web (.NET, node.js stacks) and cross-platform mobile development (native and hybrid). He can be found on Twitter @sejoker.
Read more
  • 0
  • 0
  • 5080

article-image-testing-workflows-microsoft-dynamics-ax-2009-administration
Packt
27 Jan 2011
3 min read
Save for later

Testing Workflows for Microsoft Dynamics AX 2009 Administration

Packt
27 Jan 2011
3 min read
Microsoft Dynamics AX 2009 Administration Testing Workflow At this point, you have performed all the steps required to process workflows. Running an actual Workflow is the best way to test the Workflow system. Depending on your license scheme, Dynamics AX will be equipped with default Workflow templates. In this example, we will cover the process of testing the Workflow system using the Purchase requisition workflow template. In Dynamics AX, go to Account Payable | Setup | Workflow configurations to load the Workflow configuration form specific for Accounts Payable business processes. In the Workflow configuration form, select the PurchReqApproval template from the Template drop-down. To create a new Workflow configuration for Purchase requisitions, click on the New button. The Create configuration: Select a template form will load. Select Purchase requisition approval and click on the Create configuration button to start creating the new configuration. After you have clicked on the Create configuration button, a new form Workflow: Purchase requisition approval will load. Provide the relevant field information in the current view. Various fields are required to be filled out in order to save a configuration. In this view, we must provide text in the Submission instructions field. You can set a specific condition that will allow this workflow to initiate. If the condition isn’t satisfied, the workflow will not proceed. For example, perhaps you would want the workflow to be used for Purchase requisitions that have a specific value. Instead of waiting for the workflow to run in order to verify that it works on specific conditions, you can simply test the conditions as you create them by clicking on the Test condition button. This will allow you to test your conditions on existing Purchase requisitions. In the next step, we must specify the required parameters for the complete and approval stage of the Purchase requisition workflow template. Each workflow may have different stages and each stage has fields that are required to be populated. To specify the parameters for the complete and approval stages in the Purchase requisition workflow, click on the Details tab. Select the PurchReqComplete task to specify the parameters for the complete stage as you did when you were in the General tab. When you have specified the required fields, collapse the PurchReqApproval task and select Step 1. You must also assign a user, group, or role that can approve the PurchReqComplete task. To specify a user, click on the Assignment tab. To specify a user, click on the Choose button. This will load the Assignment form where you can select a specific user, group, role, or hierarchy. You can also specify a time limit for how long a task must be approved by until it expires. Once you have specified the appropriate parameters, click on the OK button.
Read more
  • 0
  • 0
  • 5074

article-image-machine-learning-tasks
Packt
01 Apr 2016
16 min read
Save for later

Machine Learning Tasks

Packt
01 Apr 2016
16 min read
In this article written by David Julian, author of the book Designing Machine Learning Systems with Python, the author wants to state that, he will first introduce the basic machine learning tasks. Classification is probably the most common task, due in part to the fact that it is relatively easy, well understood, and solves a lot of common problems. Multiclass classification (for instance, handwriting recognition) can sometimes be achieved by chaining binary classification tasks. However, we lose information this way, and we become unable to define a single decision boundary. For this reason, multiclass classification is often treated separately from binary classification. (For more resources related to this topic, see here.) There are cases where we are not interested in discrete classes but rather a real number, for instance, a probability. These type of problems are regression problems. Both classification and regression require a training set of correctly labelled data. They are supervised learning problems. Originating from these basic machine tasks are a number of derived tasks. In many applications, this may simply be applying the learning model to a prediction to establish a causal relationship. We must remember that explaining and predicting are not the same. A model can make a prediction, but unless we know explicitly how it made the prediction, we cannot begin to form a comprehensible explanation. An explanation requires human knowledge of the domain. We can also use a prediction model to find exceptions from a general pattern. Here, we are interested in the individual cases that deviate from the predictions. This is often called anomaly detection and has wide applications in areas such as detecting bank fraud, noise filtering, and even in the search for extraterrestrial life. An important and potentially useful task is subgroup discovery. Our goal here is not, as in clustering, to partition the entire domain but rather to find a subgroup that has a substantially different distribution. In essence, subgroup discovery is trying to find relationships between a dependent target variable and many independent explaining variables. We are not trying to find a complete relationship but rather a group of instances that are different in ways that are important in the domain. For instance, establishing the subgroups, smoker = true and family history =true, for a target variable of heart disease =true. Finally, we consider control type tasks. These act to optimize control setting to maximize a pay off is given different conditions. This can be achieved in several ways. We can clone expert behavior; the machine learns directly from a human and makes predictions of actions given different conditions. The task is to learn a prediction model for the expert's actions. This is similar to reinforcement learning, where the task is to learn about the relationship between conditions and optimal action. Clustering, on the other hand, is the task of grouping items without any information on that group; this is an unsupervised learning task. Clustering is basically making a measurement of similarity. Related to clustering is association, which is an unsupervised task to find a certain type of pattern in the data. This task is behind movie recommender systems, and customers who bought this also bought .. on checkout pages of online stores. Data for machine learning When considering raw data for machine learning applications, there are three separate aspects: The volume of the data The velocity of the data The variety of the data Data volume The volume problem can be approached from three different directions: efficiency, scalability, and parallelism. Efficiency is about minimizing the time it takes for an algorithm to process a unit of information. A component of this is the underlying processing power of the hardware. The other component, and one that we have more control over, is ensuring our algorithms are not wasting precious processing cycles on unnecessary tasks. Scalability is really about brute force, and throwing as much hardware at a problem as you can. With Moore's law, which predicts the trend of computer power doubling every two years and reaching its limit, it is clear that scalability is not, by its self, going to be able to keep pace with the ever increasing amounts of data. Simply adding more memory and faster processors is not, in many cases, going to be a cost effective solution. Parallelism is a growing area of machine learning, and it encompasses a number of different approaches from harnessing capabilities of multi core processors, to large scale distributed computing on many different platforms. Probably, the most common method is to simply run the same algorithm on many machines, each with a different set of parameters. Another method is to decompose a learning algorithm into an adaptive sequence of queries, and have these queries processed in parallel. A common implementation of this technique is known as MapReduce, or its open source version, Hadoop. Data velocity The velocity problem is often approached in terms of data producers and data consumers. The data transfer rate between the two is its velocity, and it can be measured in interactive response times. This is the time it takes from a query being made to its response being delivered. Response times are constrained by latencies such as hard disk read and write times, and the time it takes to transmit data across a network. Data is being produced at ever greater rates, and this is largely driven by the rapid expansion of mobile networks and devices. The increasing instrumentation of daily life is revolutionizing the way products and services are delivered. This increasing flow of data has led to the idea of streaming processing. When input data is at a velocity that makes it impossible to store in its entirety, a level of analysis is necessary as the data streams, in essence, deciding what data is useful and should be stored and what data can be thrown away. An extreme example is the Large Hadron Collider at CERN, where the vast majority of data is discarded. A sophisticated algorithm must scan the data as it is being generated, looking at the information needle in the data haystack. Another instance where processing data streams might be important is when an application requires an immediate response. This is becoming increasingly used in applications such as online gaming and stock market trading. It is not just the velocity of incoming data that we are interested in. In many applications, particularly on the web, the velocity of a system's output is also important. Consider applications such as recommender systems, which need to process large amounts of data and present a response in the time it takes for a web page to load. Data variety Collecting data from different sources invariably means dealing with misaligned data structures, and incompatible formats. It also often means dealing with different semantics and having to understand a data system that may have been built on a pretty different set of logical principles. We have to remember that, very often, data is repurposed for an entirely different application than the one it was originally intended for. There is a huge variety of data formats and underlying platforms. Significant time can be spent converting data into one consistent format. Even when this is done, the data itself needs to be aligned such that each record consists of the same number of features and is measured in the same units. Models The goal in machine learning is not to just solve an instance of a problem, but to create a model that will solve unique problems from new data. This is the essence of learning. A learning model must have a mechanism for evaluating its output, and in turn, changing its behavior to a state that is closer to a solution. A model is essentially a hypothesis: a proposed explanation for a phenomenon. The goal is to apply a generalization to the problem. In the case of supervised learning, problem knowledge gained from the training set is applied to the unlabeled test. In the case of an unsupervised learning problem, such as clustering, the system does not learn from a training set. It must learn from the characteristics of the dataset itself, such as degree of similarity. In both cases, the process is iterative. It repeats a well-defined set of tasks, that moves the model closer to a correct hypothesis. There are many models and as many variations on these models as there are unique solutions. We can see that the problems that machine learning systems solve (regression, classification, association, and so on) come up in many different settings. They have been used successfully in almost all branches of science, engineering, mathematics, commerce, and also in the social sciences; they are as diverse as the domains they operate in. This diversity of models gives machine learning systems great problem solving powers. However, it can also be a bit daunting for the designer to decide what is the best model, or models, for a particular problem. To complicate things further, there are often several models that may solve your task, or your task may need several models. The most accurate and efficient pathway through an original problem is something you simply cannot know when you embark upon such a project. There are several modeling approaches. These are really different perspectives that we can use to help us understand the problem landscape. A distinction can be made regarding how a model divides up the instance space. The instance space can be considered all possible instances of your data, regardless of whether each instance actually appears in the data. The data is a subset of the instance space. There are two approaches to dividing up this space: grouping and grading. The key difference between the two is that grouping models divide the instance space into fixed discrete units called segments. Each segment has a finite resolution and cannot distinguish between classes beyond this resolution. Grading, on the other hand, forms a global model over the entire instance space, rather than dividing the space into segments. In theory, the resolution of a grading model is infinite, and it can distinguish between instances no matter how similar they are. The distinction between grouping and grading is not absolute, and many models contain elements of both. Geometric models One of the most useful approaches to machine learning modeling is through geometry. Geometric models use the concept of instance space. The most obvious example is when all the features are numerical and can become coordinates in a Cartesian coordinate system. When we only have two or three features, they are easy to visualize. Since many machine learning problems have hundreds or thousands of features, and therefore dimensions, visualizing these spaces is impossible. Importantly, many of the geometric concepts, such as linear transformations, still apply in this hyper space. This can help us better understand our models. For instance, we expect many learning algorithms to be translation invariant, which means that it does not matter where we place the origin in the coordinate system. Also, we can use the geometric concept of Euclidean distance to measure similarity between instances; this gives us a method to cluster alike instances and form a decision boundary between them. Probabilistic models Often, we will want our models to output probabilities rather than just binary true or false. When we take a probabilistic approach, we assume that there is an underlying random process that creates a well-defined, but unknown, probability distribution. Probabilistic models are often expressed in the form of a tree. Tree models are ubiquitous in machine learning, and one of their main advantages is that they can inform us about the underlying structure of a problem. Decision trees are naturally easy to visualize and conceptualize. They allow inspection and do not just give an answer. For example, if we have to predict a category, we can also expose the logical steps that gave rise to a particular result. Also, tree models generally require less data preparation than other models and can handle numerical and categorical data. On the down side, tree models can create overly complex models that do not generalize very well to new data. Another potential problem with tree models is that they can become very sensitive to changes in the input data, and as we will see later, this problem can be mitigated by using them as ensemble learners. Linear models A key concept in machine learning is that of the linear model. Linear models form the foundation of many advanced nonlinear techniques such as support vector machines and neural networks. They can be applied to any predictive task such as classification, regression, or probability estimation. When responding to small changes in the input data, and provided that our data consists of entirely uncorrelated features, linear models tend to be more stable than tree models. Tree models can over-respond to small variation in training data. This is because splits at the root of a tree have consequences that are not recoverable further down a branch, potentially making the rest of the tree significantly different. Linear models, on the other hand, are relatively stable, being less sensitive to initial conditions. However, as you would expect, this has the opposite effect of making it less sensitive to nuanced data. This is described by the terms variance (for over fitting models) and bias (for under fitting models). A linear model is typically low variance and high bias. Linear models are generally best approached from a geometric perspective. We know we can easily plot two dimensions of space in a Cartesian co-ordinate system, and we can use the illusion of perspective to illustrate a third. We have also been taught to think of time as being a fourth dimension, but when we start speaking of n dimensions, a physical analogy breaks down. Intriguingly, we can still use many of the mathematical tools that we intuitively apply to three dimensions of space. While it becomes difficult to visualize these extra dimensions, we can still use the same geometric concepts (such as lines, planes, angles, and distance) to describe them. With geometric models, we describe each instance as having a set of real-valued features, each of which is a dimension in a space. Model ensembles Ensemble techniques can be divided broadly into two types. The Averaging Method: With this method, several estimators are run independently, and their predictions are averaged. This includes the random forests and bagging methods. The Boosting Methods: With this method, weak learners are built sequentially using weighted distributions of the data, based on the error rates. Ensemble methods use multiple models to obtain better performance than any single constituent model. The aim is to not only build diverse and robust models, but also to work within limitations such as processing speed and return times. When working with large datasets and quick response times, this can be a significant developmental bottleneck. Troubleshooting and diagnostics are important aspects of working with all machine learning models, but they are especially important when dealing with models that might take days to run. The types of machine learning ensembles that can be created are as diverse as the models themselves, and the main considerations revolve around three things: how we divide our data, how we select the models, and the methods we use to combine their results. This simplistic statement actually encompasses a very large and diverse space. Neural nets When we approach the problem of trying to mimic the brain, we are faced with a number of difficulties. Considering all the different things the brain does, we might first think that it consists of a number of different algorithms, each specialized to do a particular task, and each hard wired into different parts of the brain. This approach translates to considering the brain as a number of subsystems, each with its own program and task. For example, the auditory cortex for perceiving sound has its own algorithm that, say, does a Fourier transform on an incoming sound wave to detect the pitch. The visual cortex, on the other hand, has its own distinct algorithm for decoding the signals from the optic nerve and translating them into the sensation of sight. There is, however, growing evidence that the brain does not function like this at all. It appears, from biological studies, that brain tissue in different parts of the brain can relearn how to interpret inputs. So, rather than consisting of specialized subsystems that are programmed to perform specific tasks, the brain uses the same algorithm to learn different tasks. This single algorithm approach has many advantages, not least of which is that it is relatively easy to implement. It also means that we can create generalized models and then train them to perform specialized tasks. Like in real brains, using a singular algorithm to describe how each neuron communicates with the other neurons around it allows artificial neural networks to be adaptable and able to carry out multiple higher-level tasks. Much of the most important work being done with neural net models, and indeed machine learning in general, is through the use of very complex neural nets with many layers and features. This approach is often called deep architecture or deep learning. Human and animal learning occurs at a rate and depth that no machine can match. Many of the elements of biological learning still remain a mystery. One of the key areas of research, and one of the most useful in application, is that of object recognition. This is something quite fundamental to living systems, and higher animals have evolved to possessing an extraordinary ability to learn complex relationships between objects. Biological brains have many layers; each synaptic event exists in a long chain of synaptic processes. In order to recognize complex objects, such as people's faces or handwritten digits, a fundamental task is to create a hierarchy of representation from the raw input to higher and higher levels of abstraction. The goal is to transform raw data, such as a set of pixel values, into something that we can describe as, say, a person riding bicycle. Resources for Article: Further resources on this subject: Python Data Structures [article] Exception Handling in MySQL for Python [article] Python Data Analysis Utilities [article]
Read more
  • 0
  • 0
  • 5074
article-image-responsive-applications-asynchronous-programming
Packt
13 Jul 2016
9 min read
Save for later

Responsive Applications with Asynchronous Programming

Packt
13 Jul 2016
9 min read
In this article by Dirk Strauss, author of the book C# Programming Cookbook, he sheds some light on how to handle events, exceptions and tasks in asynchronous programming, making your application responsive. (For more resources related to this topic, see here.) Handling tasks in asynchronous programming Task-Based Asynchronous Pattern (TAP) is now the recommended method to create asynchronous code. It executes asynchronously on a thread from the thread pool and does not execute synchronously on the main thread of your application. It allows us to check the task's state by calling the Status property. Getting ready We will create a task to read a very large text file. This will be accomplished using an asynchronous Task. How to do it… Create a large text file (we called ours taskFile.txt) and place it in your C:temp folder: In the AsyncDemo class, create a method called ReadBigFile() that returns a Task<TResult> type, which will be used to return an integer of bytes read from our big text file: public Task<int> ReadBigFile() { } Add the following code to open and read the file bytes. You will see that we are using the ReadAsync() method that asynchronously reads a sequence of bytes from the stream and advances the position in that stream by the number of bytes read from that stream. You will also notice that we are using a buffer to read those bytes. public Task<int> ReadBigFile() { var bigFile = File.OpenRead(@"C:temptaskFile.txt"); var bigFileBuffer = new byte[bigFile.Length]; var readBytes = bigFile.ReadAsync(bigFileBuffer, 0, " (int)bigFile.Length); return readBytes; } Exceptions you can expect to handle from the ReadAsync() method are ArgumentNullException, ArgumentOutOfRangeException, ArgumentException, NotSupportedException, ObjectDisposedException and InvalidOperatorException. Finally, add the final section of code just after the var readBytes = bigFile.ReadAsync(bigFileBuffer, 0, (int)bigFile.Length); line that uses a lambda expression to specify the work that the task needs to perform. In this case, it is to read the bytes in the file: public Task<int> ReadBigFile() { var bigFile = File.OpenRead(@"C:temptaskFile.txt"); var bigFileBuffer = new byte[bigFile.Length]; var readBytes = bigFile.ReadAsync(bigFileBuffer, 0, (int)bigFile.Length); readBytes.ContinueWith(task => { if (task.Status == TaskStatus.Running) Console.WriteLine("Running"); else if (task.Status == TaskStatus.RanToCompletion) Console.WriteLine("RanToCompletion"); else if (task.Status == TaskStatus.Faulted) Console.WriteLine("Faulted"); bigFile.Dispose(); }); return readBytes; } If not done so in the previous section, add a button to your Windows Forms application's Form designer. On the winformAsync form designer, open Toolbox and select the Button control, which is found under the All Windows Forms node: Drag the button control onto the Form1 designer: With the button control selected, double-click the control to create the click event in the code behind. Visual Studio will insert the event code for you: namespace winformAsync { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { } } } Change the button1_Click event and add the async keyword to the click event. This is an example of a void returning asynchronous method: private async void button1_Click(object sender, EventArgs e) { } Now, make sure that you add code to call the AsyncDemo class's ReadBigFile() method asynchronously. Remember to read the result from the method (which are the bytes read) into an integer variable: private async void button1_Click(object sender, EventArgs e) { Console.WriteLine("Start file read"); Chapter6.AsyncDemo oAsync = new Chapter6.AsyncDemo(); int readResult = await oAsync.ReadBigFile(); Console.WriteLine("Bytes read = " + readResult); } Running your application will display the Windows Forms application: Before clicking on the button1 button, ensure that the Output window is visible: From the View menu, click on the Output menu item or type Ctrl + Alt + to display the Output window. This will allow us to see the Console.Writeline() outputs as we have added them to the code in the Chapter6 class and in the Windows application. Clicking on the button1 button will display the outputs to our Output window. Throughout this code execution, the form remains responsive. Take note though that the information displayed in your Output window will differ from the screenshot. This is because the file you used is different from mine. How it works… The task is executed on a separate thread from the thread pool. This allows the application to remain responsive while the large file is being processed. Tasks can be used in multiple ways to improve your code. This recipe is but one example. Exception handling in asynchronous programming Exception handling in asynchronous programming has always been a challenge. This was especially true in the catch blocks. As of C# 6, you are now allowed to write asynchronous code inside the catch and finally block of your exception handlers. Getting ready The application will simulate the action of reading a logfile. Assume that a third-party system always makes a backup of the logfile before processing it in another application. While this processing is happening, the logfile is deleted and recreated. Our application, however, needs to read this logfile on a periodic basis. We, therefore, need to be prepared for the case where the file does not exist in the location we expect it in. Therefore, we will purposely omit the main logfile, so that we can force an error. How to do it… Create a text file and two folders to contain the logfiles. We will, however, only create a single logfile in the BackupLog folder. The MainLog folder will remain empty: In our AsyncDemo class, write a method to read the main logfile in the MainLog folder: private async Task<int> ReadMainLog() { var bigFile = " File.OpenRead(@"C:tempLogMainLogtaskFile.txt"); var bigFileBuffer = new byte[bigFile.Length]; var readBytes = bigFile.ReadAsync(bigFileBuffer, 0, " (int)bigFile.Length); await readBytes.ContinueWith(task => { if (task.Status == TaskStatus.RanToCompletion) Console.WriteLine("Main Log RanToCompletion"); else if (task.Status == TaskStatus.Faulted) Console.WriteLine("Main Log Faulted"); bigFile.Dispose(); }); return await readBytes; } Create a second method to read the backup file in the BackupLog folder: private async Task<int> ReadBackupLog() { var bigFile = " File.OpenRead(@"C:tempLogBackupLogtaskFile.txt"); var bigFileBuffer = new byte[bigFile.Length]; var readBytes = bigFile.ReadAsync(bigFileBuffer, 0, " (int)bigFile.Length); await readBytes.ContinueWith(task => { if (task.Status == TaskStatus.RanToCompletion) Console.WriteLine("Backup Log " RanToCompletion"); else if (task.Status == TaskStatus.Faulted) Console.WriteLine("Backup Log Faulted"); bigFile.Dispose(); }); return await readBytes; } In actual fact, we would probably only create a single method to read the logfiles, passing only the path as a parameter. In a production application, creating a class and overriding a method to read the different logfile locations would be a better approach. For the purposes of this recipe, however, we specifically wanted to create two separate methods so that the different calls to the asynchronous methods are clearly visible in the code. We will then create a main ReadLogFile() method that tries to read the main logfile. As we have not created the logfile in the MainLog folder, the code will throw a FileNotFoundException. It will then run the asynchronous method and await that in the catch block of the ReadLogFile() method (something which was impossible in the previous versions of C#), returning the bytes read to the calling code: public async Task<int> ReadLogFile() { int returnBytes = -1; try { Task<int> intBytesRead = ReadMainLog(); returnBytes = await ReadMainLog(); } catch (Exception ex) { try { returnBytes = await ReadBackupLog(); } catch (Exception) { throw; } } return returnBytes; } If not done so in the previous recipe, add a button to your Windows Forms application's Form designer. On the winformAsync form designer, open Toolbox and select the Button control, which is found under the All Windows Forms node: Drag the button control onto the Form1 designer: With the button control selected, double-click on the control to create the click event in the code behind. Visual Studio will insert the event code for you: namespace winformAsync { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { } } } Change the button1_Click event and add the async keyword to the click event. This is an example of a void returning an asynchronous method: private async void button1_Click(object sender, EventArgs e) { } Next, we will write the code to create a new instance of the AsyncDemo class and attempt to read the main logfile. In a real-world example, it is at this point that the code does not know that the main logfile does not exist: private async void button1_Click(object sender, EventArgs "e) { Console.WriteLine("Read backup file"); Chapter6.AsyncDemo oAsync = new Chapter6.AsyncDemo(); int readResult = await oAsync.ReadLogFile(); Console.WriteLine("Bytes read = " + readResult); } Running your application will display the Windows Forms application: Before clicking on the button1 button, ensure that the Output window is visible: From the View menu, click on the Output menu item or type Ctrl + Alt + O to display the Output window. This will allow us to see the Console.Writeline() outputs as we have added them to the code in the Chapter6 class and in the Windows application. To simulate a file not found exception, we deleted the file from the MainLog folder. You will see that the exception is thrown, and the catch block runs the code to read the backup logfile instead: How it works… The fact that we can await in catch and finally blocks allows developers much more flexibility because asynchronous results can consistently be awaited throughout the application. As you can see from the code we wrote, as soon as the exception was thrown, we asynchronously read the file read method for the backup file. Summary In this article we looked at how TAP is now the recommended method to create asynchronous code. How tasks can be used in multiple ways to improve your code. This allows the application to remain responsive while the large file is being processed also how exception handling in asynchronous programming has always been a challenge and how to use catch and finally block to handle exceptions. Resources for Article: Further resources on this subject: Functional Programming in C#[article] Creating a sample C#.NET application[article] Creating a sample C#.NET application[article]
Read more
  • 0
  • 0
  • 5073

article-image-using-google-maps-apis-knockoutjs
Packt
22 Sep 2015
7 min read
Save for later

Using Google Maps APIs with Knockout.js

Packt
22 Sep 2015
7 min read
This article by Adnan Jaswal, the author of the book, KnockoutJS by Example, will render a map of the application and allow the users to place markers on it. The users will also be able to get directions between two addresses, both as description and route on the map. (For more resources related to this topic, see here.) Placing marker on the map This feature is about placing markers on the map for the selected addresses. To implement this feature, we will: Update the address model to hold the marker Create a method to place a marker on the map Create a method to remove an existing marker Register subscribers to trigger the removal of the existing markers when an address changes Update the module to add a marker to the map Let's get started by updating the address model. Open the MapsApplication module and locate the AddressModel variable. Add an observable to this model to hold the marker like this: /* generic model for address */ var AddressModel = function() { this.marker = ko.observable(); this.location = ko.observable(); this.streetNumber = ko.observable(); this.streetName = ko.observable(); this.city = ko.observable(); this.state = ko.observable(); this.postCode = ko.observable(); this.country = ko.observable(); }; Next, we create a method that will create and place the marker on the map. This method should take location and address model as parameters. The method will also store the marker in the address model. Use the google.maps.Marker class to create and place the marker. Our implementation of this method looks similar to this: /* method to place a marker on the map */ var placeMarker = function (location, value) { // create and place marker on the map var marker = new google.maps.Marker({ position: location, map: map }); //store the newly created marker in the address model value().marker(marker); }; Now, create a method that checks for an existing marker in the address model and removes it from the map. Name this method removeMarker. It should look similar to this: /* method to remove old marker from the map */ var removeMarker = function(address) { if(address != null) { address.marker().setMap(null); } }; The next step is to register subscribers that will trigger when an address changes. We will use these subscribers to trigger the removal of the existing markers. We will use the beforeChange event of the subscribers so that we have access to the existing markers in the model. Add subscribers to the fromAddress and toAddress observables to trigger on the beforeChange event. Remove the existing markers on the trigger. To achieve this, I created a method called registerSubscribers. This method is called from the init method of the module. The method registers the two subscribers that triggers calls to removeMarker. Our implementation looks similar to this: /* method to register subscriber */ var registerSubscribers = function () { //fire before from address is changed mapsModel.fromAddress.subscribe(function(oldValue) { removeMarker(oldValue); }, null, "beforeChange"); //fire before to address is changed mapsModel.toAddress.subscribe(function(oldValue) { removeMarker(oldValue); }, null, "beforeChange"); }; We are now ready to bring the methods we created together and place a marker on the map. Create a map called updateAddress. This method should take two parameters: the place object and the value binding. The method should call populateAddress to extract and populate the address model, and placeMarker to place a new marker on the map. Our implementation looks similar to this: /* method to update the address model */ var updateAddress = function(place, value) { populateAddress(place, value); placeMarker(place.geometry.location, value); }; Call the updateAddress method from the event listener in the addressAutoComplete custom binding: google.maps.event.addListener(autocomplete, 'place_changed', function() { var place = autocomplete.getPlace(); console.log(place); updateAddress(place, value); }); Open the application in your browser. Select from and to addresses. You should now see markers appear for the two selected addresses. In our browser, the application looks similar to the following screenshot: Displaying a route between the markers The last feature of the application is to draw a route between the two address markers. To implement this feature, we will: Create and initialize the direction service Request routing information from the direction service and draw the route Update the view to add a button to get directions Let's get started by creating and initializing the direction service. We will use the google.maps.DirectionsService class to get the routing information and the google.maps.DirectionsRenderer to draw the route on the map. Create two attributes in the MapsApplication module: one for directions service and the other for directions renderer: /* the directions service */ var directionsService; /* the directions renderer */ var directionsRenderer; Next, create a method to create and initialize the preceding attributes: /* initialise the direction service and display */ var initDirectionService = function () { directionsService = new google.maps.DirectionsService(); directionsRenderer = new google.maps.DirectionsRenderer({suppressMarkers: true}); directionsRenderer.setMap(map); }; Call this method from the mapPanel custom binding handler after the map has been created and cantered. The updated mapPanel custom binding should look similar to this: /* custom binding handler for maps panel */ ko.bindingHandlers.mapPanel = { init: function(element, valueAccessor){ map = new google.maps.Map(element, { zoom: 10 }); centerMap(localLocation); initDirectionService(); } }; The next step is to create a method that will build and fire a request to the direction service to fetch the direction information. The direction information will then be used by the direction renderer to draw the route on the map. Our implementation of this method looks similar to this: /* method to get directions and display route */ var getDirections = function () { //create request for directions var routeRequest = { origin: mapsModel.fromAddress().location(), destination: mapsModel.toAddress().location(), travelMode: google.maps.TravelMode.DRIVING }; //fire request to route based on request directionsService.route(routeRequest, function(response, status) { if (status == google.maps.DirectionsStatus.OK) { directionsRenderer.setDirections(response); } else { console.log("No directions returned ..."); } }); }; We create a routing request in the first part of the method. The request object consists of origin, destination, and travelMode. The origin and destination values are set to the locations for from and to addresses. The travelMode is set to google.maps.TravelMode.DRIVING, which, as the name suggests, specifies that we require driving route. Add the getDirections method to the return statement of the module as we will bind it to a button in the view. One last step before we can work on the view is to clear the route on the map when the user selects a new address. This can be achieved by adding an instruction to clear the route information in the subscribers we registerd earlier. Update the subscribers in the registerSubscribers method to clear the routes on the map: /* method to register subscriber */ var registerSubscribers = function () { //fire before from address is changed mapsModel.fromAddress.subscribe(function(oldValue) { removeMarker(oldValue); directionsRenderer.set('directions', null); }, null, "beforeChange"); //fire before to address is changed mapsModel.toAddress.subscribe(function(oldValue) { removeMarker(oldValue); directionsRenderer.set('directions', null); }, null, "beforeChange"); }; The last step is to update the view. Open the view and add a button under the address input components. Add click binding to the button and bind it to the getDirections method of the module. Add enable binding to make the button clickable only after the user has selected the two addresses. The button should look similar to this: <button type="button" class="btn btn-default" data-bind="enable: MapsApplication.mapsModel.fromAddress && MapsApplication.mapsModel.toAddress, click: MapsApplication.getDirections"> Get Directions </button> Open the application in your browser and select the From address and To address option. The address details and markers should appear for the two selected addresses. Click on the Get Directions button. You should see the route drawn on the map between the two markers. In our browser, the application looks similar to the following screenshot: Summary In this article, we walked through placing markers on the map and displaying the route between the markers. Resources for Article: Further resources on this subject: KnockoutJS Templates[article] Components [article] Web Application Testing [article]
Read more
  • 0
  • 0
  • 5071

article-image-designing-and-creating-database-tables-ruby-rails
Packt
23 Oct 2009
9 min read
Save for later

Designing and Creating Database Tables in Ruby on Rails

Packt
23 Oct 2009
9 min read
Background Information The User Management Module is created for a website called 'TaleWiki'. TaleWiki is a website about user submitted tales and stories, which can be added, modified, deleted, and published by the user, depending on the Role or Privileges the user has. Taking into consideration this small piece of information, we will design and create tables that will become the back-end for the User Management functionality. Designing the Tables To Design and to create tables, we need to understand the entities and their relationship, the schema corresponding to the entities, and then the table creation queries. If we go step-by-step, we can say that following are the steps in designing the tables for the User Management module: Designing the E-R model Deriving the Schema from the E-R model Creating the Tables from the Schema So, let us follow the steps. Designing the E-R Model To design the E-R model, let us first look at what we have understood about the data required by the functionalities, which we just discussed. It tells us that 'only the Users with a particular Role can access TaleWiki'. Now we can consider this as our 'problem statement' for our E-R model design. If you observe closely, the statement is vague. It doesn't tell about the particular Roles. However, for the E-R design, this will suffice as it clearly mentions the two main entities, if we use the E-R terminology. They are: User Role Let us look at the User entity. Now this entity represents a real-world user. It is not difficult to describe its attributes. Keeping a real-world user in mind and the functionalities discussed for managing a user, we can say that the User entity should have the following attributes: Id: It will identify the different users, and it will be unique. User name: The name which will be displayed with the submitted story. Password: The pass key with which the user will be authenticated. First name: The first name of the user. Last name: The last name of the user. The combination of the first and last name will be the real name of the user. Age: The age of the user. This will help in deciding whether or not the user is of required age which is 15. E-mail id: The email id of the user in which he/she would like to get emails from the administrator regarding the submissions. Country: To keep track of the 'geographic distribution' of users. Role: To know what privileges are granted for the user. The Role is required because the problem statement mentions "User with a particular Role". The entity diagram will be as follows: Next, let us look at the Role entity. Role, as already discussed, will represent the privileges a user can have. And as these privileges are static, the Role entity won't need to have the attribute to store the privileges. The important point about the static privileges that you have to keep in mind is that they will have to be programmatically checked against a user. In other words, the privileges are not present in the database and there can only be a small number of Roles with predefined privileges. Keeping this in mind, we can say that the Role entity will have the following attributes: Id: The unique identification number for the Role. Name: The name with which the id will be known and that will be displayed along with the user name. The entity diagram for Role entity will be as follows: We have completed two out of three steps in designing the E-R model. Next, we have to define how the User entity is related with the Role entity. From the problem statement we can say that a user will definitely have a Role. And the functionality for assigning the Role tells us that a user can have only one Role. So if we combine these two, we can say that 'A user will have only one Role but different users can have the same Role'. In simple terms, a Role—let us say normal user—can be applied to different users such as John, or Jane. However, the users John or Jane cannot be both normal user as well as administrator. In technical terms, we can say that a Role has a one-to-many relationship with the User entity and a User has a many-to-one relationship with a Role. Diagrammatically, it will be as follows: One piece of the puzzle is still left. If you remember there is one more entity called Story. We had found that each story had a submitter. The submitter is a user. So that means there is a relationship between the User and the Story entity. Now, a user, let us say, John or Jane, can submit many stories. However, the same story cannot be submitted by more than one user. On the basis of this we can say that a User has a many-to-one relationship with a Story and a Story has a many-to-one relationship with a User. According to the E-R diagram it will be as follows: The final E-R design including all the entities and the attributes will be as follows: That completes our E-R design step. Next, we will derive the schema from theE-R model. Deriving the Schema We have all we need to derive the schema for our purpose. While deriving a schema from an E-R model, it is always a good choice to start with the entities at the 'one' end of a 'one-to-many' relationship. In our case, it is the Role entity. As we did in the previous chapter, let us start by providing the details for each attribute of the Role entity. The following is the schema for the Role entity: Attribute Data type of the attribute Length of the acceptable value Id Integer 10 Name Varchar 25 >Next, let us look at the schema of the User entity. As it is at the 'many' end of the 'one-to-many' relationship, the Role attribute will be replaced by the Id of Role. The schema will be as follows: Attribute Data type of the attribute Length of the acceptable value Id Integer 10 User name Varchar 50 First name Varchar 50 Last name Varchar 50 Password Varchar 15 Age Integer 3 e-mail id Varchar 25 Country Varchar 20 Id of the Role Integer 10 Now, let us visit the Story entity. The attributes of the entity were: Id: This is the Primary key attribute as it can uniquely identify a story. Heading: The title of the story. Body text: The body of the story. Date of Submission: The day the user submitted the story. Source: The source from where the story was found. If it is written by the user himself/herself, the source will be the user's id. Genre: The category of the story. User: The user who submitted the story. Name of the attribute Data type of the attribute Length of the acceptable value Id Integer 10 Title Varchar 100 Body Text Varchar 1000 Date of Submission Date   Source Varchar 50 Status Varchar 15 Id of Genre Integer 10 Id of the User Integer 10 The schema has been derived and now we can move to the last part of the database design—creation of the tables. Creating the Tables Looking at the schema  required for tables in Ruby on Rails, here is the table creation statement for the Role schema: CREATE TABLE `roles` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,`name` VARCHAR( 25 ) NOT NULL ,`description` VARCHAR( 100 ) NOT NULL) ENGINE = innodb; Next comes the table creation statement for the User schema. Note that here also we are following the one-to-many path, that is, the table at the 'one' end is created first. Whenever there is a one-to-many relationship between entities, you will have to create the table for the entity at the 'one' end. Otherwise you will not be able to create a foreign key reference in the table for the entity at the 'many' end, and if you try to create one, you will get an error (obviously). So here is the create table statement for the User schema: CREATE TABLE `users` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,`user_name` VARCHAR( 50 ) NOT NULL ,`password` VARCHAR( 15 ) NOT NULL ,`first_name` VARCHAR( 50 ) NOT NULL ,`last_name` VARCHAR( 50 ) NOT NULL ,`age` INT( 3 ) NOT NULL ,`email` VARCHAR( 25 ) NOT NULL ,`country` VARCHAR( 20 ) NOT NULL ,`role_id` INT NOT NULL,CONSTRAINT `fk_users_roles` FOREIGN KEY (`role_id`) REFERENCES `role`( `id`) ON DELETE CASCADE) ENGINE = innodb; Next, let us create the table for Story, we will call it the 'tales' table, we will also add a foreign key reference to the users table in it. Here is the query for creating the table CREATE TABLE `tales` (`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY,`title` VARCHAR( 100 ) NOT NULL,`body_text` TEXT NOT NULL,`submission_date` DATE NOT NULL,`source` VARCHAR( 50 ) NOT NULL,`status` VARCHAR( 15 ) NOT NULL,`genre_id` INT NOT NULL,`user_id` INT NOT NULL,CONSTRAINT `fk_tales_genres` FOREIGN KEY (`genre_id`) REFERENCES genres( `id`)) ENGINE = innodb; Next, we will make a reference to the users table after executing the above query, with the following query: ALTER TABLE `tales` ADD FOREIGN KEY ( `user_id` ) REFERENCES `users` (`id`) ON DELETE CASCADE ; That completes our task of creating the required tables and making necessary changes to the tales table. The effect of this change will be visible to you when we implement session management in the next chapter. And incidentally, it completes the 'designing the tables' section. Let us move onto the development of the user management functionality. Summary In this article, we learned how to design and create tables for a User Management Module in Ruby on Rails. We looked at designing the E-R model, deriving the schema from the E-R model and creating the tables from the schema.
Read more
  • 0
  • 0
  • 5065
article-image-factor-variables-r
Packt
01 Apr 2015
7 min read
Save for later

Factor variables in R

Packt
01 Apr 2015
7 min read
This article by Jaynal Abedin and Kishor Kumar Das, authors of the book Data Manipulation with R Second Edition, will discuss factor variables in R. In any data analysis task, the majority of the time is dedicated to data cleaning and preprocessing. Sometimes, it is considered that about 80 percent of the effort is devoted to data cleaning before conducting the actual analysis. Also, in real-world data, we often work with categorical variables. A variable that takes only a limited number of distinct values is usually known as a categorical variable, and in R, it is known as a factor. Working with categorical variables in R is a bit technical, and in this article, we have tried to demystify this process of dealing with categorical variables. (For more resources related to this topic, see here.) During data analysis, the factor variable sometimes plays an important role, particularly in studying the relationship between two categorical variables. In this section, we will see some important aspects of factor manipulation. When a factor variable is first created, it stores all its levels along with the factor. But if we take any subset of that factor variable, it inherits all its levels from the original factor levels. This feature sometimes creates confusion in understanding the results. Numeric variables are convenient during statistical analysis, but sometimes, we need to create categorical (factor) variables from numeric variables. We can create a limited number of categories from a numeric variable using a series of conditional statements, but this is not an efficient way to perform this operation. In R, cut is a generic command to create factor variables from numeric variables. The split-apply-combine strategy Data manipulation is an integral part of data cleaning and analysis. For large data, it is always preferable to perform the operation within a subgroup of a dataset to speed up the process. In R, this type of data manipulation can be done with base functionality, but for large-scale data, it requires considerable amount of coding and eventually takes a longer time to process. In the case of big data, we can split the dataset, perform the manipulation or analysis, and then again combine the results into a single output. This type of split using base R is not efficient, and to overcome this limitation, Wickham developed an R package, plyr, where he efficiently implemented the split-apply-combine strategy. Often, we require similar types of operations in different subgroups of a dataset, such as group-wise summarization, standardization, and statistical modeling. This type of task requires us to break down a big problem into manageable pieces, perform operations on each piece separately, and finally combine the output of each piece into a single piece of output. To understand the split-apply-combine strategy intuitively, we can compare it with the map-reduce strategy for processing large amounts of data, recently popularized by Google. In the map-reduce strategy, the map step corresponds to split and apply and the reduce step consists of combining. The map-reduce approach is primarily designed to deal with a highly parallel environment where the work has been done by several hundreds or thousands of computers independently. The split-apply-combine strategy creates an opportunity to see the similarities of problems across subgroups that were not previously connected. This strategy can be used in many existing tools, such as the GROUP BY operation in SAS, PivotTable in MS Excel, and the SQL GROUP BY operator. The plyr package works on every type of data structure, whereas the dplyr package is designed to work only on data frames. The dplyr package offers a complete set of functions to perform every kind of data manipulation we would need in the process of analysis. These functions take a data frame as the input and also produce a data frame as the output, hence the name dplyr. There are two different types of functions in the dplyr package: single-table and aggregate. The single-table function takes a data frame as the input and an action such as subsetting a data frame, generating new columns in the data frame, or rearranging a data frame. The aggregate function takes a column as the input and produces a single value as the output, which is mostly used to summarize columns. These functions do not allow us to perform any group-wise operation, but a combination of these functions with the group_by() function allows us to implement the split-apply-combine approach. Reshaping a dataset Reshaping data is a common and tedious task in real-life data manipulation and analysis. A dataset might come with different levels of grouping, and we need to implement some reorientation to perform certain types of analyses. A dataset's layout could be long or wide. In a long layout, multiple rows represent a single subject's record, whereas in a wide layout, a single row represents a single subject's record. Statistical analysis sometimes requires wide data and sometimes long data, and in such cases, we need to be able to fluently and fluidly reshape the data to meet the requirements of statistical analysis. Data reshaping is just a rearrangement of the form of the data—it does not change the content of the dataset. In this article, we will show you different layouts of the same dataset and see how they can be transferred from one layout to another. This article mainly highlights the melt and cast paradigm of reshaping datasets, which is implemented in the reshape contributed package. Later on, this same package is reimplemented with a new name, reshape2, which is much more time and memory efficient. A single dataset can be rearranged in many different ways, but before going into rearrangement, let's look back at how we usually perceive a dataset. Whenever we think about any dataset, we think of a two-dimensional arrangement where a row represents a subject's (a subject could be a person and is typically the respondent in a survey) information for all the variables in a dataset, and a column represents the information for each characteristic for all subjects. This means that rows indicate records and columns indicate variables, characteristics, or attributes. This is the typical layout of a dataset. In this arrangement, one or more variables might play a role as an identifier, and others are measured characteristics. For the purpose of reshaping, we can group the variables into two groups: identifier variables and measured variables: The identifier variables: These help us identify the subject from whom we took information on different characteristics. Typically, identifier variables are qualitative in nature and take a limited number of unique values. In database terminology, an identifier is termed as the primary key, and this can be a single variable or a composite of multiple variables. The measured variables: These are those characteristics whose information we took from a subject of interest. These can be qualitative, quantitative, or a mixture of both. Now, beyond this typical structure of a dataset, we can think differently, where we will have only identification variables and a value. The identification variable identifies a subject along with which the measured variable the value represents. In this new paradigm, each row represents one observation of one variable. In the new paradigm, this is termed as melting and it produces molten data. The difference between this new layout of the data and the typical layout is that it now contains only the ID variable and a new column, value, which represents the value of that observation. Text processing Text data is one of the most important areas in the field of data analytics. Nowadays, we are producing a huge amount of text data through various media every day; for example, Twitter posts, blog writing, and Facebook posts are all major sources of text data. Text data can be used to retrieve information, in sentiment analysis and even entity recognition. Summary This article briefly explained the factor variables, the split-apply-combine strategy, reshaping a dataset in R, and text processing. Resources for Article: Further resources on this subject: Introduction to S4 Classes [Article] Warming Up [Article] Driving Visual Analyses with Automobile Data (Python) [Article]
Read more
  • 0
  • 0
  • 5065

article-image-kendo-mvvm-framework
Packt
06 Sep 2013
19 min read
Save for later

The Kendo MVVM Framework

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