Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds
Hands-On Software Engineering with Python
Hands-On Software Engineering with Python

Hands-On Software Engineering with Python: Move beyond basic programming and construct reliable and efficient software with complex code

Arrow left icon
Profile Icon Nimesh Verma Profile Icon Brian Allbee
Arrow right icon
$57.99
Paperback Oct 2018 736 pages 1st Edition
eBook
$41.39 $45.99
Paperback
$57.99
eBook + Subscription
$24.99 Monthly
Arrow left icon
Profile Icon Nimesh Verma Profile Icon Brian Allbee
Arrow right icon
$57.99
Paperback Oct 2018 736 pages 1st Edition
eBook
$41.39 $45.99
Paperback
$57.99
eBook + Subscription
$24.99 Monthly
eBook
$41.39 $45.99
Paperback
$57.99
eBook + Subscription
$24.99 Monthly

What do you get with a Packt Premium Subscription?

Subscribe today for full access to all titles. After checkout, you’ll receive an eBook credit that you can manually redeem on any title — including this one.
Product feature icon Access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon Weekly additions on emerging tech and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon A monthly credit and 50% off any future digital purchases.
Table of content icon View table of contents Preview book icon Preview Book

Hands-On Software Engineering with Python

Programming versus Software Engineering

Development shops often have specific levels, grades, or ranks that their developers fall into, indicating the levels of experience, expertise, and industry wisdom expected of staff at each level. These may vary (perhaps wildly) from location to location, but a typical structure looks something like the following:

  • Junior developers: A junior developer is typically someone that doesn't have much programming experience. They probably know the basics of writing code, but they are not expected to know much beyond that.
  • Developers: Mid-level developers (referred to by whatever formal title might apply) usually have enough experience that they can be relied on to write reasonably solid code, with little to no supervision. They probably have enough experience to determine implementation details and strategies, and they will often have some understanding of how different chunks of code can (and do) interact with each other, and what approaches will minimize difficulties in those interactions.
  • Senior developers: Senior developers have enough experience - even if it's focused on a set of specific products/projects - to firmly grasp all of the technical skills involved in typical development efforts. At this point in their careers, they will almost always have a solid handle on a lot of the non-technical (or semi-technical) skills that are involved, as well—especially policies and procedures, and strategies and tactics that encourage or enforce business values such as stability and the predictability of development efforts. They may not be experts in those areas, but they will know when to call out risks, and they will often have several options to suggest for mitigating those risks.

Above the level of the senior developer, the terminology and definition often varies even more wildly, and the skill set usually starts to focus more on business-related abilities and responsibilities (scope and influence) than on technical capabilities or expertise.

The dividing line between programming and software engineering falls somewhere within the differences between developers and senior developers, as far as technical capabilities and expertise are concerned. At a junior level, and sometimes at a developer level, efforts are often centered around nothing more than writing code to meet whatever requirements apply, and conforming to whatever standards are in play. Software engineering, at a senior developer level, has a big-picture view of the same end results. The bigger picture involves awareness of, and attention paid to, the following things:

  • Standards, both technical/developmental and otherwise, including best practices
  • The goals that code is written to accomplish, including the business values that are attached to them
  • The shape and scope of the entire system that the code is a part of

The bigger picture

So, what does this bigger picture look like? There are three easily-identifiable areas of focus, with a fourth (call it user interaction) that either weaves through the other three or is broken down into its own groups.

Software engineering must pay heed to standards, especially non-technical (business) ones, and also best practices. These may or may not be followed but, since they are standards or best practices for a reason, not following them is something that should always be a conscious (and defensible) decision. It's not unusual for business-process standards and practices to span multiple software components, which can make them difficult to track if a certain degree of discipline and planning isn't factored into the development process to make them more visible. On the purely development-related side, standards and best practices can drastically impact the creation and upkeep of code, its ongoing usefulness, and even just the ability to find a given chunk of code, when necessary.

It's rare for code to be written simply for the sake of writing code. There's almost always some other value associated with it, especially if there's business value or actual revenue associated with a product that the code is a part of. In those cases, understandably, the people that are paying for the developmental effort will be very interested in ensuring that everything works as expected (code-quality) and can be deployed when expected (process-predictability).

Code-quality concerns will be addressed during the development of the hms_sys project a few chapters from now, and process-predictability is mostly impacted by the developmental methodologies discussed in Chapter 5The hms_sys System-Project.

The remaining policy-and-procedure related concerns are generally managed by setting up and following various standards, processes, and best practices during the startup of a project (or perhaps a development team). Those items - things such as setting up source control, having standard coding conventions, and planning for repeatable, automated testing - will be examined in some detail during the set up chapter for the hms_sys project. Ideally, once these kinds of developmental process are in place, the ongoing activities that keep them running and reliable will just become habits, part of the day-to-day process, almost fading into the background.

Finally, with more of a focus on the code side, software engineering must, by necessity, pay heed to entire systems, keeping a universal view of the system in mind. Software is composed of a lot of elements that might be classified as atomic; they are indivisible units in and of themselves, under normal circumstances. Just like their real-world counterparts, when they start to interact, things get interesting, and hopefully useful. Unfortunately, that's also when unexpected (or even dangerous) behaviors—bugs—usually start to appear.

This awareness is, perhaps, one of the more difficult items to cultivate. It relies on knowledge that may not be obvious, documented, or readily available. In large or complex systems, it may not even be obvious where to start looking, or what kinds of question to ask to try to find the information needed to acquire that knowledge.

Asking questions

There can be as many distinct questions that can be asked about any given chunk of code as there are chunks of code to ask about—even very simple code, living in a complex system, can raise questions in response to questions, and more questions in response to those questions.

If there isn't an obvious starting point, starting with the following really basic questions is a good first step:

  • Who will be using the functionality?
  • What will they be doing with it?
  • When, and where, will they have access to it?
  • What problem is it trying to solve? For example, why do they need it?
  • How does it have to work? If detail is lacking, breaking this one down into two separate questions is useful:
    • What should happen if it executes successfully?
    • What should happen if the execution fails?

Teasing out more information about the whole system usually starts with something as basic as the following questions:

  • What other parts of the system does this code interact with?
  • How does it interact with them?

Having identified all of the moving parts, thinking about "What happens if…" scenarios is a good way to identify potential points where things will break, risks, and dangerous interactions. You can ask questions such as the following:

  • What happens if this argument, which expects a number, is handed a string?
  • What happens if that property isn't the object that's expected?
  • What happens if some other object tries to change this object while it's already being changed?

Whenever one question has been answered, simply ask, What else? This can be useful for verifying whether the current answer is reasonably complete.

Let's see this process in action. To provide some context, a new function is being written for a system that keeps track of mineral resources on a map-grid, for three resources: gold, silver, and copper. Grid locations are measured in meters from a common origin point, and each grid location keeps track of a floating-point number, from 0.0 to 1.0, which indicates how likely it is that resource will be found in the grid square. The developmental dataset already includes four default nodes - at (0,0), (0,1), (1,0), and (1,1) - with no values, as follows:

The system already has some classes defined to represent individual map nodes, and functions to provide basic access to those nodes and their properties, from whatever central data store they live in:

Constants, exceptions, and functions for various purposes already exist, as follows:

  • node_resource_names: This contains all of the resource names that the system is concerned with, and can be thought of and treated as a list of strings: ['gold','silver','copper']
  • NodeAlreadyExistsError: An exception that will be raised if an attempt is made to create a MapNode that already exists
  • NonexistentNodeError: An exception that will be raised if a request is made for a MapNode that doesn't exist
  • OutOfMapBoundsError: An exception that will be raised if a request is made for a MapNode that isn't allowed to exist in the map area
  • create_node(x,y): Creates and returns a new, default MapNode, registering it in the global dataset of nodes in the process
  • get_node(x,y): Finds and returns a MapNode at the specified (xy) coordinate location in the global dataset of available nodes

A developer makes an initial attempt at writing the code to set a value for a single resource at a given node, as a part of a project. The resulting code looks as follows (assume that all necessary imports already exist):

def SetNodeResource(x, y, z, r, v):
    n = get_node(x,y)
    n.z = z
    n.resources.add(r, v)

This code is functional, from the perspective that it will do what it's supposed to (and what the developer expected) for a set of simple tests; for example, executing, as follows:

SetNodeResource(0,0,None,'gold',0.25) print(get_node(0,0)) SetNodeResource(0,0,None,'silver',0.25) print(get_node(0,0)) SetNodeResource(0,0,None,'copper',0.25) print(get_node(0,0))

The results are in the following output:

By that measure, there's nothing wrong with the code and its functions, after all. Now, let's ask some of our questions, as follows:

  • Who will be using this functionality?: The function may be called, by either of two different application front-ends, by on-site surveyors, or by post-survey assayers. The surveyors probably won't use it often, but if they see obvious signs of a deposit during the survey, they're expected to log it with a 100% certainty of finding the resource(s) at that grid location; otherwise, they'll leave the resource rating completely alone.
  • What will they be doing with it?: Between the base requirements (to set a value for a single resource at a given node) and the preceding answer, this feels like it's already been answered.
  • When, and where, do they have access to it?: Through a library that's used by the surveyor and assayer applications. No one will use it directly, but it will be integrated into those applications.
  • How should it work?: This has already been answered, but raises the question: Will there ever be a need to add more than one resource rating at a time? That's probably worth nothing, if there's a good place to implement it.
  • What other parts of the system does this code interact with?: There's not much here that isn't obvious from the code; it uses MapNode objects, those objects' resources, and the get_node function.
  • What happens if an attempt is made to alter an existing MapNode?: With the code as it was originally written, this behaves as expected. This is the happy path that the code was written to handle, and it works.
  • What happens if a node doesn't already exist?: The fact that there is a NonexistentNodeError defined is a good clue that at least some map operations require a node to exist before they can complete. Execute a quick test against that by calling the existing function, as follows:
SetNodeResource(0,6,None,'gold',0.25)

The preceding command results in the following:

This is the result because the development data doesn't have a MapNode at that location yet.

  • What happens if a node can't exist at a given location?: Similarly, there's an OutOfMapBoundsError defined. Since there are no out-of-bounds nodes in the development data, and the code won't currently get past the fact that an out-of-bounds node doesn't exist, there's no good way to see what happens if this is attempted.
  • What happens if the z-value isn't known at the time?: Since the create_node function doesn't even expect a z-value, but MapNode instances have one, there's a real risk that calling this function on an existing node would overwrite an existing z-altitude value, on an existing node. That, in the long run, could be a critical bug.
  • Does this meet all of the various developmental standards that apply?: Without any details about standards, it's probably fair to assume that any standards that were defined would probably include, at a minimum, the following:
    • Naming conventions for code elements, such as function names and arguments; an existing function at the same logical level as get_node, using SetNodeResources as the name of the new function, while perfectly legal syntactically, may be violating a naming convention standard.
    • At least some of the effort towards documentation, of which there's none.
    • Some inline comments (maybe), if there is a need to explain parts of the code to future readersthere are none of these also, although, given the amount of code in this version and the relatively straightforward approach, it's arguable whether there would be any need.
  • What should happen if the execution fails?: It should probably throw explicit errors, with reasonably detailed error messages, if something fails during execution.
  • What happens if an invalid value is passed for any of the arguments?: Some of them can be tested by executing the current function (as was done previously), while supplying invalid arguments—an out-of -range number first, then an invalid resource name.

Consider the following code, executed with an invalid number:

SetNodeResource(0,0,'gold',2)

The preceding code results in the following output:

Also, consider the following code, with an invalid resource type:

SetNodeResource(0,0,'tin',0.25)

The preceding code results in the following:

The function itself can either succeed or raise an error during execution, judging by these examples; so, ultimately, all that really needs to happen is that those potential errors have to be accounted for, in some fashion.

Other questions may come to mind, but the preceding questions are enough to implement some significant changes. The final version of the function, after considering the implications of the preceding answers and working out how to handle the issues that those answers exposed, is as follows:

def set_node_resource(x, y, resource_name, 
    resource_value, z=None):
    """
Sets the value of a named resource for a specified 
node, creating that node in the process if it doesn't 
exist.

Returns the MapNode instance.

Arguments:
 - x ................ (int, required, non-negative) The
                      x-coordinate location of the node 
                      that the resource type and value is 
                      to be associated with.
 - y ................ (int, required, non-negative) The 
                      y-coordinate location of the node 
                      that the resource type and value is 
                      to be associated with.
 - z ................ (int, optional, defaults to None) 
                      The z-coordinate (altitude) of the 
                      node.
 - resource_name .... (str, required, member of 
                      node_resource_names) The name of the 
                      resource to associate with the node.
 - resource_value ... (float, required, between 0.0 and 1.0, 
                      inclusive) The presence of the 
                      resource at the node's location.

Raises
 - RuntimeError if any errors are detected.
"""
    # Get the node, if it exists
    try:
        node = get_node(x,y)
    except NonexistentNodeError:
        # The node doesn't exist, so create it and 
        # populate it as applicable
        node = create_node(x, y)
    # If z is specified, set it
if z != None: node.z = z # TODO: Determine if there are other exceptions that we can # do anything about here, and if so, do something # about them. For example: # except Exception as error: # # Handle this exception # FUTURE: If there's ever a need to add more than one # resource-value at a time, we could add **resources # to the signature, and call node.resources.add once # for each resource. # All our values are checked and validated by the add # method, so set the node's resource-value try: node.resources.add(resource_name, resource_value) # Return the newly-modified/created node in case # we need to keep working with it. return node except Exception as error: raise RuntimeError( 'set_node_resource could not set %s to %0.3f ' 'on the node at (%d,%d).' % (resource_name, resource_value, node.x, node.y) )

Stripping out the comments and documentation for the moment, this may not look much different from the original code—only nine lines of code were added—but the differences are significant, as follows:

  • It doesn't assume that a node will always be available.
  • If the requested node doesn't exist, it creates a new one to operate on, using the existing function defined for that purpose.
  • It doesn't assume that every attempt to add a new resource will succeed.
  • When such an attempt fails, it raises an error that shows what happened.

All of these additional items are direct results of the questions asked earlier, and of making conscious decisions on how to deal with the answers to those questions. That kind of end result is where the difference between the programming and software engineering mindsets really appears.

Summary

There's more to software engineering than just writing code. Experience; attention to detail; and asking questions about how the code functions, interacts with the rest of a system, and so on; are important aspects of evolving from a programming to a software engineering mindset. The time required to acquire experience can be shortened, perhaps significantly, by simply asking the right questions.

There are also factors completely outside the realm of creating and managing code that require examination and questioning. They mainly focus on what can, or should, be expected from the pre-development planning around a developmental effort, and that starts with understanding a typical software development life cycle.

Left arrow icon Right arrow icon
Download code icon Download Code

Key benefits

  • Master the tools and techniques used in software engineering
  • Evaluates available database options and selects one for the final Central Office system-components
  • Experience the iterations software go through and craft enterprise-grade systems

Description

Software Engineering is about more than just writing code—it includes a host of soft skills that apply to almost any development effort, no matter what the language, development methodology, or scope of the project. Being a senior developer all but requires awareness of how those skills, along with their expected technical counterparts, mesh together through a project's life cycle. This book walks you through that discovery by going over the entire life cycle of a multi-tier system and its related software projects. You'll see what happens before any development takes place, and what impact the decisions and designs made at each step have on the development process. The development of the entire project, over the course of several iterations based on real-world Agile iterations, will be executed, sometimes starting from nothing, in one of the fastest growing languages in the world—Python. Application of practices in Python will be laid out, along with a number of Python-specific capabilities that are often overlooked. Finally, the book will implement a high-performance computing solution, from first principles through complete foundation.

Who is this book for?

Hands-On Software Engineering with Python is for you if you are a developer having basic understanding of programming and its paradigms and want to skill up as a senior programmer. It is assumed that you have basic Python knowledge.

What you will learn

  • Understand what happens over the course of a system s life (SDLC)
  • Establish what to expect from the pre-development life cycle steps
  • Find out how the development-specific phases of the SDLC affect development
  • Uncover what a real-world development process might be like, in an Agile way
  • Find out how to do more than just write the code
  • Identify the existence of project-independent best practices and how to use them
  • Find out how to design and implement a high-performance computing process

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Oct 26, 2018
Length: 736 pages
Edition : 1st
Language : English
ISBN-13 : 9781788622011
Category :
Languages :

What do you get with a Packt Premium Subscription?

Subscribe today for full access to all titles. After checkout, you’ll receive an eBook credit that you can manually redeem on any title — including this one.
Product feature icon Access to the largest independent learning library in tech. Access this title and thousands more!
Product feature icon Weekly additions on emerging tech and exclusive early access to books as they are being written.
Product feature icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Product feature icon A monthly credit and 50% off any future digital purchases.

Product Details

Publication date : Oct 26, 2018
Length: 736 pages
Edition : 1st
Language : English
ISBN-13 : 9781788622011
Category :
Languages :

Packt Subscriptions

See our plans and pricing
Modal Close icon
$19.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
$199.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts
$279.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just $5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total $ 149.97
Hands-On Software Engineering with Python
$57.99
Python Automation Cookbook
$40.99
Clean Code in Python
$50.99
Total $ 149.97 Stars icon

Table of Contents

20 Chapters
Programming versus Software Engineering Chevron down icon Chevron up icon
The Software Development Life Cycle Chevron down icon Chevron up icon
System Modeling Chevron down icon Chevron up icon
Methodologies, Paradigms, and Practices Chevron down icon Chevron up icon
The hms_sys System Project Chevron down icon Chevron up icon
Development Tools and Best Practices Chevron down icon Chevron up icon
Setting Up Projects and Processes Chevron down icon Chevron up icon
Creating Business Objects Chevron down icon Chevron up icon
Testing Business Objects Chevron down icon Chevron up icon
Thinking About Business Object Data Persistence Chevron down icon Chevron up icon
Data Persistence and BaseDataObject Chevron down icon Chevron up icon
Persisting Object Data to Files Chevron down icon Chevron up icon
Persisting Data to a Database Chevron down icon Chevron up icon
Testing Data Persistence Chevron down icon Chevron up icon
Anatomy of a Service Chevron down icon Chevron up icon
The Artisan Gateway Service Chevron down icon Chevron up icon
Handling Service Transactions Chevron down icon Chevron up icon
Testing and Deploying Services Chevron down icon Chevron up icon
Multiprocessing and HPC in Python Chevron down icon Chevron up icon
Other Books You May Enjoy Chevron down icon Chevron up icon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is included in a Packt Premium subscription? Chevron down icon Chevron up icon

A subscription provides you with full access to view all Packt and licnesed content online, this includes exclusive access to Early Access titles. Depending on the tier chosen you can also earn credits and discounts to use for owning content

What are credits? Chevron down icon Chevron up icon

Credits can be used to buy books DRM free, the same way that you would pay for a book. Your credits can be found in the subscription homepage - subscription.packtpub.com - clicking on ‘the my’ library dropdown and selecting ‘credits’. You'll get one to use immediately after checkout, and then every time you renew. You require an active subscription to use your credits, once used you keep the title forever.

How can I cancel my subscription? Chevron down icon Chevron up icon

To cancel your subscription with us simply go to the account page - found in the top right of the page or at https://subscription.packtpub.com/my-account/subscription - From here you will see the ‘cancel subscription’ button in the grey box with your subscription information in. You can cancel at anytime, you will keep access for the remaining period you have paid for. On the date of cancellation you will lose all access to online content, along with any unused credits.

What happens if an Early Access Course is cancelled? Chevron down icon Chevron up icon

Projects are rarely cancelled, but sometimes it's unavoidable. If an Early Access course is cancelled or excessively delayed, you can exchange your purchase for another course. For further details, please contact us here.

Where can I send feedback about an Early Access title? Chevron down icon Chevron up icon

If you have any feedback about the product you're reading, or Early Access in general, then please fill out a contact form here and we'll make sure the feedback gets to the right team. 

Can I download the code files for Early Access titles? Chevron down icon Chevron up icon

We try to ensure that all books in Early Access have code available to use, download, and fork on GitHub. This helps us be more agile in the development of the book, and helps keep the often changing code base of new versions and new technologies as up to date as possible. Unfortunately, however, there will be rare cases when it is not possible for us to have downloadable code samples available until publication.

When we publish the book, the code files will also be available to download from the Packt website.

How accurate is the publication date? Chevron down icon Chevron up icon

The publication date is as accurate as we can be at any point in the project. Unfortunately, delays can happen. Often those delays are out of our control, such as changes to the technology code base or delays in the tech release. We do our best to give you an accurate estimate of the publication date at any given time, and as more chapters are delivered, the more accurate the delivery date will become.

How will I know when new chapters are ready? Chevron down icon Chevron up icon

We'll let you know every time there has been an update to a course that you've bought in Early Access. You'll get an email to let you know there has been a new chapter, or a change to a previous chapter. The new chapters are automatically added to your account, so you can also check back there any time you're ready and download or read them online.

I am a Packt subscriber, do I get Early Access? Chevron down icon Chevron up icon

Yes, all Early Access content is fully available through your subscription. You will need to have a paid for or active trial subscription in order to access all titles.

How is Early Access delivered? Chevron down icon Chevron up icon

Early Access is currently only available as a PDF or through our online reader. As we make changes or add new chapters, the files in your Packt account will be updated so you can download them again or view them online immediately.

How do I buy Early Access content? Chevron down icon Chevron up icon

Early Access is a way of us getting our content to you quicker, but the method of buying the Early Access course is still the same. Just find the course you want to buy, go through the check-out steps, and you’ll get a confirmation email from us with information and a link to the relevant Early Access courses.

What is Early Access? Chevron down icon Chevron up icon

Keeping up to date with the latest technology is difficult; new versions, new frameworks, new techniques. This feature gives you a head-start to our content, as it's being created. With Early Access you'll receive each chapter as it's written, and get regular updates throughout the product's development, as well as the final course as soon as it's ready.We created Early Access as a means of giving you the information you need, as soon as it's available. As we go through the process of developing a course, 99% of it can be ready but we can't publish until that last 1% falls in to place. Early Access helps to unlock the potential of our content early, to help you start your learning when you need it most. You not only get access to every chapter as it's delivered, edited, and updated, but you'll also get the finalized, DRM-free product to download in any format you want when it's published. As a member of Packt, you'll also be eligible for our exclusive offers, including a free course every day, and discounts on new and popular titles.

Modal Close icon
Modal Close icon