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

How-To Tutorials

7018 Articles
article-image-introduction-successful-records-management-implementation-alfresco-3
Packt
14 Jan 2011
15 min read
Save for later

Introduction to Successful Records Management Implementation in Alfresco 3

Packt
14 Jan 2011
15 min read
  Alfresco 3 Records Management Comply with regulations and secure your organization’s records with Alfresco Records Management. Successfully implement your records program using Alfresco Records Management, fully certified for DoD-5015.2 compliance The first and only book to focus exclusively on Alfresco Records Management Step-by-step instructions describe how to identify records, organize records, and manage records to comply with regulatory requirements Learn in detail about the software internals to get a jump-start on performing customizations  A preliminary investigation will also give us good information about the types of records we have and roughly how many records we're talking about. We'll also dig deeper into the area of Authority Documents and we'll determine exactly what our obligations are as an organization in complying with them. The data that we collect in the preliminary investigation will provide the basis for us to make a Business Case that we can present to the executives in the organization. It will outline the benefits and advantages of implementing a records system. We also will need to put in place and communicate organization-wide a formal policy that explains concisely the goals of the records program and what it means to the organization. The information covered in this article is important and easily overlooked when starting a Records Management program. We will discuss: The Preliminary Investigation Authority Documents The Steering Committee and Roles in the Records Management Program Making the Business Case for Records Management Project Management Best practices and standards In this article, we will focus on discussing Records Management best practices. Best practices are the processes, methods, and activities that, when applied correctly, can achieve the most repeatable, effective, and efficient results. While an important function of standards is to ensure consistency and interoperability, standards also often provide a good source of information for how to achieve best practice. Much of our discussion here draws heavily on the methodology described in the DIRKS and ISO-15489 standards that describe Records Management best practices. Before getting into a description of best practices though, let's look and see how these two particular standards have come into being and how they relate to other Records Management standards, like the DoD 5015.2 standard. Origins of Records Management Somewhat surprisingly, standards have only existed in Records Management for about the past fifteen years. But that's not to say that prior to today's standards, there wasn't a body of knowledge and written guidelines that existed as best practices for managing records. Diplomatics Actually, the concept of managing records can be traced back a long way. In the Middle Ages in Europe, important written documents from court transactions were recognized as records, and even then, there were issues around establishing authenticity of records to guard against forgery. From those early concerns around authenticity, the science of document analysis called diplomatics came into being in the late 1600s and became particularly important in Europe with the rise of government bureaucracies in the 1800s. While diplomatics started out as something closer to forensic handwriting analysis than Records Management, it gradually established principles that are still important to Records Management today, such as reliability and authenticity. Diplomatics even emphasized the importance of aligning rules for managing records with business processes, and it treated all records the same, regardless of the media that they are stored on. Records Management in the United States Records Management is something that has come into being very slowly in the United States. In fact, Records Management in the United States is really a twentieth century development. It wasn't even until 1930 that 90 percent of all births and deaths in the United States were recorded. The United States National Archives was first established in 1934 to manage only the federal government historical records, but the National Archives quickly became involved in the management of all federal current records. In 1941, a records administration program was created for federal agencies to transfer their historical records to the National Archives. In 1943, the Records Disposal Act authorized the first use of record disposition schedules. In 1946, all agencies in the executive branch of government were ordered as part of Executive Order 9784 to implement Records Management programs. It wasn't until 1949 with the publication of a pamphlet called Public Records Administration, written by an archivist at the National Archives, that the idea of Records Management was beginning to be seen as an activity that is separate and distinct from the long-term archival of records for preservation. Prior to the 1950s in the United States, most businesses did not have a formalized program for records management. However, that slowly began to change as the federal government provided itself as an example for how records should be managed. The 1950 Federal Records Act formalized Records Management in the United States. The Act included ideas about the creation, maintenance, and disposition of records. Perhaps somewhat similar to the dramatic growth in electronic documents that we are seeing today, the 1950s saw a huge increase in the number of paper records that needed to be managed. The growth in the volume of records and the requirements and the responsibilities imposed by the Federal Records Act led to the creation of regional records centers in the United States, and those centers slowly became models for records managers outside of government. In 1955, the second Hoover Commission was tasked with developing recommendations for paperwork management and published a document entitled Guide to Record Retention Requirements in 1955. While not officially sanctioned as a standard, this document, in many ways, served the same purpose. The guide was popular and has been republished frequently since then and has served as an often-used reference by both government and non-government organizations. As late as 1994, a revised version of the guide was printed by the Office of the Federal Register. That same year, in 1955, ARMA International, the international organization for records managers, was founded. ARMA continues through today to provide a forum for records and information managers, both inside and outside the government, to share information about best practices in the area of Records Management. From the 1950s, companies and non-government organizations were becoming more involved with record management policies, and the US federal government continued to drive much of the evolution of Records Management within the United States. In 1976, the Federal Records Act was amended and sections were added that emphasized paperwork reduction and the importance of documenting the recordkeeping process. The concept of the record lifecycle was also described in the amendments to the Act. In 1985, the National Archives was renamed as NARA, the National Archives and Records Administration, finally acknowledging in the name the role the agency plays in managing records as well as being involved in the long-term archival and preservation of documents. However, it wasn't until the 1990s that standards around Records Management began to take shape. In 1993, a government task force in the United States that included NARA, the US Army, and the US Air Force, began to devise processes for managing records that would include both the management of paper and electronic documents. The recommendations of that task force ultimately led to the DoD-5015.2 standard that was first released in 1997. Australia's AS-4390 and DIRKS In parallel to what was happening in the United States, standards for Records Management were also advancing in Australia. AS-4390 Standards Australia issued AS-4390 in 1996, a document that defined the scope of Records Management with recommendations for implementation in both public and private sectors in Australia. This was the first standard issued by any nation, but much of the language in the standard was very specific, making it usable really only within Australia. AS-4390 approached the management of records as a "continuum model" and addressed the "whole extent of the records' existence". DIRKS In 2000, the National Archives of Australia published DIRKS (Design and Implementation of Recordkeeping System), a methodology for implementing AS-4390. The Australian National Archives developed, tested, and successfully implemented the approach, summarizing the methodology for managing records into an eight-step process. The eight steps of the DIRKS methodology include: Organization assessment: Preliminary Investigation Analysis of business activity Identification of records requirements Assess areas for improvement: Assessment of the existing system Strategies for recordkeeping Design, implement, and review the changes: Design the recordkeeping system Implement the recordkeeping system Post-implementation review An international Records Management standard These two standards, AS-4390 and DIRKS, have had a tremendous influence not only within Australia, but also internationally. In 2001, ISO-15489 was published as an international standard for best practices for Records Management. Part one of the standard was based on AS-4390, and part two was based on the guidelines, as laid out in DIRKS. The same eight-step methodology of DIRKS is used in the part two guidelines of ISO-15489. The DIRKS manual can be freely downloaded from the National Archives of Australia: http://www.naa.gov.au/recordsmanagement/publications/dirks-manual.aspx The ISO-15489 document can be purchased from ISO: http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=31908 and http://www.iso.org/iso/iso_catalogue/catalogue_tc/catalogue_detail.htm?csnumber=35845 ISO-15489 has been a success in terms of international acceptance. 148 countries are members of ISO, and many of the participating countries have embraced the use of ISO-15489. Some countries where ISO-15489 is actively applied include Australia, China, UK, France, Germany, Netherlands, and Jamaica. Both ARMA International and AIIM now also promote the importance of the ISO-15489 standard. Much of the appeal behind the ISO-15489 standard is the fact that it is fairly generic. Because it describes the recordkeeping process at a very high level, it avoids contentious details that may be specific to any particular Records Management implementation. Consider, for example, the eight steps of the DIRKS process, as listed above, and replace the words "record" and "recordkeeping" with the name of some other type of enterprise software or project, like "ERP". The steps and associated recommendations from DIRKS are equally applicable. In fact, we recognize clear parallels between the steps presented in the DIRKS methodology and methodologies used for Project Management. Later in this article, we will look at similarities between Records Management and Project Management methodologies like PMBOK and Agile. Does ISO-15489 overlap with standards like DoD-5015.2 and MoReq? ISO-15489 differs considerably in approach from other Records Management standards, like the DoD-5015.2 standard and the MoReq standard which developed in Europe. While ISO-15489 outlines basic principles of Records Management and describes best practices, these latter two standards are very prescriptive in terms of detailing the specifics for how to implement a Records Management system. They are essentially functional requirement documents for computer systems. MoReq (Model Requirements for the Management of Electronic Records) was initiated by the DLM Forum and funded by the European Commission. MoReq was first published in 2001 as MoReq1 and was then extensively updated and republished as MoReq2 in 2008. In 2010, an effort was undertaken to update the specification with the new name MoReq2010. The MoReq2 standard has been translated into 12 languages and is referenced frequently when building Records Management systems in Europe today. Other international standards for Records Management A number of other standards exist internationally. In Australia, for example, the Public Record Office has published a standard known as the Victorian Electronic Records Strategy (VERS) to address the problem of ensuring that electronic records can be preserved for long periods of time and still remain accessible and readable. The preliminary investigation Before we start getting our hands dirty with the sticky details of designing and implementing our records system, let's first get a big-picture idea of how Records Management currently fits into our organization and then define our vision for the future of Records Management in our organization. To do that, let's make a preliminary investigation of the records that our organization deals with. In the preliminary investigation, we'll make a survey of the records in our organization to find out how they are currently being handled. The results of the survey will provide important input into building the Business Case for moving forward with building a new Records Management system for our organization. With the results of the preliminary investigation, we will be able to create an information map or diagram of where records currently are within our organization and which groups of the organization those records are relevant to. With that information, we will be able to create a very high-level charter for the records program, provide data to be used when building the Business Case for Records Management, and then have sufficient information to be able to calculate a rough estimate of the cost and effort needed for the program scope. Before executing on the preliminary investigation, a detailed plan of attack for the investigation should be made. While the primary goal of the investigation is to gather information, a secondary goal should be to do it in a way that minimizes any disruptions to staff members. To perform the investigation, we will need assistance from the various business units in the organization. Before starting, a 'heads up' should be sent out to the managers of the different business units involved so that they will understand the nature of the investigation, when it will be carried out, and they'll know roughly the amount of time that both they and their unit will need to make available to assist in the investigation. It would also be useful to hold a briefing meeting with staff members from business units, where we expect to find most of the records. The records survey Central to the preliminary investigation is the records survey, which is taken across the organization. A records survey attempts to identify the location and record types for both the electronic and non-electronic records used in the organization. Physical surveys versus questionnaires The records survey is usually either carried out as a physical one or as one managed remotely via questionnaires. In a physical survey, members of the records management team visit each business unit, and working together with staff members from that unit, make a detailed inventory. During the survey, all physical storage locations, such as cabinets, closets, desks, and boxes are inspected. Staff members are asked where they store their files, which business applications they use, and which network drives they have access to. The alternative to the physical survey is to send questionnaires to each of the business units and to ask them to complete the forms on their own. Inspections similar to that of the physical survey would be made, but the business unit is not supported by a records management team member. Which of the two approaches we use will depend on the organization. Of course, a hybrid approach, where a combination of both physical surveys and questionnaires is used would work too. Physical in-person surveys tend to provide more accurate and complete inventories, but they also are typically more expensive and time consuming to perform. Questionnaires, while cheaper, rely on each of the individual business units to complete the information on their own, which means that the reporting and investigation styles used by the different units might not be uniform. There is also the problem that some business units may not be sufficiently motivated to complete the questionnaires in a timely manner. Preparing for the survey: Review existing documentation Before we begin the survey, we should check to see if there already exists any background documentation that describes how records are currently being handled within the organization. Documentation has a habit of getting out of date quickly. Documentation can also be deceiving because sometimes it is written, but never implemented, or implemented in ways that deviate dramatically from the originally written description. So if we're actually lucky enough to find any documentation, we'll need to also validate how accurate that information really is. These are some examples of documents which may already exist and which can provide clues about how some organizational records are being handled today: The organization's disaster recovery plan Previous records surveys or studies The organization's record management policy statement Internal and external audit reports that involve consideration of records Organizational reports like risk assessment and cost-benefit analyses Other types of documents may also exist, which can be good indicators for where records, particularly paper records, might be getting stored. These include: Blueprints, maps, and building plans that show the location of furniture and equipment Contracts with storage companies or organizations that provide records or backup services Equipment and supply inventories that may indicate computer hardware Lists of databases, enterprise application software, and shared drives It may take some footwork and digging to find out exactly where and how records in the organization are currently being stored. Physical records could be getting stored in numerous places throughout office and storage areas. Electronic records might be currently saved on shared drives, local desktops, or other document repositories. The main actions of the records survey can be summarized by the LEAD acronym: Locate the places where records are being stored Examine the records and their contents Ask questions about the records to understand their significance Document the information about the records
Read more
  • 0
  • 0
  • 3693

article-image-3d-animation-techniques-xna-game-studio-40-2
Packt
14 Jan 2011
3 min read
Save for later

3D Animation Techniques with XNA Game Studio 4.0

Packt
14 Jan 2011
3 min read
Object animation We will first look at the animation of objects as a whole. The most common ways to animate an object are rotation and translation (movement). We will begin by creating a class that will interpolate a position and rotation value between two extremes over a given amount of time. We could also have it interpolate between two scaling values, but it is very uncommon for an object to change size in a smooth manner during gameplay, so we will leave it out for simplicity's sake. The ObjectAnimation class has a number of parameters—starting and ending position and rotation values, a duration to interpolate during those values, and a Boolean indicating whether or not the animation should loop or just remain at the end value after the duration has passed: public class ObjectAnimation { Vector3 startPosition, endPosition, startRotation, endRotation; TimeSpan duration; bool loop; } We will also store the amount of time that has elapsed since the animation began, and the current position and rotation values: TimeSpan elapsedTime = TimeSpan.FromSeconds(0); public Vector3 Position { get; private set; } public Vector3 Rotation { get; private set; } The constructor will initialize these values: public ObjectAnimation(Vector3 StartPosition, Vector3 EndPosition, Vector3 StartRotation, Vector3 EndRotation, TimeSpan Duration, bool Loop) { this.startPosition = StartPosition; this.endPosition = EndPosition; this.startRotation = StartRotation; this.endRotation = EndRotation; this.duration = Duration; this.loop = Loop; Position = startPosition; Rotation = startRotation; } Finally, the Update() function takes the amount of time that has elapsed since the last update and updates the position and rotation values accordingly: public void Update(TimeSpan Elapsed) { // Update the time this.elapsedTime += Elapsed; // Determine how far along the duration value we are (0 to 1) float amt = (float)elapsedTime.TotalSeconds / (float)duration. TotalSeconds; if (loop) while (amt > 1) // Wrap the time if we are looping amt -= 1; else // Clamp to the end value if we are not amt = MathHelper.Clamp(amt, 0, 1); // Update the current position and rotation Position = Vector3.Lerp(startPosition, endPosition, amt); Rotation = Vector3.Lerp(startRotation, endRotation, amt); } As a simple example, we'll create an animation (in the Game1 class) that rotates our spaceship in a circle over a few seconds: We'll also have it move the model up and down for demonstration's sake: ObjectAnimation anim; We initialize it in the constructor: models.Add(new CModel(Content.Load<Model>("ship"), Vector3.Zero, Vector3.Zero, new Vector3(0.25f), GraphicsDevice)); anim = new ObjectAnimation(new Vector3(0, -150, 0), new Vector3(0, 150, 0), Vector3.Zero, new Vector3(0, -MathHelper.TwoPi, 0), TimeSpan.FromSeconds(10), true); We update it as follows: anim.Update(gameTime.ElapsedGameTime); models[0].Position = anim.Position; models[0].Rotation = anim.Rotation;
Read more
  • 0
  • 0
  • 6276

article-image-integrating-twitter-magento
Packt
14 Jan 2011
2 min read
Save for later

Integrating Twitter with Magento

Packt
14 Jan 2011
2 min read
Integrating your Magento website with Twitter is a useful way to stay connected with your customers. You'll need a Twitter account (or more specifically an account for your business)  but once that's in place it's actually pretty easy. Adding a 'Follow Us On Twitter' button to your Magento store One of the more simple ways to integrate your store's Twitter feed with Magento is to add a 'Follow Us On Twitter' button to your store's design. Generating the markup from the Twitter website Go to the Twitter Goodies website (): Select the Follow Buttons option and then select the Looking for Follow us on Twitter buttons? towards the bottom of the screen: The buttons will now change to the FOLLOW US ON Twitter buttons: Select the style of button you'd like to make use of on your Magento store and then select the generated HTML that is provided in the pop-up that is displayed: The generated HTML for the M2 Store's Twitter account (with the username of M2MagentoStore) looks like the following: <a href="http://www.twitter.com/M2MagentoStore"> <img src="http://twitter-badges.s3.amazonaws.com/follow_us-a.png" alt="Follow M2MagentoStore on Twitter"/> </a> Adding a static block in Magento for your Twitter button Now you will need to create a new static block in the Magento CMS feature: navigate to CMS Static Blocks| in your Magento store's administration panel and click on Add New Block. As you did when creating a static block for the supplier logos used in your store's footer, complete the form to create the new static block. Add the Follow Us On Twitter button to the Content field by disabling the Rich Text Editor with the Show/Hide Editor button and pasting in the markup you generated previously: You don't need to upload an image to your store through Magento's CMS here as the Twitter buttons are hosted elsewhere. Note that the Identifier field reads follow-twitter—you will need this for the layout changes you are about to make!
Read more
  • 0
  • 0
  • 3670

article-image-introduction-cloud-computing-microsoft-azure
Packt
13 Jan 2011
6 min read
Save for later

Introduction to cloud computing with Microsoft Azure

Packt
13 Jan 2011
6 min read
What is an enterprise application? Before we hop into the cloud, let's talk about who this book is for. Who are "enterprise developers"? In the United States, over half of the economy is small businesses, usually privately owned, with a couple dozen of employees and revenues up to the millions of dollars. The applications that run these businesses have lower requirements because of smaller data volumes and a low number of application users. A single server may host several applications. Many of the business needs for these companies can be met with off-the-shelf software requiring little to no modification. The minority of the United States economy is made up of huge publicly owned corporations—think Microsoft, Apple, McDonald's, Coca-Cola, Best Buy, and so on. These companies have thousands of employees and revenues in the billions of dollars. Because these companies are publicly owned, they are subject to tight regulatory scrutiny. The applications utilized by these companies must faithfully keep track of an immense amount of data to be utilized by hundreds or thousands of users, and must comply with all matters of regulations. The infrastructure for a single application may involve dozens of servers. A team of consultants is often retained to install and maintain the critical systems of a business, and there is often an ecosystem of internal applications built around the enterprise systems that are just as critical. These are the applications we consider to be "enterprise applications", and the people who develop and extend them are "enterprise developers". The high availability of cloud platforms makes them attractive for hosting these critical applications, and there are many options available to the enterprise developer. What is cloud computing? At its most basic, cloud computing is moving applications accessible from our internal network onto an internet (cloud)-accessible space. We're essentially renting virtual machines in someone else's data center, with the capabilities for immediate scale-out, failover, and data synchronization. In the past, having an Internet-accessible application meant we were building a website with a hosted database. Cloud computing changes that paradigm—our application could be a website, or it could be a client installed on a local PC accessing a common data store from anywhere in the world. The data store could be internal to our network or itself hosted in the cloud. The following diagram outlines three ways in which cloud computing can be utilized for an application. In option 1, both data and application have been hosted in the cloud, the second option is to host our application in the cloud and our data locally, and the third option is to host our data in the cloud and our application locally. The expense (or cost) model is also very different. In our local network, we have to buy the hardware and software licenses, install and configure the servers, and finally we have to maintain them. All this counts in addition to building and maintaining the application! In cloud computing, the host usually handles all the installation, configuration, and maintenance of the servers, allowing us to focus mostly on the application. The direct costs of running our application in the cloud are only for each machine-hour of use and storage utilization. The individual pieces of cloud computing have all been around for some time. Shared mainframes and supercomputers have for a long time billed the end users based on that user's resource consumption. Space for websites can be rented on a monthly basis. Providers offer specialized application hosting and, relatively recently, leased virtual machines have also become available. If there is anything revolutionary about cloud computing, then it is its ability to combine all the best features of these different components into a single affordable service offering. Some benefits of cloud computing Cloud computing sounds great so far, right? So, what are some of the tangible benefits of cloud computing? Does cloud computing merit all the attention? Let's have a look at some of the advantages: Low up-front cost:At the top of the benefits list is probably the low up-front cost. With cloud computing, someone else is buying and installing the servers, switches, and firewalls, among other things. In addition to the hardware, software licenses and assurance plans are also expensive on the enterprise level, even with a purchasing agreement. In most cloud services, including Microsoft's Azure platform, we do not need to purchase separate licenses for operating systems or databases. In Azure, the costs include licenses for Windows Azure OS and SQL Azure. As a corollary, someone else is responsible for the maintenance and upkeep of the servers—no more tape backups that must be rotated and sent to off-site storage, no extensive strategies and lost weekends bringing servers up to the current release level, and no more counting the minutes until the early morning delivery of a hot swap fan to replace the one that burned out the previous afternoon. Easier disaster recovery and storage management:With synchronized storage across multiple data centers, located in different regions in the same country or even in different countries, disaster recovery planning becomes significantly easier. If capacity needs to be increased, it can be done quite easily by logging into a control panel and turning on an additional VM. It would be a rare instance indeed when our provider doesn't sell us additional capacity. When the need for capacity passes, we can simply turn off the VMs we no longer need and pay only for the uptime and storage utilization. Simplified migration:Migration from a test to a production environment is greatly simplified. In Windows Azure, we can test an updated version of our application in a local sandbox environment. When we're ready to go live, we deploy our application to a staged environment in the cloud and, with a few mouse clicks in the control panel, we turn off the live virtual machine and activate the staging environment as the live machine—we barely miss a beat! The migration can be performed well in advance of the cut-over, so daytime migrations and midnight cut-overs can become routine. Should something go wrong, the environments can be easily reversed and the issues analyzed the following day. Familiar environment:Finally, the environment we're working on is very familiar. In Azure's case, the environment can include the capabilities of IIS and .NET (or Java or PHP and Apache), with Windows and SQL Server or MySQL. One of the great features of Windows is that it can be confi gured in so many ways, and to an extent, Azure can also be configured in many ways, supporting a rich and familiar application environment.
Read more
  • 0
  • 0
  • 4363

article-image-regular-expressions-python-26-text-processing
Packt
13 Jan 2011
17 min read
Save for later

Regular Expressions in Python 2.6 Text Processing

Packt
13 Jan 2011
17 min read
Python 2.6 Text Processing: Beginners Guide Simple string matching Regular expressions are notoriously hard to read, especially if you're not familiar with the obscure syntax. For that reason, let's start simple and look at some easy regular expressions at the most basic level. Before we begin, remember that Python raw strings allow us to include backslashes without the need for additional escaping. Whenever you define regular expressions, you should do so using the raw string syntax. Time for action – testing an HTTP URL In this example, we'll check values as they're entered via the command line as a means to introduce the technology. We'll dive deeper into regular expressions as we move forward. We'll be scanning URLs to ensure our end users inputted valid data. Create a new file and name it number_regex.py. Enter the following code: import sys import re # Make sure we have a single URL argument. if len(sys.argv) != 2: print >>sys.stderr, "URL Required" sys.exit(-1) # Easier access. url = sys.argv[1] # Ensure we were passed a somewhat valid URL. # This is a superficial test. if re.match(r'^https?:/{2}w.+$', url): print "This looks valid" else: print "This looks invalid" Now, run the example script on the command line a few times, passing various different values to it on the command line. (text_processing)$ python url_regex.py http://www.jmcneil.net This looks valid (text_processing)$ python url_regex.py http://intranet This looks valid (text_processing)$ python url_regex.py http://www.packtpub.com This looks valid (text_processing)$ python url_regex.py https://store This looks valid (text_processing)$ python url_regex.py httpsstore This looks invalid (text_processing)$ python url_regex.py https:??store This looks invalid (text_processing)$ What just happened? We took a look at a very simple pattern and introduced you to the plumbing needed to perform a match test. Let's walk through this little example, skipping the boilerplate code. First of all, we imported the re module. The re module, as you probably inferred from the name, contains all of Python's regular expression support. Any time you need to work with regular expressions, you'll need to import the re module. Next, we read a URL from the command line and bind a temporary attribute, which makes for cleaner code. Directly below that, you should notice a line that reads re.match(r'^https?:/{2}w.+$', url). This line checks to determine whether the string referenced by the url attribute matches the ^https?:/{2}w.+$ pattern. If a match is found, we'll print a success message; otherwise, the end user would receive some negative feedback indicating that the input value is incorrect. This example leaves out a lot of details regarding HTTP URL formats. If you were performing validation on user input, one place to look would be http://formencode.org/. FormEncode is a HTML form-processing and data-validation framework written by Ian Bicking. Understanding the match function The most basic method of testing for a match is via the re.match function, as we did in the previous example. The match function takes a regular expression pattern and a string value. For example, consider the following snippet of code: Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits", or "license" for more information. >>> import re >>> re.match(r'pattern', 'pattern') <_sre.SRE_Match object at 0x1004811d0> >>> Here, we simply passed a regular expression of "pattern" and a string literal of "pattern" to the re.match function. As they were identical, the result was a match. The returned Match object indicates the match was successful. The re.match function returns None otherwise. >>> re.match(r'pattern', 'failure') >>> Learning basic syntax A regular expression is generally a collection of literal string data and special metacharacters that represents a pattern of text. The simplest regular expression is just literal text that only matches itself. In addition to literal text, there are a series of special characters that can be used to convey additional meaning, such as repetition, sets, wildcards, and anchors. Generally, the punctuation characters field this responsibility. Detecting repetition When building up expressions, it's useful to be able to match certain repeating patterns without needing to duplicate values. It's also beneficial to perform conditional matches. This lets us check for content such as "match the letter a, followed by the number one at least three times, but no more than seven times." For example, the code below does just that: Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits", or "license" for more information. >>> import re >>> re.match(r'^a1{3,7}$', 'a1111111') <_sre.SRE_Match object at 0x100481648> >>> re.match(r'^a1{3,7}$', '1111111') >>> If the repetition operator follows a valid regular expression enclosed in parenthesis, it will perform repetition on that entire expression. For example: >>> re.match(r'^(a1){3,7}$', 'a1a1a1') <_sre.SRE_Match object at 0x100493918> >>> re.match(r'^(a1){3,7}$', 'a11111') >>> The following table details all of the special characters that can be used for marking repeating values within a regular expression. Specifying character sets and classes In some circumstances, it's useful to collect groups of characters into a set such that any of the values in the set will trigger a match. It's also useful to match any character at all. The dot operator does just that. A character set is enclosed within standard square brackets. A set defines a series of alternating (or) entities that will match a given text value. If the first character within a set is a caret (^) then a negation is performed. All characters not defined by that set would then match. There are a couple of additional interesting set properties. For ranged values, it's possible to specify an entire selection using a hyphen. For example, '[0-6a-d]' would match all values between 0 and 6, and a and d. Special characters listed within brackets lose their special meaning. The exceptions to this rule are the hyphen and the closing bracket. If you need to include a closing bracket or a hyphen within a regular expression, you can either place them as the first elements in the set or escape them by preceding them with a backslash. As an example, consider the following snippet, which matches a string containing a hexadecimal number. Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits", or "license" for more information. >>> import re >>> re.match(r'^0x[a-f0-9]+$', '0xff') <_sre.SRE_Match object at 0x100481648> >>> re.match(r'^0x[a-f0-9]+$', '0x01') <_sre.SRE_Match object at 0x1004816b0> >>> re.match(r'^0x[a-f0-9]+$', '0xz') >>> In addition to the bracket notation, Python ships with some predefined classes. Generally, these are letter values prefixed with a backslash escape. When they appear within a set, the set includes all values for which they'll match. The d escape matches all digit values. It would have been possible to write the above example in a slightly more compact manner. >>> re.match(r'^0x[a-fd]+$', '0x33') <_sre.SRE_Match object at 0x100481648> >>> re.match(r'^0x[a-fd]+$', '0x3f') <_sre.SRE_Match object at 0x1004816b0> >>> The following table outlines all of the character sets and classes available: One thing that should become apparent is that lowercase classes are matches whereas their uppercase counterparts are the inverse. Applying anchors to restrict matches There are times where it's important that patterns match at a certain position within a string of text. Why is this important? Consider a simple number validation test. If a user enters a digit, but mistakenly includes a trailing letter, an expression checking for the existence of a digit alone will pass. Python 2.6.1 (r261:67515, Feb 11 2010, 00:51:29) [GCC 4.2.1 (Apple Inc. build 5646)] on darwin Type "help", "copyright", "credits", or "license" for more information. >>> import re >>> re.match(r'd', '1f') <_sre.SRE_Match object at 0x1004811d0> >>> Well, that's unexpected. The regular expression engine sees the leading '1' and considers it a match. It disregards the rest of the string as we've not instructed it to do anything else with it. To fix the problem that we have just seen, we need to apply anchors. >>> re.match(r'^d$', '6') <_sre.SRE_Match object at 0x100481648> >>> re.match(r'^d$', '6f') >>> Now, attempting to sneak in a non-digit character results in no match. By preceding our expression with a caret (^) and terminating it with a dollar sign ($), we effectively said "between the start and the end of this string, there can only be one digit." Anchors, among various other metacharacters, are considered zero-width matches. Basically, this means that a match doesn't advance the regular expression engine within the test string. We're not limited to the either end of a string, either. Here's a collection of all of the available anchors provided by Python. Wrapping it up Now that we've covered the basics of regular expression syntax, let's double back and take a look at the expression we used in our first example. It might be a bit easier if we break it down a bit more with a diagram. Now that we've provided a bit of background, this pattern should make sense. We begin the regular expression with a caret, which matches the beginning of the string. The very next element is the literal http. As our caret matches the start of a string and must be immediately followed by http, this is equivalent to saying that our string must start with http. Next, we include a question mark after the s in https. The question mark states that the previous entity should be matched either zero, or one time. By default, the evaluation engine is looking character-by-character, so the previous entity in this case is simply "s." We do this so our test passes for both secure and non-secure addresses. As we advanced forward in our string, the next special term we run into is {2}, and it follows a simple forward slash. This says that the forward slash should appear exactly two times. Now, in the real world, it would probably make more sense to simply type the second slash. Using the repetition check like this not only requires more typing, but it also causes the regular expression engine to work harder. Immediately after the repetition match, we include a w. The w, if you'll remember from the previous tables, expands to [0-9a-zA-Z_], or any word character. This is to ensure that our URL doesn't begin with a special character. The dot character after the w matches anything, except a new line. Essentially, we're saying "match anything else, we don't so much care." The plus sign states that the preceding wild card should match at least once. Finally, we're anchoring the end of the string. However, in this example, this isn't really necessary. Have a go hero – tidying up our URL test There are a few intentional inconsistencies and problems with this regular expression as designed. To name a few: Properly formatted URLs should only contain a few special characters. Other values should be URL-encoded using percent escapes. This regular expression doesn't check for that. It's possible to include newline characters towards the end of the URL, which is clearly not supported by any browsers! The w followed by the. + implicitly set a minimum limit of two characters after the protocol specification. A single letter is perfectly valid. You guessed it. Using what we've covered thus far, it should be possible for you to backtrack and update our regular expression in order to fix these flaws. For more information on what characters are allowed, have a look at http://www.w3schools.com/tags/ref_urlencode.asp. Advanced pattern matching In addition to basic pattern matching, regular expressions let us handle some more advanced situations as well. It's possible to group characters for purposes of precedence and reference, perform conditional checks based on what exists later, or previously, in a string, and limit exactly how much of a match actually constitutes a match. Don't worry; we'll clarify that last phrase as we move on. Let's go! Grouping When crafting a regular expression string, there are generally two reasons you would wish to group expression components together: entity precedence or to enable access to matched parts later in your application. Time for action – regular expression grouping In this example, we'll return to our LogProcessing application. Here, we'll update our log split routines to divide lines up via a regular expression as opposed to simple string manipulation. In core.py, add an import re statement to the top of the file. This makes the regular expression engine available to us. Directly above the __init__ method definition for LogProcessor, add the following lines of code. These have been split to avoid wrapping. _re = re.compile( r'^([d.]+) (S+) (S+) [([w/:+ ]+)] "(.+?)" ' r'(?P<rcode>d{3}) (S+) "(S+)" "(.+)"') Now, we're going to replace the split method with one that takes advantage of the new regular expression: def split(self, line): """ Split a logfile. Uses a simple regular expression to parse out the Apache logfile entries. """ line = line.strip() match = re.match(self._re, line) if not match: raise ParsingError("Malformed line: " + line) return { 'size': 0 if match.group(6) == '-' else int(match.group(6)), 'status': match.group('rcode'), 'file_requested': match.group(5).split()[1] } Running the logscan application should now produce the same output as it did when we were using a more basic, split-based approach. (text_processing)$ cat example3.log | logscan -c logscan.cfg What just happened? First of all, we imported the re module so that we have access to Python's regular expression services. Next, at the LogProcessor class level, we defined a regular expression. Though, this time we did so via re.compile rather than a simple string. Regular expressions that are used more than a handful of times should be "prepared" by running them through re.compile first. This eases the load placed on the system by frequently used patterns. The re.compile function returns a SRE_Pattern object that can be passed in just about anywhere you can pass in a regular expression. We then replace our split method to take advantage of regular expressions. As you can see, we simply pass self._re in as opposed to a string-based regular expression. If we don't have a match, we raise a ParsingError, which bubbles up and generates an appropriate error message, much like we would see on an invalid split case. Now, the end of the split method probably looks somewhat peculiar to you. Here, we've referenced our matched values via group identification mechanisms rather than by their list index into the split results. Regular expression components surrounded by parenthesis create a group, which can be accessed via the group method on the Match object later down the road. It's also possible to access a previously matched group from within the same regular expression. Let's look at a somewhat smaller example. >>> match = re.match(r'(0x[0-9a-f]+) (?P<two>1)', '0xff 0xff') >>> match.group(1) '0xff' >>> match.group(2) '0xff' >>> match.group('two') '0xff' >>> match.group('failure') Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: no such group >>> Here, we surround two distinct regular expressions components with parenthesis, (0x[0-9a-f]+), and (?P&lttwo>1). The first regular expression matches a hexadecimal number. This becomes group ID 1. The second expression matches whatever was found by the first, via the use of the 1. The "backslash-one" syntax references the first match. So, this entire regular expression only matches when we repeat the same hexadecimal number twice, separated with a space. The ?P&lttwo> syntax is detailed below. As you can see, the match is referenced after-the-fact using the match.group method, which takes a numeric index as its argument. Using standard regular expressions, you'll need to refer to a matched group using its index number. However, if you'll look at the second group, we added a (?P&ltname>) construct. This is a Python extension that lets us refer to groupings by name, rather than by numeric group ID. The result is that we can reference groups of this type by name as opposed to simple numbers. Finally, if an invalid group ID is passed in, an IndexError exception is thrown. The following table outlines the characters used for building groups within a Python regular expression: Finally, it's worth pointing out that parenthesis can also be used to alter priority as well. For example, consider this code. >>> re.match(r'abc{2}', 'abcc') <_sre.SRE_Match object at 0x1004818b8> >>> re.match(r'a(bc){2}', 'abcc') >>> re.match(r'a(bc){2}', 'abcbc') <_sre.SRE_Match object at 0x1004937b0> >>> Whereas the first example matches c exactly two times, the second and third line require us to repeat bc twice. This changes the meaning of the regular expression from "repeat the previous character twice" to "repeat the previous match within parenthesis twice." The value within the group could have been its own complex regular expression, such as a([b-c]) {2}. Have a go hero – updating our stats processor to use named groups Spend a couple of minutes and update our statistics processor to use named groups rather than integer-based references. This makes it slightly easier to read the assignment code in the split method. You do not need to create names for all of the groups, simply the ones we're actually using will do. Using greedy versus non-greedy operators Regular expressions generally like to match as much text as possible before giving up or yielding to the next token in a pattern string. If that behavior is unexpected and not fully understood, it can be difficult to get your regular expression correct. Let's take a look at a small code sample to illustrate the point. Suppose that with your newfound knowledge of regular expressions, you decided to write a small script to remove the angled brackets surrounding HTML tags. You might be tempted to do it like this: >>> match = re.match(r'(?P<tag><.+>)', '<title>Web Page</title>') >>> match.group('tag') '<title>Web Page</title>' >>> The result is probably not what you expected. The reason we got this result was due to the fact that regular expressions are greedy by nature. That is, they'll attempt to match as much as possible. If you look closely, &lttitle> is a match for the supplied regular expression, as is the entire &lttitle&gtWeb Page</title> string. Both start with an angled-bracket, contain at least one character, and both end with an angled bracket. The fix is to insert the question mark character, or the non-greedy operator, directly after the repetition specification. So, the following code snippet fixes the problem. >>> match = re.match(r'(?P<tag><.+?>)', '<title>Web Page</title>') >>> match.group('tag') '<title>' >>> The question mark changes our meaning from "match as much as you possibly can" to "match only the minimum required to actually match."
Read more
  • 0
  • 0
  • 6212

article-image-microsoft-application-virtualization-managing-dynamic-suite-composition
Packt
12 Jan 2011
6 min read
Save for later

Microsoft application virtualization: managing Dynamic Suite Composition

Packt
12 Jan 2011
6 min read
With Dynamic Suite Composition, you get the chance to avoid large-sized packages or redundant sets of components, virtualized separately in different applications. You can virtualize one application normally, like Microsoft Office, and on a different package a Microsoft Offce plugin that will only be streamed down to the clients whenever it is required Having separate environments not only reduces the chance of getting application components captured more than once in different packages but also gives us control of these dependencies and lets you distribute the applications with more accuracy to users, achieving a one-to-many strategy on applications. For example, having several web applications packages but only one Java Runtime Environment (JRE) used by all these web applications. The dependencies mentioned in DSC are nothing but parameters in the virtual environment of each application. Manually editing the OSD file represents the main task in DSC preparation, but, of course, the risks increase as editing some of these parameters could end up causing erratic functionality in the App-V packages. Fortunately, Microsoft provides the Dynamic Suite Composition tool with which you can easily establish the necessary communication channels between applications. How Dynamic Suite Composition works Dynamic Suite Composition represents the way in which administrators can define dependencies between App-V packages and guarantee final users transparent operability in applications. In normal use of the operating system, you can find several applications which are dependent on other applications. Probably the best example are web applications interacting, from a browser of course, constantly with Java Runtime Environment, Silverlight, and other applications like a PDF reader. DSC is also suitable in any plugin scenario for other large applications like Microsoft Office. Dynamic Suite Composition always identifies two types of applications: Primary application: This is the main application and is usually the full software product. This should be identified as the application users execute primarily before needing a second application. Secondary application: This is usually a plugin attached to the primary application. It can be streamed in the normal way and does not need to be fully cached to run. An important note is that a primary application can have more than one secondary application but only one level of dependency is supported. You cannot define a secondary package as dependent on another secondary package. Here is an example from the App-V Sequencing Guide by Microsoft, showing the "many-to-one" and "one-to-many" relationship in Dynamic Suite Composition. These These application dependencies are customizable in the App-V configuration file for virtual applications, the OSD, where you are going to use the <DEPENDENCIES> tag in the primary application, adding the identifiers of the secondary application(s). So every time the main application needs a secondary application (like a plugin), it can find the right path and execute it without any additional user intervention. In some environments you can find secondary applications that could be a requirement for normal use of a primary application. With DSC, you can also use the variable MANDATORY=TRUE in the primary application OSD file. This value is added at the end of the secondary application reference. DSC does not control the interaction When you discuss implementing Dynamic Suite Composition in your organization you must always remember that DSC does not control the interaction between the two applications, and is only in charge of sharing the virtual environment between the App-V packages. The SystemGuard, the virtual environment created by each App-V application, is stored in one file, OSGuard.cp (you can find it in the OSD file description using the name SYSGUARDFILE). Once the application is distributed, every change made by the operating system's client and/or user changes, are stored in Settings.cp. DSC represents by sharing, between primary and secondary application, the Settings.cp file, while always maintaining the OSGuard.cp. This task will guarantee the interaction between the two applications, but Dynamic Suite Composition does not control how this interaction is occurring and which components are involved. The reason for this is that when you find yourself in a complex DSC scenario, where you have a primary application with several secondary applications that use the same shared environment as well, some conflicts may appear in the virtual environment; secondary applications overriding DLLs or registry keys, which were already being used by another secondary application in the same environment. If a conflict occurs, the last application to load wins. So, for example, the user data, which is saved in PKG files, will be kept within the secondary application package. Dynamic Suite Composition was designed to be used on simple dependencies situations and not when you want full and large software packages interacting as secondary packages. Microsoft Office is a good example of software that must be used as a "primary application" but never as a "secondary application". Configuring DSC manually Now you are going to take a closer look at configuring Dynamic Suite Composition. When you are working with DSC, using virtual machine snapshots is highly recommended as both applications, the primary and secondary, must be captured separately. This example will use a familiar environment for most, integrating an Internet browser with another program; Mozilla Firefox 3.6 with Adobe Reader 9. The scenario is very well known to most users as most find themselves with a PDF file that needs to be opened from within the browser while you are surfing around (or receiving an attachment via web mail). If a PDF reader is not a requirement on the client machines you will be obligated to capture and deliver one to all possible users, even though they only use it when a PDF files appears in their browsing session. Using Dynamic Suite Composition you can easily configure the browser, Mozilla Firefox, with a secondary application, Adobe Reader, which will only be streamed down to clients if the browser accesses a PDF file. These are the steps to follow: Log on to the sequencer machine using a clean image, install and capture the primary application. Import the primary application in the App-V Management Server. Set the permissions needed for the selected users. Restore the sequencer operating system to the base clean image. Install the primary application locally again; do not capture this installation. Install and capture the secondary application with App-V Sequencer. Import the secondary application in the App-V Management Server. Set the permissions needed for the selected users. Modify the dependencies on the OSD file from the primary application. Here is a detailed look at this process. Install and capture the primary application, Mozilla Firefox.This example is using an already captured application; you can review the process of sequencing Mozilla Firefox in the previous chapter. Here's a quick look at the procedure: Start the App-V Sequencer Application and begin the capture. Start the Mozilla Firefox installation (if using Windows 7 you may need to use compatibility mode for the installer). Select the installation folder in Q: using an 8.3 name in the folder. Complete the installation. Stop the capturing process and launch the application. It is recommended to remove automatic updates from the Mozilla Firefox options. Complete the package customization and save the App-V project.
Read more
  • 0
  • 0
  • 5532
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-microsoft-sql-server-2008-high-availability-installing-database-mirroring
Packt
11 Jan 2011
4 min read
Save for later

Microsoft SQL Server 2008 High Availability: Installing Database Mirroring

Packt
11 Jan 2011
4 min read
  Microsoft SQL Server 2008 High Availability Minimize downtime, speed up recovery, and achieve the highest level of availability and reliability for SQL server applications by mastering the concepts of database mirroring,log shipping,clustering, and replication  Install various SQL Server High Availability options in a step-by-step manner  A guide to SQL Server High Availability for DBA aspirants, proficient developers and system administrators  Learn the pre and post installation concepts and common issues you come across while working on SQL Server High Availability  Tips to enhance performance with SQL Server High Availability  External references for further study         Introduction First let's briefly see what is Database Mirroring. Database Mirroring is an option that can be used to cater to the business need, in order to increase the availability of SQL Server database as standby, for it to be used as an alternate production server in the case of any emergency. As its name suggests, mirroring stands for making an exact copy of the data. Mirroring can be done onto a disk, website, or somewhere else. Now let's move on to the topic of this article – installation of Database Mirroring. Preparing for Database Mirroring Before we move forward, we shall prepare the database for the Database Mirroring. Here are the steps: The first step is to ensure that the database is in Full Recovery mode. You can set the mode to “Full Recovery” using the following code: Execute the backup command, followed by the transaction log backup command, and move the backups to the server we wish to have as a mirror. I have run the RESTORE VERIFYONLY command after backup completes. This command ensures the validity of a backup file. It is recommended to always verify the backup. As we have a full database and log backup file, move them over to the Mirror server that we have identified. We will now perform the database restoration, followed by the restore log command with NORECOVERY. It is necessary to use the NORECOVERY option so that additional log backups or transactions can be applied. Installing Database Mirroring As the database that we want to participate in the Database Mirroring is now ready, we can move on with the actual installation process. Right-click on the database we want to mirror and select Tasks | Mirror..... It will open the following screen. To start with the actual setup, click on the Configure Security... button. In this dialog box, select the No option as we are not including the Witness Server at this stage and will be performing this task later. In the next dialog box, connect to the Principal Server. Specify the Listener Port and Endpoint name, and click Next. We are now asked to configure the property for the Mirror Server, Listener port, and Endpoint name. In this step, the installation wizard asks us to specify the service account that will be used by the Database Mirroring operation. If a person is using local system account as a service account, he/she must use Certificates for authentication. Generally, these certificates are used by the websites to assure their users that the information is secured. Certificates are the digital documents that store digital signature or identity information of the holder for authenticity purpose. They ensure that every byte of information being sent over the internet/intranet/vpn, and stored at the server, is safe. Certificates are installed at the servers, either by obtaining them from the providers such as http://www.thwate.com or can be self-issued by Database Administrator or Chief Information Officer of the company using the httpcfg.exe utility. The same is true for SQL Server. SQL Server uses certificates to ensure that the information is secured and these certificates can be issued by self, using httpcfg.exe, or can be obtained from issuing authority. In the next dialog box, make sure that the configuration details we have furnished are valid. Ensure that the name of the Principal and Mirror Server, Endpoints, and port number are correct. Click Finish. Ensure that the setup wizard returns a success report at the end.
Read more
  • 0
  • 0
  • 2212

article-image-setting-microsoft-dynamics-gp-system
Packt
11 Jan 2011
9 min read
Save for later

Setting up the Microsoft Dynamics GP System

Packt
11 Jan 2011
9 min read
  Microsoft Dynamics GP 2010 Implementation A step-by-step guide to implementing Microsoft Dynamics GP 2010 Master how to implement Microsoft Dynamics GP 2010 with real world examples and guidance from a Microsoft Dynamics GP MVP Understand how to install Microsoft Dynamics GP 2010 and related applications, following detailed, step-by-step instructions Learn how to set-up the core Microsoft Dynamics GP modules effectively Discover the additional tools available from Microsoft for Dynamics GP           When you launch Dynamics GP for the first time on a new computer, you will be prompted for a Server, User ID, and Password: For the Server, choose the ODBC data source pointing to your SQL Server (remember this will need to be created identically on each computer). The first time you log in, use sa for the User ID. Dynamics GP will detect that this is a new installation and will prompt you to run Dynamics GP Utilities. Choose Yes, log into Dynamics GP Utilities as sa, and follow the prompts. Your local Dynamics GP application will be initialized and synchronized to the settings on the server. Once done, click the Launch Microsoft Dynamics GP button at the bottom of the Additional Tasks window. Log into Dynamics GP again as sa and you will see the Company Login window with a drop-down selection for the companies that have been created in Dynamics GP. For performing system setup steps, you can choose any company on the list. To perform company setup, you will need to choose the specific company you will be setting up. System setup System setup for Dynamics GP includes settings that are global to your entire Dynamics GP installation such as the system password, registration, creating users, setting up user security, currency settings, exchange rates, and additional system-wide settings. A very useful feature in Dynamics GP is the Setup Checklist, which lists all of the setup steps with a brief description of each and provides automatic links to the related setup windows. The setup checklist also gives you the ability to assign tasks to others and change the status of the various installation tasks as you go through them. In the following sections, the navigation paths to get to each setup window will be detailed using the Dynamics GP menus, however you may find that bringing up the setup checklist can save you time during the setup. The setup checklist is found under Microsoft Dynamics GP | Tools | Setup | Setup Checklist. Show required fields To help with system setup you may want to have Dynamics GP highlight the required fields on windows for you. This option is turned off by default. To turn it on: Click on the Help icon in the upper-right corner and click on Show required fields. This setting is a toggle, once clicked it will display a checkmark next to it to show it is activated. Navigate to Microsoft Dynamics GP |User Preferences. On the User Preferences window, click on Display to open the User Display Preferences window. Change the settings under Required Fields to be something other than the default settings. You can click on Apply to preview your changes and click OK to close the window. Changes to the display preferences are specific to the Dynamics GP user. Once set, they will be used on any computer where the user logs into Dynamics GP. System password Most system setup windows will require the Dynamics GP system password you entered during the initial Dynamics GP installation. You can set this password to be blank while performing the system setup, so that you are not constantly prompted for it. To change the system password navigate to Microsoft Dynamics GP | Tools | Setup | System | System Password. It is highly recommended to assign a system password once you are done with the system setup. System preferences You can set overall system preferences for Dynamics GP by navigating to Microsoft Dynamics GP | Tools | Setup | System | System Preferences. All of these settings are optional. The Office SharePoint Server is used to enable searching Dynamics GP data from SharePoint. The Home Page Defaults control what loads for newly created users in Dynamics GP. Note the critical word loads. These sections will still exist on the home page for new users, but they will not load with initial data if unchecked on this window. It is recommended to uncheck all of the Home Page Defaults to save time during initial login, especially when installing on a computer where there may not be Outlook installed, or when logged in with a Windows user ID that might not have an Outlook profile. Changes to these settings will only apply to newly created users, no existing user setup will be changed. Remember User is a new feature in Dynamics GP 2010. This activates the Remember user and password and Remember this company checkboxes on the Dynamics GP login windows. Unfortunately, there is no way to separate these two options. While many companies may feel that remembering the company is a nice option for users, remembering the User ID and password may be against security policies in many organizations. Dynamics GP registration Dynamics GP will typically install without asking for registration keys, however this should be the first thing entered as part of system setup to ensure that the system is set up with the modules you are registered for. Registration keys can be obtained either from your Dynamics GP partner or from Microsoft. To enter your registration keys, navigate to Microsoft Dynamics GP | Tools | Setup | System | Registration. On the Registration window enter your Site Name and Registration Keys. The Site Name is listed under License Holder on your licensing information and must appear the exact same way, with the same punctuation, spelling, and spacing. Even though there are five Registration Keys possible, you may have less. The keys listed as – No key – on the licensing information should be left blank on the Registration window. Click on the Validate button and the Modules list will populate with the Dynamics GP modules you have purchased. It is recommended to uncheck any modules that you are not planning to use. Leaving all the modules activated may cause some functionality not to work as expected and to require setup for those modules prior to entering transaction for other modules. Modules can be activated at a later time if needed. Some of the modules may not sound familiar, but may be core or internal modules needed for other functionality you are using. If you are unsure about some of the modules on the list, consult with your Dynamics GP resource. Creating Dynamics GP users Dynamics GP is licensed for concurrent users, so you can create as many named users as you would like. It is recommended to create a Dynamics GP user for each individual that will be using Dynamics GP. The following are the steps to create new Dynamics GP users: Log into Dynamics GP as either sa, DYNSA, or a user that has been set up in SQL Server with the sysadmin server role. Navigate to Microsoft Dynamics GP | Tools | Setup | System | User. Enter a User ID. Unlike most user IDs, the Dynamics GP user IDs are case sensitive. Consider making user IDs the same as the users' Windows logins. Even though Dynamics GP uses SQL Server authentication, it may be easier to administer users when all the IDs follow the same pattern. Enter the User Name. While not required, it is helpful to enter the full name of the user, so that this information is available when looking through a list of users in the future. Enter and confirm the Password. Dynamics GP passwords are case sensitive. If you leave the password blank, the user will be required to create a password the first time they log into Dynamics GP. While that sounds like a handy feature, this can be a security risk because while the password is blank anyone can log in with just the user ID. This is not a concern if the user will be logging in immediately, however if users may log in for the first time days or even weeks later, this is not very secure. Users can change their own passwords in Dynamics GP at any time, so create a unique password for each user and ask them to change it as soon as they log in the first time. Class ID is an optional setting that may be useful for grouping users in the future. With the changes to the Dynamics GP security model starting with version 10.0, user classes are not widely used anymore and are not needed for security setup. The Class ID can be changed at any time. Setting the Home Page Role is also optional. If set while creating the user, this will save the user from having to pick their home page role when they first log into Dynamics GP. Set the Advanced SQL Server options. These options allow using your Active Directory domain password policies with Dynamics GP. This is another feature that sounds more useful than it often proves to be. There are many limitations and workarounds for this, detailed in KB article 922456, Frequently asked questions about the advanced SQL Server options in the User Setup window in Microsoft Dynamics GP: https://mbs.microsoft.com/knowledgebase/KBDisplay.aspx?scid=kb;en-us;922456 (requires login). A common recommendation is to uncheck the Advanced SQL Server options when creating new Dynamics GP users. If the Collections Management module has been installed and activated for Dynamics GP, once you click Save on the User Setup window you will receive the following pop-up message: Clicking on Add will open the Collections Management Collector Setup window where you can set up this user as a collector. Clicking Cancel will allow you to continue without setting the user up as a collector. A user can be set up as a collector at any time, so if you are not sure, click on Cancel. When a user ID is created in Dynamics GP, a SQL Server login is created with the DYNGRP role. The user password is encrypted by Dynamics GP so that this login cannot be used outside of the Dynamics GP application.
Read more
  • 0
  • 0
  • 8290

article-image-promoting-efficient-communication-moodle-curriculum-and-information-management-system-curriculum-and-information-management-system
Packt
11 Jan 2011
8 min read
Save for later

Promoting efficient communication with Moodle

Packt
11 Jan 2011
8 min read
A key component of any quality educational program is its ability to facilitate communication among all of the parties involved in the program. Communication and the subsequent relaying of information and knowledge between instructional faculty, administrators, students, and support personnel must be concise, efficient, and, when so desired, as transparent as possible. Using Moodle as a hub for internal information distribution, collaboration, and communication Moodle's ability to facilitate information flow and communication among users within the system, who are registered users such as students and teachers, is a capability that has been a core function of Moodle since its inception. The module most often used to facilitate communication and information flow is the forum and we will thus focus primarily on creative uses of forums for communication within an educational program. Facilitating intra- or inter-departmental or program communication, collaboration, and information flow Many educational programs comprise sub-units such as departments or programs. These units usually consist of students, teachers, and administrators who interact with one another at varying levels in terms of the type of communication, its frequency, and content. The following example will demonstrate how a sub-unit—the reading program within our language program example—might set up a communication system, using a meta course in Moodle, that accomplishes the following: Allows the program to disseminate information to all students, teachers, and administrators involved in the program. The system must, of course, allow for settings enabling dissemination to only selected groups or to the entre group, if so desired. Establishes a forum for communication between and among teachers, students, and administrators. Again, this system must be fine-tunable such that communication can be limited to specific parties within the program. The example will also demonstrate, indirectly, how a meta course could be set up to facilitate communication and collaboration between individuals from different programs or sub-units. In such a case, the meta course would function as an inter-departmental communication and collaboration system. Time for action – setting up the meta course To set up a communication system that can be finely tuned to allow specific groups of users to interact with each other, follow these steps: We are going to set up a communication system using a meta course. Log in to your site as admin and click on the Show all courses link found at the bottom of your MyCourses block on the front page of your site. At the bottom of the subsequent Course Categories screen, click on the Add a new course button. Change the category from Miscellaneous to Reading and enter a Full name and Short name such as Reading Program and ReadProg. Enter a short description explaining that the course is to function as a communication area for the reading program. Use the drop-down menu next to the meta course heading, shown in the following screenshot, to select Yes in order to make this course a meta course: Change the Start date as you see fit. You don't need to add an Enrollment key under the Availability heading to prevent users who are not eligible to enter the course because the enrollment for meta courses is taken from child courses. If you've gotten into the habit of entering enrollment keys just to be safe however, doing so here won't cause any problems. Change the group setting, found under the Groups heading, to Separate. Do not force this setting however, in order to allow it to be set on an individual activity basis. This will allow us to set up forums that are only accessible to teachers and/or administrators. Other forums can be set up to allow only student and teacher access, for example. Click on the Save changes button found at the bottom of the screen and on the next screen, which will be the Child courses screen, search for all reading courses by entering Reading in the search field. After clicking on the Search button to initiate the search, you will see all of the reading courses, including the meta course we have just created. Add all of the courses, except the meta course, as shown in the following screenshot. Use the short name link found in the breadcrumb path at the top-left of the window, shown in the following screenshot, to navigate to the course after you have added all of the reading child courses: What just happened? We just created a meta course and included all of the reading courses as child courses of the meta course. This means that all of the users enrolled in the reading child courses have been automatically enrolled in the meta course with the same roles that they have in the child courses. It should be noted here that enrollments in meta courses are controlled via the enrollments in each of the child courses. If you wish to unenroll a user from a meta course, he or she must be unenrolled from the respective child course. In the next step, we'll create the groups within the meta course that will allow us to create targeted forums. Time for action – creating a group inside the meta course We are now going to create groups within our meta course in order to allow us to specify which users will be allowed to participate in, and view, the forums we set up later. This will allow us to control which sets of users have access to the information and communication that will be contained in each forum. Follow these steps to set up the forums: Log in to your Moodle site as admin and navigate to the meta course we just created. It will be located under the Reading heading from the MyCourses block and titled Reading Program if you followed the steps outlined earlier in this article. Click on the Groups link found inside the Administration block. The subsequent screen will be titled ReadingProg Groups. The ReadingProg portion of the title is from the short name of our course. From this screen, click on the Create group button. Title the group Teachers and write a short description for the group. Ignore the enrollment key option as enrollments for meta courses are controlled by the child course enrollments. Leave the picture field blank unless you would like to designate a picture for this group. Click on the Save changes button to create the group. You will now see the ReadingProg Groups screen again and it will now contain the Teachers group, we just created. Click once on the group name to enable the Add/remove users button. Click on the Add/remove users button to open the Add/remove users window. From this window, enter the word Teacher in the search window and click on the Search button. Select all of the teachers by clicking once on the first teacher and then scrolling to the last teacher and, while holding down the shift button on your keyboard, click on the last teacher. This will highlight all of the teachers in the list. Click on the Add button to add the selected teachers to the Existing members list on the left. Click on the Back to groups button to return to the ReadingProg Groups screen. The Teachers group will now appear as Teachers(20) and, when selected, the list of teachers will appear in the Members of: list found on the right side of the screen, as shown in the following screenshot: Next, navigate to the front page of your site and from the Site Administration block, click on the Miscellaneous heading link and then on the Experimental link. Scroll down to the Enable groupings setting and click the tickbox to enable this setting. This setting enables you to group multiple groups together and also to make activities exclusively available to specific groupings. We'll need this capability when we set up the forums later. For a more detailed explanation of the groupings feature, visit the associated Moodle Docs page at: http://docs.moodle.org/en/Groupings. What just happened? We just created a group, within our Reading Program meta course, for all of the teachers enrolled in the course. Because the enrollments for a meta course are pulled from the child courses associated with a meta course, the teachers are all teachers who are teaching reading courses in our program. Later in this article, we'll see how we can use this group when we set up forums that we only want our teachers to have access to.
Read more
  • 0
  • 0
  • 2062

article-image-making-ajax-requests-yui
Packt
10 Jan 2011
5 min read
Save for later

Making Ajax Requests with YUI

Packt
10 Jan 2011
5 min read
In this Ajax tutorial, you will learn the YUI way of making Asynchronous JavaScript and XML (AJAX) requests. Although, all modern browsers support sending asynchronous requests to the server, not all browsers work the same way. Additionally, you are not required to return XML; your AJAX requests may return JSON, text, or some other format if you prefer. The Connection component provides a simple, cross-browser safe way to send and retrieve information from the server. How to make your first AJAX request This recipe will show you how to make a simple AJAX request using YUI. Getting ready To use the Connection component, you must include the YUI object, the Event component, and the core of the Connection component: <script src="pathToBuild/yahoo/yahoo-min.js" type="text/javascript"></script> <script src="pathToBuild/event/event-min.js" type="text/javascript"></script> <script src="pathToBuild/connection/connection_core-min.js" type="text/javascript"></script> If you plan on using the form serialization example, or other advanced features, you will need to include the whole component, instead of only the core features: <script src="pathToBuild/connection/connection-min.js" type="text/javascript"></script> How to do it... Make an asynchronous GET request: var url = "/myUrl.php?param1=asdf&param2=1234"; var myCallback = { success: function(o) {/* success handler code */}, failure: function(o) {/* failure handler code */}, /* ... */ }; var transaction = YAHOO.util.Connect.asyncRequest('GET', url, myCallback); Make an asynchronous POST request: var url = "/myUrl.php"; var params = "param1=asdf&param2=1234"; var myCallback = { success: function(o) {/* success handler code */}, failure: function(o) {/* failure handler code */}, /* ... */ }; var transaction = YAHOO.util.Connect.asyncRequest( 'POST', url, myCallback, params); Make an asynchronous POST request using a form element to generate the post data: var url = "/myUrl.php"; var myCallback = { success: function(o) {/* success handler code */}, failure: function(o) {/* failure handler code */}, /* ... */ }; YAHOO.util.Connect.setForm('myFormEelementId'); var transaction = YAHOO.util.Connect.asyncRequest('POST', url, myCallback); How it works... All modern browsers have supported AJAX natively since the early 2000. However, IE implemented a proprietary version using the ActiveXObject object , while other browsers implemented the standard compliant XMLHttpRequest (XHR) object . Each object has its own implementation and quirks, which YUI silently handles for you. Both objects make an HTTP request to the provided URL, passing any parameters you specified. The server should handle AJAX requests like any normal URL request. When making a GET request , the parameters should be added to the URL directly (as in the example above). When making a POST request, the parameters should be a serialized form string (&key=value pairs) and provided as the fourth argument. Connection Manager also allows you to provide the parameters for a GET request as the fourth argument, if you prefer. Using the setForm function attaches a form element for serialization with the next call to the asyncRequest function . The element must be a form element or it will throw an exception. YUI polls the browser XHR object until a response is detected, then it examines the response code and the response data to see if it is valid. If it is valid, the success event fires, and if it is not, the failure event fires. YUI wraps the XHR response with its own connection object, thereby masking browser variations, and passes the wrapper object as the first argument of all the AJAX callback functions. There's more... Beside POST and GET, you may also use PUT, HEAD, and DELETE requests, but these may not be supported by all browsers or servers. It is possible to send synchronous request through the native XHR objects, however Connection Manager does not support this. The asyncRequest function returns an object known as the transaction object . This is the same object that YUI uses internally to manage the XHR request. It has the following properties: See also Exploring the callback object properties recipe, to learn what properties you can set on the callback object. Exploring the response object recipe, to learn what properties are available on the YUI object passed into your callback functions. Exploring the callback object properties The third argument you can provide to the asyncRequest function defines your callback functions and other related response/request properties. This recipe explains what those properties are and how to use them. How to do it... The properties available on the callback object are: var callback = { argument: {/* ... */}, abort: function(o) {/* ... */}, cache: false, failure: function(o) {/* ... */}, scope: {/* ... */}, success: function(o) {/* ... */}, timeout: 10000, // 10 seconds upload: function(o) {/* ... */}, }; How it works... The various callback functions attached to the connection object use the CustomEvent.FLAT callback function signature. This way the response object is the first argument of the callback functions. Each of the callback functions is subscribed to the appropriate custom event by the asyncRequest function. When the Connection Manager component detects the corresponding event conditions, it fires the related custom event. The upload callback function is special because an iframe is used to make this request. Consequently, YUI cannot reasonably discern success or failure, nor can it determine the HTTP headers. This callback will be executed both when an upload is successful and when it fails, instead of the success and failure callback functions. The argument property is stored on the response object and passed through to the callback functions. You can set the argument to anything that evaluates as true. When the cache property is true, YUI maps the responses to the URLs, so if the same URL is requested a second time, Connection Manager can simply execute the proper callback function immediately. The timeout property uses the native browser setTimeout function to call the abort function when the timeout expires. The timeout is cleared when an AJAX response is detected for a transaction. See also Exploring the response object properties recipe, to learn what properties are available on the YUI object passed into your callback functions. Using event callback functions recipe, to learn common practices for handling failure and success callback functions.
Read more
  • 0
  • 0
  • 4018
article-image-tortoisesvn-revision-graphs
Packt
10 Jan 2011
8 min read
Save for later

TortoiseSVN: revision graphs

Packt
10 Jan 2011
8 min read
Revision graphs provide an easy way for you to tell at-a-glance what is going on with your project. They provide a map, in easy-to-understand tree form, of the revision history of your project, including copies, branches, and tags. One useful feature of revision graphs is that you can export them into a vector graphics format (WMF is a good option because they scale well and produce fairly small file size images. If you need a more widely supported format, then PNG is a good option) for inclusion with your source code, or on your project's website, giving everyone an easy overview of the status of your project. You can view revision graphs for files, directories, or the whole project. Time for action – viewing a revision graph To view a revision graph, go to your working copy, and right-click inside the project, and then select TortoiseSVN | Revision Graph. The graph that appears in the following screenshot shows the history of any branches and tags created, in an easy-to-understand, tree-like structure: If you prefer to read from top to bottom, rather than having the newest node at the top of the screen, then click the Show oldest node at top button (this can be found two buttons to the right of the drop-down which allows you to change the zoom level). This will invert the view, as shown in the following screenshot: You can view information about a particular branch by right-clicking on it and selecting Show Log: You can also use the same context menu to merge revisions, switch your working copy to a particular branch or tag, browse the repository, and collapse trees. What just happened? You have just used the revision graph to get an overview of the revisions, branches, and tags in your project. The last revision graph that we saw is a simple one, taken from our example project. In a real-world scenario, it is likely that the revision graph would be much more complex, and it is in these complex projects that having a revision graph becomes so useful. When there are dozens of branches which are being created and merged, it can become difficult to keep track of what happened when, and why. A revision graph gives you a clear high-level view of everything that is happening in your software project. To fully understand the revision graph, it helps to understand what each node means. The following table will help with this: ItemShapeDefault ColorItems which have been added or copied Rounded rectangle GreenItems which have been deleted   RedItems which have been renamed   BlueBranch HEAD revisions (if you have elected to show these)   PlainWorking copy revisions Oval Plain with bold outline (a red outline indicates modifications)Modified working copies Oval Plain with bold red outlineMoved items Edged Rectangle BlueAll other items Rectangle Plain   You can use the graph to get more detailed information about the differences between revisions. Just Ctrl-click on the two revisions you are interested in, right-click to bring up the context-sensitive menu, and then select Compare Revisions. You will be able to see a list of the revisions made to each file. Compare them using TortoiseDiff, as shown in the following screenshot: You can also compare HEAD revisions, and view the unified differences using this method. Changing your view If your software project is quite large and complex, then you may find it useful to change the view used in the revision graph. There are several options that you can use to change the view you are using, and they can all be found under the view menu. Rather than replicating the TortoiseSVN documentation by describing every single option, only the more interesting options will be described here. The other options are mostly clearly labelled, and otherwise are explained in the online help for TortoiseSVN: Group by Branch: This option is off by default, so all rows are sorted by revision. This can be a problem if you have branches with a long life and a few commits, because those branches will occupy a whole column, making the graph expand unnecessarily. This is demonstrated in the following screenshot: Turning on Group by Branch will change this so that revisions on a branch will be shown on consecutive lines, and branches will be grouped into columns, keeping the graph slim. The previous screenshot shows the default appearance of the revision graph (a shorter revision graph has been used here, for ease of viewing), the next screenshot shows the same revision graph with Group by Branch: With this fairly simple tree layout, the difference isn't immediately clear, but if you have a lot of branches, you'll find that the group by branch feature keeps the layout much neater, and avoids needless scrolling. Oldest on top: This option switches the graph so that the oldest revisions are shown at the top of the screen. By default, the oldest revisions are at the bottom, and the 'tree' grows upwards. Align trees on top: This option forces trees to grow down, rather than appearing in their natural revision order, or aligned at the bottom of the window. Reduce cross lines: This option cleans up the revision graph if there are lots of crossing lines. In some cases, this option can make the layout appear less logical, and can also make the graph take up a larger area of the screen. Differential path names: This option makes the path names in the node boxes as short as possible—so if you create a branch called /branches/katakana/images/characters out of /trunk/images/characters, the branch would be shown as merely /branches/katakana/.. the remainder of the path has not changed. Exact copy sources: The default behavior of the revision graph is to show branches as being taken from the last node where the change was made. In practice, many people make branches from the HEAD rather than from a specific revision. If you have a reason for needing to know which revision was used to create a copy, then you can use this option to show those details. Fold tags: If your project has a lot of tags, then you may find that they take up unnecessary screen space, hiding the information that you are interested in. You can use this option to hide the nodes for tags. If you still need to find a tag, you will find them displayed as tooltips on the node that they were copied from. Each source node that had a tag made from it will have an icon on the right-hand side indicating that a tag was made. Tree stripes: No, this option isn't related to landscape gardening. The tree stripes option tells TortoiseSVN to use alternating background colors so that it is easy to distinguish between different trees in the graph. Keeping your view up-to-date If you are viewing a revision graph of an active project, you may want to check for updates. Just as you would in your web browser, you can refresh the revision graph by pressing F5. This will connect you to the server (if you have been working offline) and check to see if there have been any new commits. Pressing F5 to refresh works for most screens in TortoiseSVN. You can update your log dialog, for example, by pressing F5 too. Pruning trees Large software projects can end up with lots of trees. This can make the revision graph look excessively complex, and can make it harder for you to find the information that you need. The good news is that you can tame the trees in your graph, shrinking and expanding them as you need them. To shrink a tree or a branch, simply hover your mouse over the point where the branch begins (where the node link enters the node), and you will be given the option to collapse the related tree (-), or expand it (+). If applicable, you will also be presented with the option to split a sub-tree into a separate graph (x), or re-attach a tree that had been split (o): Summary In this article you learned how to view revision graphs, and how to manipulate your view of the graph to give a clearer view of the things that you are interested in. Revision graphs are useful for even small development teams. The good thing about the way TortoiseSVN displays them is that they are highly customizable, and scale well for larger projects. So, if you need to keep up with the lifecycle of branches and tags in a big project, then you can do so easily—thanks to the highly customizable views offered by TortoiseSVN! Further resources on this subject: Working with Revision Logs in TortoiseSVN [Article] Change Control for Personal Projects - Subversion Style [Article] Managing Software Development with Trac and Subversion [Book]
Read more
  • 0
  • 0
  • 5028

article-image-working-revision-logs-tortoisesvn
Packt
10 Jan 2011
3 min read
Save for later

Working with Revision Logs in TortoiseSVN

Packt
10 Jan 2011
3 min read
Differences in detail Differences are useful to allow you to see what has changed between recent revisions of a file. There are several different ways that you can view differences between files, or between a file and a previous version of the file. Viewing differences between versions of a specific file in your working copy You can view differences using the change log. There is another way to view differences from within your working copy folder, using the right-click menu. Time for action – viewing differences in a working copy To view the differences between a file in your working copy and a previous version, follow these steps: Navigate to your working copy folder. Select the file that you want to compare version history for. Right-click the file, and select TortoiseSVN | Diff with previous version. A TortoiseMerge window will appear, showing the differences between the current version of the file and the previous version. (Move the mouse over the image to enlarge.) What just happened? You have viewed the differences between a current version of a file and the previously checked in one. If you have made changes to a file, but not yet checked in those changes, you can view the difference between the BASE revision (the version that was in the repository when you last updated), and the working copy by selecting TortoiseSVN | Diff, instead of TortoiseSVN | Diff with previous version. In addition to using this method, you can view specific differences by going to TortoiseSVN | Show Log and selecting the revision you are interested in from the list at the top of the window. Double-click on the relevant file in the list at the bottom of the window—this will bring up a TortoiseMerge window showing the difference list for the revisions in question. Viewing differences between files outside your working copy You don't have to be inside your working copy to view differences. In fact, you can view differences between files that aren't under version control. Time for action – viewing differences in files outside your working copy To view the differences between files that aren't within your working copy: Navigate to the folder where the files are stored. Click on the older version of the file. Hold down the Ctrl key and then click on the newer version of the file. Right-click on the file, and select TortoiseSVN | Diff. The next window will show the differences between the two files (depending on what applications you have installed, and the file type of the file you view the differences for, your screen may differ from the following screenshot): What just happened? You have just viewed the differences between two files which are not under version control. You could use this to compare submitted patches, documents or source code. When you use this method to compare differences, the differences may be displayed in the editor or IDE that supports the file (as shown in the previous screenshot), or using the TortoiseMerge window:
Read more
  • 0
  • 0
  • 6247

article-image-getting-started-python-26-text-processing
Packt
10 Jan 2011
14 min read
Save for later

Getting Started with Python 2.6 Text Processing

Packt
10 Jan 2011
14 min read
  Python 2.6 Text Processing: Beginners Guide The easiest way to learn how to manipulate text with Python The easiest way to learn text processing with Python Deals with the most important textual data formats you will encounter Learn to use the most popular text processing libraries available for Python Packed with examples to guide you through         Read more about this book       (For more resources on this subject, see here.) Categorizing types of text data Textual data comes in a variety of formats. For our purposes, we'll categorize text into three very broad groups. Isolating down into segments helps us to understand the problem a bit better, and subsequently choose a parsing approach. Each one of these sweeping groups can be further broken down into more detailed chunks. One thing to remember when working your way through the book is that text content isn't limited to the Latin alphabet. This is especially true when dealing with data acquired via the Internet. Providing information through markup Structured text includes formats such as XML and HTML. These formats generally consist of text content surrounded by special symbols or markers that give extra meaning to a file's contents. These additional tags are usually meant to convey information to the processing application and to arrange information in a tree-like structure. Markup allows a developer to define his or her own data structure, yet rely on standardized parsers to extract elements. For example, consider the following contrived HTML document. <html> <head> <title>Hello, World!</title> </head> <body> <p> Hi there, all of you earthlings. </p> <p> Take us to your leader. </p> </body></html> In this example, our document's title is clearly identified because it is surrounded by opening and closing &lttitle> and </title> elements. Note that although the document's tags give each element a meaning, it's still up to the application developer to understand what to do with a title object or a p element. Notice that while it still has meaning to us humans, it is also laid out in such a way as to make it computer friendly. One interesting aspect to these formats is that it's possible to embed references to validation rules as well as the actual document structure. This is a nice benefit in that we're able to rely on the parser to perform markup validation for us. This makes our job much easier as it's possible to trust that the input structure is valid. Meaning through structured formats Text data that falls into this category includes things such as configuration files, marker delimited data, e-mail message text, and JavaScript Object Notation web data. Content within this second category does not contain explicit markup much like XML and HTML does, but the structure and formatting is required as it conveys meaning and information about the text to the parsing application. For example, consider the format of a Windows INI file or a Linux system's /etc/hosts file. There are no tags, but the column on the left clearly means something other than the column on the right. Python provides a collection of modules and libraries intended to help us handle popular formats from this category. Understanding freeform content This category contains data that does not fall into the previous two groupings. This describes e-mail message content, letters, article copy, and other unstructured character-based content. However, this is where we'll largely have to look at building our own processing components. There are external packages available to us if we wish to perform common functions. Some examples include full text searching and more advanced natural language processing. Ensuring you have Python installed Our first order of business is to ensure that you have Python installed. We'll be working with Python 2.6 and we assume that you're using that same version. If there are any drastic differences in earlier releases, we'll make a note of them as we go along. All of the examples should still function properly with Python 2.4 and later versions. If you don't have Python installed, you can download the latest 2.X version from http://www.python.org. Most Linux distributions, as well as Mac OS, usually have a version of Python preinstalled. At the time of this writing, Python 2.6 was the latest version available, while 2.7 was in an alpha state. Providing support for Python 3 The examples in this book are written for Python 2. However, wherever possible, we will provide code that has already been ported to Python 3. You can find the Python 3 code in the Python3 directories in the code bundle available on the Packt Publishing FTP site. Unfortunately, we can't promise that all of the third-party libraries that we'll use will support Python 3. The Python community is working hard to port popular modules to version 3.0. However, as the versions are incompatible, there is a lot of work remaining. In situations where we cannot provide example code, we'll note this. Implementing a simple cipher Let's get going early here and implement our first script to get a feel for what's in store. A Caesar Cipher is a simple form of cryptography in which each letter of the alphabet is shifted down by a number of letters. They're generally of no cryptographic use when applied alone, but they do have some valid applications when paired with more advanced techniques. This preceding diagram depicts a cipher with an offset of three. Any X found in the source data would simply become an A in the output data. Likewise, any A found in the input data would become a D. Time for action – implementing a ROT13 encoder The most popular implementation of this system is ROT13. As its name suggests, ROT13 shifts – or rotates – each letter by 13 spaces to produce an encrypted result. As the English alphabet has 26 letters, we simply run it a second time on the encrypted text in order to get back to our original result. Let's implement a simple version of that algorithm. Start your favorite text editor and create a new Python source file. Save it as rot13.py. Enter the following code exactly as you see it below and save the file. import sysimport stringCHAR_MAP = dict(zip( string.ascii_lowercase, string.ascii_lowercase[13:26] + string.ascii_lowercase[0:13] ))def rotate13_letter(letter): """ Return the 13-char rotation of a letter. """ do_upper = False if letter.isupper(): do_upper = True letter = letter.lower() if letter not in CHAR_MAP: return letter else: letter = CHAR_MAP[letter] if do_upper: letter = letter.upper() return letterif __name__ == '__main__': for char in sys.argv[1]: sys.stdout.write(rotate13_letter(char)) sys.stdout.write('n') Now, from a command line, execute the script as follows. If you've entered all of the code correctly, you should see the same output. $ python rot13.py 'We are the knights who say, nee!' Run the script a second time, using the output of the first run as the new input string. If everything was entered correctly, the original text should be printed to the console. $ python rot13.py 'Dv ziv gsv pmrtsgh dsl hzb, mvv!' What just happened? We implemented a simple text-oriented cipher using a collection of Python's string handling features. We were able to see it put to use for both encoding and decoding source text. We saw a lot of stuff in this little example, so you should have a good feel for what can be accomplished using the standard Python string object. Following our initial module imports, we defined a dictionary named CHAR_MAP, which gives us a nice and simple way to shift our letters by the required 13 places. The value of a dictionary key is the target letter! We also took advantage of string slicing here. In our translation function rotate13_letter, we checked whether our input character was uppercase or lowercase and then saved that as a Boolean attribute. We then forced our input to lowercase for the translation work. As ROT13 operates on letters alone, we only performed a rotation if our input character was a letter of the Latin alphabet. We allowed other values to simply pass through. We could have just as easily forced our string to a pure uppercased value. The last thing we do in our function is restore the letter to its proper case, if necessary. This should familiarize you with upper- and lowercasing of Python ASCII strings. We're able to change the case of an entire string using this same method; it's not limited to single characters. >>> name = 'Ryan Miller'>>> name.upper()'RYAN MILLER'>>> "PLEASE DO NOT SHOUT".lower()'please do not shout'>>> It's worth pointing out here that a single character string is still a string. There is not a char type, which you may be familiar with if you're coming from a different language such as C or C++. However, it is possible to translate between character ASCII codes and back using the ord and chr built-in methods and a string with a length of one. Notice how we were able to loop through a string directly using the Python for syntax. A string object is a standard Python iterable, and we can walk through them detailed as follows. In practice, however, this isn't something you'll normally do. In most cases, it makes sense to rely on existing libraries. $ pythonPython 2.6.1 (r261:67515, Jul 7 2009, 23:51:51)[GCC 4.2.1 (Apple Inc. build 5646)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> for char in "Foo":... print char...Foo>>> Finally, you should note that we ended our script with an if statement such as the following: Python modules all contain an internal __name__ variable that corresponds to the name of the module. If a module is executed directly from the command line, as is this script, whose name value is set to __main__, this code only runs if we've executed this script directly. It will not run if we import this code from a different script. You can import the code directly from the command line and see for yourself. >>> if__name__ == '__main__' Notice how we were able to import our module and see all of the methods and attributes inside of it, but the driver code did not execute. Have a go hero – more translation work Each Python string instance contains a collection of methods that operate on one or more characters. You can easily display all of the available methods and attributes by using the dir method. For example, enter the following command into a Python window. Python responds by printing a list of all methods on a string object. $ pythonPython 2.6.1 (r261:67515, Jul 7 2009, 23:51:51)[GCC 4.2.1 (Apple Inc. build 5646)] on darwinType "help", "copyright", "credits" or "license" for more information.>>> import rot13>>> dir(rot13)['CHAR_MAP', '__builtins__', '__doc__', '__file__', '__name__', '__package__', 'rotate13_letter', 'string', 'sys']>>> Much like the isupper and islower methods discussed previously, we also have an isspace method. Using this method, in combination with your newfound knowledge of Python strings, update the method we defined previously to translate spaces to underscores and underscores to spaces. Processing structured markup with a filter Our ROT13 application works great for simple one-line strings that we can fit on the command line. However, it wouldn't work very well if we wanted to encode an entire file, such as the HTML document we took a look at earlier. In order to support larger text documents, we'll need to change the way we accept input. We'll redesign our application to work as a filter. A filter is an application that reads data from its standard input file descriptor and writes to its standard output file descriptor. This allows users to create command pipelines that allow multiple utilities to be strung together. If you've ever typed a command such as cat /etc/hosts | grep mydomain.com, you've set up a pipeline In many circumstances, data is fed into the pipeline via the keyboard and completes its journey when a processed result is displayed on the screen. Time for action – processing as a filter Let's make the changes required to allow our simple ROT13 processor to work as a command-line filter. This will allow us to process larger files. Create a new source file and enter the following code. When complete, save the file as rot13-b.py. >>> dir("content")['__add__', '__class__', '__contains__', '__delattr__', '__doc__','__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__','__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__','__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count','decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index','isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle','isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace','rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split','splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate','upper', 'zfill']>>> Enter the following HTML data into a new text file and save it as sample_page.html. We'll use this as example input to our updated rot13.py. import sysimport stringCHAR_MAP = dict(zip( string.ascii_lowercase, string.ascii_lowercase[13:26] + string.ascii_lowercase[0:13] ))def rotate13_letter(letter): """ Return the 13-char rotation of a letter. """ do_upper = False if letter.isupper(): do_upper = True letter = letter.lower() if letter not in CHAR_MAP: return letter else: letter = CHAR_MAP[letter] if do_upper: letter = letter.upper() return letterif __name__ == '__main__': for line in sys.stdin: for char in line: sys.stdout.write(rotate13_letter(char)) Now, run our rot13.py example and provide our HTML document as standard input data. The exact method used will vary with your operating system. If you've entered the code successfully, you should simply see a new prompt. <html> <head> <title>Hello, World!</title> </head> <body> <p> Hi there, all of you earthlings. </p> <p> Take us to your leader. </p> </body></html> The contents of rot13.html should be as follows. If that's not the case, double back and make sure everything is correct. $ cat sample_page.html | python rot13-b.py > rot13.html$ Open the translated HTML file using your web browser. What just happened? We updated our rot13.py script to read standard input data rather than rely on a command-line option. Doing this provides optimal configurability going forward and lets us feed input of varying length from a collection of different sources. We did this by looping on each line available on the sys.stdin file stream and calling our translation function. We wrote each character returned by that function to the sys.stdout stream. Next, we ran our updated script via the command line, using sample_page.html as input. As expected, the encoded version was printed on our terminal. As you can see, there is a major problem with our output. We should have a proper page title and our content should be broken down into different paragraphs. Remember, structured markup text is sprinkled with tag elements that define its structure and organization. In this example, we not only translated the text content, we also translated the markup tags, rendering them meaningless. A web browser would not be able to display this data properly. We'll need to update our processor code to ignore the tags. We'll do just that in the next section.
Read more
  • 0
  • 0
  • 2306
article-image-installing-app-v-sequencer-client-and-streaming-server
Packt
10 Jan 2011
3 min read
Save for later

Installing the App-V Sequencer, Client and Streaming Server

Packt
10 Jan 2011
3 min read
Getting Started with Microsoft Application Virtualization 4.6 Virtualize your application infrastructure efficiently using Microsoft App-V Publish, deploy, and manage your virtual applications with App-V Understand how Microsoft App-V can fit into your company. Guidelines for planning and designing an App-V environment. Step-by-step explanations to plan and implement the virtualization of your application infrastructure Installing the App-V Sequencer After reviewing the requirements and recommendations you can see that the App-V Sequencer installation is pretty straightforward. The procedure is as follows: Once you run the installation file, you should get the notification for missing requirement, in this case Microsoft Visual C++ 2005 SP1 Redistributable Package (x86). Click on Install. On the first wizard page, click on Next. Accept the License Terms and click on Next. Select the installation path for the App-V Sequencer binaries. Click on Next. Click on Install and the installation process will start. After the installation completes, you can automatically launch the application where you can see the new and refreshing interface. Installing the App-V Client The installation of the App-V Client component is also very simple and intuitive. The only consideration before starting the installation is that should already have the proper cache size defined. Once you start the installation, a few prerequisites will be installed. On the first page of the wizard click on Next. Accept the License Terms and click on Next. Select Custom setup type and click on Next. Accept or modify the installation path for the App-V Desktop Client. Verify that the data locations used by the App-V Desktop Client, including the drive letter that will be used, are the same as the ones selected for the App-V Sequencer. Click on Next. Now you can select the cache size used by the client to store the loaded applications.The default is the maximum size of 6 GB (6144 MB) or you can use the Use free disk space threshold option, where you can set the value for minimum hard disk space available. Click on Next. On this page you can set the behavior of the Runtime Package. The only recommended option to change from the default selection is marking the On Publishing Refresh on Automatically Load Application. The Application Source Root option, here left blank (default), is used when you want to override the streaming location of the .sft files (this location is set in the .osd of the App-V package). If you set a path in the Application Source Root, the applications will look for the SFT in that location instead of the one they are receiving in the OSD. This option is another alternative when you are using slow links to avoid transmitting large amounts of data. Also take note that you can use the auto-load options. In this example Automatically load previously used applications has been selected. On the next page you can configure the server you are receiving the packages from and the communication method used. In this case, the server's name is appv-server and the type of communication is Application Virtualization Server, using the RTSP 554 protocol. Click on Next. On the last page, just click on Install. After the wizard completes, you can use the App-V Client Management Console to verify the Publishing Servers options.
Read more
  • 0
  • 0
  • 3883

article-image-django-javascript-integration-jquery-place-editing-using-ajax
Packt
07 Jan 2011
8 min read
Save for later

Django JavaScript Integration: jQuery In-place Editing Using Ajax

Packt
07 Jan 2011
8 min read
Django JavaScript Integration: AJAX and jQuery Develop AJAX applications using Django and jQuery Learn how Django + jQuery = AJAX Integrate your AJAX application with Django on the server side and jQuery on the client side Learn how to handle AJAX requests with jQuery Compare the pros and cons of client-side search with JavaScript and initializing a search on the server side via AJAX Handle login and authentication via Django-based AJAX This will allow us to create a results page as shown: When someone clicks OK, the data is saved on the server, and also shown on the page. Let's get started on how this works. Including a plugin We include a jQuery plugin on a page by including jQuery, then including the plugin (or plugins, if we have more than one). In our base.html, we update: {% block footer_javascript_site %} <script language="JavaScript" type="text/javascript" src="/static/js/jquery.js"></script> <script language="JavaScript" type="text/javascript" src="/static/js/jquery-ui.js"></script> <script language="JavaScript" type="text/javascript" src="/static/js/jquery.jeditable.js"></script> {% endblock footer_javascript_site %} This is followed by the footer_javascript_section and footer_javascript_page blocks. This means that if we don't want the plugin ,which is the last inclusion, to be downloaded for each page, we could put it in overridden section and page blocks. This would render as including the plugin after jQuery. How to make pages more responsive We would also note that the setup, with three JavaScript downloads, is appropriate for development purposes but not for deployment. In terms of YSlow client-side performance optimization, the recommended best practice is to have one HTML/XHTML hit, one CSS hit at the top, and one JavaScript hit at the bottom. One of the basic principles of client-side optimization, discussed by Steve Souders (see http://developer.yahoo.com/yslow/) is,since HTTP requests slow the page down, the recommended best practice is to have one (preferably minifed) CSS inclusion at the top of the page, and then one (preferably minifed) JavaScript inclusion at the bottom of each page. Each HTTP request beyond this makes things slower, so combining CSS and/or JavaScript requests into a single concatenated file is low-hanging fruit to improve how quick and responsive your web pages appear to users. For deployment, we should minify and combine the JavaScript. As we are developing, we also have JavaScript included in templates and rendered into the delivered XHTML; this may be appropriate for development purposes. For deployment though, as much shared functionality as possible should be factored out into an included JavaScript fle. For content that can be delivered statically, such as CSS, JavaScript, and even non-dynamic images, setting far-future Expires/Cache-Control headers is desirable. (One practice is to never change the content of a published URL for the kind of content that has a far-future expiration set, and then if it needs updating, instead of changing the content at the same location, leave the content where it is, publish at a new location possibly including a version number, and reference the new location.) A template handling the client-side requirements Here's the template. Its view will render it with an entity and other information. At present it extends the base directly; it is desirable in many cases to have the templates that are rendered extend section templates, which in turn extend the base. In our simple application, we have two templates which are directly rendered to web pages. One is the page that handles both search and search results—and the other, the page that handles a profile, from the following template: {% extends "base.html" %} We include honorifics before the name, and post-nominals after. At this point we do not do anything to make it editable. {% extends "base.html" %} Following earlier discussion, we include honorifcs before the name, and post-nominals after. At this point we do not do anything to make it editable. {% block head_title %} {{ entity.honorifics }} {{ entity.name }} {{ entity.post_nominals }} {% endblock head_title %} {% block body_main %} There is one important point about Django and the title block. The Django developers do not fnd it acceptable to write a templating engine that produces errors in production if someone attempts to access an undefned value (by typos, for instance). As a result of this design decision, if you attempt to access an undefned value, the templating engine will silently insert an empty string and move on. This means that it is safe to include a value that may or may not exist, although there are ways to test if a value exists and is nonempty, and display another default value in that case. We will see how to do this soon. Let's move on to the main block, defned by the last line of code. Once we are in the main block, we have an h1 which is almost identical to the title block, but this time it is marked up to support editing in place. Let us look at the honorifics span; the name and post_nominals spans work the same way: <h1> <span id="Entity_honorifics_{{ entity.id }}" class="edit"> {% if entity.honorifics %} {{ entity.honorifics }} {% else %} Click to edit. {% endif %} </span> The class edit is used to give all $(".edit") items some basic special treatment with Jeditable; there is nothing magical about the class name, which could have been replaced by user-may-change-this or something else. edit merely happens to be a good name choice, like almost any good variable/function/object name. We create a naming convention in the span's HTML ID which will enable the server side to know which—of a long and possibly open-ended number of things we could intend to change—is the one we want. In a nutshell, the convention is modelname_feldname_instanceID. The frst token is the model name, and is everything up to the first underscore. (Even if we were only interested in one model now, it is more future proof to design so that we can accommodate changes that introduce more models.) The last token is the instance ID, an integer. The middle token, which may contain underscores (for example post_nominals in the following code), is the feld name. There is no specifc requirement to follow a naming convention, but it allows us to specify an HTML ID that the server-side view can parse for information about which feld on which instance of which model is being edited. We also provide a default value, in this case Click to edit, intended not only to serve as a placeholder, but to give users a sense on how this information can be updated. We might also observe that here and in the following code, we do not presently have checks against race conditions in place. So nothing here or in the following code will stop users from overwriting each others' changes. This may be taken as a challenge to refne and extend the solution to either prevent race conditions or mitigate their damage. <span id="Entity_name_{{ entity.id }}" class="edit"> {% if entity.name %} {{ entity.name }} {% else %} Click to edit. {% endif %} </span> <span id="Entity_post_nominals_{{ entity.id }}" class="edit"> {% if entity.post_nominals %} {{ entity.post_nominals }} {% else %} Click to edit. {% endif %} </span> </h1> This approach is an excellent frst approach but in practice is an h1 with three slots that say Click to edit on a profle, creating needless confusion. We move to a simplifed: <span id="Entity_name_{{ entity.id }}" class="edit"> {% if entity.name %} {{ entity.name }}jQuery In-place Editing Using Ajax {% else %} Click to edit. {% endif %} </span> <span id="Entity_post_nominals_{{ entity.id }}" class="edit"> {% if entity.post_nominals %} {{ entity.post_nominals }} {% else %} Click to edit. {% endif %} </span> </h1> Taken together, the three statements form the heading in this screenshot: If we click on the name (for instance) it becomes: The image is presently a placeholder; this should be expanded to allow an image to be uploaded if the user clicks on the picture (implementing consistent-feeling behavior whether or not we do so via the same plugin). We also need the view and urlpattern on the backend: <h1 class="edit" id="Entity_name_{{ entity.id }}"> {{ entity.name }} </h1>
Read more
  • 0
  • 0
  • 7151
Modal Close icon
Modal Close icon