Courseware Software Programmer Python English (en-US) Par�cipant Handbook Sector IT-ITeS Sub-Sector IT Services Occupa�on Applica�on Development Reference ID: SSC/Q0510, Version 1.0 NSQF level: 4 So�ware Programmer - Python Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Published by IT- ITeS Sector Skills Council NASSCOM Plot No – 7, 8, 9 & 10, Sector 126, Noida, Uttar Pradesh - 201303 Email: ssc@nasscom.com Website: www.sscnasscom.com Phone: 0120 4990111 - 0120 4990172 First Edition, March 2023 This book is sponsored by IT- ITeS Sector Skills Council NASSCOM Printed in India by NASSCOM Under Creative Commons License: Attribution-ShareAlike: CC BY-SA This license lets others remix, tweak, and build upon your work even for commercial purposes, as long as they credit you and license their new creations under the identical terms. This license is often compared to “copyleft” free and open-source software licenses. All new works based on yours will carry the same license, so any derivatives will also allow commercial use. This is the license used by Wikipedia and is recommended for materials that would benefit from incorporating content from Wikipedia and similarly licensed projects. Disclaimer The information contained herein has been obtained from various reliable sources. IT- ITeS Sector Skills Council NASSCOM disclaims all warranties to the accuracy, completeness or adequacy of such information. NASSCOM shall have no liability for errors, omissions, or inadequacies, in the information contained herein, or for interpretations thereof. Every effort has been made to trace the owners of the copyright material included in the book. The publishers would be grateful for any omissions brought to their notice for acknowledgements in future editions of the book. No entity in NASSCOM shall be responsible for any loss whatsoever, sustained by any person who relies on this material. All pictures shown are for illustration purpose only. The coded boxes in the book called Quick Response Code (QR code) will help to access the e-resources linked to the content. These QR codes are generated from links and YouTube video resources available on Internet for knowledge enhancement on the topic and are not created by NASSCOM. Embedding of the link or QR code in the content should not be assumed endorsement of any kind. NASSCOM is not responsible for the views expressed or content or reliability of linked videos. NASSCOM cannot guarantee that these links/QR codes will work all the time as we do not have control over availability of the linked pages. Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Skilling is building a be�er India. If we have to move India towards development then Skill Development should be our mission. Shri Narendra Modi Prime Minister of India iii Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime COMPLIANCE TO QUALIFICATION PACK – NATIONAL OCCUPATIONAL STANDARDS is hereby issued by the IT – ITeS Sector Skill Council NASSCOM for SKILLING CONTENT: PARTICIPANT HANDBOOK Complying to National Occupational Standards of Job Role/ Qualification Pack: ‘Software Programmer - Python’ QP No. ‘SSC/Q0510, NSQF Level 4’ Date of Issuance: November 17th, 2022 Authorised Signatory (IT – ITeS Sector Skill Council NASSCOM) Valid up to: November 17th, 2025 * Valid up to the next review date of the Qualification Pack iv Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Acknowledgements NASSCOM would like to express its gratitude towards company representatives, who belieive in our vision of improving employability for the available pool of engineering students. SSC NASSCOM makes the process easier by developing and implementing courses that are relevant to the projected industry requirements. The aim is to close the industry-academia skill gap and create a talent pool that can withstand upcoming externalities within the IT-BPM industry. This initiative is the belief of NASSCOM and concerns every stakeholder – students, academia, and industries. The ceaseless support and tremendous amount of work offered by IT-ITeS members to strategize meaningful program training materials, both from the context of content and design are truly admirable. We would also like to show our appreciation to Orion ContentGrill Pvt. Ltd. for their persistent effort, and for the production of this course publication. v Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook About this book This Participant Handbook has been prepared as a guide for participants who aim to acquire the knowledge and skills required to perform various activities in the role of software developer. Its content is aligned with the latest Qualification Pack (QP) designed for the job role. With the guidance of a qualified instructor, participants will be equipped to perform the following efficiently in a job role: • • • Knowledge and Understanding: Operational knowledge and understanding relevant to performing the required functions. Performance Criteria: The skills required through practical training to perform the operations required by the applicable quality standards. Business acumen: Ability to make appropriate operational decisions regarding the work area. The Participant Handbook details the relevant activities to be performed by the software -Programmer. After studying this handbook, the job holders will be proficient enough to perform their duties as per the applicable quality standards. The latest and approved edition of The Software Programmer’s Handbook aligns with the following National Occupational Standards (NOS) detailed in. 1. SSC/N0509: Verify the specifications and contribute to the design of software program 2. SSC/N0511: Develop, test and execute software programs as per specifications using Python 3. DGT/VSQ/N0102: Employability Skill NOS (60 Hrs) The handbook has been divided into an appropriate number of units and sub-units based on the contents of the relevant QPs. We hope that it will facilitate easy and structured learning for the participants, enabling them to acquire advanced knowledge and skills. vi Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Table of Contents S.NModules and Units Page No 1. Programming and Algorithms (SSC/N0509) 1 Unit 1.1 - Software Programming & Algorithm Development 3. 3 Unit 1.2 - Software Development Life Cycle 18 Unit 1.3 - Elements for Measuring Software Development Process 32 Develop, Test and Execute Software Programs as per Specifications using Python (SSC/N0511) 37 Unit 3.1 - Introduction to Python 39 Unit 3.2 - Introduction to Data Structures and Databases 97 Unit 3.3 - Core Python Concepts 131 Unit 3.4 - Testing and Execution 291 Employability Skills (DGT/VSQ/N0102) 355 Employability Skills is available at the following location : https://www.skillindiadigital.gov.in/content/list Scan the QR code below to access the ebook Annexure 357 vii Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook viii Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime 1. Programming and Algorithms Unit 1.1 - Software Programming & Algorithm Development Unit 1.2 - Software Development Life Cycle Unit 1.3 - Elements for Measuring Software Development Process SSC/N0509 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Key Learning Outcomes By the end of this module, the participants will be able to: 1. Implement appropriate standards to assist in performing software construction as per specifications 2. Identify software development needs and changes 3. Design algorithms to solve problems and execute test cases to convert them into code 2 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer UNIT 1.1: Software Programming & Algorithm Development Unit Objectives By the end of this unit, the participants will be able to: 1. List the steps involved in solving computational problems 2. List the disadvantages of data flow diagrams 3. Identify the process of algorithm development for software programming 1.1.1 Appropriate Standards for Software Construction as Per Specifications Software construction is the detailed creation of working, meaningful software through a combination of coding, verification, unit testing, integration testing, and debugging. Software construction is strongly intertwined with all other aspects of software engineering, especially software design and testing. It is due to the fact that the software development process entails significant software design and testing activity. It also uses the output of design as one of the inputs to testing, with both design and testing being activities. The precise boundaries between design, construction, and testing (if any) will vary depending on the software life cycle processes used in a project. Since some of the detailed design work gets done before construction, the majority of design work is carried out during the construction process. As a result, software construction and software design are inextricably linked. Throughout the development process, software engineer’s unit-test and integrate their work. Thus, software development is inextricably linked to software testing too. Software development typically generates the most configuration items that must be managed in a software project (source files, content, test cases, and so on). As a result, software development is inextricably linked to software configuration management. The following are the basic fundamentals/standards of software development: Fig. 1.1.1: Software Construction Fundamentals 3 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 1. Minimizing complexity: Most people have a limited ability to retain complex structures and information in their working memories, particularly over long periods of time. This has a significant impact on how people communicate their intent to computers, resulting in one of the most powerful forces in software development: minimizing complexity. The need to reduce complexity applies to nearly every aspect of software development, but it is especially critical in software testing. Software development complexity is reduced by emphasizing simple and readable code creation over clever code creation. 2. Anticipating Change: Most software will evolve over time, and the anticipation of change drives many aspects of software development; changes in the environments in which software operates also have a variety of effects on software. Anticipating change assists software engineers in developing extensible software, which allows them to improve a software product without disrupting its underlying structure. Many specific techniques aid in anticipating change. 3. Constructing for Verification: Constructing for verification entails developing software in such a way that flaws can be easily identified by software engineers writing the software as well as testers and users during independent testing and operational activities. Following coding standards to support code reviews and unit testing, organizing code to support automated testing, and limiting the use of complex or difficult-to-understand language structures are some of the specific techniques that support constructing for verification. 4. Reuse: The term "reuse" refers to the use of existing assets to solve various problems. Commonly reused assets in software development include libraries, modules, components, source code, and commercial off-the-shelf (COTS) assets. Reuse works best when done methodically, according to a well-defined, repeatable process. Systematic reuse can lead to significant gains in software productivity, quality, and cost. Construction for reuse and construction with reuse are two closely related aspects of reuse. The former refers to the creation of reusable software assets, whereas the latter refers to the reuse of software assets in the development of a new solution. Reuse frequently crosses project boundaries, which means that reused assets can be built in other projects or organizations. 5. Standards in Construction: Using external or internal development standards during construction aids in meeting project goals for efficiency, quality, and cost. Allowable programming language subsets and usage standards, in particular, are important aids in achieving higher security. Standards that have a direct impact on construction issues include a. Methods of communication (for example, standards for document formats and contents) b. Programming languages (for example, java and C++ language standards) *coding standards (for example, standards for naming conventions, layout, and indentation) c. The platforms (for example, interface standards for operating system calls) d. Tools (for example, diagrammatic notation standards such as UML (unified modeling language). 1.1.2 Steps involved in Computational Problems: A computational problem is one that a computer can solve or one that a computer can answer. Consider the factoring problem: "Find a nontrivial prime factor of n given a positive integer n." A computational problem can be solved step by step by a computer. These problems usually have a well-defined input, constraints, and conditions that the output must meet. A computational problem can be thought of as a collection of instances or cases, each with its own set of solutions, which may or may not be empty. For example, in the factoring problem, instances are integers n, and solutions are prime numbers p that describes nontrivial prime factors of n. 4 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.1.2: Computational Problems Types of computational problems: Fig. 1.1.3: Types of Computational Problems 5 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Data collection or identification of a data set (numerical, text, audio, video, images, or symbols) and analysis to discover similarities, differences, or trends. Abstraction Filtering out irrelevant information to reduce complexity. This can help to simplify problem-solving and create a general understanding of the computational problem. Fig. 1.1.4: Problem Development Steps 1.1.3 Software Needs and Changes It is critical for businesses because it allows them to stand out from competitors and become more competitive. Enhancing customer experiences, bringing more feature-rich and innovative products to market, and making setups safer, more productive, and more efficient are all benefits of software development. Digitization and online information storage not only save space but also integrate and centralize information, making it easily accessible to those who need it. It is also simple to safeguard your data against intruders. As the company expands, so will the pool of data, and efficiently storing this data will become a priority. In order to continue providing consistent performance to those who use this data, businesses must develop and upgrade their digital organizations. Data analysis also necessitates software development. When combined with the right software, businesses can use the data collected from day-to-day tasks to keep track of trends among their clients. Purpose of software development in business: 6 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.1.5: Purpose of software development in business Important steps in developing software: Fig. 1.1.6: Important steps in developing software 7 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 1.1.4 Data flow Diagrams A data flow diagram (DFD) is a graphical depiction of data flow in an information system. It displays incoming data flow, outgoing data flow, and stored data. The DFD makes no mention of how data flows through the system. This technique is used for visually representing complex and difficult-to-describe systems and processes. Data flow diagrams depict the flow of data through a process or system. It also includes data inputs and outputs, data stores, and the different sub processes that data moves through. DFD uses standardized notations and symbols to describe various entities and their relationships. It is easier to identify flaws in a system when all of its components are visualized. These flaws are then addressed to create a strong solution. Fig. 1.1.7: Data Flow Diagrams There is a significant distinction between DFD and Flowchart. The flowchart depicts the control flow within programme modules. DFDs depict the data flow in a system at various levels. DFD contains no control or branch elements. Types of Data Flow Diagram Data Flow Diagrams are classified as either logical or physical. Logical DFD - This type of DFD focuses on the system process and data flow in the system. In a banking software system, for example, how is data moved between different entities. Physical DFD - This DFD type demonstrates how the data flow is implemented in the system. It is more specific and closer to completion. Components of Data Flow Diagram Using the following components, DFD can represent the source, destination, storage, and flow of data. 8 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.1.8: Data Components Important Concepts Associated with Designing Data Flow Diagrams: Before going into the details of constructing a DFD model of a system, let us discuss some important concepts associated with DFDs. 1. Synchronous and Asynchronous operations If two bubbles are directly connected by a data flow arrow, they are synchronous. It means they run at the same rate. If two bubbles are connected via a data store, the speed of operation of the bubbles is independent. Data generated by the producer bubble is saved in the data store. Before the consumer bubble consumes any data items, the producer bubble may store them in the data store. 2. Data process Composite data items can be defined in terms of primitive data items using the following data definition operators: a. + denotes the composition of two data items, e.g. a+b represents data a and b. b. [,] represents selection, i.e. any one of the data items listed in the brackets can occur. For example, [a, b] represents either a occurs or b occurs. c. ( ) the contents inside the bracket represent optional data that may or may not appear. For example, a+(b) represents either a occurs or a+b occurs. d. { } represents iterative data definition, for example, {name}5 represents five name data. {name}* represents zero or more instances of name data. e. = represents equivalence, for example, a=b+c means that a represents b and c. f. /* */ anything appearing within /* and */ is considered as a comment. 9 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook A DFD is developed by the following steps: Fig. 1.1.9: Steps in Developing a Data Flow Diagram Levels of Data Flow Diagram a. Level 0 - It is the highest abstraction level of DFD, and it depicts the entire information system as a single diagram that conceals all the underlying details. Context level DFDs are another name for level 0 DFDs. Fig. 1.1.10: Level 0 DFD b. Level 1 - The Level 0 DFD is further subdivided into Level 1 DFD. Level 1 DFD depicts the system's basic modules as well as the data flow between them. Level 1 DFD also mentions fundamental processes and information sources. 10 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.1.11: Level 1 DFD c. Level 2 - At this level, DFD demonstrates how data flows within the modules mentioned in Level 1 at this level. Unless the desired level of specification is achieved, higher-level DFDs can be transformed into more specific lower-level DFDs with a deeper level of understanding. As previously stated, the DFD method is a component of object-oriented analysis and is widely used. The use of DFDs encourages quick and simple project code development. FDs are simple to learn due to their few simple symbols (once you decide on a particular DFD model). The syntax for designing DFDs is straightforward, relying on English nouns or noun-adjective-verb constructs. 11 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Fig. 1.1.12: Advantages of DFD Limitations of Data Flow Diagram DFDs for large systems can become clumsy, difficult to translate and read, and time-consuming to create. Data flow diagrams (DFDs) can be perplexing to programmers, but they are useless without the necessary detail. Different DFD models use various symbols (circles and rectangles, for example, for entities). 1. It makes the programmers a little confusing concerning the system. 2. The biggest drawback of the DFD is that it simply takes a long time to create, so long that the analyst may not receive support from management to complete it. 3. Physical considerations are left out. 1.1.5 Algorithm Development for Software Programming Algorithm development, debugging, and testing are typically carried out using a high-level programming tool like MATLAB or C/C++. The algorithm is ready for hardware implementation after successful algorithm development and simulations on test signals. The primary goal of detailed design is to specify the logic for the various modules described during system design. Specifying the logic will necessitate the creation of an algorithm that will carry out the given specifications. Let's look at a few design principles for creating algorithms or logic that implement the given specifications. The term "algorithm" is quite broad and covers a wide range of topics. In the context of software, an algorithm is a clear procedure for solving a problem. A procedure is a finite sequence of well-defined steps or operations, each requiring a finite amount of memory and time to complete. In this definition, we assume that procedure termination is a necessary property. We will now use the terms "procedures," "algorithms, and "logic" interchangeably. When creating an algorithm, several steps must be taken. A problem statement is the first step in the design of algorithms. The problem for which an algorithm is being designed must be stated precisely, clearly, and thoroughly by the person responsible for designing 12 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer the algorithm. The problem statement for detailed design is derived from the system design. That is, when the detailed design of a module begins, the problem statement is already available. The next step is to create a mathematical model of the problem. In modelling, the mathematical structures that are best suited to the problem must be chosen. Looking at other similar problems that have been solved can be beneficial. Most models are built by taking models from similar problems and modifying them to fit the current problem. The algorithm's design is the next step. The data structure and programme structure are decided during this step. After the algorithm has been designed, its correctness must be verified. There is no clear procedure for designing algorithms. Having such a procedure would be equivalent to automating the problem of algorithm development, which is not possible with current methods. However, some heuristics or methods can be provided to assist the designer in designing modules' algorithms. The stepwise refinement technique is the most commonly used method for designing algorithms or module logic. The stepwise refinement technique divides the logic design problem into a series of steps, allowing for gradual development. The procedure begins by converting the module specifications into an abstract description of an algorithm containing a few abstract statements. In each step, one or more statements from the previously developed algorithm are decomposed into more detailed instructions. Fig. 1.1.13: Design and Analysis of Algorithms Algorithm: An algorithm is a set of instructions, also known as a "process," that must be followed when solving a specific problem. While the term is technically not defined, it is almost always associated with computers because computer-processed algorithms can solve much larger problems much faster than humans. Because algorithms are used much more frequently in modern computing than at any other time in human history, a field has developed around their design, analysis, and refinement. A strong mathematical background is required in the field of algorithm design, with computer science degrees being particularly sought-after qualifications. It provides an increasing number of well-paying job opportunities as the demand for more (and more sophisticated) algorithms grows. Conceptual Design of Algorithm: Algorithms, at their most basic, are simply a set of instructions needed to complete a task. For all of recorded history, the development of algorithms, though they were not generally referred to as such, has been a popular hobby and a professional pursuit. People established set routines for how they 13 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook would go about their daily tasks long before the dawn of the modern computer age, often writing down lists of steps to take to accomplish important goals, reducing the risk of forgetting something important. This is, in essence, what an algorithm is. Designers approach the development of algorithms for computational purposes in the same way: they start with a problem. They then outline the steps that would be required to resolve the issue. Finally, they develop a series of mathematical operations to accomplish those steps. Algorithm Design Creating an efficient algorithm to solve a problem in the shortest amount of time and space is an important aspect of algorithm design. Different approaches can be taken to solve a problem. Some of them may be efficient in terms of time consumption, whereas others may be memory efficient. However, keep in mind that both time consumption and memory usage cannot be optimized at the same time. If we need an algorithm to run in less time, we must invest in more memory, and if we need an algorithm to run in less memory, we must invest in more time. Problem Development Steps: Fig. 1.1.14: Problem Development Steps Characteristics of Algorithms: The main characteristics of algorithms are as follows – 14 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.1.15: Characteristics of Algorithms Translation Problems of Algorithm Translators usually have to deal with six different problematic areas in their work, whether they are translating technical documents or a sworn statement. These include lexical-semantic problems; grammar; syntax; rhetoric; and pragmatic and cultural problems. Not to mention administrative issues, computer-related problems, and stress. 15 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Fig. 1.1.16: Translation Problems of Algorithm The successive refinement process ends when all instructions are precise enough to be easily converted into programming language statements. Both data and instructions must be refined during the refinement process. A rule of thumb for refinement is that the amount of decomposition in each step should be manageable and represent one or two design decisions. In general, detailed design is specified using languages that have formal programming language features like outer structures (like loops, conditionals, etc.) but a freer format for internal description. It enables the designer to concentrate on the logic rather than its representation in the programming language. Summary • • • • • A development environment, also known as an integrated development environment (IDE), provides comprehensive software development facilities to programmers by integrating a set of development tools. A computational problem is one that a computer can solve step by step. These problems typically have a well-defined input, constraints, and conditions that must be met by the output. A computational problem can be thought of as a collection of instances or cases, each with its own, possibly empty, set of solutions. There are several steps that one has to perform while developing an algorithm. The starting step in the design of algorithms is a statement of the problem. The problem for which an algorithm is being devised has to be precisely and clearly stated and properly understood by the person responsible for designing the algorithm. Algorithm development, debugging, and testing are typically accomplished with a high-level programming tool such as MATLAB or C/C++. After successful algorithm development and simulations on test signals, the algorithm is ready for hardware implementation. Appropriate Data Store: A data flow diagram shows a store as two parallel lines. A store is any type of storage for data or information and can refer to any automated database, file, or manual file system. A data flow diagram can aid a systems analyst to determine if the data store has the required input data to be processed to generate the needed output data or information. A data flow diagram can assist in determining if the data store is appropriate for the generated output information. Specific Processes: A data flow diagram shows a process, or bubble, as a circle, oval, or rectangle. A process or bubble describes a program function and data flow diagrams provide simple names and numbers to describe the specific program function. By numbering the process and keeping the process names simple, the systems analyst can easily and accurately reference the specific process. Examples of a process are: Calculate a Monthly Salary, Calculate Interest Rate, and Print a Report. 16 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Exercise Answer the Following Questions: 1. 2. 3. 4. What is the DFD? What are the Advantages and Disadvantages of DFD? Explain Algorithm Development. Explain Data Definition. MCQ Questions: 1. In a data flow diagram which among the following process is at the most detailed level? a. Data flows b. Interface c. Functional primitive d. Transform description 2. Which of the following model is used to show how data flows through a sequence of processing steps? a. Objects models b. System model c. Semantic data models d. Data flow model 3. Which of the following identifies data flow in motion? a. Circle b. Arrow c. Open-embedded box d. Square Fill in the blanks: 1. An ______________is a series of instructions, often referred to as a “process”, which is to be followed when solving a particular problem. 2. A __________________shows a process, or bubble, as a circle, oval, or rectangle. 3. Translators usually have to deal with six different problematic areas in their work, whether they are ____________________or a_________________. 17 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook UNIT 1.2: Software Development Life Cycle Unit Objectives By the end of this unit, the participants will be able to: 1. Define the Software Development Life Cycle encompassing Business Requirements Specification (BRS), Software Requirements Specification (SRS), High-Level Design (HLD), and Low-Level Design (LLD) 2. List the different techniques used for Requirements Analysis 1.2.1 Software Development Life Cycle (SDLC) The Software Development Lifecycle (SDLC) is a framework for defining the steps involved in software development. It describes the detailed plan for developing, deploying, and maintaining software. The SDLC defines the entire development cycle, which includes all tasks involved in gathering requirements for product maintenance. The goal of SDLC is to deliver a high-quality product that meets the needs of the customer. The SDLC's phases are as follows: requirement gathering, design, coding, testing, and maintenance. It is critical to follow the phases to provide the product systematically. For example, software must be developed, and a team is formed to work on a specific feature of the product while being free to do so. 1.2.2 SDLC Cycle The SDLC Cycle represents the software development process and is depicted diagrammatically below: Fig. 1.2.1: SDLC cycle 18 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 1.2.3 Business Requirements Specification (BRS) These are documents that list the business objectives that the client is attempting to achieve, as well as the key targets and performance expectations of the products or system. It also demonstrates how the client's business requirements are met on a broader level. It is known as a high-level document and is one of the most widely used and universally accepted specification documents. Typically, the Business Requirement Specification (BRS) is created at the beginning of the project life cycle. A business analyst's BRS document is typically based on the specifications of other important stakeholders who will interact with the final product following a thorough analysis of the client company. The client then goes over the final draught of the document to ensure that it meets all of the expectations of the business stakeholders. Product investors, middle and upper management, and business analysts are the primary users of BRS documents. A Business Requirement Specification (BRS) document typically includes the entire scope of the project, the performance requirements and usability, the purpose of the product, the functions of the product, the features of the product, and any other relevant information. Fig. 1.2.2: Features of Business Requirements Specification 19 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Business Requirements: Fig. 1.2.3: Business Requirements 1.2.4 Business Requirements Process This is the process of identifying, analysing, defining, and documenting the requirements for a particular business goal. And it is the process of defining the project's scope clearly and precisely to assess the timeframes and resources needed to complete it. Similar to a CONOPS, business requirements, also known as stakeholder requirements specifications (StRS), describe the characteristics of a proposed system from the perspective of the system's end user. Methods for delivering, satisfying, or meeting business requirements include products, systems, software, and processes. Fig. 1.2.4: Business Requirements Process 1.2.5 Software Requirement Specification The Software Requirements Specification (SRS) is a document that describes the main functionality and business purpose of a product, the software that is to be developed, and how the core functions of the software are to be performed. It is a summary of a project that includes the features of the technology as well as the desired business goal. The SRS document is important because it bridges the gap between what the business will get by documenting the characteristics, broad layout, and 20 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer workflows of the software being developed and what the business wants. Software Requirements Specification (SRS) serves as the basis of any project because it consists of a framework that each team member will follow. System analysts are in charge of gathering all necessary information from the relevant stakeholders. They then share the information with the other departments. The primary audience for the Software Requirement Specification is project managers (SRS). SRS contains functional and non-functional requirements. SRS provides a significant advantage in software development by reducing frustration and non-productive time. It also assists team members in working together to ensure that all requirements are met. Product Requirements Document (PRD) is another name for the Software Requirement Specification (SRS) (PRD). A proposed software that is designed to track an employee's office time is an example of a Software Requirement Specification (SRS) document. In this case, the document should include the login module, the employee module, the administrator module, and the reporting module. Fig. 1.2.5: Features of Software Requirement Specification Steps involved in SRS: 21 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Fig. 1.2.6: Steps in SRS 1.2.6 High-Level Design HLD is an abbreviation for "general system design," which refers to the overall description and architecture of the application. It describes the system architecture, database design, and a summary of systems, services, platforms, and module relationships. HLD, or high-level design, is a general design system. It is also known as system or macro-level design. A high-level design includes an overall description of the system architecture, the design of its database, and a brief description of its services, systems, platforms used, and module relationships. A solution architect creates the HLD. It essentially translates the overall client/business requirements into a high-level solution. It enters the picture before the low-level design. Fig. 1.2.7: Features of High-Level Design 22 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.2.8: Example of a High-level Design (Disruptive Architecture) (Image Source: disruptivearchitecture.info) 1.2.7 Low-level Design LLD, or low-level design, is essentially a detailed description of each module. In other words, the LLD thoroughly describes each module, including the actual logic of each system component. It goes into great detail with each system specification, earning it the moniker detailed/micro-level design. Lowlevel design is created and implemented by designers and developers. It can transform a high-level solution into a very detailed solution. As a result, the LLD comes into play only after the HLD has been designed and implemented. Fig. 1.2.9: Key Features of Low Level Design 23 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Fig. 1.2.10: Low level Design Document Sample (Image Source: enterstarcrypticcity.blogspot.com) 1.2.8 Different Techniques Used for Requirements Analysis There are different techniques used for Requirements Analysis. Below is a list of different Requirements Analysis Techniques: Fig. 1.2.11: Techniques used for Requirements Analysis 1. Business process modelling notation (BPMN) This method is similar to creating process flowcharts, though BPMN has its own symbols and elements. Graphs for business processes are created using business process modelling and notation. These graphs make it easier to understand the business process. BPMN is a well-known process improvement methodology. 24 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.2.12: Business Process Modelling Notation (BPMN) (Image Source: processmaker.com) 2. UML (Unified Modelling Language) UML is an integrated set of diagrams used to specify, visualize, build, and document the artifacts of a software system. When developing object-oriented software and working with the software development process, UML is a useful technique. UML employs graphical notations to represent the design of a software project. UML also aids in the validation of the software's architectural design. Fig. 1.2.13: UML (Unified Modelling Language) (image Source: Microsoft Support) 3. Flowchart technique A flowchart depicts the sequential flow and control logic of a group of related activities and comes in a variety of formats, including linear, cross-functional, and top-down. The flowchart can depict system interactions, data flows, and so on. Flow charts are simple to understand and can be used by members of both technical and non-technical teams. The flowchart technique is useful for highlighting the critical characteristics of a process. 25 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Fig. 1.2.14: Example of Flowchart Technique (Image Source: conceptDraw) 4. Data flow diagram This technique is used for visually representing complex and difficult-to-describe systems and processes. Data flow diagrams depict the flow of data through a process or system. It also includes the data inputs and outputs, data stores, and the various sub processes that data passes through. DFD uses standardized notations and symbols to describe different entities and their relationships. It is easier to identify flaws in a system when all of its components get visualized. These flaws are then addressed to create a strong solution. 26 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Fig. 1.2.15: Data Flow Diagram Template (Image Source: creately.com) 5. Role Activity Diagrams (RAD) A role-activity diagram (RAD) is a rule-oriented process model that represents role-activity diagrams. Role activity diagrams are a high-level view of an organization's dynamics and role structure. Roles are used for organizing activities into discrete units of responsibility. Activities are the fundamental components of a role. An activity may be performed in isolation or in conjunction with other activities within the role. Fig. 1.2.16: Role Activity Diagrams (RAD) 6. Gantt Charts Gant charts are used in project planning because they provide a visual representation of scheduled tasks as well as timelines. The Gant charts assist in determining what is scheduled to be completed by which date. All of the project's tasks' start and end dates are visible in a single view. 27 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Fig. 1.2.17: Gantt Charts 7. IDEF (Integrated Definition for Function Modelling) The integrated definition for function modelling (IDEFM) technique represents the functions of a process and their relationships to child and parent systems with the help of a box. It provides a blueprint to gain an understanding of an organization’s system. Fig. 1.2.18: IDEF (Image Link: japaneseclass.jp) 28 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 8. Gap Analysis Gap analysis is a technique that helps to analyse the gaps in the performance of a software application to determine whether the business requirements are met or not. It also involves the steps that are to be taken to ensure that all the business requirements are met successfully. Gap denotes the difference between the present state and the target state. Gap analysis is also known as need analysis, need assessment or need-gap analysis. Gap Analysis Process: Fig. 1.2.19: Gap Analysis Process Fig. 1.2.20: Gap Analysis (Image Source: Template Lab) 29 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Summary • • • • • • • • Software Development Lifecycle (SDLC) is a framework that defines the steps involved in the development of software. It covers the detailed plan for building, deploying, and maintaining the software. SDLC defines the complete cycle of development i.e. all the tasks involved in gathering a requirement for the maintenance of a Product. The business analyst and Project Manager set up a meeting with the customer to gather all the information like what the customer wants to build, who will be the end-user, and what is the purpose of the product. Before building a product a core understanding or knowledge of the product is very important. the requirement gathered in the SRS document is used as an input, and the software architecture that is used for implementing system development is derived. In the case of UAT, a replica of the production environment is created and the customer along with the developers does the testing. If the customer finds the application as expected, then sign-off is provided by the customer to go live. Testing starts once the coding is complete and the modules are released for testing. In this phase, the developed software is tested thoroughly and any defects found are assigned to developers to get fixed. The low-level design, abbreviated as LLD, is essentially a detailed description of each module. In other words, the LLD describes each module in detail by including the actual logic of each system component. High-Level Design (HLD) is an abbreviation for general system design, which refers to the overall system design. It describes the application's overall description/architecture. It describes the system architecture, database design, and brief description of systems, services, platforms. Exercise Answer the Following Questions: 1. Differentiate between low-level Design and High-level Design. 2. Describe Software Requirements Specifications. 3. What are the business requirements in BRS? Fill in the blanks: 1. ____________________is a technique that helps to analyse the gaps in the performance of a software application to determine whether the business requirements are met or not. 2. The _________________________technique represents the functions of a process and their relationships to child and parent systems with the help of a box. 3. Flowcharts are in different formats such as_________, _____________, and___________________. MCQ Questions: 1. What is the first step in the software development lifecycle? a. System Design b. Coding 30 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer c. System Testing d. Preliminary Investigation and Analysis 2. Which of the following is involved in the system planning and designing phase of the Software Development Life Cycle (SDLC)? a. Sizingb. Parallel run c. Specification freeze d. All of the above 3. Which of the following prototypes does not associated with Prototyping Model? a. Domain Prototype b. Vertical Prototype c. Horizontal Prototype 31 d. Diagonal Prototype Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook UNIT 1.3: Elements for Measuring Software Development Process Unit Objectives By the end of this unit, the participants will be able to: 1. Classify elements for measuring various aspects of the software development process 1.3.1 Software Development Process The set of instructions in the form of programs that govern the computer system and process the hardware components is referred to as software. A set of activities is used to create a software product. This collection is known as a software process. Designing, programming, documenting, testing, and bug fixing are all part of the software development process. Software Components: There are three software components: There are three of them: programme, documentation, and operating procedures. Fig. 1.3.1: Software Components The following figure explains four basic key process activities in software development process. Fig. 1.3.2: Fig 4.22 Key Process Activities 32 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer The following figure explains the software crisis: Fig. 1.3.3: Software Crisis 1.3.2 Software Development Process A software metric is a measurable or countable measure of software characteristics. Software metrics are useful for a variety of purposes, including measuring software performance, planning work items, calculating productivity, and many others. Many metrics are associated with the software development process. Software metrics are analogous to the four management functions: planning, organization, control, and improvement. Software metrics are divided into two categories: 1. Product Metrics: These are measurements of various aspects of the software product. The following are the two most important software characteristics: a. Size and complexity b. Quality and reliability These metrics can be computed at various stages of the SDLC. 2. Process Metrics: These are measurements of various aspects of the software development process. Consider the effectiveness of fault detection. They are used to assess the characteristics of software development methods, techniques, and tools. 33 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Fig. 1.3.4: Software Metrix (Image source: https://www.javatpoint.com/software-engineering-software-metrics) Summary • • • • • • • • • The set of instructions in the form of programs that govern the computer system and process the hardware components is referred to as software. A set of activities is used to create a software product. This collection is known as a software process. Designing, programming, documenting, testing, and bug fixing are all part of the software development process. Software Components: There are three software components: There are three of them: program, documentation, and operating procedures. A computer program is a list of instructions that tell a computer what to do. Source information about the product is contained in design documents, detailed code comments, etc. Software Specifications – A detailed description of a software system to be developed, including functional and non-functional requirements, is provided in this process. Software Development – In this process, designing, programming, documenting, testing, and bug fixing are done. Software Validation – This process involves evaluating software products to ensure that they meet both business and end-user requirements. Software Evolution – Software evolution is the process of creating software and then updating it on a regular basis for various reasons. A software metric is a measurable or countable measure of software characteristics. Software metrics are useful for a variety of purposes, including measuring software performance, planning work items, calculating productivity, and many others. 34 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Exercise Answer the Following Questions: 1. Describe the Waterfall Model. 2. What is Software Process Model? 3. What is Software Development Process? Fill in the blanks: 1. _______________, _______________, _________________, _____________, and ____________________are all part of the software development process. 2. _________________is a continuous process of software development, and it occurs concurrently with development. 3. The first step to any process is always ________. 4. The _______________________process divides software development into tiny, sequential steps in order to improve the product, project, and design as a whole. 5. _________________refers to the iterative logical process of developing software programs or applications to meet the needs of any business or personal objectives. 35 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Notes __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ 36 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3. Develop, Test and Execute Software Programs as per Specifications using Python Unit 3.1 - Introduction to Python Unit 3.2 - Introduction to Data Structures and Databases Unit 3.3 - Core Python Concepts Unit 3.4 - Testing and Execution 37 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime SSC/N0511 Participant Handbook Key Learning Outcomes By the end of this module, the participants will be able to: 1. Understand the basics of Python programming. 38 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer UNIT 3.1: Introduction to Python Unit Objectives By the end of this unit, the participants will be able to: 1. 2. 3. 4. 5. 6. 7. 8. 9. Outline the evolution of programming languages Distinguish between imperative and declarative programming paradigms List the features of object-oriented programming: Class, Object, Encapsulation, Abstraction, etc. Describe the features of Python as programming language Outline the terminology used in Python programming such as interpreter, lambda, loader, method, etc. Explain how Python can act as both compiled and interpreted language List the tools used for programming in Python such as IDLE, Jupyter etc. Demonstrate the elements of imperative programming such as variables, flow control and functions Familiarize with the platforms used for Python programming (e.g., IDLE and Jupyter) 3.1.1 Outline the evolution of programming languages Guido van Rossum is the person responsible for developing Python. In 1989, Guido van Rossum began the process of implementing Python. Python is a pretty straightforward programming language, so even if you have no prior experience with computer programming, you shouldn't have any trouble picking it up. It's an interesting fact that the language Python got its name from the British comedy series Monty Python's Flying Circus. There is no connection to the Python snake in its naming. Python's programming language's defining characteristics 1. Readable: Python is a language that is known for being very easy to read. 2. Simple to Learn Python is an expressive and high-level programming language, which means that the language itself is simple to understand, making it simple to learn as well. This makes learning Python a simple process. 39 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 3. Python is compatible with a wide variety of platforms and operating systems, including but not limited to Mac OS X, Microsoft Windows, Linux, and Unix. Because of this, it is compatible with other platforms and can be easily transported. 4. Open Source: Python is a programming language that is available under an open source license. 5. Python comes with a huge standard library that contains some useful codes and functions that may be used while writing code in Python. This is one of the features that makes Python such a popular programming language. 6. No cost: both the download and the use of Python are completely free. This means that you are able to utilise it in your application and download it for free to do so. See the Open Source Python License for more information. Python is an example of a Free/Libre Open Source Software (which stands for "Free/Libre Open Source Software"), which indicates that you are free to view its source code, alter it, and distribute copies of this software. 7. Allows for the management of exceptions If you are just starting out, you might be wondering what an exception is. An occurrence that can occur during a program exception is referred to as an exception, and it can impede the typical flow of the program. Python supports exception handling which means we can write less error prone code and can test various scenarios that can cause an exception later on. 8. Support for generators and list comprehensions is included in the list of advanced features. These characteristics will be discussed at a later time. 9. Support for automated memory management Python is equipped with support for automatic memory management, which indicates that the memory can be automatically cleared and freed. It is not necessary for you to clear the memory at this time. What Can You Do with Python? It's possible that you're curious about the several ways Python can be put to use. Python has an extremely wide range of potential applications; the following are just a few of them. 1. Web development — Python is the foundation for many web frameworks, including Django and Flask. They assist you in writing server-side code, which in turn assists you in managing databases, writing backend programming logic, mapping urls, and other similar tasks. 2. Machine learning - Python has been used to create a great deal of software that can be used for machine learning. The process of writing a logic in such a way that a computer can learn and solve a specific problem on its own is referred to as machine learning. For instance, the product recommendations found on websites such as Amazon, Flipkart, and eBay are generated by an algorithm that uses machine learning to identify the user's areas of interest. The ability of your smartphone to recognise your face and voice is another illustration of machine learning at action. 3. Data Analysis Python may be used to construct not only methods for data analysis but also methods for data visualisation in the form of charts. 4. Scripting — Writing small programs to automate simple tasks, such as sending automated answer emails, is an example of scripting. Scripting refers to the practise of scripting. The computer language Python is likewise capable of being used to write apps of this kind. 5. Game development - Python can be used to program game development. 6. Python can be used to construct programs that are embedded. 7. Desktop apps You can use Python to construct desktop programs, and you can use libraries such as TKinter or QT to do so. 40 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.1.2 Difference between Imperative and Declarative Programming You might think of a programming paradigm as an approach to problem-solving that makes use of a particular programming language; alternatively, you could say that it is a strategy for problem-solving that makes use of the tools and techniques that are accessible to us and that follows some methodology. There are a great number of known programming languages, but in order to be implemented, each of these languages must adhere to a particular methodology or strategy, and the term "paradigm" refers to this methodology or approach. In addition to the many different programming languages, there are also many different paradigms to choose from to satisfy any requirement. Fig. 3.1.1: programming paradigms As its name suggests, imperative programming is a form of programming paradigm that explains how the program is carried out in its various iterations. The process of arriving at a solution step by step is of more interest to developers. It includes the rundown of command imperatives in sequential order. When it comes to this, the order of execution is quite significant, and it makes use of mutable as well as immutable data. Examples of languages that use the imperative programming style include Fortran, Java, C, and C++. Declarative programming is a form of programming paradigm that, as the name suggests, defines what programs are going to be run. The response that is obtained is of the utmost importance to the developers. It makes the desired outcomes explicit while leaving the specifics of the programming language in the background so that the focus can remain on the production of the outcomes themselves. To put it another way, the main emphasis is placed on the final product. It is an expression of the logic that underlies computation. The programming languages Miranda, Erlang, Haskell, and Prolog are only a few examples of popular declarative languages. After obtaining a foundational understanding of both languages, the next step is to compare and contrast the primary distinctions that exist between these two distinct forms of programming. Imperative Programming 1. In this, programs specify how it is to be done. 2. It simply describes the control flow of computation. 3. Its main goal is to describe how to get it or accomplish it. 4. Its advantages include ease to learn and read, the notional model is simple to understand, etc. Declarative aprogramming 1. In this, programs specify what is to be done. 2. It simply expresses the logic of computation. 3. Its main goal is to describe the desired result without direct dictation on how to get it. 4. Its advantages include effective code, which can be applied by using ways, easy extension, high level of abstraction, etc. 41 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Imperative Programming 4. Its type includes procedural programming, object-oriented programming, parallel processing approach. 5. In this, the user is allowed to make decisions and commands to the compiler. 6. It has many side effects and includes mutable variables as compared to declarative programming. 7. It gives full control to developers that are very important in low-level programming. Declarative aprogramming 5. Its type includes logic programming and functional programming. 6. In this, a compiler is allowed to make decisions. 7. It has no side effects and does not include any mutable variables as compared to imperative programming. 8. It may automate repetitive flow along with simplifying code structure. 3.1.3 Features of OOPs Object-oriented programming, abbreviated as OOPs, is a programming paradigm that makes use of both classes and objects while writing code in the Python programming language. Programmatically incorporating real-world concepts such as inheritance, polymorphism, encapsulation, and so on is the goal of this initiative. The primary idea behind OOPs is to tie the data and the functions that work on that together as a single unit, so that no other portion of the code can access this data. This prevents the data from being accessed in error. Main Concepts of Object-Oriented Programming (OOPs) • • • • • • Class Objects Polymorphism Encapsulation Inheritance Data Abstraction Fig. 3.1.2: OOPS features 42 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Class A group of individual items is known as a class. A class is the repository for the blueprints or the prototype that serve as the basis for the creation of things. It is a logical entity that holds a few methods and attributes within its framework. To further understand why it is necessary to create a class, let's look at an example: suppose you needed to keep track of the number of dogs, each of which could have distinctive characteristics such as breed and age. In the event that a list is utilised, the first item on the list might represent the breed of the dog, while the second item might stand for the dog's age. Let's say there are a hundred distinct kinds of dogs; how would you determine which of the elements is intended to be which of them? What would happen if you wanted to give these dogs more characteristics? Because of this, classes are required because there is a lack of organization. A few notes on the Python class: The word "class" is what's used to establish new classes. Variables that are part of a class are referred to as its attributes. The dot operator (.) can be used to gain access to attributes, which are by definition open to the public. For example: "Myclass." "Myattribute." Class Definition Syntax: class ClassName: # Statement-1 . . . # Statement-N Example: Creating an empty Class in Python # Python3 program to # demonstrate defining # a clas class Dog: pass Objects The object is an entity that is associated with a state as well as action on its own own. It might be anything from the actual world, like a mouse, keyboard, chair, table, pen, or anything else. Objects can have several forms, including integers, texts, floating-point numbers, and even arrays and dictionaries. To provide further clarification, an object can be any single integer or any single string. One example 43 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook of an object is the number 12, another example is the string "Hello, world," another example is a list, which is an object that can include other objects, and so on. You may not even be aware that you've been making use of items this whole time. A object is made up of the following: • • • The attributes of an object are what are used to represent the state of the object. In addition to this, it represents the characteristics of the thing. The behaviour of an object is exemplified by the techniques that it possesses. It also represents how a thing reacts when it comes into contact with other objects. Identity is the process of assigning a one-of-a-kind name to an object and enabling that thing to communicate with other similar objects. Take the example of the class dog to better comprehend the state, behaviour, and identification of the situation (explained above). • • • The identification may be thought of as the dog's name in some contexts. The dog's breed, its age, or its coat colour are all examples of states or attributes that can be examined. The dog's actions can be interpreted as either a sign that it is eating or that it is sleeping. Example: Making something from nothing obj = Dog() Inheritance Inheritance refers to the ability of one class to derive its attributes from those of another class, often known as inheriting those properties. The class that derives properties is referred to as the "derived class" or the "child class," while the class that derives properties from another class is referred to as the "base class" or the "parent class." The following are some of the advantages of inheriting: • • • It does a good job at representing relationships in real life. It allows for the code to be used in multiple places. It is not necessary for us to rewrite the same code over and over again. Additionally, it enables us to extend the functionality of a class without having to edit the class itself. It is of a transitive nature, which means that if one class B inherits properties from another class A, then all of class B's subclasses will necessarily inherit those same properties from class A. Inheritance in Its Many Forms – Inheritance Received Only Once: A derived class is able to inherit properties from a single-parent class when using the single- level inheritance inheritance technique. Inheritance at Multiple Levels Using multi-level inheritance, a derived class is able to inherit properties from an immediate parent class, which then inherits properties from its own parent class. This process continues until all properties are inherited. Inheritance at the Hierarchical Level Inheritance at the hierarchical level allows for several derived classes to inherit properties from a single parent class. Multiple inheritance is a type of inheritance that allows one derived class to inherit properties from more than one source class. Multiple level inheritance is a type of multiple inheritance. 44 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Python code demonstrating inheritance as an example class Person(object): self.idnumber =idnumber #init is known as the constructor def init (self, name, idnumber): self.name = name def display(self): print(self.name) print(self.idnumber) def details(self): print("My name is {}".format(self.name)) print("IdNumber: {}".format(self.idnumber)) # child class class Employee(Person): def init (self, name, idnumber, salary, post): self.salary = salary self.post = post # invoking the init of the parent class Person. init (self, name, idnumber) def details(self): print("My name is {}".format(self.name)) print("IdNumber: {}".format(self.idnumber)) print("Post: {}".format(self.post)) # creation of an object variable or an instance a = Employee('Rahul', 886012, 200000, "Intern") # calling a function of the class Person using # its instance a.display() a.details() Output Rahul 886012 My name is Rahul IdNumber: 886012 Post: Intern Polymorphism Having multiple distinct forms is what is meant by the term polymorphism. For instance, we need to figure out whether or not the particular species of birds can fly, and because to polymorphism, we can accomplish this goal with just a single function. 45 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example for Polymorphism class Bird: def intro(self): print("There are many types of birds.") def flight(self): print("Most of the birds can fly but some cannot.") class sparrow(Bird): def flight(self): print("Sparrows can fly.") class ostrich(Bird): def flight(self): print("Ostriches cannot fly.") obj_bird = Bird() obj_spr = sparrow() obj_ost = ostrich() obj_bird.intro() obj_bird.flight() obj_spr.intro() obj_spr.flight() obj_ost.intro() obj_ost.flight() Output There are many types of birds. Most of the birds can fly but some cannot. There are many types of birds. Sparrows can fly. There are many types of birds. Ostriches cannot fly. Encapsulation Encapsulation is a key notion in object-oriented programming, which is one of the most prevalent programming paradigms today (OOP). It explains the concept of enclosing both the data and the procedures that operate on the data within a single unit. This places limits on directly accessing methods and variables, which helps avoid the unintentional change of data. Only the object's method is able to make changes to the object's variables; this is done to prevent unintentional changes. These particular 46 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer variables fall under the category of "private variables." Encapsulation can be illustrated by the way in which a class stores all of the information that pertains to its member functions, variables, and so on. Example: Encapsulation in Python # demonstrate private members # Creating a Base class class Base: def init (self): self.a = "your Author" self. c = "Your Author" # Creating a derived class class Derived(Base): def init (self): # Calling constructor of # Base class Base. init(self) print("Calling private member of base class: ") print(self. c) # Driver code obj1 = Base() print(obj1.a) # Uncommenting print(obj1.c) will # raise an Attribute Error # Uncommenting obj2 = Derived() will # also raise an AtrributeError as # private member of base class # is called inside derived class Output: Your Author Data Abstraction It conceals from the user the specifics of the code that are not necessary. In addition, there are times when we do not wish to reveal private aspects of the implementation of our code, and it was for these situations that data abstraction was developed. Creating abstract classes in Python is one way to achieve data abstraction in the programming language. 3.1.4 Features of Python • • • Compared to other programming languages, it allows for more run-time flexibility It includes the basic text manipulation facilities of Perl and Awk It offers rich data types and syntax that is easier to read than any other programming language 47 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook • • • • • • • • It is a platform-independent scripting language that has full access to operating system APIs It is a scripting language that is a platform independent scripted language Python programs can have a module that contains one or more free classes and functions. Python libraries are cross-platform compatible with Linux, Macintosh, and Windows. Python can be compiled to byte code for the purpose of building large applications; Python supports functional and structured programming in addition to object-oriented programming. Python supports interactive mode, which enables users to interact with programs; and Testing and debugging of individual pieces of code Since there is no compilation process in Python, editing, testing, and debugging are all performed very quickly in this programming language 3.1.5 Terminology used in Python Programming Python Interpreter Every high level programming language is either a compiler-executed or an interpreter-based programming language. That means, the source code written by the developers is either interpreted or compiled. Compiler executes the whole program at a time while the interpreter executes instructions line by line. In this article, we will talk about Python interpreter and its working along with some secrets that a lot of Python developers are also not familiar with. Python was created by Guido van Rossum and is a type of interpreted programming language. We refer to it as an interpreted programming language due to the fact that it carries out each Python-based instruction one line at a time. It is able to comprehend Python's syntaxes as well as the tokens that are written in a high- level language and can render the information computer-comprehensible. Python, in contrast to functional programming languages, uses code modules, which are convertible, rather than a single extensive list of code. This allows Python to work with both types of languages. "CPython" is the name of the traditionally used version of Python. Python has two different ways of interpreting the code that is written in it. The script mode and the interactive mode both have a Python prompt. The interactive mode is one way to use Python. The script mode is the other way. Python Lambda Functions An anonymous function in Python is referred to as a Lambda Function. This indicates that the function does not have a name. As is already common knowledge, the def keyword in Python is what's required to define a typical function. In a similar manner, the lambda keyword in Python is what's used to define an anonymous function. The Lambda Function Syntax in Python • Syntax: lambda arguments: expression This function can take an arbitrary number of arguments, but it only evaluates and returns the results of a single expression. 48 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Lambda functions can be used in place of function objects in any situation where the latter is needed. Lambda functions are syntactically limited to a single expression, which is something you need to keep in mind at all times. In addition to the uses for other types of expressions in functions, it also has a number of uses in particular areas of programming. Example: str1 = 'Author' # lambda returns a function object rev_upper = lambda string: string.upper()[::-1] print(rev_upper(str1)) Output: ROHTUA Python Loader Importing a dataset into Open Spending can be done with the help of a loader. In order to populate the database with Entry, Entity, and Classifier entries, these loaders make use of one or more dataset sources. You are free to make use of anything that Python is able to read, such as csv, json, xls, or xml files. Helper functions that read data directly from Google Docs are also provided by us. Methods in Python Python is a wonderful programming language, but learning it can be challenging for beginners. Before we can move on to developing more varied and comprehensive applications in the realm of data science, we must first understand the fundamentals of the Python programming language, just as we would with any spoken language. Here's the deal: if you master the fundamentals first, learning Python will be a piece of cake for you. It is essential, however, to devote a significant portion of the time allotted for initial instruction to becoming acquainted with the capabilities that Python possesses. It will end up being well worth it in the long run! Python is, without a doubt, what's known as an Object-Oriented Programming (OOP) language. This is a broad idea, and it is not possible to completely understand it all at once. In point of fact, becoming an expert in OOP may take several months or even years. Your capacity for comprehension is the sole determining factor in this matter. I strongly suggest beginning with a read through of the article I wrote previously on the "Basic concepts of Object-Oriented Programming." The idea of methods in object-oriented programming will be developed further in the following section of this particular article. In this lesson, we will discuss the various kinds of Methods that can be found in Python. This article will provide a comprehensive discussion of Python methods and their various types. If you are unfamiliar with OOP, you may find that python Methods are sometimes difficult to understand. After that, we will examine some real- world applications of these methodologies. 49 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Objects are an essential part of Object-Oriented Programming (please cue the drum roll). These objects are made up of their properties and the behaviours they exhibit. In addition, the behaviour of the object is specified by its methods, while its attributes are responsible for defining its properties. These methods are defined within a class's structure. These methods are the reusable chunks of code that can be activated or called at any time during the course of the program. There are many variations of these methods available in Python. These are essential to achieving success as a programmer, and as a result, they are beneficial for a data science professional. 3.1.6 Python as both compiled and interpreted language It is mentioned in a number of books on Python programming that the Python language is interpreted in these books. But you're only partially right; a Python program is compiled first, and then it's interpreted after that. As a result of the fact that the programmer is shielded from the compilation process, a large number of programmers are under the impression that the language can only be interpreted. When we execute our code, the compilation process is carried out initially. This results in the generation of byte code, which is then converted internally by the Python virtual machine (p.v.m) in accordance with the underlying platform (machine plus operating system). Now, the question that needs to be answered is whether there is any evidence that Python first compiles the program on its own and then runs the code through an interpreter. The answer is yes to both! It is important to keep in mind that Python will delete this compiled part as soon as your code is executed because the language does not want programmers to get into complexity. Example Code: print("i am learning python") print("i am enjoying it") Now, if you want to execute this code using the command prompt, simply save this above code in notepad and save it with the extension ".py." The syntax for this is: python (name of the program.py) and press enter. Note: If you are writing code in notepad, simply save the code with the extension "py." Assume that you have created a folder on your hard drive labelled "python prog." as you press enter the byte code will get generated. A folder created and this will contain the byte code of your program. This folder is in the python_prog folder where you will save your python codes. now to run the compiled byte code just type the following command in the command prompt:- 50 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer the extension .pyc is python compiler. Thus, it is proven that python programs are both compiled as well as interpreted!! but the compilation part is hidden from the programmer. Exercise Answer the following questions: 1. Python is a ___object-oriented programming language. a) Special purpose b) General purpose c) Medium level programming language d) All of the mentioned above 2. Amongst the following, who is the developer of Python programming? a) Guido van Rossum b) Denis Ritchie c) Y.C. Khenderakar d) None of the mentioned above 3. Amongst which of the following is / are the application areas of Python programming? a) Web Development b) Game Development c) Artificial Intelligence and Machine Learning d) All of the mentioned above 4. Amongst which of the following is / are the Numeric Types of Data Types? a) intb) float c) complex d) All of the mentioned above 5. list, tuple, and range are the ___ of Data Types. a) Sequence Types c) Boolean Types b) Binary Types d) None of the mentioned above 6. Float type of data type is represented by the float class. a) Trueb) False 7. bytes, bytearray, memoryview are type of the ___ data type. a) Mapping Type b) Boolean Type c) Binary Types d) None of the mentioned above 8. The type() function can be used to get the data type of any object. a) Trueb) False 9. Binary data type is a fixed-width string of length bytes? a) Trueb) False 51 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 10. Varbinary data type returns variable-width string up to a length of max-length bytes? a) TRUEb) FALSE 3.1.7 Tools used for programming in Python 1. PyCharm IDE As an integrated development environment (IDE), PyCharm provides user-friendly features such as auto-completion, hints, PEP8 checks, and other ways to improve code quality. You can rely on it for a variety of features, including intelligent automated code refactoring, testing assistance, and code inspections, among others. PyCharm provides support for a variety of well-known frameworks, including Django, Flask, web2py, and others. Each of the built-in database and developer tools for debugging and profiling in the integrated development environment (IDE) integrates effortlessly with Visual Studio Code to provide additional functionality. The scientific computation capabilities can be expanded using the NumPy and Matplotlib library integrations. Facilities for integrated testing, cross-technology interoperability, and remote development are included in PyCharm, which rounds out the overall feature set of this integrated development environment (IDE). 2. Jupyter Notebook Jupyter Notebook provides you with everything you could possibly require for interactive development, documentation, and the execution of code. Authoring documents can be done through a console-based system that is included with the Notebook. 52 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer To begin, it gives you access to a web application component that runs in your browser and combines elements of mathematics, computations, rich media, and explanations in text form. Second, it is able to list the inputs and outputs that are used in calculations, in addition to rich-media enhanced objects and other content that is pertinent to the calculation. This feature makes it easier for you to edit code by enabling in-browser inspections and automatically highlighting committed syntax changes. Jupyter also gives you the ability to control indentation and tab completion. The code commentary function of this tool is implemented using the Markdown markup language, which is not restricted to plain-text only. You are able to insert mathematical notations within markdown cells and have them rendered natively by MathJax thanks to the LaTeX integration that Jupyter provides. 3. Keras Keras is a high-level API library for neural networks that is driving machine learning and deep learning projects in Python. Keras makes it possible for you to extend the ecosystem of the AI neural network programming you do in Python to include back-ends such as TensorFlow, Microsoft Cognitive Toolkit, PlaidML, Theano, and a great many others. You'll have a much easier time debugging your code thanks to the comprehensive and actionable error messages that Keras generates for you. Given its ability to mesh with a wide variety of infrastructural configurations—whether it be a GPU cluster or an entire TPU pod— the deep learning framework is adaptable to a wide variety of workflow use cases, allowing you to use it for a wide range of work processes. Deep learning experts can lessen their machine learning cognitive load by integrating Keras into their workflow. Because of its user-friendliness, extensibility, and modular programming approach, the open-source library has attracted a significant number of users. 4. Pip Package The Pip Package Manager is the default package manager for Python, and it is included as part of every installation of Python. Pip makes it possible for you to use packages that are stored in other local or remote repositories, provided that these repositories comply with Python Enhancement Proposal 503. Pip is responsible for managing comprehensive package lists along with the corresponding package version numbers. It helps you catalogue the same packages for a different desktop or virtual environment by recording the management of your packages in a requirements file and logging it there. 53 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Pip continues to be a dependable and easily accessible package manager that is well suited for both basic and advanced package library management. Despite this, a significant number of developers and teams rely on third-party package management solutions such as PyPL, despite the fact that Pip is available with Python 3 and its subsequent versions. 5. Python Anywhere Python Anywhere has a well-deserved reputation for dependability, having proven itself capable of meeting end-to-end SDLC requirements. Using this Platform as a Service (PaaS), you are able to build, run, and host Python programs on the internet.Directly from your web browser, you are able to commit changes and deploy automated updates thanks to the Python NumPy, SciPy, Mechanize, and BeautifulSoup libraries that are built-in to the platform. Python Anywhere makes it easier for you to rapidly deploy your codebase on servers based on Amazon Web Services EC2. Decentralized hosting makes it possible to conduct Python- based research, study, and development remotely. 6. Scikit-Learn The open-source library provided by Scikit-Learn is standing by and prepared to assist you with your Python-scripted machine learning endeavours. The tools for predictive analysis that are included in Scikit help to speed up the object classification process, provide assistance with continuous-valued attribute prediction and regression, clustering of support-vector machines, gradient boosting, random forests, and automatic grouping of objects that are similar to one another. For more advanced machine learning analyses, Scikit provides you with advanced ML tools such as dimensionality reduction and model selection. It is constructed on the Matplotlib, NumPy, and SciPy libraries, all of which are ideal for use in any bespoke machine learning environment. 7. Sphinx Another Python documentation option that can be considered a suitable replacement for Jupyter Notebook is called Sphinx. It can generate highly articulate Python documentation in a variety of formats, including HTML, LaTeX, and ePub. In addition, Sphinx can assist you in the establishment of automatic, language-specific indices and testing for code snippets. In addition to the built-in docstrings libraries, Sphinx comes pre-packaged with a number of third-party extensions. 54 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Exercise Answer the following questions: 1. Amongst which of the following is / are the logical operators in Python? a) andb) or c) not d) All of the mentioned above 2. Is Python supports exception handling? a) Yesb) No 3. What is the name of the operator ** in Python? a) Exponentiationb) Modulus c) Floor division d) None of the mentioned above 4. The % operator returns the ___. a) Quotientb) Divisor c) Remainder d) None of the mentioned above 5. Amongst which of the following is / are the method of list? a) append()b) extend() c) insert() d) All of the mentioned above 3.1.8 Elements of imperative programming A quick rundown of Python's four primary programming paradigms 1. Functional programming treats every statement as if it were a mathematical equation, and it avoids any forms of state and data that can be changed. The fact that there is no need to take the current state of the system into account is the approach's primary strength, which makes it suitable for parallel processing. When it comes to recursion and lambda calculus, this style of coding is preferred by many developers. (It is important to keep in mind that Python's implementation of functional programming deviates from the standard—that is, it is impure—due to the fact that it is possible to preserve state and introduce side effects if you are not cautious.) Haskell is a possible superior option to consider using if you require an implementation of purely functional programming. 2. Imperative means that the computation is carried out as a direct modification to the state of the program. This style creates code that is both elegant and easy to understand, making it particularly suitable for the manipulation of data structures. Python provides a complete implementation of this paradigm. 3. Object-oriented: relies on data fields that are handled as if they were objects and can only be manipulated using the methods that have been specified. Python is not capable of providing complete support for this paradigm due to the fact that it is unable to implement features such as data hiding (encapsulation), which is considered by many to be an essential prerequisite of the object-oriented programming paradigm. Reusing existing code is encouraged by this particular coding style. 4. Tasks are handled like step-by-step iterations, and typical tasks are stored in functions that are run whenever they are required. This is referred to as a procedural approach. Iteration, sequencing, 55 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook selection, and modularization are some of the coding techniques that benefit from this style. Python does exceptionally well when it comes to implementing this particular paradigm. Four styles, one example my_list = [1, 2, 3, 4, 5] 1. Using the functional coding style The approach to programming known as functional coding views everything as an equation. Utilizing a local function or a lambda expression would be the two methods that are used most frequently when attempting to compute the total of my list. The following is an example of how you could accomplish this using a local function in Python 3.10: import functools my_list = [1, 2, 3, 4, 5] def add_it(x, y): return (x + y) sum = functools.reduce(add_it, my_list) print(sum) Access to higher-order functions that can be used for manipulating data is provided via the functools package. On the other hand, you don't always have to use it in order to carry out functional programming with Python. A straightforward illustration of the use of my list in conjunction with a lambda function is as follows: square = lambda x: x**2 double = lambda x: x + x print(list(map(square, my_list))) print(list(map(double, my_list))) As can be seen, the lambda expression is more straightforward (or at the very least, shorter) compared to a comparable procedural method. The following is a lambda function representation of the call to functools.reduce(): import functools my_list = [1, 2, 3, 4, 5] sum = functools.reduce(lambda x, y: x + y, my_list) print(sum) 2. Using the imperative coding style As can be seen, the lambda expression is more straightforward (or at the very least, shorter) compared to a comparable procedural method. The following is a lambda function representation of the call to functools.reduce(): sum = 0 for x in my_list: sum += x print(sum) In contrast to the examples that came before it, the value of total shifts with each new iteration of the loop. As a result, sum has state. If a variable has state, then something else must keep that state, which indicates that the variable is connected to a particular processor. Imperative programming works for applications that are relatively straightforward, but the execution speed of the code is too sluggish to produce ideal results on applications that include extensive data science. 56 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3. Using the object-oriented coding style Increasing an application's capacity to reuse code and making that code simpler to understand are the two primary goals of object-oriented programming (OOP). Developers are able to treat the code they write as a "black box" thanks to the encapsulation that object-orientation. Introduction Data, Expressions, Statements Introduction to Python and installation, variables, expressions, statements, Numeric data types: Int, float, Boolean, string. Basic data types: list--- list operations, list slices, list methods, list loop, mutability, aliasing, cloning lists, list parameters. Tuple --- tuple assignment, tuple as return value, tuple methods. Dictionaries: operations and methods. Introduction to Python and installation: Python is a widely used general-purpose, high level programming language. It was initially designed by Guido van Rossum in 1991 and developed by Python Software Foundation. It was mainly developed for emphasis on code readability, and its syntax allows programmers to express concepts in fewer lines of code. Python is a programming language that lets you work quickly and integrate systems more efficiently. There are two major Python versions- Python 2 and Python 3. • • On 16 October 2000, Python 2.0 was released with many new features. On 3rd December 2008, Python 3.0 was released with more testing and includes new features. Beginning with Python programming: Finding an Interpreter: Before we start Python programming, we need to have an interpreter to interpret and run our programs. There are certain online interpreters like https://ide.geeksforgeeks.org/, http://ideone. com/ or http://codepad.org/ that can be used to start Python without installing an interpreter. Windows: There are many interpreters available freely to run Python scripts like IDLE (Integrated Development Environment) which is installed when you install the python software from http:// python.org/downloads/ Writing first program: # Script Begins • • • • Statement1 Statement2 Statement3 # Script Ends 57 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Why to use Python: The following are the primary factors to use python in day-to-day life: 1. Python is object-oriented • Structure supports such concepts as polymorphism, operation overloading and multiple inheritance. • Indentation: Indentation is one of the greatest feature in python • It‟s free (open source) • Downloading python and installing python is free and easy • It‟s Powerful • Dynamic typing • Built-in types and tools • Library utilities • Third party utilities (e.g. Numeric, NumPy, sciPy) • Automatic memory management • It‟s Portable • Python runs virtually every major platform used today • As long as you have a compaitable python interpreter installed, python programs will run in exactly the same manner, irrespective of platform. • It‟s easy to use and learn • No intermediate compile • Python Programs are compiled automatically to an intermediate form called byte code, which the interpreter then reads. This gives python the development speed of an interpreter without the performance loss inherent in purely interpreted languages. • Structure and syntax are pretty intuitive and easy to grasp. • Interpreted Language • Python is processed at runtime by python Interpreter • Interactive Programming Language • Users can interact with the python interpreter directly for writing the programs • Straight forward syntax • The formation of python syntax is simple and straight forward which also makes it popular. Installation: There are many interpreters available freely to run Python scripts like IDLE (Integrated Development Environment) which is installed when you install the python software from http://python.org/ downloads/ Steps to be followed and remembered: Step 1: Select Version of Python to Install. Step 2: Download Python Executable Installer. Step 3: Run Executable Installer. Step 4: Verify Python Was Installed On Windows. 58 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Step 5: Verify Pip Was Installed. Step 6: Add Python Path to Environment Variables (Optional) Working with Python Python Code Execution: Python‟s traditional runtime execution model: Source code you type is translated to byte code, which is then run by the Python Virtual Machine (PVM). Your code is automatically compiled, but then it is interpreted. Source code extension is .py Byte code extension is .pyc (Compiled python code) There are two modes for using the Python interpreter: • • Interactive Mode Script Mode Running Python in interactive mode: Without passing python script file to the interpreter, directly execute code to Python prompt. Once you‟re inside the python interpreter, then you can start. >>> print("hello world") hello world 59 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook # Relevant output is displayed on subsequent lines without the >>> symbol >>> x=[0,1,2] # Quantities stored in memory are not displayed by default. >>> x #If a quantity is stored in memory, typing its name will display it. [0, 1, 2] >>> 2+3 5 The chevron at the beginning of the 1st line, i.e., the symbol >>> is a prompt the python interpreter uses to indicate that it is ready. If the programmer types 2+6, the interpreter replies 8. Running Python in script mode: Alternatively, programmers can store Python script source code in a file with the .py extension, and use the interpreter to execute the contents of the file. To execute the script by the interpreter, you have to tell the interpreter the name of the file. For example, if you have a script name MyFile.py and you're working on Unix, to run the script you have to type: python MyFile.py Working with the interactive mode is better when Python programmers deal with small pieces of code as you can type and execute them immediately, but when the code is more than 2-4 lines, using the script for coding can help to modify and use the code in future. Example: Variables: Variables are nothing but reserved memory locations to store values. This means that when you create a variable you reserve some space in memory. Based on the data type of a variable, the interpreter allocates memory and decides what can be stored in the reserved memory. Therefore, by assigning different data types to variables, you can store integers, decimals or characters in these variables. 60 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Rules for Python variables: • • • • A variable name must start with a letter or the underscore character A variable name cannot start with a number A variable name can only contain alpha-numeric characters and underscores (A-z, 0-9, and _ ) Variable names are case-sensitive (age, Age and AGE are three different variables) Assigning Values to Variables: Python variables do not need explicit declaration to reserve memory space. The declaration happens automatically when you assign a value to a variable. The equal sign (=) is used to assign values to variables. The operand to the left of the = operator is the name of the variable and the operand to the right of the = operator is the value stored in the variable. For example – a= 100# An integer assignment b = 1000.0 # A floating point c = "John" # A string print (a) print (b) print (c) This produces the following result − 100 1000.0 John Multiple Assignment: Python allows you to assign a single value to several variables simultaneously. For example : a = b = c = 1 Here, an integer object is created with the value 1, and all three variables are assigned to the same memory location. You can also assign multiple objects to multiple variables. For example − a,b,c = 1,2,"CET“ Here, two integer objects with values 1 and 2 are assigned to variables a and b respectively, and one string object with the value "john" is assigned to the variable c. Output Variables: The Python print statement is often used to output variables. Variables do not need to be declared with any particular type and can even change type after they have been set. 61 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook x=5 # x is of type int x = "CET "# x is now of type str print(x) Output: CET To combine both text and a variable, Python uses the “+” character: Example x = "awesome" print("Python is " + x) Output Python is awesome You can also use the + character to add a variable to another variable: Example x = "Python is " y = "awesome" z=x+y print(z) Output: Python is awesome Expressions: An expression is a combination of values, variables, and operators. An expression is evaluated using assignment operator. Examples: Y=x + 17 >>> x=10 >>> z=x+20 >>> z 30 >>> x=10 >>> y=20 >>> c=x+y >>> c 30 62 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer A value all by itself is a simple expression, and so is a variable. >>> y=20 >>> y 20 Python also defines expressions only contain identifiers, literals, and operators. So, Identifiers: Any name that is used to define a class, function, variable module, or object is an identifier. Literals: These are language-independent terms in Python and should exist independently in any programming language. In Python, there are the string literals, byte literals, integer literals, floating point literals, and imaginary literals. Operators: In Python you can implement the following operations using the corresponding tokens. Operator add subtract multiply Integer Division remainder Binary left shift Binary right shift and or Less than Greater than Less than or equal to Greater than or equal to Check equality Check not equal Token + * / % << >> & \ < > <= >= == != Some of the python expressions are: Generator expression: Syntax: ( compute(var) for var in iterable ) >>> x = (i for i in 'abc') #tuple comprehension >>> x <generator object <genexpr> at 0x033EEC30> >>> print(x) <generator object <genexpr> at 0x033EEC30> 63 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook You might expect this to print as ('a', 'b', 'c') but it prints as <generator object <genexpr> at 0x02AAD710> The result of a tuple comprehension is not a tuple: it is actually a generator. The only thing that you need to know now about a generator now is that you can iterate over it, but ONLY ONCE. Conditional expression: Syntax: true_value if Condition else false_value >>> x = "1" if True else "2" >>> x '1' Statements: A statement is an instruction that the Python interpreter can execute. We have normally two basic statements, the assignment statement and the print statement. Some other kinds of statements that are if statements, while statements, and for statements generally called as control flows. Examples: An assignment statement creates new variables and gives them values: >>> x=10 >>> coll="CET" An print statement is something which is an input from the user, to be printed / displayed on to the screen (or ) monitor. >>> print("CET colege") CET coll Precedence of Operators: Operator precedence affects how an expression is evaluated. For example, x = 7 + 3 * 2; here, x is assigned 13, not 20 because operator * has higher precedence than +, so it first multiplies 3*2 and then adds into 7. Example 1: >>> 3+4*2 11 Multiplication gets evaluated before the addition operation >>> (10+10)*2 40 Parentheses () overriding the precedence of the arithmetic operators Example 2: a = 20 b = 10 c = 15 64 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer d=5 e=0 e = (a + b) * c / d #( 30 * 15 ) / 5 print("Value of (a + b) * c / d is ", e) e = ((a + b) * c) / d # (30 * 15 ) / 5 print("Value of ((a + b) * c) / d is ", e) e = (a + b) * (c / d); # (30) * (15/5) print("Value of (a + b) * (c / d) is ", e) e = a + (b * c) / d; # 20 + (150/5) print("Value of a + (b * c) / d is ", e) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/opprec.py Value of (a + b) * c / d is 90.0 Value of ((a + b) * c) / d is 90.0 Value of (a + b) * (c / d) is 90.0 Value of a + (b * c) / d is 50.0 Comments: Single-line comments begins with a hash(#) symbol and is useful in mentioning that the whole line should be considered as a comment until the end of line. A Multi line comment is useful when we need to comment on many lines. In python, triple double quote(“ “ “) and single quote(„ „ „)are used for multi-line commenting. Example: Output: C:/Users/AppData/Local/Programs/Python/Python38-32/pyyy/comm.py 30 65 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Numeric Data types: The data stored in memory can be of many types. For example, a student roll number is stored as a numeric value and his or her address is stored as alphanumeric characters. Python has various standard data types that are used to define the operations possible on them and the storage method for each of them. Int: Int, or integer, is a whole number, positive or negative, without decimals, of unlimited length. >>> print(24656354687654+2) 24656354687656 >>> print(20) 20 >>> print(0b10) 2 >>> print(0B10) 2 >>> print(0X20) 32 >>> 20 20 >>> 0b10 2 >>> a=10 >>> print(a) 10 # To verify the type of any object in Python, use the type() function: >>> type(10) <class 'int'> >>> a=11 >>> print(type(a)) <class 'int'> Float: Float, or "floating point number" is a number, positive or negative, containing one or more decimals. Float can also be scientific numbers with an "e" to indicate the power of 10. >>> y=2.8 >>> y 2.8 >>> y=2.8 >>> print(type(y)) <class 'float'> >>> type(.4) <class 'float'> >>> 2. 66 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 2.0 Example: x = 35e3 y = 12E4 z = -87.7e100 print(type(x)) print(type(y)) print(type(z)) Output: <class 'float'> <class 'float'> <class 'float'> Boolean: Objects of Boolean type may have one of two values, True or False: >>> type(True) <class 'bool'> >>> type(False) <class 'bool'> Strings: A string is a group/ a sequence of characters. Since Python has no provision for arrays, we simply use strings. This is how we declare a string. We can use a pair of single or double quotes. Every string object is of the type „str‟. >>> type("name") <class 'str'> >>> name=str() >>> name '' >>> a=str('CET') >>> a 'CET' >>> a=str(CET) >>> a[2] 'c' >>> fruit = 'banana' >>> letter = fruit[1] 67 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook The second statement selects character number 1 from fruit and assigns it to letter. The expression in brackets is called an index. The index indicates which character in the sequence we want String slices: A segment of a string is called a slice. Selecting a slice is similar to selecting a character: Subsets of strings can be taken using the slice operator ([ ] and [:]) with indexes starting at 0 in the beginning of the string and working their way from -1 at the end. Slice out substrings, sub lists, sub Tuples using index. Syntax:[Start: stop: steps] • • • • Slicing will start from index and will go up to stop in step of steps. Default value of start is 0, Stop is last index of list And for step default is 1 For example 1− str = 'Hello World!' print str# Prints complete string print str[0] # Prints first character of the string print str[2:5] # Prints characters starting from 3rd to 5th print str[2:] # Prints string starting from 3rd character print str * 2 # Prints string two times print str + "TEST" # Prints concatenated string Output: Hello World! H llo llo World! Hello World!Hello World! Hello World!TEST Example 2: >>> x='computer' >>> x[1:4] 'omp' >>> x[1:6:2] 'opt' >>> x[3:] 'puter' 68 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer >>> x[:5] 'compu' >>> x[-1] 'r' >>> x[-3:] 'ter' >>> x[:-2] 'comput' >>> x[::-2] 'rtpo' >>> x[::-1] 'retupmoc' Immutability: It is tempting to use the [] operator on the left side of an assignment, with the intention of changing a character in a string. For example: >>> greeting='CET coll!' >>> greeting[0]='n' TypeError: 'str' object does not support item assignment The reason for the error is that strings are immutable, which means we can‟t change an existing string. The best we can do is creating a new string that is a variation on the original: >>> greeting = 'Hello, world!' >>> new_greeting = 'J' + greeting[1:] >>> new_greeting 'Jello, world!' Note: The plus (+) sign is the string concatenation operator and the asterisk (*) is the repetition operator String functions and methods: There are many methods to operate on String. S.no 1 Method name isalnum() Description Returns true if string has at least 1 character and all characters are alphanumeric and false otherwise. 69 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook S.no 2 3 4 5 6 7 8 9 10 11 12 13 14 Method name Description Returns true if string has at least 1 character and all isalpha() characters are alphabetic and false otherwise. isdigit() Returns true if string contains only digits and false otherwise. Returns true if string has at least 1 cased character and all islower() cased characters are in lowercase and false otherwise. Returns true if a string contains only numeric characters isnumeric() and false otherwise. Returns true if string contains only whitespace characters isspace() and false otherwise. Returns true if string is properly “titlecased” and false istitle() otherwise. Returns true if string has at least one cased character and isupper() all cased characters are in uppercase and false otherwise. Replaces all occurrences of old in string with new or at most replace(old, new [, max]) max occurrences if max given. Splits string according to delimiter str (space if not provided) split() and returns list of substrings; count() Occurrence of a string in another string Finding the index of the first occurrence of a string in find() another string Converts lowercase letters in a string to uppercase and swapcase() viceversa Determines if string or a substring of string (if starting index s t a r t s w i t h ( s t r, beg and ending index end are given) starts with substring beg=0,end=le n(string)) str; returns true if so and false otherwise. Note: All the string methods will be returning either true or false as the result isalnum(): Isalnum() method returns true if string has at least 1 character and all characters are alphanumeric and false otherwise. Syntax: String.isalnum() Example: >>> string="123alpha" >>> string.isalnum() True isalpha(): 70 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer isalpha() method returns true if string has at least 1 character and all characters are alphabetic and false otherwise. Syntax: String.isalpha() Example: >>> string="nikhil" >>> string.isalpha() True isdigit(): isdigit() returns true if string contains only digits and false otherwise. Syntax: String.isdigit() Example: >>> string="123456789" >>> string.isdigit() True islower(): Islower() returns true if string has characters that are in lowercase and false otherwise. Syntax: String.islower() Example: >>> string="nikhil" >>> string.islower() True isnumeric(): isnumeric() method returns true if a string contains only numeric characters and false otherwise. Syntax: String.isnumeric() 71 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example: >>> string="123456789" >>> string.isnumeric() True isspace(): isspace() returns true if string contains only whitespace characters and false otherwise. Syntax: String.isspace() Example: >>> string=" " >>> string.isspace() True istitle() istitle() method returns true if string is properly “titlecased”(starting letter of each word is capital) and false otherwise Syntax: String.istitle() Example: >>> string="Nikhil Is Learning" >>> string.istitle() True isupper() isupper() returns true if string has characters that are in uppercase and false otherwise. Syntax: String.isupper() Example: >>> string="HELLO" >>> string.isupper() True replace() replace() method replaces all occurrences of old in string with new or at most max occurrences if max given. 72 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Syntax: String.replace() Example: >>> string="Nikhil Is Learning" >>> string.replace('Nikhil','Neha') 'Neha Is Learning' split() split() method splits the string according to delimiter str (space if not provided) Syntax: String.split() Example: >>> string="Nikhil Is Learning" >>> string.split() ['Nikhil', 'Is', 'Learning'] count() count() method counts the occurrence of a string in another string Syntax: String.count() Example: >>> string='Nikhil Is Learning' >>> string.count('i') 3 find() Find() method is used for finding the index of the first occurrence of a string in another string Syntax: String.find(„string‟) Example: >>> string="Nikhil Is Learning" >>> string.find('k') 2 swapcase() converts lowercase letters in a string to uppercase and viceversa 73 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Syntax: String.find(„string‟) Example: >>> string="HELLO" >>> string.swapcase() 'hello' startswith() Determines if string or a substring of string (if starting index beg and ending index end are given) starts with substring str; returns true if so and false otherwise. Syntax: String.startswith(„string‟) Example: >>> string="Nikhil Is Learning" >>> string.startswith('N') True endswith() Determines if string or a substring of string (if starting index beg and ending index end are given) ends with substring str; returns true if so and false otherwise. Syntax: String.endswith(„string‟) Example: >>> string="Nikhil Is Learning" >>> string.startswith('g') True Exercise Answer the following questions: 1. The list.pop ([i]) removes the item at the given position in the list? a) Trueb) False 2. The list.index(x[, start[, end]]) is used to ______. a) Return zero-based index in the list b) Raises a ValueError if there is no such item 74 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer c) Both A and B d) None of the mentioned above 3. Python Dictionary is used to store the data in a ___ format. a) Key value pair b) Group value pair c) Select value pair d) None of the mentioned above 4. The following is used to define a ___. d={ <key>: <value>, <key>: <value>, ...<key>: <value> } a) Groupb) List c) Dictionary d) All of the mentioned above 5. Python Literals is used to define the data that is given in a variable or constant? a) Trueb) False 3.1.9 String module String module: This module contains a number of functions to process standard Python strings. In recent versions, most functions are available as string methods as well. It‟s a built-in module and we have to import it before using any of its constants and classes Syntax: import string Note: help(string) --- gives the information about all the variables ,functions, attributes and classes to be used in string module. Example: import string print(string.ascii_letters) print(string.ascii_lowercase) print(string.ascii_uppercase) print(string.digits) print(string.hexdigits) #print(string.whitespace) print(string.punctuation) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/strrmodl.py ========================================= abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS TUVWXYZabcdefghijklmnopqrstuvwxyz 75 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook ABCDEFGHIJKLMNOPQRSTUVWXYZ 0123456789 0123456789abcdefABCDEF !"#$%&'()*+,-./:;<=>?@[\]^_`{|}~ Python String Module Classes Python string module contains two classes – Formatter and Template. Formatter • It behaves exactly same as str.format() function. This class becomes useful if you want to subclass it and define your own format string syntax. Syntax: from string import Formatter Template • This class is used to create a string template for simpler string substitutions Syntax: from string import Template Basic Data Types: List: • • • • It is a general purpose most widely used in data structures List is a collection which is ordered and changeable and allows duplicate members. (Grow and shrink as needed, sequence type, sortable). To use a list, you must declare it first. Do this using square brackets and separate values with commas. We can construct / create list in many ways. Ex: >>> list1=[1,2,3,'A','B',7,8,[10,11]] >>> print(list1) [1, 2, 3, 'A', 'B', 7, 8, [10, 11]] >>> x=list() >>> x [] >>> tuple1=(1,2,3,4) >>> x=list(tuple1) >>> x 76 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer [1, 2, 3, 4] List operations: These operations include indexing, slicing, adding, multiplying, and checking for membership Basic List Operations: Lists respond to the + and * operators much like strings; they mean concatenation and repetition here too, except that the result is a new list, not a string. Python Expression len([1, 2, 3]) [1, 2, 3] + [4, 5, 6] ['Hi!'] * 4 3 in [1, 2, 3] for x in [1, 2, 3]: print x, Results 3 [1, 2, 3, 4, 5, 6] ['Hi!', 'Hi!', 'Hi!', 'Hi!'] True 123 Description Length Concatenation Repetition Membership Iteration Indexing, Slicing, and Matrixes Because lists are sequences, indexing and slicing work the same way for lists as they do for strings. Assuming following input – L = ['CET', 'coll', 'CET!'] Python Expression L[2] L[-2] L[1:] Results CET coll ['coll', 'CET!'] Description Offsets start at zero Negative: count from the right Slicing fetches sections List slices: >>> list1=range(1,6) >>> list1 range(1, 6) >>> print(list1) range(1, 6) >>> list1=[1,2,3,4,5,6,7,8,9,10] >>> list1[1:] [2, 3, 4, 5, 6, 7, 8, 9, 10] >>> list1[:1] [1] >>> list1[2:5] [3, 4, 5] >>> list1[:6] [1, 2, 3, 4, 5, 6] >>> list1[1:2:4] [2] >>> list1[1:8:2] [2, 4, 6, 8] 77 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook List methods: The list data type has some more methods. Here are all of the methods of list objects: • • • • • • • • Del() Append() Extend() Insert() Pop() Remove() Reverse() Sort() Delete: Delete a list or an item from a list >>> x=[5,3,8,6] >>> del(x[1]) #deletes the index position 1 in a list >>> x [5, 8, 6] __________ >>> del(x) >>> x # complete list gets deleted Append: Append an item to a list >>> x=[1,5,8,4] >>> x.append(10) >>> x [1, 5, 8, 4, 10] Extend: Append a sequence to a list. >>> x=[1,2,3,4] >>> y=[3,6,9,1] >>> x.extend(y) >>> x [1, 2, 3, 4, 3, 6, 9, 1] Insert: To add an item at the specified index, use the insert () method: >>> x=[1,2,4,6,7] >>> x.insert(2,10) #insert(index no, item to be inserted) >>> x [1, 2, 10, 4, 6, 7] ______________ >>> x.insert(4,['a',11]) 78 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer >>> x [1, 2, 10, 4, ['a', 11], 6, 7] Pop: The pop() method removes the specified index, (or the last item if index is not specified) or simply pops the last item of list and returns the item. >>> x=[1, 2, 10, 4, 6, 7] >>> x.pop() 7 >>> x [1, 2, 10, 4, 6] ______________ >>> x=[1, 2, 10, 4, 6] >>> x.pop(2) 10 >>> x [1, 2, 4, 6] Remove: The remove() method removes the specified item from a given list. >>> x=[1,33,2,10,4,6] >>> x.remove(33) >>> x [1, 2, 10, 4, 6] >>> x.remove(4) >>> x [1, 2, 10, 6] Reverse: Reverse the order of a given list. >>> x=[1,2,3,4,5,6,7] >>> x.reverse() >>> x [7, 6, 5, 4, 3, 2, 1] Sort: Sorts the elements in ascending order >>> x=[7, 6, 5, 4, 3, 2, 1] >>> x.sort() >>> x [1, 2, 3, 4, 5, 6, 7] _____________ >>> x=[10,1,5,3,8,7] 79 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook >>> x.sort() >>> x [1, 3, 5, 7, 8, 10] List loop: Loops are control structures used to repeat a given section of code a certain number of times or until a particular condition is met. Method #1: For loop #list of items list = ['G','R','A','E','T'] i=1 #Iterating over the list for item in list: print ('coll ',i,' is ',item) i = i+1 Output: C:/Users/AppData/Local/Programs/Python/Python38-32/pyyy/lis.py coll 1 is G coll 2 is R coll 3 is A coll 4 is E coll 5 is T Method #2: For loop and range() In case we want to use the traditional for loop which iterates from number x to number y. # Python3 code to iterate over a list list = [1, 3, 5, 7, 9] # getting length of list length = len(list) # Iterating the index # same as 'for i in range(len(list))' for i in range(length): print(list[i]) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/listlooop.py 1 3 5 80 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 7 9 Method #3: using while loop # Python3 code to iterate over a list list = [1, 3, 5, 7, 9] # Getting length of list length = len(list) i=0 # Iterating using while loop while i < length: print(list[i]) i += 1 Mutability: A mutable object can be changed after it is created, and an immutable object can't. Append: Append an item to a list >>> x=[1,5,8,4] >>> x.append(10) >>> x [1, 5, 8, 4, 10] Extend: Append a sequence to a list. >>> x=[1,2,3,4] >>> y=[3,6,9,1] >>> x.extend(y) >>> x Delete: Delete a list or an item from a list >>> x=[5,3,8,6] >>> del(x[1]) #deletes the index position 1 in a list >>> x [5, 8, 6] Insert: To add an item at the specified index, use the insert () method: >>> x=[1,2,4,6,7] >>> x.insert(2,10) #insert(index no, item to be inserted) >>> x [1, 2, 10, 4, 6, 7] ____________ 81 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook >>> x.insert(4,['a',11]) >>> x [1, 2, 10, 4, ['a', 11], 6, 7] Pop: The pop() method removes the specified index, (or the last item if index is not specified) or simply pops the last item of list and returns the item. >>> x=[1, 2, 10, 4, 6, 7] >>> x.pop() 7 >>> x [1, 2, 10, 4, 6] _______________ >>> x=[1, 2, 10, 4, 6] >>> x.pop(2) 10 >>> x [1, 2, 4, 6] Remove: The remove() method removes the specified item from a given list. >>> x=[1,33,2,10,4,6] >>> x.remove(33) >>> x [1, 2, 10, 4, 6] >>> x.remove(4) >>> x [1, 2, 10, 6] Reverse: Reverse the order of a given list. >>> x=[1,2,3,4,5,6,7] >>> x.reverse() >>> x [7, 6, 5, 4, 3, 2, 1] Sort: Sorts the elements in ascending order >>> x=[7, 6, 5, 4, 3, 2, 1] >>> x.sort() >>> x [1, 2, 3, 4, 5, 6, 7] ____________ 82 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer >>> x=[10,1,5,3,8,7] >>> x.sort() >>> x [1, 3, 5, 7, 8, 10] Aliasing: An alias is a second name for a piece of data, often easier (and more useful) than making a copy. • • • If the data is immutable, aliases don‟t matter because the data can‟t change. But if data can change, aliases can result in lot of hard – to – find bugs. Aliasing happens whenever one variable‟s value is assigned to another variable. For ex: a = [81, 82, 83] b = [81, 82, 83] print(a == b) print(a is b) b = a print(a == b) print(a is b) b[0] = 5 print(a) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/alia.py True False True True [5, 82, 83] Because the same list has two different names, a and b, we say that it is aliased. Changes made with one alias affect the other. In the example above, you can see that a and b refer to the same list after executing the assignment statement b = a. Cloning Lists: If we want to modify a list and also keep a copy of the original, we need to be able to make a copy of the list itself, not just the reference. This process is sometimes called cloning, to avoid the ambiguity of the word copy. The easiest way to clone a list is to use the slice operator. Taking any slice of a creates a new list. In this case the slice happens to consist of the whole list. Example: a = [81, 82, 83] b = a[:] # make a clone using slice print(a == b) 83 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print(a is b) b[0] = 5 print(a) print(b) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/clo.py True False [81, 82, 83] [5, 82, 83] Now we are free to make changes to b without worrying about a List parameters: Passing a list as an argument actually passes a reference to the list, not a copy of the list. Since lists are mutable, changes made to the elements referenced by the parameter change the same list that the argument is referencing. # for example, the function below takes a list as an argument and multiplies each element in the list by 2: def doubleStuff(List): """ Overwrite each element in aList with double its value. """ for position in range(len(List)): List[position] = 2 * List[position] things = [2, 5, 9] print(things) doubleStuff(things) print(things) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/lipar.py == [2, 5, 9] [4, 10, 18] List comprehension: List: List comprehensions provide a concise way to create lists. Common applications are to make new lists where each element is the result of some operations applied to each member of another sequence or iterable, or to create a subsequence of those elements that satisfy a certain condition. For example, assume we want to create a list of squares, like: >>> list1=[] >>> for x in range(10): list1.append(x**2) >>> list1 84 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] (or) This is also equivalent to >>> list1=list(map(lambda x:x**2, range(10))) >>> list1 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] (or) Which is more concise and redable. >>> list1=[x**2 for x in range(10)] >>> list1 [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] Similarily some examples: >>> x=[m for m in range(8)] >>> print(x) [0, 1, 2, 3, 4, 5, 6, 7] >>> x=[z**2 for z in range(10) if z>4] >>> print(x) [25, 36, 49, 64, 81] >>> x=[x ** 2 for x in range (1, 11) if x % 2 == 1] >>> print(x) [1, 9, 25, 49, 81] 85 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook >>> a=5 >>> table = [[a, b, a * b] for b in range(1, 11)] >>> for i in table: print(i) [5, 1, 5] [5, 2, 10] [5, 3, 15] [5, 4, 20] [5, 5, 25] [5, 6, 30] [5, 7, 35] [5, 8, 40] [5, 9, 45] [5, 10, 50] Tuples: A tuple is a collection which is ordered and unchangeable. In Python tuples are written with round brackets. • • • • • Supports all operations for sequences. Immutable, but member objects may be mutable. If the contents of a list shouldn‟t change, use a tuple to prevent items from accidently being added, changed, or deleted. Tuples are more efficient than list due to python‟s implementation. We can construct tuple in many ways: X=() #no item tuple X=(1,2,3) X=tuple(list1) X=1,2,3,4 Example: >>> x=(1,2,3) >>> print(x) (1, 2, 3) >>> x (1, 2, 3) ____________ >>> x=() >>> x () ____________ 86 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer >>> x=[4,5,66,9] >>> y=tuple(x) >>> y (4, 5, 66, 9) ____________ >>> x=1,2,3,4 >>> x (1, 2, 3, 4) Some of the operations of tuple are: • • • • • • Access tuple items Change tuple items Loop through a tuple Count() Index() Length() Access tuple items: Access tuple items by referring to the index number, inside square brackets >>> x=('a','b','c','g') >>> print(x[2]) c Change tuple items: Once a tuple is created, you cannot change its values. Tuples are unchangeable. >>> x=(2,5,7,'4',8) >>> x[1]=10 Traceback (most recent call last): File "<pyshell#41>", line 1, in <module> x[1]=10 TypeError: 'tuple' object does not support item assignment >>> x (2, 5, 7, '4', 8) # the value is still the same Loop through a tuple: We can loop the values of tuple using for loop >>> x=4,5,6,7,2,'aa' >>> for i in x: print(i) 4 87 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 5 6 7 2 aa Count (): Returns the number of times a specified value occurs in a tuple >>> x=(1,2,3,4,5,6,2,10,2,11,12,2) >>> x.count(2) 4 Index (): Searches the tuple for a specified value and returns the position of where it was found >>> x=(1,2,3,4,5,6,2,10,2,11,12,2) >>> x.index(2) 1 (Or) >>> x=(1,2,3,4,5,6,2,10,2,11,12,2) >>> y=x.index(2) >>> print(y) 1 Length (): To know the number of items or values present in a tuple, we use len(). >>> x=(1,2,3,4,5,6,2,10,2,11,12,2) >>> y=len(x) >>> print(y) 12 Tuple Assignment Python has tuple assignment feature which enables you to assign more than one variable at a time. In here, we have assigned tuple 1 with the coll information like coll name, year, etc. and another tuple 2 with the values in it like number (1, 2, 3… 7). For Example, Here is the code, >>> tup1 = ('CET', 'eng coll','2004','cse', 'it','csit'); >>> tup2 = (1,2,3,4,5,6,7); >>> print(tup1[0]) CET >>> print(tup2[1:4]) 88 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer (2, 3, 4) Tuple 1 includes list of information of CET Tuple 2 includes list of numbers in it We call the value for [0] in tuple and for tuple 2 we call the value between 1 and 4 Run the above code- It gives name CET for first tuple while for second tuple it gives number (2, 3, 4) Tuple as return values: A Tuple is a comma separated sequence of items. It is created with or without (). Tuples are immutable. # A Python program to return multiple values from a method using tuple # This function returns a tuple def fun(): str = "CET coll" x = 20 return str, x; # Return tuple, we could also # write (str, x) # Driver code to test above method str, x = fun() # Assign returned tuple print(str) print(x) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/tupretval.py CET coll 20 Functions can return tuples as return values. def circleInfo(r): """ Return (circumference, area) of a circle of radius r """ c = 2 * 3.14159 * r a = 3.14159 * r * r return (c, a) print(circleInfo(10)) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/functupretval.py (62.8318, 314.159) def f(x): y0 = x + 1 y1 = x * 3 y2 = y0 ** y3 return (y0, y1, y2) Tuple comprehension: Tuple Comprehensions are special: The result of a tuple comprehension is special. You might expect it to produce a tuple, but what it does is produce a special "generator" object that we can iterate over. 89 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook For example: >>> x = (i for i in 'abc') #tuple comprehension >>> x <generator object <genexpr> at 0x033EEC30> >>> print(x) <generator object <genexpr> at 0x033EEC30> You might expect this to print as ('a', 'b', 'c') but it prints as <generator object <genexpr> at 0x02AAD710> The result of a tuple comprehension is not a tuple: it is actually a generator. The only thing that you need to know now about a generator now is that you can iterate over it, but ONLY ONCE. So, given the code >>> x = (i for i in 'abc') >>> for i in x: print(i) abc Create a list of 2-tuples like (number, square): >>> z=[(x, x**2) for x in range(6)] >>> z [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] Set: Similarly to list comprehensions, set comprehensions are also supported: >>> a = {x for x in 'abracadabra' if x not in 'abc'} >>> a {'r', 'd'} >>> x={3*x for x in range(10) if x>5} >>> x {24, 18, 27, 21} Dictionaries: A dictionary is a collection which is unordered, changeable and indexed. In Python dictionaries are written with curly brackets, and they have keys and values. 90 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Key-value pairs Unordered We can construct or create dictionary like: X={1:‟A‟,2:‟B‟,3:‟c‟} X=dict([(„a‟,3) („b‟,4)] X=dict(„A‟=1,‟B‟ =2) Example: >>> dict1 = {"brand":"CET","model":"coll","year":2004} >>> dict1 {'brand': 'CET', 'model': 'coll', 'year': 2004} Operations and methods: Methods that are available with dictionary are tabulated below. Some of them have already been used in the above examples. Method clear() copy() fromkeys(seq[, v]) get(key[,d]) items() keys() pop(key[,d]) popitem() setdefault(key[,d]) update([other]) values() Description Remove all items form the dictionary. Return a shallow copy of the dictionary. Return a new dictionary with keys from seq and value equal to v (defaults to None). Return the value of key. If key doesnot exit, return d (defaults to None). Return a new view of the dictionary's items (key, value). Return a new view of the dictionary's keys. Remove the item with key and return its value or d if key is not found. If d is not provided and key is not found, raises KeyError. Remove and return an arbitary item (key, value). Raises KeyError if the dictionary is empty. If key is in the dictionary, return its value. If not, insert key with a value of d and return d (defaults to None). Update the dictionary with the key/value pairs from other, overwriting existing keys. Return a new view of the dictionary's values Below are some dictionary operations: To access specific value of a dictionary, we must pass its key, >>> dict1 = {"brand":"CET","model":"coll","year":2004} >>> x=dict1["brand"] >>> x 91 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 'CET' To access keys and values and items of dictionary: >>> dict1 = {"brand":"CET","model":"coll","year":2004} >>> dict1.keys() dict_keys(['brand', 'model', 'year']) >>> dict1.values() dict_values(['CET', 'coll', 2004]) >>> dict1.items() dict_items([('brand', 'CET'), ('model', 'coll'), ('year', 2004)]) >>> for items in dict1.values(): print(items) CET coll 2004 >>> for items in dict1.keys(): print(items) brand model year >>> for i in dict1.items(): print(i) ('brand', 'CET') ('model', 'coll') ('year', 2004) Some more operations like: • • • • Add/change Remove Length Delete Add/change values: You can change the value of a specific item by referring to its key name >>> dict1 = {"brand":"CET","model":"coll","year":2004} >>> dict1["year"]=2005 >>> dict1 {'brand': 'CET', 'model': 'coll', 'year': 2005} Remove(): It removes or pop the specific item of dictionary. 92 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer >>> dict1 = {"brand":"CET","model":"coll","year":2004} >>>print(dict1.pop("model")) coll >>> dict1 {'brand': 'CET', 'year': 2005} Delete: Deletes a particular item. >>> x = {1:1, 2:4, 3:9, 4:16, 5:25} >>> del x[5] >>> x Length: we use len() method to get the length of dictionary. >>>{1: 1, 2: 4, 3: 9, 4: 16} {1: 1, 2: 4, 3: 9, 4: 16} >>> y=len(x) >>> y 4 Iterating over (key, value) pairs: >>> x = {1:1, 2:4, 3:9, 4:16, 5:25} >>> for key in x: print(key, x[key]) 11 4 9 16 25 >>> for k,v in x.items(): print(k,v) 11 24 9 16 25 93 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook List of Dictionaries: >>> customers = [{"uid":1,"name":"John"}, {"uid":2,"name":"Smith"}, {"uid":3,"name":"Andersson"}, ] >>> >>> print(customers) [{'uid': 1, 'name': 'John'}, {'uid': 2, 'name': 'Smith'}, {'uid': 3, 'name': 'Andersson'}] ## Print the uid and name of each customer >>> for x in customers: print(x["uid"], x["name"]) 1. John 2. Smith 3. Andersson ## Modify an entry, This will change the name of customer 2 from Smith to Charlie >>> customers[2]["name"]="charlie" >>> print(customers) [{'uid': 1, 'name': 'John'}, {'uid': 2, 'name': 'Smith'}, {'uid': 3, 'name': 'charlie'}] ## Add a new field to each entry >>> for x in customers: x["password"]="123456" # any initial value >>> print(customers) [{'uid': 1, 'name': 'John', 'password': '123456'}, {'uid': 2, 'name': 'Smith', 'password': '123456'}, {'uid': 3, 'name': 'charlie', 'password': '123456'}] ## Delete a field >>> del customers[1] >>> print(customers) [{'uid': 1, 'name': 'John', 'password': '123456'}, {'uid': 3, 'name': 'charlie', 'password': '123456'}] >>> del customers[1] >>> print(customers) [{'uid': 1, 'name': 'John', 'password': '123456'}] ## Delete all fields >>> for x in customers: del x["uid"] 94 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer >>> x {'name': 'John', 'password': '123456'} Comprehension: Dictionary comprehensions can be used to create dictionaries from arbitrary key and value expressions: >>> z={x: x**2 for x in (2,4,6)} >>> z {2: 4, 4: 16, 6: 36} >>> dict11 = {x: x*x for x in range(6)} >>> dict11 {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25} Exercise Answer the following questions: 1. Conditional statements are also known as ___ statements. a) Decision-makingb) Array c) List d) None of the mentioned above 2. The if statement is the most fundamental decision-making statement? a) Truec) False 3. Amongst which of the following if syntax is true? a) if condition: #Will executes this block if the condition is true b) if condition { #Will executes this block if the condition is true } c) if(condition) #Will executes this block if the condition is true d) None of the mentioned above 4. Amongst which of the following is / are the conditional statement in Python code? a) if a<=100: b) if (a >= 10) c) if (a => 200) d) None of the mentioned above 95 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 5. Which of the following is not used as conditional statement in Python? a) switchb) if...else c) elif d) None of the mentioned above 96 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer UNIT 3.2: Introduction to Data Structures and Databases Unit Objectives By the end of this unit, the participants will be able to: 1. Explain various core datatypes (numbers, strings, dictionaries, etc.) variables, operators (arithmetic, relational, logical, bitwise, etc.), strings and arrays in the context of python programming 2. Discuss the concepts of memory allocation 3. Explain the concepts of relational database management system 4. Demonstrate the use of type conversions 5. Use arrays, strings, and operators to declare variables 6. Demonstrate the use of RDBMS in Python programming 3.2.1 Arrays, strings, and operators to declare variables 3.2.1.1 Python Arraysvariables An array is a collection of elements that are stored in a sequence of consecutive memory regions. The goal is to group together several things of the same kind for storage purposes. This makes it much simpler to calculate the position of each element, as all that needs to be done is to add an offset to a base value, which is the memory location of the array's initial element (generally denoted by the name of the array). For the sake of simplicity, let's imagine that an array is a set of stairs in which a value (let's say one of your friends) is placed on each step. If you know the count of the step that any of your pals are on, then you can easily determine where they are located within this area. A module simply titled "array" is available in Python for working with arrays. When we need to manipulate only the values of a particular data type, they can be very helpful. A user may approach lists as though they were arrays. The user, however, is unable to impose any restrictions on the kinds of elements that are saved in the list. When you make arrays with the array module, every element in the array has to be of the same type as the rest of the elements. 3.2.1.2 Creating a Array Array in Python can be created by importing array module. array(data_type, value_list) is used to create an array with data type and value list specified in its arguments. 97 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example: # Python program to demonstrate # Creation of Array # importing "array" for array creations import array as arr # creating an array with integer type a = arr.array('i', [1, 2, 3]) # printing original array print ("The new created array is : ", end =" ") for i in range (0, 3): print (a[i], end =" ") print() # creating an array with double type b = arr.array('d', [2.5, 3.2, 3.3]) # printing original array print ("The new created array is : ", end =" ") for i in range (0, 3): print (b[i], end =" ") Output: The new created array is : 1 2 3 The new created array is : 2.5 3.2 3.3 3.2.1.3 Complexities for Creation of Arrays • • Time Complexity: O(1) Auxiliary Space: O(n) Some of the data types are mentioned below which will help in creating an array of different data types. 98 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.2.2 Python String In Python, Strings are arrays of bytes representing Unicode characters. Python does not have a character data type, a single character is simply a string with a length of 1. Square brackets can be used to access elements of the string. Ex: print("A Computer ") Output: A computer 3.2.2.1 Accessing characters in Python String Utilizing the Indexing technique is the means by which individual characters of a String can be accessed in Python. When indexing, negative address references can be used to access characters further back in a String; for example, the value -1 refers to the very last character, - 2 refers to the very second to last character, and so on. While accessing an index that is outside of the range will result in an IndexError being generated. When passing values as an index, float, or any other type that will result in a TypeError, only integers may be used. 3.2.3 Python Operators The general purpose of Python Operators is to carry out operations on values and variables. These are the standard symbols that are used for carrying out logical and numerical operations. In this piece, we will investigate the many kinds of Python operators available. OPERATORS: These are the special symbols that are used. Eg- + , * , /, etc. OPERAND: This term refers to the value that the operator is applied to. 99 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 3.2.3.1 Arithmetic Operators Adding, subtracting, multiplying, and dividing are all examples of mathematical operations that can be performed with the help of arithmetic operators. In Python 3.x, division produces a floating-point result, although in Python 2.x, an integer result was produced when an integer was divided by another integer; in Python 3.x, the floored (/ integer) operator is used to produce an integer result. Example: # Examples of Arithmetic Operator a = 9 b=4 # Addition of numbers add = a + b # Subtraction of numbers sub = a - b # Multiplication of number mul = a * b # Division(float) of number div1 = a / b # Division(floor) of number div2 = a // b # Modulo of both number mod = a % b # Power p = a ** b #print results print(add) print(sub) print(mul) print(div1) print(div2) print(mod) print(p) 100 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Output: 13 5 36 2.25 2 1 6561 3.2.3.2 Comparison Operators Comparison of Relational operators compares the values. It either returns True or False according to the condition. Example: # Examples of Relational Operators a = 13 b = 33 # a > b is False print(a > b) # a < b is True print(a < b) # a == b is False print(a == b) # a != b is True print(a != b) # a >= b is False print(a >= b) # a <= b is True print(a <= b) 101 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: False True False True False True 3.2.3.3 Logical Operators Logical operators perform Logical AND, Logical OR, and Logical NOT operations. It is used to combine conditional statements. Example: # Examples of Logical Operator a = True b = False # Print a and b is False print(a and b) # Print a or b is True print(a or b) # Print not a is False print(not a) Output: False True False 102 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.2.3.4 Bitwise Operators Bitwise operators act on bits and perform the bit-by-bit operations. These are used to operate on binary numbers. Example: # Examples of Bitwise operators a = 10 b=4 # Print bitwise AND operation print(a & b) # Print bitwise OR operation print(a | b) # Print bitwise NOT operation print(~a) # print bitwise XOR operation print(a ^ b) # print bitwise right shift operation print(a >> 2) # print bitwise left shift operation print(a << 2) Output: 0 14 -11 14 2 4 103 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 3.2.3.4 Bitwise Operators Bitwise operators act on bits and perform the bit-by-bit operations. These are used to operate on binary numbers. Example: # Examples of Bitwise operators a = 10 b=4 # Print bitwise AND operation print(a & b) # Print bitwise OR operation print(a | b) # Print bitwise NOT operation print(~a) # print bitwise XOR operation print(a ^ b) # print bitwise right shift operation print(a >> 2) # print bitwise left shift operation print(a << 2) Output: 0 14 -11 14 2 4 104 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.2.3.5 Assignment Operators Assignment operators are used to assign values to the variable 3.2.3.6 Identity Operators is and is not are the identity operators both are used to check if two values are located on the same part of the memory. Two variables that are equal do not imply that they are identical. is is not True if the operands are identical True if the operands are not identical Example: a = 10 b = 20 c=a print(a is not b) print(a is c) Output: True True 105 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 3.2.3.7 Membership Operators in and not in are the membership operators; used to test whether a value or variable is in a sequence. in not in True if value is found in the sequence True if value is not found in the sequence Example: # Python program to illustrate # not 'in' operator x = 24 y = 20 list = [10, 20, 30, 40, 50] if (x not in list): print("x is NOT present in given list") else: print("x is present in given list") if (y in list): print("y is present in given list") else: print("y is NOT present in given list") Output: x is NOT present in given list y is present in given list 3.2.3.8 Operator Associativity If an expression contains two or more operators with the same precedence then Operator Associativity is used to determine. It can either be Left to Right or from Right to Left. Example: # Examples of Operator Associativity # Left-right associativity # 100 / 10 * 10 is calculated as # (100 / 10) * 10 and not # as 100 / (10 * 10) print(100 / 10 * 10) 106 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer #Left-right associativity # 5 - 2 + 3 is calculated as # (5 - 2) + 3 and not # as 5 - (2 + 3) print(5 - 2 + 3) # left-right associativity print(5 - (2 + 3)) # right-left associativity # 2 ** 3 ** 2 is calculated as # 2 ** (3 ** 2) and not # as (2 ** 3) ** 2 print(2 ** 3 ** 2) Output: 100.0 6 0 512 3.2.4 Python Variables Python Variables are storage containers for the values they hold. Python is not a "statically typed" programming language. We are not required to define variables before using them, nor are we need to describe the type of the variables. When we give a value to a variable for the first time, we have just created the variable. A memory region can be given a name in Python, which is called a variable. It is the fundamental building block for storing data in a computer program. Example of Python Variables Var = "Your Author" print(Var) Output: Your Author The Python syntax for the creation of variables • • The name of a variable must begin with either a letter or the underscore character. It is not possible to put a number at the beginning of a variable name. 107 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook • • • Only alpha-numeric characters and underscores (A-Z, 0-9, and _) are allowed to be used in the name of a variable. Variable names are case-sensitive (name, Name and NAME are three different variables). It is not possible to name the variable using any of the reserved terms or keywords. The number data type is responsible for storing numerical values. Because they are immutable data types, any attempt to alter the value of a number data type will result in a new object being allocated. The following are some examples of different data types for numbers: • • • int float complex Let's take a look at each one of them: INT The whole number, including negative numbers but excluding fractions, is represented by the Integer data type. There is no upper bound on the length of an integer value that can be stored in Python. Example: Performing arithmetic operations on int a = 5 b=6 #Addition c = a + b print("Addition:",c) d=9 e=6 # Subtraction f = d - e print("Subtraction:",f) g=8 h=2 # Division i = g // h print("Division:",i) j=3 k=5 108 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer # Multiplication l = j * k print("Multiplication:",l) m = 25 n=5 # Modulus o = m % n print("Modulus:",o) p=6 q=2 # Exponent r = p ** q print("Exponent:",r) Output Addition: 11 Subtraction: 3 Division: 4 Multiplication: 15 Modulus: 0 Exponent: 36 Float This is a representation of a real number using floating-point math. A decimal point is used to provide the specification for it. In order to specify scientific notation, the character e or E, followed by a positive or negative integer, may be appended to the end of the expression. The numbers 0.5 and -7.823457 are both examples of numbers that can be represented as floats. It is possible to generate them either directly by entering a number that contains a decimal point or indirectly by performing operations such as division on integers. When there are extra zeros at the end of the number, they are automatically ignored. Example: Creating float and float type checking num = 3/4 # print the data type print(type(num)) Output: <class 'float'> 109 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Complex A complex number is a number that consists of the real and imaginary parts. For example, 2 + 3j is a complex number where 2 is the real component, and 3 multiplied by j is an imaginary part. Example 1: Creating Complex and checking type num = 6 + 9j print(type(num)) Output: <class 'complex'> 3.2.5 Python Dictionary In Python, a dictionary is a collection of keys and values that can be used to store data values like a map. This is in contrast to other data types, which can only hold a single value as an element in their representation. Example of Dictionary in Python Dictionary holds key:value pair. Key-Value is provided in the dictionary to make it more optimized. Dict = {1: 'Your', 2: 'Author'} print(Dict) Output: {1: 'Your', 2: 'Author'} 3.2.5.1 Creating a Dictionary In Python, a dictionary can be created by enclosing a series of elements within curly braces {}, with each element being separated by a comma. Dictionary stores values in pairs, with each pair consisting of a Key and a corresponding value for that Key. In a dictionary, the values can be of any data type, and there can be multiple copies of each value, but the keys cannot be repeated and must be immutable. Note that dictionary keys are case sensitive; even though they have the same name, different cases of Key will be treated differently. Example: # Creating a Dictionary # with Integer Keys Dict = {1: 'Your', 2: 'Author'} print("\nDictionary with the use of Integer Keys: ") print(Dict) 110 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer # Creating a Dictionary # with Mixed keys Dict = {'Name': 'sandeep', 1: [1, 2, 3, 4]} print("\nDictionary with the use of Mixed Keys: ") print(Dict) Output: Dictionary with the use of Integer Keys: {1: 'Your', 2: 'Author'} Dictionary with the use of Mixed Keys: {'Name': 'sandeep', 1: [1, 2, 3, 4]} 3.2.6 Python Tuples A collection of Python objects, a tuple operates similarly to a list. The order of values that are stored in a tuple can be of any type, and those values are indexed using integers. A tuple's values are syntactically separated by commas, which are called semicolons. To define a tuple, it is common practise to enclose the sequence of values in parentheses, even though this step is technically optional. This makes understanding the Python tuples much simpler to accomplish. 3.2.6.1 Creating a Tuple Tuples can be generated in Python by inserting a string of values that are delimited by commas, with or without the utilisation of parentheses for the purpose of grouping the data sequence. Note that the process of creating a tuple in Python without making use of parentheses is referred to as "packing the tuple." Example: # Creating an empty Tuple Tuple1 = () print("Initial empty Tuple: ") print(Tuple1) # Creating a Tuple # with the use of string Tuple1 = ('Your', 'Author') print("\nTuple with the use of String: ") print(Tuple1) # Creating a Tuple with # the use of list list1 = [1, 2, 4, 5, 6] print("\nTuple using List: ") print(tuple(list1)) 111 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook # Creating a Tuple # with the use of built-in function Tuple1 = tuple('sandy') print("\nTuple with the use of function: ") print(Tuple1) Output: Initial empty Tuple: () Tuple with the use of String: ('Your', 'Author') Tuple using List: (1, 2, 4, 5, 6) Tuple with the use of function: ('s', 'a', 'n', 'd', 'y') Example: # Examples of Assignment Operators a = 10 # Assign value b = a print(b) # Add and assign value b += a print(b) # Subtract and assign value b -= a print(b) # multiply and assign b *= a print(b) # bitwise lishift operator b <<= a print(b) Output: 10 20 10 112 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 100 102400 Exercise Answer the following questions: 1. Which of the following is false regarding conditional statement in Python? a) If-elif is the shortcut for the if-else chain b) We use the dictionary to replace the Switch case statement c) We cannot use python classes to implement the switch case statement d) None of the mentioned above 2. In Python, an else statement comes right after the block after 'if'? a) Trueb) False 3. In a Python program, Nested if Statements denotes? a) if statement inside another if statement b) if statement outside the another if statement c) Both A and B d) None of the mentioned above 4. What will be the output of the following Python code? a=7if a>4: print("Greater") a) Greaterb) 7 c) 4d) None of the mentioned above 5. What will be the output of the following Python code? x,y = 12,14if(x+y==26): print("true") else: print("false") a) trueb) false 6. What will be the output of the following Python code? x=13if x>12 or x<15 and x==16: print("Given condition matched") else: print("Given condition did not match") a) Given condition matched c) Both A and B 113 b) Given condition did not match d) None of the mentioned above Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 7. Consider the following code segment and identify what will be the output of given Python code? a = int(input("Enter an integer: ")) b = int(input("Enter an integer: ")) if a <= 0: b = b +1else: a=a+1 a) if inputted number is a negative integer then b = b +1 b) if inputted number is a positive integer then a = a +1 c) Both A and B d) None of the mentioned above 8. In Python, ___ defines a block of statements. a) Blockb) Loop c) Indentation d) None of the mentioned above 9. An ___ statement has less number of conditional checks than two successive ifs. a) if else ifb) if elif c) if-else d) None of the mentioned above 10. In Python, the break and continue statements, together are called ___ statement. a) Jumpb) goto c) compound d) None of the mentioned above 3.2.7 Memory Allocation Understanding Memory allocation is essential for any software developer since designing efficient code requires writing code that is also efficient with memory. Memory allocation is the process of assigning a section of storage space in the memory of a computer to a specific software. As a result of the Python developers creating a garbage collector for Python, the memory allocation and deallocation procedure in Python is automatic. This frees the user from the burden of having to perform manual garbage collection. 3.2.7.1 Garbage Collection It is called garbage collection because it is the process by which the interpreter frees up memory that is no longer being used and makes it available for use by other things. Consider the scenario in which there is no reference pointing to an object in memory, which indicates that the object is not being used; consequently, the virtual machine has a garbage collector that deletes that object automatically from the heap memory when it detects that the object is no longer needed. 114 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.2.7.2 Reference Counting In order to perform its function, reference counting counts the number of times an item is referred to by other objects inside the system. The reference count for an object has a value that is decremented whenever references to that object are deleted. When the reference count reaches zero, the object will be deallocated and freed up for use. For instance, let's assume that two or more variables share the same value. In this scenario, the Python virtual machine, rather of generating a new object with the same value in the private heap, will make the second variable point to the value that was there before. Therefore, having a number of references may take up a significant amount of space in the memory when it comes to classes; in this scenario, referring counting is quite helpful in order to save the memory so that it can be used for other objects. Example: x = 10 When x = 10 is executed an integer object 10 is created in memory and its reference is assigned to variable x, this is because everything is object in Python. x = 10 y=x if id(x) == id(y): print("x and y refer to the same object") Output: x and y refer to the same object Because Python optimises memory utilisation by allocating the same object reference to a new variable if the object already exists with the same value, the preceding example will result in the creation of a new reference variable y when y = x is executed. This new reference variable y will refer to the same object. x = 10 115 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook y=xx += 1 if id(x) != id(y): print("x and y do not refer to the same object") Output: x and y do not refer to the same object So now x refer to a new object x and the link between x and 10 disconnected but y still refer to 10. 3.2.7.3 Memory Allocation in Python There are two parts of memory: • • stack memory heap memory The methods/method calls and the references are stored in stack memory and all the values objects are stored in a private heap. 3.2.7.4 Work of Stack Memory The allocation works on groups of memory that are joined together. We refer to it as stack memory allocation due to the fact that the allocation takes place in the function call stack. The size of the memory that will be allocated is already known to the compiler, and whenever a function is called, the memory for that function's variables is allocated on the stack. It refers to the memory that is required only for the duration of a single function or method call. When a function is invoked within a program, its entry is appended to the call stack. Any local memory 116 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer assignments made within a given function, such as the initialization of variables, are saved momentarily on the function call stack. This information is erased once the function completes its execution, at which point the call stack is free to move on to the next job. This allocation onto a contiguous block of memory is managed by the compiler through the use of preset functions, and developers do not need to be concerned about it in any way. 3.2.7.5 Work of Heap Memory The RAM is allocated when programmers are executing their instructions. Keep in mind that the heap data structure has nothing to do with the word heap. Because it is a pile of memory space that programmers can allocate and free up, it is known as a heap. The variables that are used in numerous functions globally or that are required outside of method or function calls are kept in heap memory. Example: # This memory for 10 integers # is allocated on heap. a = [0]*10 3.2.8 Relational Database Management Systems (RDBMS) Relational Database Management System is referred to as RDBMS. RDBMS is the foundation of every contemporary database management system, including SQL, MS SQL Server, IBM DB2, ORACLE, My-SQL, and Microsoft Access. Because it is based on the relational model created by E.F. Codd, it is known as Relational Database Management System (RDBMS). What it does • • • In RDBMS, data is displayed as rows of tuples. The most popular type of database is a relational database. It has a number of tables, each with a unique primary key. Data may be accessible quickly in RDBMS because of a collection of a well-organized set of tables. 3.2.8.1 Brief History of RDBMS From 1970 to 1972, E.F. Codd published a paper to propose using a relational database model. RDBMS is originally based on E.F. Codd's relational model invention. 117 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook What is table/Relation? A relational database stores data in the form of relations for everything. Tables are used in the RDBMS database to hold data. A table is a collection of connected data elements that stores data in rows and columns. Each table represents a specific real-world item, such as a person, location, or event, about which data is being gathered. The logical view of the database is the orderly collection of data included in a relational table. Qualities of a Relationship: • • • • • Each relation has a distinct name that may be used to locate it in the database. There are no duplicate tuples in the relationship. A relation's tuples are not in any particular sequence. Each cell of a connection holds precisely one value since all characteristics in a relation are atomic. The table the simplest example of data stored in RDBMS. Let's see the example of the student table. 3.2.8.2 What is a row or record? A record or tuple is another name for a database row. It includes all of the specific details for each table entry. In the table, it is a horizontal element. For instance, the table above has 5 records. a row's attributes are: • • • In all of their entries, no two tuples are identical to one another. The format and number of entries are the same for all tuples in the relation. The tuple's order is not important. They are recognised by their ideas, not by where they are located. Let's see one record/row in the table. What is a column/attribute? A column is a vertical item within a table that stores all of the information that is related with a certain field. For instance, the column labelled "name" in the aforementioned database includes any and all information that pertains to the given name of a student. 118 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Attribute characteristics include the following: • • • • Each and every one of a relation's attributes needs to have a name. The attributes may accept null values at their discretion. If no additional value is supplied for an attribute, the default value for that attribute will be used instead. Default values might be specified for an attribute. The primary key consists of characteristics of a relation's tuples that may individually and unambiguously be identified. What is data item/Cells? The individual data item is the most basic unit of information that can be found in the table. It is kept in the spot where the tuples and the attributes overlap. Characteristics of the pieces of data: • • • Items of data are atomic in nature. It is important that all of the data pieces that make up an attribute come from the same domain. The data item in the student table shown below comprises of Ajeet, his age, and his degree in Btech, among other things. Degree: The total number of attributes that comprise a relation is known as the degree of the table. For example, the student table has 4 attributes, and its degree is 4. 119 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Cardinality: The total number of tuples at any one time in a relation is known as the table's cardinality. The relation whose cardinality is 0 is called an empty table. For example, the student table has 5 rows, and its cardinality is 5. Domain: In computer science, the term "domain" refers to the set of all potential values that an attribute could have. It is possible to specify it using conventional data types like integers,floating-point numbers, and so on. For instance, the values that can be assigned to the variable "Marital Status" can be restricted to "married" or "unmarried." NULL Values The value "NULL" in the table indicates that the corresponding field was not filled in when the record was initially created. It is not the same as a field that has been left blank or a value that has been filled in with zero. Data Integrity There are several different types of data integrity that are included in every RDBMS, including the following: • • • • In order to maintain the table's integrity, there must not be any duplicate rows, as specified by entity integrity. Domain integrity ensures that only legitimate items are stored in a given column by imposing constraints on either the data type, the data format, or the value range. Referential integrity requires that rows that are referenced by other records cannot be erased under any circumstances. User-defined integrity: This feature ensures compliance with a set of predetermined business standards. These rules are distinct from those pertaining to entity integrity, domain integrity, and referential integrity. 3.2.9 RDBMS in Python programming Data scientists have access to some strong tools in the form of databases. Python's default application programming interface (API) for connecting to databases is called DB-API. It enables you to develop a single application that is compatible with a variety of relational database types, rather than having to 120 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer write a separate program for each type of relational database. Using Python code that is created on a Jupyter notebook, which is an editor that is web-based, a typical user will access databases in this manner. The Python software can interface with the database management system through the following mechanism: • • • • The application program makes one or more API calls in order to establish a connection with the database management system before beginning its access to the database. After that, in order to transmit the SQL statement to the DBMS, the program first constructs the statement in the form of a text string, and then it makes a call to an API in order to transfer the contents of the string to the DBMS. API calls are made by the application program in order to check the progress of its DBMS request and to manage any issues that may occur. An API call made by the application program will eventually result in the program being severed from its connection to the database. The Python Database Application Programming Interface consists of two primary ideas: 1. Objects of connection that are used for • Establish a connection to a database. • Manage your transactions. The following is a list of different ways to connect: • • • • cursor() is a method that, when called, returns a new object that uses the connection as its basis. This method is used to commit any pending transaction to the database and is referred to as commit(). rollback() is a method that, when executed on a database, forces the database to revert to the beginning of any pending transaction. close() is the method that is called in order to terminate a connection to a database. 121 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 2. The execution of queries is accomplished by using query objects. This is a database querying application written in Python that makes use of the DB-API library. Example: from dbmodule import connect # Create connection object connection = connect('databasename', 'username', 'pswd') # Create a cursor object cursor = connection.cursor() # Run queries cursor.execute('select * from mytable') results =cursor.fetchall() # Free resources cursor.close() connection.close() • • • • First, we connect to the database using the module's connect API in order to import the database module. Use the connection function and then pass in the required parameters, which are the name of the database, the username, and the password, in order to establish a connection to the database. The connection object is what's handed back to you when you use the connect function. After this, a cursor object will be created and attached to the connection object. It is possible to run queries and obtain the results by utilising the cursor. Following the execution of the queries with the cursor, we next use the cursor once more to retrieve the results of the queries. After all of the inquiries have been processed, the system will finally close the connection in order to free up any remaining resources. Keep in mind that closing connections is always vital to do in order to prevent unneeded connections from using up resources. Assuming you have installed Anaconda then run the following command in the Anaconda Prompt Window to install the SQLAlchemy package. conda install sqlalchemy 3.2.10 Reading Relational Tablesprogramming We will use Sqlite3 as our relational database as it is very light weight and easy to use. Though the SQLAlchemy library can connect to a variety of relational sources including MySql, Oracle and Postgresql and Mssql. We first create a database engine and then connect to the database engine using the to_sql function of the SQLAlchemy library. In the below example we create the relational table by using the to_sql function from a dataframe already created by reading a csv file. Then we use the read_sql_query function from pandas to execute and capture the results from various SQL queries. 122 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer from sqlalchemy import create_engine import pandas as pd data = pd.read_csv('/path/input.csv') # Create the db engine engine = create_engine('sqlite:///:memory:') # Store the dataframe as a table data.to_sql('data_table', engine) # Query 1 on the relational table res1 = pd.read_sql_query('SELECT * FROM data_table', engine) print('Result 1') print(res1) print('' # Query 2 on the relational table res2 = pd.read_sql_query('SELECT dept,sum(salary) FROM data_table group by dept', engine) print('Result 2') print(res2) Result: 123 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 3.2.11 Inserting Data to Relational Tables We can also insert data into relational tables using sql.execute function available in pandas. In the below code we previous csv file as input data set, store it in a relational table and then insert another record using sql.execute. from sqlalchemy import create_engine from pandas.io import sql import pandas as pd data = pd.read_csv('C:/Users/Rasmi/Documents/pydatasci/input.csv') engine = create_engine('sqlite:///:memory:') # Store the Data in a relational table data.to_sql('data_table', engine) # Insert another row sql.execute('INSERT INTO data_table VALUES(?,?,?,?,?,?)', engine, params=[('id',9,'Ruby',711.20,'201503-27','IT')]) # Read from the relational table res = pd.read_sql_query('SELECT ID,Dept,Name,Salary,start_date FROM data_table', engine) print(res) Result: 3.2.12 Deleting Data from Relational Tables We can also delete data into relational tables using sql.execute function available in pandas. The below code deletes a row based on the input condition given. from sqlalchemy import create_engine from pandas.io import sql 124 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer import pandas as pd data = pd.read_csv('C:/Users/Rasmi/Documents/pydatasci/input.csv') engine = create_engine('sqlite:///:memory:') data.to_sql('data_table', engine) sql.execute('Delete from data_table where name = (?) ', engine, params=[('Gary')]) res = pd.read_sql_query('SELECT ID,Dept,Name,Salary,start_date FROM data_table', engine) print(res) Result: Exercise Answer the following questions: 1. What will be the output of the following Python code? num = 10if num > 0: print("Positive number") elif num == 0: print("Zero") else: print("Negative number") a) Positive numberb) Negative number c) Real number d) None of the mentioned above 2. The elif statement allows us to check multiple expressions. a) Trueb) False 125 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 3. What will be the output of the following Python code? i=5if i>11 : print ("i is greater than 11") a) No output c) Both A and B b) Abnormal termination of program d) None of the mentioned above 4. What will be the output of the following Python code? a = 13 b = 15print("A is greater") if a > b else print("=") if a == b else print("B is greater") a) A is greater c) Both A and B b) B is greater d) None of the mentioned above 5. If a condition is true the not operator is used to reverse the logical state? a) Trueb) False 3.2.10 Type Conversions Usage Implicit Type Conversion In Implicit type conversion of data types in Python, the Python interpreter automatically converts one data type to another without any user involvement. To get a more clear view of the topic see the below examples. Example: x = 10 print("x is of type:",type(x)) y = 10.6 print("y is of type:",type(y)) z = x + y print(z) print("z is of type:",type(z)) Output: x is of type: <class 'int'> y is of type: <class 'float'> 20.6 z is of type: <class 'float'> 3.2.10.1 Explicit Type Conversion In Explicit Type Conversion in Python, the data type is manually changed by the user as per their requirement. With explicit type conversion, there is a risk of data loss since we are forcing an expression to be changed in some specific data type. Various forms of explicit type conversion are explained below: 1. int(a, base): This function converts any data type to integer. ‘Base’ specifies the base in which string is if the data type is a string. 126 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 2. float(): This function is used to convert any data type to a floating-point number. Example: # Python code to demonstrate Type conversion # using int(), float() # initializing string s = "10010" # printing string converting to int base 2 c = int(s,2) print ("After converting to integer base 2 : ", end="") print (c) # printing string converting to float e = float(s) print ("After converting to float : ", end="") print (e) Output: After converting to integer base 2 : 18 After converting to float: 10010.0 3. ord() : This function is used to convert a character to integer. 4. hex() : This function is to convert integer to hexadecimal string. 5. oct() : This function is to convert integer to octal string. Example: # Python code to demonstrate Type conversion # using ord(), hex(), oct() # initializing integer s = '4' # printing character converting to integer c = ord(s) print ("After converting character to integer : ",end="") print (c) # printing integer converting to hexadecimal string c = hex(56) print ("After converting 56 to hexadecimal string : ",end="") print (c) # printing integer converting to octal string 127 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook c = oct(56) print ("After converting 56 to octal string : ",end="") print (c) Output: After converting character to integer : 52 After converting 56 to hexadecimal string : 0x38 After converting 56 to octal string : 0o70 6. tuple() : This function is used to convert to a tuple. 7. set() : This function returns the type after converting to set. 8. list() : This function is used to convert any data type to a list type. Example: # Python code to demonstrate Type conversion # using tuple(), set(), list() #initializing string s = 'Your' # printing string converting to tuple c = tuple(s) print ("After converting string to tuple : ",end="") print (c) # printing string converting to set c = set(s) print ("After converting string to set : ",end="") print (c) # printing string converting to list c = list(s) print ("After converting string to list : ",end="") print (c) Output: After converting string to tuple : ('Y', 'o', 'u', 'r') 128 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer After converting string to set : {'A', 'u', 't', 'h', ‘o’, ‘r’} After converting string to list : ['s', 'a', 'n', 'd', 'y'] 9. dict() : This function is used to convert a tuple of order (key,value) into a dictionary. 10. str() : Used to convert integer into a string. 11. complex(real,imag) : This function converts real numbers to complex(real,imag) number. Example: # Python code to demonstrate Type conversion # using dict(), complex(), str() # initializing integers a=1 b=2 # initializing tuple tup = (('a', 1) ,('f', 2), ('g', 3)) # printing integer converting to complex number c = complex(1,2) print ("After converting integer to complex number : ",end="") print (c) # printing integer converting to string c = str(a) print ("After converting integer to string : ",end="") print (c) # printing tuple converting to expression dictionary c = dict(tup) print ("After converting tuple to dictionary : ",end="") print (c) Output: After converting integer to complex number : (1+2j) After converting integer to string : 1 After converting tuple to dictionary : {'a': 1, 'f': 2, 'g': 3} 12. chr(number): This function converts number to its corresponding ASCII character. Example: # Convert ASCII value to characters a = chr(76) b = chr(77) print(a) print(b) 129 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: L M 3.2.10.2 Boolean Values and Operators: A boolean expression is an expression that is either true or false. The following examples use the operator ==, which compares two operands and produces True if they are equal and False otherwise: >>> 5 == 5 True >>> 5 == 6 False True and False are special values that belong to the type bool; they are not strings: >>> type(True) <class 'bool'> >>> type(False) <class 'bool'> The == operator is one of the relational operators; the others are: x != y # x is not equal to y x > y # x is greater than y x < y # x is less than y x >= y # x is greater than or equal to y x <= y # x is less than or equal to y Note: All expressions involving relational and logical operators will evaluate to either true or false 130 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer UNIT 3.3: Core Python Concepts Unit Objectives By the end of this unit, the participants will be able to: 1. Describe the concepts, types and operations related to core Python elements such as numeric types, dynamic typing interlude, lists, dictionaries, tuples, etc. 2. Explain the syntax rules, assignments, iteration, and comprehensions 3. Discuss various control flow statements (if, then, while, for, nested if, etc.) in Python programming 4. Explain the concepts and various types of methods/ functions, scopes, modules and class 5. Explain OOP features and more advanced elements of Python such as advanced modules, class coding, operator overloading, multiple inheritance, lambda, decorators, meta classes, gotchas, managed attributes, data streams, metadata, design patterns etc. 6. Demonstrate the use of control flow statements as part of Python code 7. Create expressions and statements to implement, core Python elements 8. Write sample codes to explore the OOP features and advanced elements of Python programming 9. Create the following: i. python library ii. data streams access modes iii. basic python app packaging 3.3.1 Core Python elements such as numeric types, dynamic typing interlude, lists, dictionaries, tuples The following are some examples of different data types for numbers: • • • int float complex Let's take a look at each one of them: 3.3.1.1 INT The whole number, including negative numbers but excluding fractions, is represented by the Integer data type. There is no upper bound on the length of an integer value that can be stored in Python. Example: Performing arithmetic operations on int a = 5 b=6 #Addition c = a + b print("Addition:",c) 131 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook d=9 e=6 # Subtraction f = d - e print("Subtraction:",f) g=8 h=2 # Division i = g // h print("Division:",i) j=3 k=5 # Multiplication l = j * k print("Multiplication:",l) m = 25 n=5 # Modulus o = m % n print("Modulus:",o) p=6 q=2 # Exponent r = p ** q print("Exponent:",r) Output Addition: 11 Subtraction: 3 Division: 4 Multiplication: 15 132 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Modulus: 0 Exponent: 36 3.3.1.2 Float This is a representation of a real number using floating-point math. A decimal point is used to provide the specification for it. In order to specify scientific notation, the character e or E, followed by a positive or negative integer, may be appended to the end of the expression. The numbers 0.5 and -7.823457 are both examples of numbers that can be represented as floats. It is possible to generate them either directly by entering a number that contains a decimal point or indirectly by performing operations such as division on integers. When there are extra zeros at the end of the number, they are automatically ignored. Example: Creating float and float type checking num = 3/4 # print the data type print(type(num)) Output: <class 'float'> 3.3.1.3 Complex A complex number is a number that consists of the real and imaginary parts. For example, 2 + 3j is a complex number where 2 is the real component, and 3 multiplied by j is an imaginary part. Example 1: Creating Complex and checking type num = 6 + 9j print(type(num)) Output: <class 'complex'> 3.3.1.4 Python Dictionary In Python, a dictionary is a collection of keys and values that can be used to store data values like a map. This is in contrast to other data types, which can only hold a single value as an element in their representation. Example of Dictionary in Python Dictionary holds key:value pair. Key-Value is provided in the dictionary to make it more optimized. 133 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Dict = {1: 'Your', 2: 'Author'} print(Dict) Output: {1: 'Your', 2: 'Author'} 3.3.1.5 Creating a Dictionary In Python, a dictionary can be created by enclosing a series of elements within curly braces {}, with each element being separated by a comma. Dictionary stores values in pairs, with each pair consisting of a Key and a corresponding value for that Key. In a dictionary, the values can be of any data type, and there can be multiple copies of each value, but the keys cannot be repeated and must be immutable. Note that dictionary keys are case sensitive; even though they have the same name, different cases of Key will be treated differently. Example: # Creating a Dictionary # with Integer Keys Dict = {1: 'Your', 2: 'Author'} print("\nDictionary with the use of Integer Keys: ") print(Dict) # Creating a Dictionary # with Mixed keys Dict = {'Name': 'sandeep', 1: [1, 2, 3, 4]} print("\nDictionary with the use of Mixed Keys: ") print(Dict) Output: Dictionary with the use of Integer Keys: {1: 'Your', 2: 'Author'} Dictionary with the use of Mixed Keys: {'Name': 'sandeep', 1: [1, 2, 3, 4]} 3.3.1.6 Python Tuples A collection of Python objects, a tuple operates similarly to a list. The order of values that are stored in a tuple can be of any type, and those values are indexed using integers. A tuple's values are syntactically separated by commas, which are called semicolons. To define a tuple, it is common practise to enclose the sequence of values in parentheses, even though this step is technically optional. This makes understanding the Python tuples much simpler to accomplish. 134 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Creating a Tuple Tuples can be generated in Python by inserting a string of values that are delimited by commas, with or without the utilisation of parentheses for the purpose of grouping the data sequence. Note that the process of creating a tuple in Python without making use of parentheses is referred to as "packing the tuple." Example: # Creating an empty Tuple Tuple1 = () print("Initial empty Tuple: ") print(Tuple1) # Creating a Tuple # with the use of string Tuple1 = ('Your', 'Author') print("\nTuple with the use of String: ") print(Tuple1) # Creating a Tuple with # the use of list list1 = [1, 2, 4, 5, 6] print("\nTuple using List: ") print(tuple(list1)) # Creating a Tuple # with the use of built-in function Tuple1 = tuple('sandy') print("\nTuple with the use of function: ") print(Tuple1) Output: Initial empty Tuple: () Tuple with the use of String: ('Your', 'Author') Tuple using List: (1, 2, 4, 5, 6) Tuple with the use of function: ('s', 'a', 'n', 'd', 'y') 3.3.2 Explain the syntax rules, assignments, iteration, and comprehensions Python Syntax Rules 1. Python is case sensitive. Hence a variable with name abc is not same as ABC. 135 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 2. For path specification, python uses forward slashes. Hence if you are working with a file, the default path for the file in case of Windows OS will have backward slashes, which you will have to convert to forward slashes to make them work in your python script. For window's path C:\folderA\folderB relative python program path should be C:/folderA/folderB 3. In python, there is no command terminator, which means no semicolon; or anything. 4. In one line only a single executable statement should be written and the line change act as command terminator in python.To write two separate executable statements in a single line, you should use a semicolon ; 5. In python, you can use single quotes '', double quotes "" and even triple quotes ''' """ to represent string literals. 6. In python, you can write comments in your program using a # at the start. A comment is ignored while the python script is executed. 7. Line Continuation: To write a code in multiline without confusing the python interpreter, is by using a backslash \ at the end of each line to explicitly denote line continuation. Expressions enclosed in ( ), [ ] or { } brackets don't need a backward slash for line continuation 8. Blank lines in between a program are ignored by python. 9. Code Indentation: This is the most important rule of python programming. In programming language like Java, C or C++, generally curly brackets { } are used to define a code block, but python doesn't use brackets, then how does python knows where a particular code block ends. Well python used indentation for this. 10. It is recommended to use tab for indentation, although you can use spaces for indentation as well, just keep in mind that the amount of indentation for a single code block should be same. 3.3.2.2 Assignment Statement An Assignment statement is a statement that is used to set a value to the variable name in a program. Assignment statement allows a variable to hold different types of values during its program lifespan. Another way of understanding an assignment statement is, it stores a value in the memory location which is denoted by a variable name. Syntax The symbol used in an assignment statement is called as an operator. The symbol is ‘=’. 136 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Note: The Assignment Operator should never be used for Equality purpose which is double equal sign ‘==’. The Basic Syntax of Assignment Statement in a programming language is : variable = expression ; where, variable = variable name expression = it could be either a direct value or a math expression/formula or a function call Few programming languages such as Java, C, C++ require data type to be specified for the variable, so that it is easy to allocate memory space and store those values during program execution. data_type variable_name = value ; Example – int a = 50 ; float b ; a = 25 ; In the above-given examples, Variable ‘a’ is assigned a value in the same statement as per its defined data type. A data type is only declared for Variable ‘b’. In the 3rd line of code, Variable ‘a’ is reassigned the value 25. Assignment Statement Forms 1. Basic Form This is one of the most common forms of Assignment Statements. Here the Variable name is defined, initialized, and assigned a value in the same statement. This form is generally used when we want to use the Variable quite a few times and we do not want to change its value very frequently. Example: a=10 137 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 2. Multiple Assignment: We can assign multiple values to variables at the same time Example: a=b=c=5 3. Augmented Assignment In this format, we use the combination of mathematical expressions and values for the Variable. Other augmented Assignment forms are: &=, -=, **=, etc. • • • speed = 40 ; speed += 10 ; // equivalent to speed = speed + 10 print (“Speed = ”, speed) ; Output – Speed = 50 Few Rules to be followed while writing the Assignment Statements are: • • • • Variable names must begin with a letter, underscore, non-number character. Each language has its own conventions. The Data type defined and the variable value must match. A variable name once defined can only be used once in the program. You cannot define it again to store other types of value. If you assign a new value to an existing variable, it will overwrite the previous value and assign the new value. 3.3.2.3 Iterator in Python An iterator in Python is an object that contains a countable number of elements that can be iterated upon. In simpler words, we can say that Iterators are objects that allow you to traverse through all the elements of a collection and return one element at a time. More specifically, we say that an iterator is an object that implements the iterator protocol. We are going to discuss this protocol in the later section. Iterator and Iterable 138 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Iterable is an object, which one can iterate over. It generates an Iterator when passed to the iter() method. Lists, tuples, dictionaries, strings and sets are all iterable objects. They are iterable containers that you can convert into an iterator. Note that every iterator is also an iterable, but not every iterable is an iterator. For example, a tuple is iterable, but it is not an iterator. An iterator can be created from an iterable by using the function iter(). Thus, when we pass this tuple to an iter() function, we will get an iterator. Actually, this is possible because the class of an object has a method __iter__, which returns an iterator. Which methods are defined in an iterator class in python? As mentioned above, an object that implements the iterator protocol is an iterator. But what is this iterator protocol? An iterator protocol is nothing but a specific class in Python which further has the __iter__() and __next__() methods. __iter__() This method returns the iterator object itself as mentioned above. This is required to allow both containers and iterators to be used with the for and in statements. This method corresponds to the tp_iter slot of the type structure for Python objects in the Python/C API. __next__() This method returns the next item from the container. If there are no further items, raise the StopIteration exception. This method corresponds to the tp_iternext slot of the type structure for Python objects in the Python/C API. Here is a simple example, describing these methods: # define a iterable such as a list >>> list1 = [0, 1, 2] # get an iterator using iter() >>> iter1 = list1.__iter__() #iertae the item using __next__method >>> print(iter1.__next__()) 0 We can use the __next__ method again to get the next item, in fact, we can use it as many times as we want and each time it’ll return the next item of the iterator. But when there are no elements in the iterator to return, it throws an error. Iterating Through an Iterator Now that we have an iterator object, what are the various ways by which we can traverse its elements such that we only get one item at a time? In this section, we are going to see a few ways in which we can do so, also we are going to show some of the examples for you to understand iterators better: Using the next() function 139 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook We can directly use next() function or __next__() method to traverse the elements as shown in the examples below: # define a iterable such as a list >>> list1 = [1, 2, 0] # get an iterator using iter() >>> iter1 = iter(list1) # iterate through it using next() >>> print(next(iter1)) 1 # next(obj) is same as obj.__next__() >>> print(iter1.__next__()) 2 >>> print(next(iter1)) 0 # This will raise error, no items left >>> next(my_iter) Traceback (most recent call last): File "<pyshell#8>", line 1, in <module> next(my_iter) Now let us see how we can traverse a string iterator: # define a iterable such as a string >>> string = "hi" # get an iterator using iter() >>> iter1 = iter(string) # iterate through it using next() >>> print(next(iter1)) h >>> print(next(iter1)) i # This will raise error, no items left >>> next(my_iter) Traceback (most recent call last): File "<pyshell#8>", line 1, in <module> next(my_iter) Iterating an iterator using while loop and for loop Since we are using the next() function repeatedly, why not use a while loop and make our work a bit easier. Also, we will use exception handling to take care of the error that we get when the iterator has 140 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer no elements left. So whenever the error “StopIteration” occurs, the control goes to the except block and the break statement is executed. Here is an example: # define an iterable such as a list list1=[1,2,3,4,5,6,7,8,9,0] # get an iterator using iter() iter1=iter(list1) # infinite loop while True: try: # get the next item print(next(iter1)) # do something with element except StopIteration: # if StopIteration is raised, break from loop break Output: 1 2 3 4 5 6 7 8 9 0 There is a much easier way to do this also by using a For loop. The for loop does all this under the hood, thus, you don’t need to explicitly call the iter() and next() functions. Here are a few examples: list1=[1,2,3,4,5,6,7,8,9,0] for i in list1: print(i) 141 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: 1 2 3 4 5 6 7 8 9 0 Now let us take some more example: list2=[1,2,"hello",[9,8,7],(11,12),{'one': 'husaain'}] for i in list2: print(i) Output: 1 2 hello [9, 8, 7] (11, 12) {‘one’: ‘husaain’} string="Hello World " for i in string: print(i) Output: H e l l o W 142 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer o r l d Create an Iterator Till now we have only used the inbuilt iterables such as lists or strings, but we can also build an iterator from scratch is easy in Python. We just have to implement the __iter__() and the __next__() methods. Here is our own custom Iterator that returns an even number or 1 every time we iterate upon it: class Evenit: def __init__(self, max=0): self.max = max def __iter__(self): self.n = 0 return self def __next__(self): if self.n <= self.max: if self.n % 2 ==0: result=self.n self.n += 1 return result else: self.n += 1 return 1 else: raise StopIteration # create an object numbers = Evenit(10) for i in numbers: print(i) 143 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: 0 1 2 1 4 1 6 1 8 1 10 As we can see, this iterator returns even numbers up to 10 (because we have given the argument to the event as 10), and whenever it encounters an odd number, it just returns 1. In a similar manner, you can create your own iterator. 3.3.2.4 Comprehensions in Python Using a given Python sequence, we may generate additional sequences. This is referred to as understanding. It is essentially a method of generating a short code block that generates a sequence that can be a list, dictionary, set, or generator by utilizing another sequence. It might entail several phases of conversion between different sorts of sequences. List Comprehension In this method, we create a new list by manipulating the values of an existing list. In the below example we take a list and create a new list by adding 3 to each element of the given list. Example given_list = [x for x in range(5)] print(given_list) new_list = [var+3 for var in given_list] print(new_list) Output Running the above code gives us the following result − [0, 1, 2, 3, 4] 144 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer [3, 4, 5, 6, 7] Dictionary Comprehensions Similar to the above we can take in a list and create a dictionary from it. Example given_list = [x for x in range(5)] print(given_list) #new_list = [var+3 for var in given_list] new_dict = {var:var + 3 for var in given_list } print(new_dict) Output Running the above code gives us the following result − [0, 1, 2, 3, 4] {0: 3, 1: 4, 2: 5, 3: 6, 4: 7} We can also take in two lists and create a new dictionary out of it. Example list1 = [x for x in range(5)] list2 = ['Mon','Tue','Wed','Thu','Fri'] print(list1) print(list2) new_dict ={key:value for (key, value) in zip(list1, list2)} print(new_dict) Output Running the above code gives us the following result − [0, 1, 2, 3, 4] ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'] {0: 'Mon', 1: 'Tue', 2: 'Wed', 3: 'Thu', 4: 'Fri'} 145 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Set Comprehension We can take a similar approach as above and create new set from existing set or list. In the below example we create a new set by adding 3 to the elements of the existing set. Example given_set = {x for x in range(5)} print(given_set) new_set = {var+3 for var in given_set} print(new_set) Output Running the above code gives us the following result − {0, 1, 2, 3, 4} {3, 4, 5, 6, 7} Generator comprehension New generators can be created from the existing list. These generators are memory efficient as they allocate memory as the items are generated instead of allocating it at the beginning. Example given_list = [x for x in range(5)] print(given_list) new_set = (var+3 for var in given_list) for var1 in new_set: print(var1, end=" ") Output Running the above code gives us the following result − [0, 1, 2, 3, 4] 34567 146 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.3.2.5 Decorators in Python Python has an interesting feature called decorators to add functionality to an existing code. This is also called metaprogramming because a part of the program tries to modify another part of the program at compile time. Prerequisites for learning decorators In order to understand about decorators, we must first know a few basic things in Python. We must be comfortable with the fact that everything in Python (Yes! Even classes), are objects. Names that we define are simply identifiers bound to these objects. Functions are no exceptions, they are objects too (with attributes). Various different names can be bound to the same function object. Here is an example. def first(msg): print(msg) first("Hello") second = first second("Hello") Output Hello Hello When you run the code, both functions first and second give the same output. Here, the names first and second refer to the same function object. Functions can be passed as arguments to another function. If you have used functions like map, filter and reduce in Python, then you already know about this. Such functions that take other functions as arguments are also called higher order functions. Here is an example of such a function. def inc(x): return x + 1 def dec(x): return x - 1 def operate(func, x): 147 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook result = func(x) return result We invoke the function as follows. >>> operate(inc,3) 4 >>> operate(dec,3) 2 Furthermore, a function can return another function. def is_called(): def is_returned(): print("Hello") return is_returned new = is_called() # Outputs "Hello" new() Output Hello Here, is_returned() is a nested function which is defined and returned each time we call is_called(). Finally, we must know about Closures in Python. Getting back to Decorators Functions and methods are called callable as they can be called. In fact, any object which implements the special __call__() method is termed callable. So, in the most basic sense, a decorator is a callable that returns a callable. Basically, a decorator takes in a function, adds some functionality and returns it. def make_pretty(func): def inner(): 148 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer print("I got decorated") func() return inner def ordinary(): print("I am ordinary") When you run the following codes in shell, >>> ordinary() I am ordinary >>> # let's decorate this ordinary function >>> pretty = make_pretty(ordinary) >>> pretty() I got decorated I am ordinary In the example shown above, make_pretty() is a decorator. In the assignment step: pretty = make_pretty(ordinary) The function ordinary() got decorated and the returned function was given the name pretty. We can see that the decorator function added some new functionality to the original function. This is similar to packing a gift. The decorator acts as a wrapper. The nature of the object that got decorated (actual gift inside) does not alter. But now, it looks pretty (since it got decorated). Generally, we decorate a function and reassign it as, ordinary = make_pretty(ordinary). This is a common construct and for this reason, Python has a syntax to simplify this. We can use the @ symbol along with the name of the decorator function and place it above the definition of the function to be decorated. For example, @make_pretty def ordinary(): print("I am ordinary") 149 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook is equivalent to def ordinary(): print("I am ordinary") ordinary = make_pretty(ordinary) This is just a syntactic sugar to implement decorators. Decorating Functions with Parameters The above decorator was simple and it only worked with functions that did not have any parameters. What if we had functions that took in parameters like: def divide(a, b): return a/b This function has two parameters, a and b. We know it will give an error if we pass in b as 0. >>> divide(2,5) 0.4 >>> divide(2,0) Traceback (most recent call last): ... ZeroDivisionError: division by zero Now let's make a decorator to check for this case that will cause the error. def smart_divide(func): def inner(a, b): print("I am going to divide", a, "and", b) if b == 0: print("Whoops! cannot divide") return return func(a, b) return inner @smart_divide def divide(a, b): print(a/b) 150 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer This new implementation will return None if the error condition arises. >>> divide(2,5) I am going to divide 2 and 5 0.4 >>> divide(2,0) I am going to divide 2 and 0 Whoops! cannot divide In this manner, we can decorate functions that take parameters. A keen observer will notice that parameters of the nested inner() function inside the decorator is the same as the parameters of functions it decorates. Taking this into account, now we can make general decorators that work with any number of parameters. In Python, this magic is done as function(*args, **kwargs). In this way, args will be the tuple of positional arguments and kwargs will be the dictionary of keyword arguments. An example of such a decorator will be: def works_for_all(func): def inner(*args, **kwargs): print("I can decorate any function") return func(*args, **kwargs) return inner Chaining Decorators in Python: Multiple decorators can be chained in Python. This is to say, a function can be decorated multiple times with different (or same) decorators. We simply place the decorators above the desired function. def star(func): def inner(*args, **kwargs): print("*" * 30) func(*args, **kwargs) print("*" * 30) return inner def percent(func): def inner(*args, **kwargs): print("%" * 30) func(*args, **kwargs) 151 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print("%" * 30) return inner @star @percent def printer(msg): print(msg) printer("Hello") Output ****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Hello %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ****************************** The above syntax of, @star @percent def printer(msg): print(msg) is equivalent to def printer(msg): print(msg) printer = star(percent(printer)) The order in which we chain decorators matter. If we had reversed the order as, @percent @star def printer(msg): print(msg) The output would be: 152 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ****************************** Hello ****************************** %%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 3.3.2.6 Metaclasses Introduction to the Python Metaclass A metaclass is a class that creates other classes. By default, Python uses the type metaclass to create other classes. For example, the following defines a Person class: class Person: def __init__(self, name, age): self.name = name self.age = age When Python executes the code, it uses the type metaclass to create the Person class. The reason is that the Person class uses the type metaclass by default. The explicit Person class definition looks like this: class Person(object, metaclass=type): def __init__(self, name, age): self.name = name self.age = age The metaclass argument allows you to specify which metaclass class to use to define the class. Therefore, you can create a custom metaclass that has its own logic to create other classes. By using a custom metaclass, you can inject functionality into the class creation process. Python metaclass example First, define a custom metaclass called Human that has the freedom attribute sets to True by default: class Human(type): def __new__(mcs, name, bases, class_dict): class_ = super().__new__(mcs, name, bases, class_dict) class_.freedom = True 153 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook return class_ Note that the __new__ method returns a new class or a class object. Second, define the Person class that uses the Human metaclass: class Person(object, metaclass=Human): def __init__(self, name, age): self.name = name self.age = age The Personclass will have the freedom attribute as shown in the class variables: pprint(Person.__dict__) wh Output: mappingproxy({'__dict__': <attribute '__dict__' of 'Person' objects>, '__doc__': None, '__init__': <function Person.__init__ at 0x000001E716C71670>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Person' objects>, 'freedom': True}) Put it all together. from pprint import pprint class Human(type): def __new__(mcs, name, bases, class_dict): class_ = super().__new__(mcs, name, bases, class_dict) class_.freedom = True return class_ class Person(object, metaclass=Human): def __init__(self, name, age): self.name = name self.age = age 154 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer pprint(Person.__dict__) Metaclass Parameters To pass parameters to a metaclass, you use the keyword arguments. For example, the following redefines the Human metaclass that accepts keyword arguments, where each argument becomes a class variable: class Human(type): def __new__(mcs, name, bases, class_dict, **kwargs): class_ = super().__new__(mcs, name, bases, class_dict) if kwargs: for name, value in kwargs.items(): setattr(class_, name, value) return class_ The following uses the Human metaclass to create a Person class with the country and freedom class variables set to USA and True respectively: class Person(object, metaclass=Human, country='USA', freedom=True): def __init__(self, name, age): self.name = name self.age = age Here are Person class variables: pprint(Person.__dict__) Output: mappingproxy({'__dict__': <attribute '__dict__' of 'Person' objects>, '__doc__': None, '__init__': <function Person.__init__ at 0x0000018A334235E0>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'Person' objects>, 'country': 'USA', 'freedom': True}) 155 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook from pprint import pprint class Human(type): def __new__(mcs, name, bases, class_dict, **kwargs): class_ = super().__new__(mcs, name, bases, class_dict) if kwargs: for name, value in kwargs.items(): setattr(class_, name, value) return class_ classPerson(object,metaclass=Human,freedom=True, country='USA'): def __init__(self, name, age): self.name = name self.age = age pprint(Person.__dict__) 3.3.2.7 Python Gotchas Python is the language of choice for the majority of newbies to the programming world. This is due to the fact that it is very simple, in great demand, and ultimately powerful. However, there are several situations that may perplex or even deceive a novice developer. These are known as "Gotchas"! A gotcha, derived from the informal expression "Got You!", is a circumstance or scenario in which the software performs the trick and produces an output that is significantly different from what was intended. A gotcha is not the same as an error or an exception. It is totally legitimate code that produces wrong output just because we overlooked a minor fact or point when developing our application. As a result, we may classify gotchas as "frequently created." python-gotchas Let’s take a look at some most common gotchas in Python3 and how to tackle them: The parenthesis gotchas : There are a few gotchas that arise when the parenthesis is used incorrectly or unnecessarily. Example: # results in False print(5>2 == True) 156 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Output: False This results in False because the above expression effectively means that 5>2 and 2==True. This implies, True and False. Hence, the final result is False. It can be corrected by the use of parenthesis. # results in True print((5>2) == True) Output: True Here is one more example: # results in False print(5 is (not None)) Output: False This is because "is not" is different from "is" and "not" being used separately. The part (not None) equals True and 5 is True results in False. It can be corrected by not using any parenthesis. # results in True print(5 is not None) Output: True “is”, “==”, “is not”, “!=” : This is a short but very common gotcha. Many new programmers often think that is and == are the same thing. But it’s definitely not! # results in True print(1 == True) # results in False print(1 is True) 157 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: True False On the other hand, is not and != are same. # results in True print(1 != False) # results in True print(1 is not False) Output: True True Default arguments gotcha : In Python, default arguments are declared only once when the function is run for the first time and from then on, the declared argument is used every time. def appendNew(appendTo =[]): appendTo.append(1) return appendTo # Driver's code print(appendNew()) print(appendNew()) It’s expected that every time we call appendNew(), a new list will be created which will have 1 in it. But what happens is this: [1] [1, 1] The variable appendTo isn’t created again when the function is run for the second time. Instead, it’s created only the first time and used again and again. We can tackle it by: def appendNew(appendTo = None): if appendTo == None: appendTo =[] appendTo.append(1) 158 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer return appendTo # Driver's code print(appendNew()) print(appendNew()) Output: [1] [1] Scope gotchas : Sometimes, we must keep in mind the scope of the variable we are dealing with, i.e whether it is a global scope(works but inside and outside of a function) or a local scope(works just inside the function). Example: list1 = [1, 2, 3] def baz1(): # the code works fine list1.append(4) return list1 def baz2(): # Doesn't work fine list1 += [5] return list1 # Driver's code print(baz1()) print(baz2()) Output: [1, 2, 3, 4] Traceback (most recent call last): File "/home/ba0dfa25407638b061076b45ce165ce5.py", line 15, in 159 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print(baz2()) File "/home/ba0dfa25407638b061076b45ce165ce5.py", line 10, in baz2 list1 += [5] UnboundLocalError: local variable 'list1' referenced before assignment This happens because list1 += [5] means that we are assigning to the variable list1 but list1 is defined outside the scope of our function. While in baz1(), we are appending to list1 instead of assigning and hence it works fine. Variables are bound late in closures : Python has an infamous late binding behavior. By this, we mean that the value of a variable which is being iterated over is finalized to the value when it reaches its last iteration. Let’s look at an example: def create_multipliers(): # lambda function creates an iterable # list anonymously return [lambda c : i * c for i in range(6)] for multiplier in create_multipliers(): print multiplier(3) The expected result is of course: 0 3 6 9 12 15 But what we get is: 15 15 15 160 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 15 15 15 This is because when the loop iteration is complete, i has a value of 5 and hence 3*5 each time results in 15. It can be solved by: def create_multipliers(): return [lambda x, i = i : i * x for i in range(6)] for multiplier in create_multipliers(): print(multiplier(3)) Output: 0 3 6 9 12 15 Mutating a list while iterating over it : This is the most common gotcha which new coders face almost all the time. While working with a list or other mutable items, if we mutate it while iterating over it, it’s certain to cause errors. It’s recommended that we create the copy of the list instead and mutate it rather than the original list. # buggy program to print a list # of odd numbers from 1 to 10 even = lambda x : bool(x % 2) numbers = [n for n in range(10)] for i in range(len(numbers)): if not even(numbers[i]): del numbers[i] 161 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: Traceback (most recent call last): File "/home/92eed8bfd8c92fca3cf85f22e8cfd9ea.py", line 9, in if not even(numbers[i]): IndexError: list index out of range But if we use a copy of numbers instead: # working program to print a # list of odd numbers from 1 to 10 even = lambda x : bool(x % 2) numbers = [n for n in range(10)] numbers[:] = [n for n in numbers if even(n)] print(numbers) Output: [1, 3, 5, 7, 9] 3.3.2.8 Managed Attributes A popular use for descriptors is managing access to instance data. The descriptor is assigned to a public attribute in the class dictionary while the actual data is stored as a private attribute in the instance dictionary. The descriptor’s __get__() and __set__() methods are triggered when the public attribute is accessed. In the following example, age is the public attribute and _age is the private attribute. When the public attribute is accessed, the descriptor logs the lookup or update: import logging logging.basicConfig(level=logging.INFO) class LoggedAgeAccess: def __get__(self, obj, objtype=None): value = obj._age logging.info('Accessing %r giving %r', 'age', value) return value def __set__(self, obj, value): 162 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer logging.info('Updating %r to %r', 'age', value) obj._age = value class Person: age = LoggedAgeAccess() # Descriptor instance def __init__(self, name, age): self.name = name self.age = age # Regular instance attribute # Calls __set__() def birthday(self): self.age += 1 # Calls both __get__() and __set__() An interactive session shows that all access to the managed attribute age is logged, but that the regular attribute name is not logged: mary = Person('Mary M', 30) # The initial age update is logged INFO:root:Updating 'age' to 30 dave = Person('David D', 40) INFO:root:Updating 'age' to 40 vars(mary) # The actual data is in a private attribute {'name': 'Mary M', '_age': 30} vars(dave) {'name': 'David D', '_age': 40} mary.age # Access the data and log the lookup INFO:root:Accessing 'age' giving 30 30 mary.birthday() # Updates are logged as well INFO:root:Accessing 'age' giving 30 INFO:root:Updating 'age' to 31 dave.name # Regular attribute lookup isn't logged 'David D' dave.age # Only the managed attribute is logged 163 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook INFO:root:Accessing 'age' giving 40 40 3.3.2.9 MetaData importlib_metadata is a library that provides access to the metadata of an installed Distribution Package, such as its entry points or its top-level names (Import Packages, modules, if any). Built in part on Python’s import system, this library intends to replace similar functionality in the entry point API and metadata API of pkg_resources. Along with importlib.resources, this package can eliminate the need to use the older and less efficient pkg_resources package. importlib_metadata operates on third-party distribution packages installed into Python’s site-packages directory via tools such as pip. Specifically, it works with distributions with discoverable dist-info or egginfo directories, and metadata defined by the Core metadata specifications. Important These are not necessarily equivalent to or correspond 1:1 with the top-level import package names that can be imported inside Python code. One distribution package can contain multiple import packages (and single modules), and one top-level import package may map to multiple distribution packages if it is a namespace package. You can use package_distributions() to get a mapping between them. By default, distribution metadata can live on the file system or in zip archives on sys.path. Through an extension mechanism, the metadata can live almost anywhere. See also https://importlib-metadata.readthedocs.io/ The documentation for importlib_metadata, which supplies a backport of importlib.metadata. This includes an API reference for this module’s classes and functions, as well as a migration guide for existing users of pkg_resources. Let’s say you wanted to get the version string for a Distribution Package you’ve installed using pip. We start by creating a virtual environment and installing something into it: python3 -m venv example source example/bin/activate python -m pip install wheel You can get the version string for wheel by running the following: >>> (example) $ python from importlib.metadata import version version('wheel') '0.32.3' You can also get a collection of entry points selectable by properties of the EntryPoint (typically ‘group’ 164 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer or ‘name’), such as console_scripts, distutils.commands and others. Each group contains a collection of EntryPoint objects. You can get the metadata for a distribution: >>> list(metadata('wheel')) ['Metadata-Version', 'Name', 'Version', 'Summary', 'Home-page', 'Author', 'Author-email', 'Maintainer', 'Maintainer-email', 'License', 'Project-URL', 'Project-URL', 'Project-URL', 'Keywords', 'Platform', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Classifier', 'Requires-Python', 'Provides-Extra', 'Requires-Dist', 'Requires-Dist'] You can also get a distribution’s version number, list its constituent files, and get a list of the distribution’s Distribution requirements. Functional API This package provides the following functionality via its public API. Entry points The entry_points() function returns a collection of entry points. Entry points are represented by EntryPoint instances; each EntryPoint has a .name, .group, and .value attributes and a .load() method to resolve the value. There are also .module, .attr, and .extras attributes for getting the components of the .value attribute. Query all entry points: >>> eps = entry_points() The entry_points() function returns an EntryPoints object, a collection of all EntryPoint objects with names and groups attributes for convenience: >>> sorted(eps.groups) ['console_scripts', 'distutils.commands', 'distutils.setup_keywords', 'egg_info.writers', 'setuptools. installation'] EntryPoints has a select method to select entry points matching specific properties. Select entry points in the console_scripts group: >>> scripts = eps.select(group='console_scripts') Equivalently, since entry_points passes keyword arguments through to select: 165 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook >>> scripts = entry_points(group='console_scripts') Pick out a specific script named “wheel” (found in the wheel project): >>> 'wheel' in scripts.names True wheel = scripts['wheel'] Equivalently, query for that entry point during selection: >>> (wheel,) = entry_points(group='console_scripts', name='wheel') (wheel,) = entry_points().select(group='console_scripts', name='wheel') Inspect the resolved entry point: >>> wheel EntryPoint(name='wheel', value='wheel.cli:main', group='console_scripts') wheel.module 'wheel.cli' wheel.attr 'main' wheel.extras [] main = wheel.load() main <function main at 0x103528488> The group and name are arbitrary values defined by the package author and usually a client will wish to resolve all entry points for a particular group. Read the setuptools docs for more information on entry points, their definition, and usage. Compatibility Note The “selectable” entry points were introduced in importlib_metadata 3.6 and Python 3.10. Prior to those changes, entry_points accepted no parameters and always returned a dictionary of entry points, keyed by group. For compatibility, if no parameters are passed to entry_points, a SelectableGroups object is 166 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer returned, implementing that dict interface. In the future, calling entry_points with no parameters will return an EntryPoints object. Users should rely on the selection interface to retrieve entry points by group. Distribution metadata Every Distribution Package includes some metadata, which you can extract using the metadata() function: >>> wheel_metadata = metadata('wheel') The keys of the returned data structure, a PackageMetadata, name the metadata keywords, and the values are returned unparsed from the distribution metadata: >>> wheel_metadata['Requires-Python'] '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' PackageMetadata also presents a json attribute that returns all the metadata in a JSON-compatible form per PEP 566: >>> wheel_metadata.json['requires_python'] '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' Note The actual type of the object returned by metadata() is an implementation detail and should be accessed only through the interface described by the PackageMetadata protocol. Changed in version 3.10: The Description is now included in the metadata when presented through the payload. Line continuation characters have been removed. New in version 3.10: The json attribute was added. Distribution versions The version() function is the quickest way to get a Distribution Package’s version number, as a string: >>> version('wheel') '0.32.3' Distribution files You can also get the full set of files contained within a distribution. The files() function takes a Distribution Package name and returns all of the files installed by this distribution. Each file object returned is a PackagePath, a pathlib.PurePath derived object with additional dist, size, and hash properties as 167 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook indicated by the metadata. For example: >>> util = [p for p in files('wheel') if 'util.py' in str(p)][0] util PackagePath('wheel/util.py') util.size 859 util.dist <importlib.metadata._hooks.PathDistribution object at 0x101e0cef0> util.hash <FileHash mode: sha256 value: bYkw5oMccfazVCoYQwKkkemoVyMAFoR34mmKBx8R1NI> Once you have the file, you can also read its contents: >>> print(util.read_text()) import base64 import sys def as_bytes(s): if isinstance(s, text_type): return s.encode('utf-8') return s You can also use the locate method to get a the absolute path to the file: >>> util.locate() PosixPath('/home/gustav/example/lib/site-packages/wheel/util.py') In the case where the metadata file listing files (RECORD or SOURCES.txt) is missing, files() will return None. The caller may wish to wrap calls to files() in always_iterable or otherwise guard against this condition if the target distribution is not known to have the metadata present. Distribution requirements To get the full set of requirements for a Distribution Package, use the requires() function: >>> requires('wheel') 168 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer ["pytest (>=3.0.0) ; extra == 'test'", "pytest-cov ; extra == 'test'"] Mapping import to distribution packages A convenience method to resolve the Distribution Package name (or names, in the case of a namespace package) that provide each importable top-level Python module or Import Package: >>> packages_distributions() {'importlib_metadata': ['importlib-metadata'], 'yaml': ['PyYAML'], 'jaraco': ['jaraco.classes', 'jaraco. functools'], ...} New in version 3.10. Distributions While the above API is the most common and convenient usage, you can get all of that information from the Distribution class. A Distribution is an abstract object that represents the metadata for a Python Distribution Package. You can get the Distribution instance: >>> from importlib.metadata import distribution dist = distribution('wheel') Thus, an alternative way to get the version number is through the Distribution instance: >>> dist.version '0.32.3' There are all kinds of additional metadata available on the Distribution instance: >>> dist.metadata['Requires-Python'] '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' dist.metadata['License'] 'MIT' The full set of available metadata is not described here. See the Core metadata specifications for additional details. Distribution Discovery By default, this package provides built-in support for discovery of metadata for file system and zip file Distribution Packages. This metadata finder search defaults to sys.path, but varies slightly in how it interprets those values from how other import machinery does. In particular: 169 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook importlib.metadata does not honor bytes objects on sys.path. importlib.metadata will incidentally honor pathlib.Path objects on sys.path even though such values will be ignored for imports. Extending the search algorithm Because Distribution Package metadata is not available through sys.path searches, or package loaders directly, the metadata for a distribution is found through import system finders. To find a distribution package’s metadata, importlib.metadata queries the list of meta path finders on sys.meta_path. By default importlib_metadata installs a finder for distribution packages found on the file system. This finder doesn’t actually find any distributions, but it can find their metadata. The abstract class importlib.abc.MetaPathFinder defines the interface expected of finders by Python’s import system. importlib.metadata extends this protocol by looking for an optional find_distributions callable on the finders from sys.meta_path and presents this extended interface as the DistributionFinder abstract base class, which defines this abstract method: @abc.abstractmethod def find_distributions(context=DistributionFinder.Context()): """Return an iterable of all Distribution instances capable of loading the metadata for packages for the indicated ``context``. """ The DistributionFinder.Context object provides .path and .name properties indicating the path to search and name to match and may supply other relevant context. What this means in practice is that to support finding distribution package metadata in locations other than the file system, subclass Distribution and implement the abstract methods. Then from a custom finder, return instances of this derived Distribution in the find_distributions() method. 3.3.2.10 Python Design Pattern What is Design Pattern? The design pattern is a technique which used by the developer to solve the commonly occurring software design. In simple word, it is a predefine pattern to solve a recurring problem in the code. These patterns are mainly designed based on requirements analysis. The design pattern is a part of the software development. It is a general repeatable solution for the potential problem in software development. We can follow the patterns details and apply a solution which suits our code. We may often confuse the patterns and algorithm, but both are separate approaches to solve repetitive problems. Algorithms generally define the clear set of the solution that can be implemented in some problems, where the patters are high-level description of the solution. For example - An algorithm is like a cooking recipe: we have a clear set of ingredients (or set of solutions) to cook something (problems or goals). On the other side, a pattern is like a blueprint: we can see what the result and its features are, but we can modify the order of implementation. 170 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Configuration of Design Pattern In the below diagram, we describe the basic structure of the design pattern documentation. It is focused on what technology we are using to solve the problems and in what ways. • • • Pattern Name - It is used to define the pattern in a shortly and effectively. Intent/ Motive - It defines the goal or what the pattern does. Applicability - It defines all the possible areas where the pattern is applicable. Participants and Consequences -It consists of classes and objects used in the design pattern with the list of consequences that exist with the pattern. History of Patterns Design patterns are the set of the solution of common problems in object-oriented design. When the problem's solution is repeated again and again in the various projects, someone eventually puts a name and defines the solution in detail. That is how the pattern gets recognized. Christopher Alexander has described the concept of the pattern for the first time in the book named A Pattern Language: Towns, Building, and Construction. This book defines a 'language' for designing the urban environment. The language is nothing but the patterns. The four authors: Erich Gamma, John, Vlissiders, Ralph Johnson, and Richard Helm, were picked the idea of a pattern language. Later, they published the book named Design Patterns: Elements of Reusable Object-Oriented Software. This book contains the concept of design patterns using the programming language. The book featured the 23 useful various problems of object-oriented designs; It gained the much popularity among the programmers and became the best seller book very quickly. Interesting Fact - This book has a very long name so people started to call it "The book of gang of four" which was soon summarized to simply "The GoF book". Many other object-oriented patterns are discovered after this book. Very soon, the pattern approach became very famous in the programming fields. There are many others patterns available apart from object-oriented design as well. Advantages of Using Design Pattern The advantages of using the design patterns are given below. All design patterns are language neutral. Patterns offer programmers to select a tried and tested solution for the specific problems. It consists of record of execution to decrease any technical risk to the projects. Patterns are easy to use and highly flexible. Design Pattern in Python We are all familiar with Python's feature; if someone does not, let's have a brief introduction - Python is a high-level, open-source, and dynamic typed language. It has English-like syntax and easy to learn. It provides numerous libraries that support a variety of designs. 171 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook We are listed below the design patterns that are supported by Python. We will use these design patterns in our tutorial. • • • • • • • • • • • • • • • • • • • Model View Controller Pattern Flyweight Pattern Factory pattern Singleton pattern Object Oriented Pattern Strategy Pattern Command Pattern Chain of Responsibility Pattern Abstract Factory Pattern Proxy Pattern Facade Pattern Observer Pattern Prototype Pattern Template Pattern Adapter Pattern Builder Pattern Prototype Pattern Decorator Pattern State Pattern Importance of Learn Design Pattern Many of the software developers might work for many years without knowing about any single pattern. It can also happen we might be implementing a pattern without even knowing it. So, here the question arises, why should we learn the design pattern? Let's look at the following points, which light up the importance of design patterns in development. Design patterns have the predefined set of tried and tested solutions to a common problem encountered while developing software. If we know about the design pattern, then we can apply the solution without wasting time. It also teaches us how to solve the problem using the principle of object-oriented design. Design pattern also enhances the common understanding between the developer and their teammates. Suppose there is a problem in the code, and you can say "Use Singleton for that," and everyone can understand if he/she knows the design pattern and its name. Design patterns are also useful for the learning purpose because they introduce the common problem that we may have ignored. They also allow thinking that area that may not have had the hand-on experience. 3.3.3 Control Structures Conditional (if): The if statement contains a logical expression using which data is compared and a decision is made based on the result of the comparison. 172 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Syntax: if expression: statement(s) If the boolean expression evaluates to TRUE, then the block of statement(s) inside the if statement is executed. If boolean expression evaluates to FALSE, then the first set of code after the end of the if statement(s) is executed. if Statement Flowchart: Example: Python if Statement a=3 if a > 2: print(a, "is greater") print("done") a = -1 if a < 0: print(a, "a is smaller") print("Finish") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/if1.py 3 is greater done -1 a is smaller Finish a=10 173 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook if a>9: print("A is Greater than 9") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/if2.py A is Greater than 9 Alternative if (If-Else): An else statement can be combined with an if statement. An else statement contains the block of code (false block) that executes if the conditional expression in the if statement resolves to 0 or a FALSE value. The else statement is an optional statement and there could be at most only one else Statement following if. Syntax of if - else : if test expression: Body of if stmts else: Body of else stmts Example of if - else: if a>5: print("a is greater") else: print("a is smaller than the input given") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/ifelse.py enter the number 2 a is smaller than the input given ---------------------------------------a=10 b=20 if a>b: print("A is Greater than B") else: print("B is Greater than A") 174 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/if2.py B is Greater than A Chained Conditional: (If-elif-else): The elif statement allows us to check multiple expressions for TRUE and execute a block of code as soon as one of the conditions evaluates to TRUE. Similar to the else, the elif statement is optional. However, unlike else, for which there can be at most one statement, there can be an arbitrary number of elif statements following an if. Syntax of if – elif - else : If test expression: Body of if stmts elif test expression: Body of elif stmts else: Body of else stmts Flowchart of if – elif - else: Fig: Operation of if – elif - else statement Example of if - elif – else: a=int(input('enter the number')) a=int(input('enter the number')) b=int(input('enter the number')) c=int(input('enter the number')) if a>b: 175 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print("a is greater") elif b>c: print("b is greater") else: print("c is greater") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/ifelse.py enter the number 5 enter the number 2 enter the number 9 a is greater >>> C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/ifelse.py enter the number 2 enter the number 5 enter the number 9 c is greater ----------------------------var = 100 if var == 200: print("1 - Got a true expression value") print(var) elif var == 150: print("2 - Got a true expression value") print(var) elif var == 100: print("3 - Got a true expression value") print(var) else: print("4 - Got a false expression value") print(var) print("Good bye!") 176 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/ifelif.py 3 - Got a true expression value 100 Good bye! Iteration: A loop statement allows us to execute a statement or group of statements multiple times as long as the condition is true. Repeated execution of a set of statements with the help of loops is called iteration. Loops statements are used when we need to run same code again and again, each time with a different value. Statements: In Python Iteration (Loops) statements are of three types: 1. While Loop 2. For Loop 3. Nested For Loops While loop: • • • Loops are either infinite or conditional. Python while loop keeps reiterating a block of code defined inside it until the desired condition is met. The while loop contains a boolean expression and the code inside the loop is repeatedly executed as long as the boolean expression is true. The statements that are executed inside while can be a single line of code or a block of multiple statements. Syntax: while(expression): Statement(s) Flowchart: 177 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example Programs: 1.i=1 while i<=6: print("CET college") i=i+1 Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/wh1.py CET college CET college CET college CET college CET college CET college 2.i=1 while i<=3: print("CET",end=" ") j=1 while j<=1: print("CSE DEPT",end="") j=j+1 i=i+1 print() j=1 while i<=3: print("CET",end=" ") while j<=1: print("CSE DEPT",end="") j=j+1 i=i+1 print() Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/wh3.py CET CSE DEPT CET CET 4. i = 1 178 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer while (i < 10): print (i) i = i+1 Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/wh4.py 1 2 3 4 5 6 7 8 9 2. a = 1 b=1 while (a<10): print ('Iteration',a) a=a+1 b=b+1 if (b == 4): break print ('While loop terminated') Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/wh5.py Iteration 1 Iteration 2 Iteration 3 While loop terminated count = 0 while (count < 9): print("The count is:", count) count = count + 1 print("Good bye!") 179 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/wh.py The count is: 0 The count is: 1 The count is: 2 The count is: 3 The count is: 4 The count is: 5 The count is: 6 The count is: 7 The count is: 8 Good bye! For loop: Python for loop is used for repeated execution of a group of statements for the desired number of times. It iterates over the items of lists, tuples, strings, the dictionaries and other iterable objects Syntax: for var in sequence: Statements Sample Program: numbers = [1, 2, 4, 6, 11, 20] seq=0 for val in numbers: seq=val*val print(seq) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/fr.py 1 4 16 36 121 400 180 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Flowchart: Iterating over a list: #list of items list = ['A','B','C','E','T'] i=1 #Iterating over the list for item in list: for i in list print ('college ',i,' is ',list) i = i+1 Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/lis.py college 1 is A college 2 is B college 3 is C college 4 is E college 5 is T Iterating over a Tuple: tuple = (2,3,5,7) print ('These are the first four prime numbers ') #Iterating over the tuple for a in tuple: 181 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print (a) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fr3.py These are the first four prime numbers 2 3 5 7 Iterating over a dictionary: #creating a dictionary college = {"ces":"block1","it":"block2","ece":"block3"} #Iterating over the dictionary to print keys print ('Keys are:') for keys in college: print (keys) #Iterating over the dictionary to print values print ('Values are:') for blocks in college.values(): print(blocks) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/dic.py Keys are: ces it ece Values are: block1 block2 block3 Iterating over a String: #declare a string to iterate over college = 'CET' #Iterating over the string for name in college: 182 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer print (name) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/strr.py ABCET Nested For loop: When one Loop defined within another Loop is called Nested Loops. Syntax: for val in sequence: for val in sequence: statements statements # Example 1 of Nested For Loops (Pattern Programs) for i in range(1,6): for j in range(0,i): print(i, end=" ") print('') Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/nesforr.py 1 22 333 4444 55555 # Example 2 of Nested For Loops (Pattern Programs) for i in range(1,6): for j in range(5,i-1,-1): print(i, end=" ") print('') C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/nesforr.py 183 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: 11111 2222 333 44 Break and continue: In Python, break and continue statements can alter the flow of a normal loop. Sometimes we wish to terminate the current iteration or even the whole loop without checking test expression. The break and continue statements are used in these cases. Break: The break statement terminates the loop containing it and control of the program flows to the statement immediately after the body of the loop. If break statement is inside a nested loop (loop inside another loop), break will terminate the innermost loop. Flowchart: The following shows the working of break statement in for and while loop: for var in sequence: # code inside for loop If condition: break (if break condition satisfies it jumps to outside loop) # code inside for loop # code outside for loop while test expression # code inside while loop If condition: 184 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer break (if break condition satisfies it jumps to outside loop) # code inside while loop # code outside while loop Example: for val in "CET COLLEGE": if val == " ": break print(val) print("The end") Output: C E T The end # Program to display all the elements before number 88 for num in [11, 9, 88, 10, 90, 3, 19]: print(num) if(num==88): print("The number 88 is found") print("Terminating the loop") break Output: 11 9 88 The number 88 is found Terminating the loop for letter in "Python": if letter == "h": break print("Current Letter :", letter ) 185 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/br.py Current Letter : P Current Letter : y Current Letter : t Continue: The continue statement is used to skip the rest of the code inside a loop for the current iteration only. Loop does not terminate but continues on with the next iteration. Flowchart: The following shows the working of break statement in for and while loop: for var in sequence: # code inside for loop If condition: continue (if break condition satisfies it jumps to outside loop)# code inside for loop # code outside for loop while test expression # code inside while loop If condition: continue(if break condition satisfies it jumps to outside loop) # code inside while loop 186 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer # code outside while loop Example: # Program to show the use of continue statement inside loops for val in "string": if val == "i": continue print(val) print("The end") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/cont.py s t r n g The end # program to display only odd numbers for num in [20, 11, 9, 66, 4, 89, 44]: # Skipping the iteration when number is even if num%2 == 0: continue # This statement will be skipped for all even numbers print(num) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/cont2.py 11 9 89 for letter in "Python": if letter == "h": continue 187 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print("Current Letter :", letter) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/con1.py Current Letter : P Current Letter : y Current Letter : t Current Letter : o Current Letter : n Pass: In Python programming, pass is a null statement. The difference between a comment and pass statement in Python is that, while the interpreter ignores a comment entirely, pass is not ignored. pass is just a placeholder for functionality to be added later. Example: sequence = {'p', 'a', 's', 's'} for val in sequence: pass Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/f1.y.py >>> Similarly we can also write, def f(arg): pass # a function that does nothing (yet) class C: pass # a class with no 188 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Exercise Answer the following questions: 1. Loops are known as ___ in programming. a) Control flow statements c) Data structure statements b) Conditional statements d) None of the mentioned above 2. The for loop in Python is used to ___ over a sequence or other iterable objects. a) Jumpb) Iterate c) Switch d) All of the mentioned above 3. With the break statement we can stop the loop before it has looped through all the items? a) Trueb) False 4. The continue keyword is used to ___ the current iteration in a loop. a) Initiateb) Start c) End d) None of the mentioned above 5. Amongst which of the following is / are true about the while loop? a) It continually executes the statements as long as the given condition is true b) It first checks the condition and then jumps into the instructions c) The loop stops running when the condition becomes fail, and control will move to the next line of code. d) All of the mentioned above 3.3.4 Functions Functions and its use: Function is a group of related statements that perform a specific task. Functions help break our program into smaller and modular chunks. As our program grows larger and larger, functions make it more organized and manageable. It avoids repetition and makes code reusable. Basically, we can divide functions into the following two types: 1. Built-in functions - Functions that are built into Python. Ex: abs(),all().ascii(),bool()………so on…. integer = -20 print('Absolute value of -20 is:', abs(integer)) Output: Absolute value of -20 is: 20 189 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 2. User-defined functions - Functions defined by the users themselves. def add_numbers(x,y): sum = x + y return sum print("The sum is", add_numbers(5, 20)) Output: The sum is 25 Flow of Execution: • • • • • The order in which statements are executed is called the flow of execution Execution always begins at the first statement of the program. Statements are executed one at a time, in order, from top to bottom. Function definitions do not alter the flow of execution of the program, but remember that statements inside the function are not executed until the function is called. Function calls are like a bypass in the flow of execution. Instead of going to the next statement, the flow jumps to the first line of the called function, executes all the statements there, and then comes back to pick up where it left off. Note: When you read a program, don‟t read from top to bottom. Instead, follow the flow of execution. This means that you will read the def statements as you are scanning from top to bottom, but you should skip the statements of the function definition until you reach a point where that function is called. Example: #example for flow of execution print("welcome") for x in range(3): print(x) print("Good morning college") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/flowof.py welcome 0 1 2 Good morning college 190 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer The flow/order of execution is: 2,3,4,3,4,3,4,5 __________________ Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/flowof.py hi hello Good morning CET done! The flow/order of execution is: 2,5,6,7,2,3,4,7,8 Parameters and arguments: Parameters are passed during the definition of function while Arguments are passed during the function call. Example: #here a and b are parameters def add(a,b): #//function definition return a+b #12 and 13 are arguments #function call result=add(12,13) print(result) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/paraarg.py 25 191 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook There are three types of Python function arguments using which we can call a function. 1. Default Arguments 2. Keyword Arguments 3. Variable-length Arguments Syntax: def functionname(): statements . . . functionname() Function definition consists of following components: 1. Keyword def indicates the start of function header. 2. A function name to uniquely identify it. Function naming follows the same rules of writing identifiers in Python. 3. Parameters (arguments) through which we pass values to a function. They are optional. 4. A colon (:) to mark the end of function header. 5. Optional documentation string (docstring) to describe what the function does. 6. One or more valid python statements that make up the function body. Statements must have same indentation level (usually 4 spaces). 7. An optional return statement to return a value from the function. Example: def hf(): hello world hf() In the above example we are just trying to execute the program by calling the function. So it will not display any error and no output on to the screen but gets executed. To get the statements of function need to be use print(). #calling function in python: def hf(): print("hello world") hf() Output: hello world 192 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer def hf(): print("hw") print("gh kfjg 66666") hf() hf() hf() Output: hw gh kfjg 66666 hw gh kfjg 66666 hw gh kfjg 66666 ________________ def add(x,y): c=x+y print(c) add(5,4) Output: 9 def add(x,y): c=x+y return c print(add(5,4)) Output: 9 ________________ def add_sub(x,y): c=x+y d=x-y return c,d print(add_sub(10,5)) 193 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: (15, 5) The return statement is used to exit a function and go back to the place from where it was called. This statement can contain expression which gets evaluated and the value is returned. If there is no expression in the statement or the return statement itself is not present inside a function, then the function will return the None object. def hf(): return "hw" print(hf()) Output: hw ________________ def hf(): return "hw" hf() Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu.py >>> def hello_f(): return "hellocollege" print(hello_f().upper()) Output: HELLOCOLLEGE # Passing Arguments def hello(wish): return '{}'.format(wish) print(hello("CET")) Output: CET ________________ 194 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Here, the function wish() has two parameters. Since, we have called this function with two arguments, it runs smoothly and we do not get any error. If we call it with different number of arguments, the interpreter will give errors. def wish(name,msg): """This function greets to the person with the provided message """ print("Hello",name + ' ' + msg) wish("CET","Good morning!") Output: Hello CET Good morning! Below is a call to this function with one and no arguments along with their respective error messages. >>> wish("CET") # only one argument TypeError: wish() missing 1 required positional argument: 'msg' >>> wish() # no arguments TypeError: wish() missing 2 required positional arguments: 'name' and 'msg' ________________ def hello(wish,hello): return “hi” '{},{}'.format(wish,hello) print(hello("CET","college")) Output: hiCET,college #Keyword Arguments When we call a function with some values, these values get assigned to the arguments according to their position. Python allows functions to be called using keyword arguments. When we call functions in this way, the order (position) of the arguments can be changed. (Or) If you have some functions with many parameters and you want to specify only some of them, then you can give values for such parameters by naming them - this is called keyword arguments - we use the name (keyword) instead of the position (which we have been using all along) to specify the arguments to the function. There are two advantages - one, using the function is easier since we do not need to worry about the order of the arguments. Two, we can give values to only those parameters which we want, provided that the other parameters have default argument values. 195 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook def func(a, b=5, c=10): print 'a is', a, 'and b is', b, 'and c is', c func(3, 7) func(25, c=24) func(c=50, a=100) Output: a is 3 and b is 7 and c is 10 a is 25 and b is 5 and c is 24 a is 100 and b is 5 and c is 50 Note: The function named func has one parameter without default argument values, followed by two parameters with default argument values. In the first usage, func(3, 7), the parameter a gets the value 3, the parameter b gets the value 5 and c gets the default value of 10. In the second usage func(25, c=24), the variable a gets the value of 25 due to the position of the argument. Then, the parameter c gets the value of 24 due to naming i.e. keyword arguments. The variable b gets the default value of 5. In the third usage func(c=50, a=100), we use keyword arguments completely to specify the values. Notice, that we are specifying value for parameter c before that for a even though a is defined before c in the function definition. For example: if you define the function like below def func(b=5, c=10,a): # shows error : non-default argument follows default argument ________________ def print_name(name1, name2): """ This function prints the name """ print (name1 + " and " + name2 + " are friends") #calling the function print_name(name2 = 'A',name1 = 'B') Output: B and A are friends #Default Arguments Function arguments can have default values in Python. We can provide a default value to an argument by using the assignment operator (=) def hello(wish,name='you'): return '{},{}'.format(wish,name) print(hello("good morning")) 196 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Output: good morning,you ________________ def hello(wish,name='you'): return '{},{}'.format(wish,name) //print(wish + „ „ + name) print(hello("good morning","nirosha")) // hello("good morning","nirosha") Output: good morning,nirosha //good morning nirosha Note: Any number of arguments in a function can have a default value. But once we have a default argument, all the arguments to its right must also have default values. This means to say, non-default arguments cannot follow default arguments. For example, if we had defined the function header above as: def hello(name='you', wish): Syntax Error: non-default argument follows default argument ________________ def sum(a=4, b=2): #2 is supplied as default argument """ This function will print sum of two numbers if the arguments are not supplied it will add the default value """ print (a+b) sum(1,2) #calling with arguments sum( ) #calling without arguments Output: 3 6 Variable-length arguments Sometimes you may need more arguments to process function then you mentioned in the definition. 197 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook If we don‟t know in advance about the arguments needed in function, we can use variable-length arguments also called arbitrary arguments. For this an asterisk (*) is placed before a parameter in function definition which can hold non-keyworded variable-length arguments and a double asterisk (**) is placed before a parameter in function which can hold keyworded variable-length arguments. If we use one asterisk (*) like *var, then all the positional arguments from that point till the end are collected as a tuple called „var‟ and if we use two asterisks (**) before a variable like **var, then all the positional arguments from that point till the end are collected as a dictionary called „var‟. def wish(*names): """This function greets all the person in the names tuple.""" # names is a tuple with arguments for name in names: print("Hello",name) wish("CET","CSE","SIR","MADAM") Output: Hello CET Hello CSE Hello SIR Hello MADAM #Program to find area of a circle using function use single return value function with argument. pi=3.14 def areaOfCircle(r): return pi*r*r r=int(input("Enter radius of circle")) print(areaOfCircle(r)) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py Enter radius of circle 3 28.259999999999998 #Program to write sum different product and using arguments with return value function. def calculete(a,b): total=a+b diff=a-b prod=a*b 198 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer div=a/b mod=a%b return total,diff,prod,div,mod a=int(input("Enter a value")) b=int(input("Enter b value")) #function call s,d,p,q,m = calculete(a,b) print("Sum= ",s,"diff= ",d,"mul= ",p,"div= ",q,"mod= ",m) #print("diff= ",d) #print("mul= ",p) #print("div= ",q) #print("mod= ",m) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py Enter a value 5 Enter b value 6 Sum= 11 diff= -1 mul= 30 div= 0.8333333333333334 mod= 5 #program to find biggest of two numbers using functions. def biggest(a,b): if a>b : return a else : return b a=int(input("Enter a value")) b=int(input("Enter b value")) #function call big= biggest(a,b) print("big number= ",big) 199 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py Enter a value 5 Enter b value-2 big number= 5 #program to find biggest of two numbers using functions. (nested if) def biggest(a,b,c): if a>b : if a>c : return a else : return c else : if b>c : return b else : return c a=int(input("Enter a value")) b=int(input("Enter b value")) c=int(input("Enter c value")) #function call big=biggest(a,b,c) print("big number= ",big) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py Enter a value 5 Enter b value -6 Enter c value 7 big number= 7 #Writer a program to read one subject mark and print pass or fail use single return values function with argument. def result(a): if a>40: return "pass" 200 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer else: return "fail" a=int(input("Enter one subject marks")) print(result(a)) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py Enter one subject marks 35 Fail #Write a program to display mercer case dept 10 times on the screen. (while loop) def usingFunctions(): count =0 while count<10: print("CET cse dept",count) count=count+1 usingFunctions() Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py CET cse dept 0 CET cse dept 1 CET cse dept 2 CET cse dept 3 CET cse dept 4 CET cse dept 5 CET cse dept 6 CET cse dept 7 CET cse dept 8 CET cse dept 9 Exercise Answer the following questions: 1. The ___ is a built-in function that returns a range object that consists series of integer numbers, which we can iterate using a for loop. a) range()b) set() c) dictionary{} d) None of the mentioned above 201 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 2. What will be the output of the following Python code? for i in range(6): print(i) a) 0 1 2 3 4 5 b) 0 1 2 3 c) 1 2 3 4 5 d) None of the mentioned above 3. The looping reduces the complexity of the problems to the ease of the problems? a) Trueb) False 4. The while loop is intended to be used in situations where we do not know how many iterations will be required in advance? a) Trueb) False 5. Amongst which of the following is / are true with reference to loops in Python? a) It allows for code reusability to be achieved. b) By utilizing loops, we avoid having to write the same code over and over again. c) We can traverse through the elements of data structures by utilizing looping. d) All of the mentioned above 3.3.5 Explain the concepts and various types of methods/ functions, scopes, modules and class Types of Python Functions Python Functions may be broken down into a wide variety of subcategories. Additionally, each one of them is incredibly important in its own special manner. The following is a list of the many sorts of functions available in Python: • • Python Built-in Functions Python Recursion Functions 202 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer • • Python Lambda Functions Python User-defined Functions Let's take a closer look at these responsibilities, shall we? Starting with the Built-in functions since they are fairly simple both to comprehend and to put into action. 3.3.6 Python Built-in Functions Built-in Functions in Python The Python interpreter comes with a variety of pre-defined functions that may be used whenever they are needed. Built-in functions are the name given to these kinds of functions. For instance, the print() method will print the specified object either to the screen, which is the default output device, or to the text stream file. There are 68 pre-defined functions that come standard with Python 3.6. However, for the purpose of clarity, let us focus on the features that are utilised the most frequently, and we can go from there. 1. The abs() Function in Python: Definition The abs() function calculates and returns the number's value in its most fundamental form, the absolute value. If the number being sent in is a complex number, abs() will return the magnitude of that number. Syntax The syntax of abs() method is: abs(num) Parameters 2. The abs() method takes a single argument: num – A number whose absolute value is to be returned. The number can be: • • • integer floating number complex number Example 1 2 3 4 203 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 5 6 7 # random integer integer = -20 print('Absolute value of -20 is:', abs(integer)) #random floating number floating = -30.33 print('Absolute value of -30.33 is:', abs(floating)) Output Absolute value of -20 is: 20 Absolute value of -30.33 is: 30.33 3. Python all() Function: Definition When all of the items in the iterable are valid, the all() function will respond with the value True. In that case, it gives the value False. Syntax The syntax of all() method is: all(iterable) Parameters The all() method takes a single parameter: iterable – Any iterable (list, tuple, dictionary, etc.) which contains the elements Example 1 2 3 4 5 204 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 6 7 8 9 10 11 12 13 14 15 16 17 18 19 # all values true l = [1, 3, 4, 5] print(all(l)) # all values false l = [0, False] print(all(l)) # one false value l = [1, 3, 4, 0] print(all(l)) # one true value l = [0, False, 5] print(all(l)) # empty iterable l = [] print(all(l)) Output True 205 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook False False False True 4. Python ascii() Function: Definition The ascii() method returns a string containing a printable representation of an object. It does so by utilising the x, u, or U escapes, depending on whatever non-ASCII letters are included in the string. Syntax The syntax of ascii() method is: ascii(object) Parameters The ascii() method takes an object (like strings, list etc). Example 1 2 3 4 5 6 7 normalText = 'Python is interesting' print(ascii(normalText)) otherText = 'Pythön is interesting' print(ascii(otherText)) print('Pythn is interesting') 206 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Output 'Python is interesting' 'Pythn is interesting' Pythön is interesting 5. Python bin() Function: Definition A given number can be converted to its string representation in binary using the bin() function, which then returns that string. It is required to implement the __index__() function in order to return an integer if the parameter being sent in is not an integer. Syntax The syntax of bin() method is: bin(num) Parameters The bin() method takes a single parameter: num – an integer number whose binary equivalent is to be calculated. If not an integer, should implement __index__() method to return an integer. Example 1 2 number = 5 print('The binary equivalent of 5 is:', bin(number)) Output The binary equivalent of 5 is: 0b101 6. Python compile() Function: Definition A Python code object is generated and returned by the compile() function from the source (normal string, a byte string, or an AST object). 207 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Syntax The syntax of compile() method is: compile(source, filename, mode, flags=0, dont_inherit=False,optimize=-1) Parameters • • • • • • source is either a regular text, a byte string, or an AST object filename, and it refers to the file that was read in order to obtain the code. If it was not read from a file, you have the option of giving it a name yourself by using one of the following modes: exec, eval, or single. eval is a command that will only take one expression at a time. exec is able to take a code block that contains Python statements, as well as class and function definitions, and so on. solitary if it consists of a single statement that may be interacted with by the user. flags (which is optional) and dont inherit (which is optional) are the controls that determine which future statements have an effect on the compilation of the source. Default Value: 0 optimise (optional) Sets the level of optimization used by the compiler. Default value -1. Example 1 2 3 4 5 6 7 codeInString = 'a = 5 b=6 sum=a+b print("sum =",sum)' codeObejct = compile(codeInString, 'sumstring', 'exec') exec(codeObejct) Output sum = 11 208 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 7. Python dict() Function: Definition Python's dict() function Object() { [native code] } is responsible for the creation of dictionaries. The following are some of the several forms of the dict() function Object() { [native code] }: class dict(**kwarg) class dict(mapping, **kwarg) class dict(iterable, **kwarg) Example 1 2 3 4 5 6 7 numbers = dict(x=5, y=0) print('numbers = ',numbers) print(type(numbers)) empty = dict() print('empty = ',empty) print(type(empty)) Output empty = dict() print('empty = ',empty) print(type(empty)) 8. Python enumerate() Function: Definition An iterable receives an additional counter, which is returned by the enumerate() function (the enumerate object). 209 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Syntax The syntax of enumerate() method is: enumerate(iterable, start=0) Parameters The enumerate() method takes two parameters: iterable – a sequence, an iterator, or objects that support iteration start (optional) – enumerate() starts counting from this number. If start is omitted, 0 is taken as the start. Example 1 2 3 4 5 6 7 8 9 10 11 grocery = ['bread', 'milk', 'butter'] enumerateGrocery = enumerate(grocery) print(type(enumerateGrocery)) # converting to list print(list(enumerateGrocery)) # changing the default counter enumerateGrocery = enumerate(grocery, 10) print(list(enumerateGrocery)) 210 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Output <class 'enumerate'> [(0, 'bread'), (1, 'milk'), (2, 'butter')] [(10, 'bread'), (11, 'milk'), (12, 'butter')] 9. Python eval() Function: Definition Within the context of the program, the python expression (code) that is supplied to the eval() function is evaluated once it has been parsed by the eval() method.Syntax The syntax of eval() method is: eval(expression, globals=None, locals=None) Parameters The eval() takes three parameters: expression – this string is parsed and evaluated as a Python expression globals (optional) – a dictionary locals (optional)- a mapping object. Dictionary is the standard and commonly used mapping type in Python. Example 1 2 x=1 print(eval('x + 1')) Output sum = 11 10. Python filter() Function: Definition 211 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook An iterator is built by the filter() method using the parts of an iterable that provide a true result when passed through a function. Syntax The syntax of filter() method is: filter(function, iterable) Parameters The filter() method takes two parameters: function – function that tests if elements of an iterable return true or false If None, the function defaults to Identity function – which returns false if any elements are false iterable – iterable which is to be filtered, could be sets, lists, tuples, or containers of any iterators Example 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # list of alphabets alphabets = ['a', 'b', 'd', 'e', 'i', 'j', 'o'] 212 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer # function that filters vowels def filterVowels(alphabet): vowels = ['a', 'e', 'i', 'o', 'u'] if(alphabet in vowels): return True else: return False filteredVowels = filter(filterVowels, alphabets) print('The filtered vowels are:') for vowel in filteredVowels: print(vowel) Output The filtered vowels are: a e i o 3.3.7 Python Recursive Functions What is recursion in Python? The technique of defining something by referring back to itself is known as recursion. A real-world illustration of this would be to position two parallel mirrors such that they face each other. Anyitem that exists in the space between them will be mirrored in a recursive manner. Python Function That Recurses Itself It is common knowledge that a Python function can "call" the functions of other modules. Even the function's ability to call itself is not completely ruled out. Recursive functions are the name given to this kind of concept in computer science. Here is an illustration of a recursive function that may be used to get the factorial of an integer. The product of all the integers ranging from 1 to the given number makes up the factorial of that number. For instance, the answer to the question "what is the factorial of 5?" is 1 * 2 * 3 * 4 * 5, which is 120. 213 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 # An example of a recursive function to # find the factorial of a number def calc_factorial(x): <em>"""This is a recursive function to find the factorial of an integer""" </em>if x == 1: return 1 else: return (x * calc_factorial(x-1)) num = 4 print("The factorial of", num, "is", calc_factorial(n A recursive function is one that calls itself, such as the calc factorial() function shown in the previous example. When we pass a positive integer to this function, it will recursively call itself by lowering the number each time. Each time a function is called, the number is multiplied by the factorial of 1, and this process continues until the number is equal to one. 214 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer When the number is reduced to 1, our recursion will come to an end. The term for this kind of circumstance is the basic condition. It is necessary for every recursive function to have a base condition that terminates the recursion; otherwise, the function would call itself an unlimited number of times. The Benefits Obtained Through Recursion • • • The code is made to seem more streamlined and sophisticated thanks to recursive functions. Using recursion, a difficult issue can be partitioned into a number of more manageable subproblems. The use of recursion, as opposed to any form of nested repetition, makes the production of sequences simpler. Drawbacks Associated with Recursion • • • It might be challenging to fully comprehend the reasoning behind recursion at times. Because they require a significant investment of both time and memory, recursive calls are considered to be inefficient and costly. It is challenging to find and fix bugs in recursive functions. Let's have a look at the Lambda Function in Python as the next topic on this blog on Python functions. 3.3.8 Python Lambda Functions What Are Lambda functions? An anonymous function is a function that is defined in Python but does not have a name associated with it. In Python, conventional functions are defined through the use of the def keyword, whereas anonymous functions are defined through the use of the lambda keyword.Anonymous functions are also referred to as lambda functions for this reason. How Do You Make Use Of Python's Lambda Functions? The following syntax is used for a Lambda function when written in Python: lambda arguments: expression Example 1 2 3 4 5 6 # Program to show the use of lambda functions 215 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook double = lambda x: x * 2 # Output: 10 print(double(5)) Output 10 In [1]: The lambda function is denoted by the expression lambda x: x * 2 in the preceding program. In this case, x is the name of the input, and the equation x * 2 is the one that is evaluated and returned. There is no name for this function. It hands back a function object that can be found in the double variable thanks to the assignment made by it. At this point, we may refer to it as a typical function. This is the assertion, double = lambda x: x * 2 is nearly the same as def double(x): return x * 2 Let's move on to the next topic on this Python Functions blog, which is going to be a discussion on how to use user-defined functions in Python. 3.3.9 Python Operator Overloading Operator overloading in Python is the ability of a single operator to perform more than one operation based on the class (type) of operands. For example, the + operator can be used to add two numbers, concatenate two strings or merge two lists. This is possible because the + operator is overloaded with int and str classes. Similarly, you can define additional methods for these operators to extend their functionality to various new classes and this process is called Operator overloading. Let us assumewe have an object called string1 which is a string object as defined below. Now, when we try to add a string to this string object, the compiler will throw an error. This is because the compiler doesn't know how to add them. Have a look at what happens when executed. Note: You will understand the below code completely by the end of this article. # declare our own string classclass String: # magic method to initiate objectdef __init__(self, string):self.string = string # print our string objectdef __repr__(self):return 'Object: {}'.format(self.string) 216 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer # Driver Codeif __name__ == '__main__': # object creation string1 = String('Hello') # concatenate String object and a string print(string1 +' world') Output: TypeError: unsupported operand type( s ) for +: String and str This error can be avoided by adding the __ add__ method to the String class. This way, we are overloading the + operator to concatenate a string object with a string. # declare our own string classclass String: # magic method to initiate objectdef __init__(self, string):self.string = string # print our string objectdef __repr__(self):return 'Object: {}'.format(self.string) def __add__(self, other):return self.string + other # Driver Codeif __name__ == '__main__': # object creation string1 = String('Hello') # concatenate String object and a string print(string1 +' World') Output: Hello World In Python, when any operator is used, a special function is internally invoked by the compiler for that particular operator.Python methods that have double underscores before and after their names are called Magic methods or Special functions.By changing this magic methods code, we can extend the functionality of the operator.For example, when we use -= operator, the magic or special method __ isub__ is invoked by the compiler. Arithmetic Operators OperatorSpecial functions+__add__(self, other)-__sub__(self, other)*__mul__(self,other)/__truediv__ (self,other)//__floordiv__(self,other)%__mod__(self,other)**__pow__(self,other) Comparison Operators OperatorSpecial 217 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook functions<__lt__(self,other)>__gt__(self,other)<=__le__(self,other)>=__ge__(self,other)==__eq__ (self,other)!=__ne__(self,other) Assignment Operators OperatorSpecial functions+=__iadd__(self,other)-=__isub__(self,other)*=__imul__(self,other)/=__ idiv__(self,other)//=__ifloor div__(self,other)%=__imod__(self,other)**=__ipow__(self,other) OperatorSpecial functions+__neg__(self,other)-__pos__(self,other)~__invert__(self,other) #program to compare the score of two students m1 & m2. class Student:def __init__(self, m1, m2): #initializationself.m1 = m1self.m2 = m2def __add__(self, m1, m2): #adding the two objects m1 = self.m1 + other.m1 m2 = self.m2 + other.m2 s3 = student (m1,m2) return s3 def __gt__(self, other):#comparingthe two objects r1 = self.m1 + self.m2 r2 = other.m1 + other.m2 if(r1 > r2): return Trueelse:return False s1 = Student(65, 85) s2 = Student(90, 80) if (s1 > s2): print ("S1 wins") else: print ("S2 wins") Output: S2 wins #Python program to compare two radiiclass Circle: def __init__(self, a): self.a = a def __lt__(self, other):if(self.a<other.a): 218 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer return 'Radius(r2) is greater'else:return "Radius(r1) is greater"def __eq__(self, other):if(self.a == other.a): return "Radius are equal"else:return "Not equal" r1 = Circle(12) r2 = Circle(9) print(r1 < r2) r3 = Circle(6) r4 = Circle(4) print(r3 == r4) Output: Radius(r1) is greater Not equal 3.3.10 Multiple Inheritance Inheritance : Inheritance allows us to define a class that inherits all the methods and properties from another class. The Parent class is the class being inherited from, also called base class. The Child class is the class that inherits from another class, also called derived class. Types of Inheritance: • • • • • • Single Inheritance Multi-level Inheritance Multiple Inheritance Multipath Inheritance Hierarchical Inheritance Hybrid Inheritance Multiple Inheritance : Multiple inheritance is a feature of some object-oriented computer programming languages in which an object or class can inherit characteristics and features from more than one parent object or the parent class . Multiple Inheritance Flow • • • • Syntax of Multiple Inheritance : Class Base1: Body of the class Class Base2: Body of the class Class Derived(Base1, Base2): Body of the class 219 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Some examples of multiple inheritance # Multiple Inheritance using two classes: class Father(): def Driving(self): print("Father Enjoys Driving") class Mother(): def Cooking(self): print("Mother Enjoys Cooking") class Child(Father, Mother): def Playing(self): Explanation of code: Here, the father and Mother are the Base classes where we have two print statements and a child class that contains all the methods of the father and mother class. The child class is also known as Derived class. We are creating the object for the child class through which we can access the functions of father, mother, and child. # Creating a multiple inheritance using more than two classes. class Car(): def Benz(self): print(" This is a Benz Car ") class Bike(): def Bmw(self): print(" This is a BMW Bike ") class Bus(): def Volvo(self): Explanation of Code: Here we have four classes named, Car,Bike,Bus,Truck,Plane that are called as the base classes. We also have one derived class Transport hat twill be holding all the data of the Car,Bike,Truck,Plane, and Transport. So, that is why we will be creating the object for the derived class, i.e., the Transport through which we can access all the data of the base class and derived class. 220 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer # Performing Addition,Multiplication,Division using Multiple Inheritance class Calculation1: def Summation(self,a,b): return a+b; class Calculation2: def Multiplication(self,a,b): return a*b; class Derived(Calculation1,Calculation2): def Divide(self,a,b): Explanation of Code: Here, in the above program we have three classes. The class with Calculation1 and Calculation2 are the Base classes and the Class named Derived is the combination of the Calculation1 and Calculation2 classes. Calculation1 class performs the arithmetic operation and Calculation2 performs the Multiplication operation. Now, in the Derived class we have both an addition and multiplication operation along with its own operation division. This is how we implement multiple inheritance using Base and derived classes. # definition of the class starts here class Cars: # defining constructor def __init__(self, CarName, CarModel): self.name = CarName self.model = CarModel # defining class methods def showName(self): print(self.name) Explanation of Code: The classes Cars and Ids are superclass and Main is the subclass. The class Main extends both Cars and Ids to inherit the properties of both classes. The example is easy to understand if you have some knowledge of Python classes and Python inheritance. 221 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook # Example on Multiple Inheritance ` class Student1: def __init__(self): self.name = 'Nani' self.age = 19 def getName(self): return self.name Pros and Cons of Multiple Inheritance : Pros: • • • • It allows a class to inherit the functionality of more than one base class; thus allowing for modeling of complex relationships. You categorize classes in many different ways. Multiple inheritance is a way of showing our natural tendency to organize the world. During analysis, for example, we use multiple inheritance to capture the way users classify objects. By having multiple superclasses, your subclass has more opportunities to reuse the inherited attributes and operations of the superclasses. Application development time is less and application takes less memory. Cons: • • It can lead to a lot of confusion when two base classes implement a method with the same name. The more superclasses your subclass inherits from, the more maintenance you are likely to perform. If one of the superclasses happens to change, the subclass may have to change as well. Real Time Examples of Multiple Inheritance: • • Storing a student’s data. Filling taxes and applying deductions. 3.3.11 Python User-Defined Functions What Are User-Defined Functions In Python? User-defined functions are functions that a user creates in order to accomplish a certain purpose. These functions are specified by the user. The process by which we define functions in Python and the order in which we call them has previously been covered. Built-in functions are those that are pre-installed on your system when you install Python. It is possible to refer to these as library functions if we employ functions that were authored by other people and stored in a library. User-defined functions are comprised of each and every one of the other functions that we create on our own. Therefore, someone else's user-defined function might be considered a library function by us. 222 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer The benefits of functions that are specified by the user User-defined functions are useful for breaking down huge programs into more manageable chunks, which in turn makes the program simpler to comprehend, maintain, and troubleshoot. If the same line of code is used several times in a program. It is possible to utilise the function to incorporate such scripts, and then execute them as necessary by invoking that function. When working on a large project, programmers have the ability to split their job by creating several functions. Syntax def function_name(argument1, argument2, ...) : statement_1 statement_2 .... Example 1 2 3 4 5 6 7 8 9 10 11 # Program to illustrate # the use of user-defined functions def add_numbers(x,y): sum = x + y return sum num1 = 5 num2 = 6 223 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print("The sum is", add_numbers(num1, num2)) Output Enter a number: 2.4 Enter another number: 6.5 The sum is 8.9 3.3.12 What is Python Scope? In Python, variables are simply inaccessible from the class in which they were declared after the class has been initialised. The manner in which variables are declared determines both their location inside a program and the means by which they may be accessed. In Python, the term "scope" refers to the portion of the code where variables, functions, and objects may be accessed without too much trouble. Types of Scopes in Python: In Python, there are four types of scopes, which are as follows: • • • • Global Scope Local Scope Enclosing Scope Built-in Scope 3.3.12.1 Global Scope The names of variables that are defined in the main body of a program are said to have global scope in a computer program. These may be seen at any time and accessed from anywhere in the software. All of the program's functions have quick and easy access to the variables and objects that have been declared in the global scope of the program. With the assistance of some code, let's get a better understanding of the global scope. message = "Hey" def python_developer(): developer = "Welcome to Python Programming!" print(message, developer) def developer_name(name): print(message, name) python_developer() developer_name("Mark!") OUTPUT: Hey Welcome to Python Programming! Hey Mark! 224 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Programming best practises suggest that you should avoid using global variables if it is at all practicable to do so. Why? because it is simple to make changes to them, and the output that results from those changes might be incorrect. The code's overall security is made more vulnerable as a result of the use of global variables. However, this does not mean that you will never make use of global variables. As a general guideline, you should make an effort to utilise the variables and objects that are contained inside the global scope. These include functions and objects, both of which are designed to be expressly used worldwide. 3.3.12.2 Local Scope The names that are specified inside of a function that are specific to that function are referred to as having a "local scope." They can be retrieved beginning at the point where the definition was made and continuing all the way through the block in which the definition was made. The local scope continues to exist up to the point at which the function has been carried out. Let's get a better understanding of the local scope by looking at some code. def local_test(): value = 1 # Print statement 1 print("The value defined is: ", value) local_test() OUTPUT: The value defines is: 1 Notice the error if you run the following code. def local_test(): value = 1 print("The first number defined is: ", value) OUTPUT: Traceback (most recent call last): File "C:/Projects/untitled/basic.py", line 4, in <module> print("The value defined is: ", value) NameError: name 'value' is not defined 225 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Enclosing Scope or Non-local Scope The concept of enclosing scope is similar to that of non-local scope. They are referring to the names of a variable that is declared in the function that is nested inside of another function. Simply said, the local scope and the global scope do not contain these variables anywhere in their respective scopes. Utilizing a non-local keyword allows you to define a non-local variable inside of an enclosing scope. With the assistance of a code, let's get a better understanding of the enclosing scope. def parent_nest(): initial_value = 5 def child_nest(): next_value = 10 print("Value defined in the parent function: ", initial_value) print("Value defined in the parent function: ", next_value) child_nest() parent_nest() OUTPUT: Value defined in the parent function : 5 Value defined in the parent function : 10 3.3.13 Modules in Python Modules provide us the ability to share reusable functions with one another. A module is nothing more than a "Python file" that stores re-usable code and can be imported into several different Python projects. A module may include functions, classes, lists, etc. Modules in Python can be of two types: • • Built-in Modules. User-defined Modules. 3.3.13.1 Built-in Modules in Python Python's "rich standard library" is only one of the numerous advantages that set it apart from other programming languages. This extensive standard library features a large number of included modules. As a result, it offers a significant amount of code that may be reused. Python has a variety of different modules, some of which include "os," "sys," "datetime," and "random." You are free to import and make use of any of the pre-installed modules in your application anytime you see fit. (We'll take a look at it in a moment.) 226 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.3.13.2 User-Defined Modules in Python Python's ability to provide you more control over your environment is just another one of its many strengths. You are free to develop your own own procedures and classes, then enclose them in modules, and you are good to go. Simply inserting an import statement is now all that is required to include tens or even hundreds of lines of code into any program. To construct a module, just place the code inside a .py file. Let's get started on it. # my Python module def greeting(x): print("Hello,", x) Copy and paste this code into a new file, and give the file the name mypymodule.py when you save it. At this point, we have developed our own own module. Now that we've finished with the first half of our work, let's figure out how to import these modules 3.3.13.3 Importing Modules in Python In Python, built-in modules and user-defined modules may both be imported with the help of the import keyword. Let’s import our user-defined module from the previous section into our Python shell: >>> import mypymodule To call the greeting function of mypymodule, we simply need to use the dot notation: >>> mypymodule.greeting("Tech") Output Hello, Tech In a similar fashion, we may import mypymodule into any Python code and then call the welcome method, just as we did in the previous example. Let’s now import a built-in module into our Python shell: >>> import random To call the randint function of random, we simply need to use the dot notation: >>> random.randint(20, 100) Output 63 227 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook A random number inside a specified range is what the randint function of the random module is responsible for generating (20 to 100). In order to make our code more Pythonic, we may import modules using a variety of different strategies. 3.3.14 What is Object-Oriented Programming? (OOPs concepts in Python) Object Oriented Programming is a way of computer programming using the idea of “objects” to represents data and methods. It is also, an approach used for creating neat and reusable code instead of a redundant one. the program is divided into self-contained objects or several mini-programs. Every Individual object represents a different part of the application having its own logic and data to communicate within themselves. Difference between Object-Oriented and Procedural Oriented Programming Object-OrientedProgramming (OOP) It is a bottom-up approach Program is divided into objects Makes use of Access modifiers ‘public’, private’, protected’ It is more secure Object can move freely within member functions It supports inheritance Procedural-OrientedProgramming (Pop) It is a top-down approach Program is divided into functions Doesn’t use Access modifiers It is less secure Data can move freely from function to function within programs It does not support inheritance 3.3.14.1 What are Python OOPs Concepts? Major OOP (object-oriented programming) concepts in Python include Class, Object, Method, Inheritance, Polymorphism, Data Abstraction, and Encapsulation. That was all about the differences, moving ahead let’s get an idea of classes and objects. What are Classes and Objects? A class is a collection of objects or youcan say it is a blueprint of objects defining the common attributes and behavior. Now the question arises, how do you do that? Well, it logically groups the data in such a way that code reusability becomes easy. I can give you a real-life example- think of an office going ’employee’ as a class and all the attributes related to it like ’emp_name’, ’emp_age’, ’emp_salary’, ’emp_id’ as the objects in Python. Let us see from the coding perspective that how do you instantiate a class and an object. Class is defined under a “Class” Keyword. 228 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Example: 1class class1(): // class 1 is the name of the class Note: Python is not case-sensitive. Objects: Objects are an instance of a class. It is an entity that has state and behavior. In a nutshell, it is an instance of a class that can access the data. Syntax: obj = class1() Here obj is the “object “ of class1. Creating an Object and Class in python: Example: class employee(): def __init__(self,name,age,id,salary): //creating a function self.name = name // self is an instance of a class self.age = age self.salary = salary self.id = id emp1 = employee("harshit",22,1000,1234) //creating objects emp2 = employee("arjun",23,2000,2234) print(emp1.__dict__)//Prints dictionary Explanation: ’emp1′ and ’emp2′ are the objects that are instantiated against the class ’employee’.Here, the word (__dict__) is a “dictionary” which prints all the values of object ‘emp1’ against the given parameter (name, age, salary).(__init__) acts like a constructor that is invoked whenever an object is created. Object-Oriented Programming methodologies: Object-Oriented Programming methodologies deal with the following concepts. • • • • Inheritance Polymorphism Encapsulation Abstraction Let us understand the first concept of inheritance in detail. 229 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 1. Inheritance: Ever heard of this dialogue from relatives “you look exactly like your father/mother” the reason behind this is called ‘inheritance’. From the Programming aspect, It generally means “inheriting or transfer of characteristics from parent to child class without any modification”. The new class is called the derived/childclass and the one from which it is derived is called a parent/baseclass. a. Single Inheritance: Single level inheritance enables a derived class to inherit characteristics from a single parent cla ss. Example: class employee1()://This is a parent class def __init__(self, name, age, salary): self.name = name self.age = age self.salary = salary class childemployee(employee1)://This is a child class def __init__(self, name, age, salary,id): self.name = name self.age = age self.salary = salary self.id = id emp1 = employee1('harshit',22,1000) print(emp1.age) Output: 22 Explanation: • • • I am taking the parent class and created a constructor (__init__), class itself is initializing the attributes with parameters(‘name’, ‘age’ and ‘salary’). Created a child class ‘childemployee’ which is inheriting the properties from a parent class and finally instantiated objects ’emp1′ and ’emp2′ against the parameters. Finally, I have printed the age of emp1. Well, you can do a hell lot of things like print the whole dictionary or name or salary. b. Multilevel Inheritance: Multi-level inheritance enables a derived class to inherit properties from an immediate parent class which in turn inherits properties from his parent class. 230 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Example: class employee()://Super class def __init__(self,name,age,salary): self.name = name self.age = age self.salary = salary class childemployee1(employee)://First child class def __init__(self,name,age,salary): self.name = name self.age = age self.salary = salary class childemployee2(childemployee1)://Second child class def __init__(self, name, age, salary): self.name = name self.age = age self.salary = salary emp1 = employee('harshit',22,1000) emp2 = childemployee1('arjun',23,2000) print(emp1.age) print(emp2.age) Output: 22,23 Explanation: • • It is clearly explained in the code written above, Here I have defined the superclass as employee and child class as childemployee1. Now, childemployee1 acts as a parent for childemployee2. I have instantiated two objects ’emp1′ and ’emp2′ where I am passing the parameters “name”, “age”, “salary” for emp1 from superclass “employee” and “name”, “age, “salary” and “id” from the parent class “childemployee1” c. Hierarchical Inheritance: Hierarchical level inheritance enables more than one derived class to inherit properties from a parent class. 231 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example: class employee(): def __init__(self, name, age, salary): //Hierarchical Inheritance self.name = name self.age = age self.salary = salary class childemployee1(employee): def __init__(self,name,age,salary): self.name = name self.age = age self.salary = salary class childemployee2(employee): def __init__(self, name, age, salary): self.name = name self.age = age self.salary = salary emp1 = employee('harshit',22,1000) emp2 = employee('arjun',23,2000) print(emp1.age) print(emp2.age) Output: 22,23 Explanation: • • In the above example, you can clearly see there are two child class “childemployee1” and “childemployee2”. They are inheriting functionalities from a common parent class that is “employee”. Objects ’emp1′ and ’emp2′ are instantiated against the parameters ‘name’, ‘age’, ‘salary’. d. Multiple Inheritance: Multiple level inheritance enables one derived class to inherit properties from more than one base class. Example: class employee1()://Parent class def __init__(self, name, age, salary): 232 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer self.name = name self.age = age self.salary = salary class employee2()://Parent class def __init__(self,name,age,salary,id): self.name = name self.age = age self.salary = salary self.id = id class childemployee(employee1,employee2): def __init__(self, name, age, salary,id): self.name = name self.age = age self.salary = salary self.id = id emp1 = employee1('harshit',22,1000) emp2 = employee2('arjun',23,2000,1234) print(emp1.age) print(emp2.id) Output: 22,1234 Explanation: In the above example, I have taken two parent class “employee1” and “employee2”. And a child class “childemployee”, which is inheriting both parent class by instantiating the objects ’emp1′ and ’emp2′ against the parameters of parent classes. This was all about inheritance, moving ahead in Object-Oriented Programming Python, let’s take a deep dive in ‘polymorphism‘. 2. Polymorphism: You all must have used GPS for navigating the route, Isn’t it amazing how many different routes you come across for the same destination depending on the traffic, from a programming point of view this is called ‘polymorphism’. It is one such OOP methodology where one task can be performed in several different ways. To put it in simple words, it is a property of an object which allows it to take multiple forms. Polymorphism is of two types: • • Compile-time Polymorphism Run-time Polymorphism 233 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook a. Compile-time Polymorphism: A compile-time polymorphism also called as static polymorphism which gets resolved during the compilation time of the program. One common example is “method overloading”. Let me show you a quick example of the same. Example: class employee1(): def name(self): print("Harshit is his name") def salary(self): print("3000 is his salary") def age(self): print("22 is his age") class employee2(): def name(self): print("Rahul is his name") def salary(self): print("4000 is his salary") def age(self): print("23 is his age") def func(obj)://Method Overloading obj.name() obj.salary() obj.age() obj_emp1 = employee1() obj_emp2 = employee2() func(obj_emp1) func(obj_emp2) Output: Harshit is his name 3000 is his salary 22 is his age Rahul is his name 234 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 4000 is his salary 23 is his age Explanation: In the above Program, I have created two classes ’employee1′ and ’employee2′ and created functions for both ‘name’, ‘salary’ and ‘age’ and printed the value of the same without taking it from the user. Now, welcome to the main part where I have created a function with ‘obj’ as the parameter and calling all the three functions i.e. ‘name’, ‘age’ and ‘salary’. Later, instantiated objects emp_1 and emp_2 against the two classes and simply called the function. Such type is called method overloading which allows a class to have more than one method under the same name. b. Run-time Polymorphism: A run-time Polymorphism is also, called as dynamic polymorphism where it gets resolved into the run time. One common example of Run-time polymorphism is “method overriding”. Let me show you through an example for a better understanding. Example: class employee(): def __init__(self,name,age,id,salary): self.name = name self.age = age self.salary = salary self.id = id def earn(self): pass class childemployee1(employee): def earn(self)://Run-time polymorphism print("no money") class childemployee2(employee): def earn(self): print("has money") c = childemployee1 c.earn(employee) d = childemployee2 235 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook d.earn(employee) Output: no money, has money Explanation: In the above example, I have created two classes ‘childemployee1’ and ‘childemployee2’ which are derived from the same base class ‘employee’. Here’s the catch one did not receive money whereas the other one gets. Now the real question is how did this happen? Well, here if you look closely I created an empty function and used Pass ( a statement which is used when you do not want to execute any command or code). Now, Under the two derived classes, I used the same empty function and made use of the print statement as ‘no money’ and ‘has money’. Lastly, created two objects and called the function. Moving on to the next Object-Oriented Programming Python methodology, I’ll talk about encapsulation. 3. Encapsulation: In a raw form, encapsulation basically means binding up of data in a single class. Python does not have any private keyword, unlike Java. A class shouldn’t be directly accessed but be prefixed in an underscore. Let me show you an example for a better understanding. Example: class employee(object): def __init__(self): self.name = 1234 self._age = 1234 self.__salary = 1234 object1 = employee() print(object1.name) print(object1._age) print(object1.__salary) Output: 1234 Traceback (most recent call last): 1234 File “C:/Users/Harshit_Kant/PycharmProjects/test1/venv/encapsu.py”, line 10, in print(object1.__salary) AttributeError: ’employee’ object has no attribute ‘__salary’ 236 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Explanation: You will get this question what is the underscore and error? Well, python class treats the private variables as(__salary) which can not be accessed directly. So, I have made use of the setter method which provides indirect access to them in my next example. Example: class employee(): def __init__(self): self.__maxearn = 1000000 def earn(self): print("earning is:{}".format(self.__maxearn)) def setmaxearn(self,earn)://setter method used for accesing private class self.__maxearn = earn emp1 = employee() emp1.earn() emp1.__maxearn = 10000 emp1.earn() emp1.setmaxearn(10000) emp1.earn() Output: earning is:1000000,earning is:1000000,earning is:10000 Explanation: Making Use of the setter method provides indirect access to the private class method. Here I have defined a class employee and used a (__maxearn) which is the setter method used here to store the maximum earning of the employee, and a setter function setmaxearn() which is taking price as the parameter. This is a clear example of encapsulation where we are restricting the access to private class method and then use the setter method to grant access. Next up in object-oriented programming python methodology talks about one of the key concepts called abstraction. 4. Abstraction: Suppose you booked a movie ticket from bookmyshow using net banking or any other process. You don’t know the procedure of how the pin is generated or how the verification is done. This is called ‘abstraction’ from the programming aspect, it basically means you only show the implementation details of a particular process and hide the details from the user. It is used to simplify complex problems by modeling classes appropriate to the problem. An abstract class cannot be instantiated which simply means you cannot create objects for this type of class. It can only be used for inheriting the functionalities. 237 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example: from abc import ABC,abstractmethod class employee(ABC): def emp_id(self,id,name,age,salary): //Abstraction pass class childemployee1(employee): def emp_id(self,id): print("emp_id is 12345") emp1 = childemployee1() emp1.emp_id(id) Output: emp_id is 12345 Explanation: As you can see in the above example, we have imported an abstract method and the rest of the program has a parent and a derived class. An object is instantiated for the ‘childemployee’ base class and functionality of abstract is being used. In Python, the beginning of a function definition is indicated by the use of the def keyword, and the same is true for the beginning of a class definition. The initial string included within the class is referred to as the docstring, and it contains a synopsis of the class. Although doing so is not required, doing so is strongly encouraged. The following is a straightforward explanation of the class. class MyNewClass: '''This is a docstring. I have created a new class''' pass A new local namespace is generated by a class, and here is where all of the class's attributes are declared. Data and functions are both examples of attributes. Additionally, it has several unique properties that are denoted by the notation _ followed by two underscores. For instance, using __doc__ returns the docstring associated with that class. The moment we declare a class, a brand-new object of that class with the same name is instantaneously generated. We are able to access the various characteristics of this class by using the class object, and we can also use it to create new objects of that class. class Person: "This is a person class" age = 10 def greet(self): 238 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer print('Hello') # Output: 10 print(Person.age) # Output: <function Person.greet> print(Person.greet) # Output: "This is a person class" print(Person.__doc__) Output 10 <function Person.greet at 0x7fc78c6e8160> This is a person class 3.3.15 Advanced elements of Python programming Python is a programming language having a range of features from simple to complex. It is a simple but expressive and powerful language. If you have learned the basics of Python, such as basic data structures and functionalities, then it's time to learn the complex features now. The new and advanced features of the Python language can be discovered with the help of extensive research and experience. Python has got attractive solutions as advanced features for many complicated problems that occur during development. More than one of these features can be used to solve a single Python problem. For example, if we want to iterate over a list in Python, we can use List Comprehension as well as Lambda Function. In this article, you will learn 12 useful advanced features of Python. You can take help from these advanced techniques in your code. Each method is explained along with code snippets and output for better understanding. Lambda Function A lambda function is defined without a name and thus called an anonymous function as well. It is a small function, and people usually refer to it as lambda only. It is one powerful tool for a data scientist. Typically, Python functions are defined using def keyword along with the function name. As lambda has no name, it is defined with the keyword lambda. Lambda function is basically used for the simple expression or operation where we need only a short one-time use function. This function takes arguments but can have only one expression. Let's understand this feature with the help of the below code. 239 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Generators It takes a lot of time to build iterables to iterate the Python objects. It is lengthy and quite unreasonable. Python Generator provides a simple way to declare a function that works as an iterator just like it can be used in for-loop. The generator is a function that returns an object (iterator), upon which one value at a time can be iterated. Typical iterables like lists and dictionaries have their items loaded in the memory. Whereas generators produce elements slowly and it does not need to load all of those items in memory. Thus, Generator functions are memory-efficient iterables. Below code is the illustration of this technique. def number_generator(n): num = 0 while num < n: yield num num += 1 total = sum(number_generator(100+1)) print(total) Output Map Function The Map is one of the commonly used functions in Python. It is a built-in Python function that makes work easier. Map() Function is applied on a function to a sequence of elements just like in a list or a dictionary. When a function and an iterables are passed in a map, the function is performed on each of those entities of that iterable by Map. The map function can be used with any of the Python functions if it is compatible with the element sequence being operated. Let's see the basic syntax and application with the following code. def isEven(Integer): return Integer % 2 == 0 240 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer myList = [0,3,6,9,12,15,18,21,24,27,30] EvenList = list(map(isEven, myList)) print(EvenList) If we would use a typical approach, the code will be lengthy and complex. Map( ) function simplifies the code. We get the output. Decorators Decorator is an interesting feature of Python, which is used to add functionality to the existing code. The decorator takes in a function and returns it after adding some functionality. It modifies the function without changing the core functionalities of the function. This process is also called metaprogramming, as one part of the program tries to modify another part of the program while compiling. In simple words, Python decorators add some tweaks in regards to the function's look or some other aspects and do not change the internal algorithm. Here is an example: def star (func): def inner(*args, **kwargs): print('*' * 25) func(*args, **kwargs) print('*' * 30) return inner def percent(func): def inner(*args, **kwargs): print('*' * 25) func(*args, **kwargs) print('*' * 30) return inner @star @percent def printer(msg): print(msg) 241 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook printer("Decorated") Output: Comprehensions Comprehension is one of the most mentioned techniques in Python language. Comprehension makes it easy to create a list, dictionary, or set that is named as a list comprehension, Dictionary comprehension, and a Set comprehension, respectively. With the help of comprehension, we do not need to use for-loops. This technique is faster and more efficient than traditional loops. Syntax of all the comprehensions looks quite similar. The code is more readable when Comprehension is used. The following code snippet explains this feature. numbers = [2, 6, 4, -4, -6, -2] a = [x+x for x in numbers] print(a) b = {x: pow(20, x) for x in numbers} print(b) Output: Filtering The Filter is a built-in function of Python. Like the Map function, Filter applies a function to a sequence of elements like list, tuple, dictionary. The primary difference between Map () and Filter () is that Filter () returns only those elements which are produced as True by applied function. It is a handy feature of Python to handle two steps: checking an expression and creating a return list. Here is one example code: letters = ['a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p'] 242 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer def filter_vowels(letters): vowels = ['a','e','i','o','u'] if (letters in vowels): return True else: return False filtered_vowels = filter(filter_vowels, letters) for x in filtered_vowels: print(x) Output: Python Iterator Python Iterators are the objects which are iterated upon. We can see many iterators in Python. They have implementation inside for loop, comprehensions or generators, etc. Iterators in Python return one element at a time. Iterables are the objects that can get an iterator from them. For example, String, List, Tuple, etc. are iterables. The following example shows python iterator code. my_list = [2,4,6,8,10,12] my_iter = iter(my_list) print(next(my_iter)) print(next(my_iter)) print(my_iter.__next__()) print(my_iter.__next__()) Output: 243 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Hashability Hashing is a process of using a hash function for a particular Python object that can be hashed. In Python dictionaries, the keys should be hashable. Hashability makes Python objects be converted to numeric hashed values. Hashing is a time-consuming process, but it provides you with instant look-up-time for fetching some particular element in the dictionary. It is an efficient mechanism for item insertion, item retrieval, and item checking. These are the main advantages of using hash tables as storage for dictionaries. Let's have a look at the example code. y = hash("Beautiful Weather!") print(y) x = hash((2, 'Software')) print(x) Output: Python RegEx RegEx stands for Regular Expression. A sequence of characters that is used to define a search pattern is called Regular Expression. RegEx defined patterns can be used to match against a string. The regular expressions are specified using meta characters i.e. [], ., ^, $, *, +, ?, {}, (), \, |, that are interpreted differently by RegEx Engine. RegEx is used to find the information that is based on complex patterns in text. In this way, RegEx is used to replace pattern in a string. There is one code defined by RegEx. The pattern is any string composed of five letters starting with a and ending with s. ^a…s$ The following example will help to understand RegEx. import re pattern = '^a...s$' test_string = 'abyss' result = re.match(pattern, test_string) if result: print('Search is successful') 244 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer else: print('Search is unsuccessful') Output: IterTools IterTools is a Python module. This module is a collection of tools that helps to handle iterators. Iterator is one data type used for loops for lists, dictionaries, and tuples. Iterator Operations typically require multi-line functions and complex list comprehension. The functions in Itertools allow performing such iterator operations with a more effortless and simple approach. Here is an example code: from itertools import * for i in ([2,3,4], ["b","d","e"]): print(i) for i in (count(1), ['Joe','Monica','Ross']): print(i) Output: Python Closure The technique that attaches some data to the code is called Closure in Python. When a nested function in Python references a value in its enclosing scope, it will require a Python Closure. Closure provides an object-oriented solution approach to the problem. It hides some form of the data and prevents the use of global values. Python Decorators use closures as well. The below code is an illustration of the feature. def make_multiplier_of(n): def multiplier(x): 245 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook return x * n return multiplier times3 = make_multiplier_of(2) times5 = make_multiplier_of(3) print(times3(6)) print(times5(2)) Output: 3.3.16 Demonstrate the use of control flow statements as part of Python code The control flow of a program specifies the sequence in which the program's code will be executed. Conditional statements, loops, and function calls are the primary mechanisms that direct how a Python program executes its instructions. The if statement, as well as the for and while loops, are addressed in this part; the chapter will move on to discuss functions in a subsequent section. Control flow is also affected by the process of raising and managing exceptions. if Statement It is common practise to require to execute some statements only if a certain condition is met, or to pick which statements to execute based on numerous circumstances that are incompatible with one another. You are able to conditionally execute chunks of sentences through the usage of Python's compound statement if, which is comprised of if, elif, and else clauses. The following is an example of the syntax for the if statement: if expression: statement(s) elif expression: statement(s) elif expression: statement(s) ... else: statement(s) Both the elif and the else clauses are entirely discretionary. You should be aware that in contrast to other languages, Python does not include a switch statement; hence, you are required to utilise if, elif, and else for any conditional processing. 246 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer The following is an example of a common if statement: if x < 0: print "x is negative" elif x % 2: print "x is positive and odd" else: print "x is even and non-negative" When there are multiple statements contained within a clause (i.e., the clause controls a block of statements), those statements are indented rightward from the header line of the clause and placed on separate logical lines after the line that contains the clause's keyword. This line is referred to as the header line of the clause. When the indentation matches that of the clause heading, the block is considered to have reached its conclusion (or further left from there). When there is just one simple statement, like this one, it can follow the: on the same logical line as the header, but it can also be placed on a separate logical line, immediately after the header line, and indented rightward from it. If there is only one simple statement, like this one, it can also be indented rightward from the header line. A significant number of Python users believe that the style with separate lines is easier to read: if x < 0: print "x is negative" elif x % 2: print "x is positive and odd" else: print "x is even and non-negative" You are free to use whatever phrase you want as the condition in an if or elif clause while working with Python. When you employ an expression in this manner, the context in which you are using it is considered to be Boolean. In the framework of Boolean logic, any value can be interpreted as either true or false. Any non-zero integer or non-empty string, tuple, list, or dictionary is considered to evaluate as true, as we covered earlier on in this lesson. False results are returned for the expressions "zero" (of any numeric type), "none," and empty strings, tuples, lists, and dictionaries. Use the following code style whenever you wish to test a value x in a Boolean context: if x:This is the form that makes the most sense and is the most Pythonic. To avoid using: if x is True: if x = = True: if bool(x): When talking about an expression, it is important to distinguish between stating that it "evaluates as true" and saying that it "returns True." When we state that an expression "returns True," we indicate that the expression returns the value 1 that is meant as a Boolean result (meaning the expression returns any result that is true in a Boolean context). When evaluating an expression, the condition that is being tested is the one that is most important to you. If the evaluation of the expression used for the if clause returns a value of true, the statements that come after the if clause are carried out, and the if statement as a whole is finished. In the event that this is not the case, the expressions for any elif clauses will be evaluated sequentially. The statements that follow the first elif clause that have a condition that is met are the ones that are carried out, and then the if statement as a whole is finished. In every other case, if an otherwise clause is present, the statements that come after it will be carried out. 247 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook while Statement Python's while statement enables the repeated execution of a statement or block of statements based on the results of a conditional expression. This functionality may be used in a variety of contexts. The following is an example of the while statement's syntax: while expression: statement(s) In addition, as we are going to go over in a moment, an else clause and break and continue statements can be used in a while statement. A common while statement looks like this: count = 0 while x > 0: x = x // 2 # truncating division count += 1 print "The approximate log2 is", count The phrase, also known as the loop condition, is first put through its paces for evaluation. In the event that the condition is not met, the while statement will be terminated. In the event that the loop condition is met, the statement or statements that make up the loop body will be carried out. After the execution of the loop body has been completed, the loop condition is re-evaluated to determine whether or not the loop should continue with another iteration. This procedure is repeated until the given loop condition is found to be untrue; once this occurs, the while statement is terminated. If the loop body does not contain code that will eventually make the loop condition false, the loop will never end unless an exception is thrown or the loop body executes a break statement. If the loop body does not contain code that will eventually make the loop condition false, the loop will never end. If a return statement is executed within the body of a loop that is part of a function, the function as a whole will be terminated, which means that the loop will also finish. for Statement Python's for statement enables the repeated execution of a statement or block of statements based on the value of an iterable expression. This may be done in a variety of ways. The following is a syntax example for the for statement: for target in iterable: statement(s) It is important to keep in mind that the in keyword is actually a component of the for-statement’s syntax and has no practical connection to the in operator that is used for membership checking. In addition, as we are going to go over in a moment, an else clause and break and continue statements can be used in a for statement. An example of a typical for statement is as follows: for letter in "ciao": print "give me a", letter, "..." Any Python expression that is appropriate to be passed as an input to the built-in function iter, which returns an iterator object, can be used as iterable (explained in detail in the next section). target is 248 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer often an identifier that is used to name the control variable of the loop. The for statement rebinds this variable progressively to each item of the iterator, in the order that they appear. The statement or statements that make up the body of the loop are carried out once for each item in the iterable (unless the loop ends because an exception is raised or a break or return statement is executed). Along the same lines as an unpacking assignment, it is also acceptable to have a target that has more than one identifier. In this scenario, the elements that make up the iterator need to be sequences, each of which must have the same length, which corresponds to the total number of identifiers included in the target. For instance, where d is a dictionary, the following is an example of a common method for looping through the objects in d: for key, value in d.items( ): if not key or not value: del d[key] # keep only true keys and values Since the items function provides a list of key/value pairs, we can use a for loop with two identifiers in the target to unpack each item into its key and value respectively by utilising this list. If the iterator is iterating over a mutable underlying object, the state of that object cannot be changed while a for loop is being executed on the iterator. It is not possible to use iteritems in place of items, for instance, in the prior example. iteritems provides an iterator whose underlying object is d; as the loop body is not allowed to modify d, the loop body cannot alter d. (by del d[key]). items, on the other hand, returns a list; hence, d is not the object that the iterator is iterating over, and the loop body is free to modify d. The control variable may undergo a rebound in the loop body; but, during the subsequent iteration of the loop, the control variable undergoes another rebound to the next item in the iterator. If the iterator does not produce any items, the loop body will never be executed at all. In this particular instance, the for statement does not impose any kind of bound or rebound conditions on the control variable. However, if the iterator produces at least one item, the control variable will continue to be bound to the value that the loop statement most recently assigned to it after the statement that controlled the loop is finished executing. Therefore, the code that follows is valid as long as someseq is not empty: for x in someseq: process(x) print "Last item processed was", x 3.3.17 Iterators Any object I for which you may call the method i.next() without passing any arguments is referred to as an iterator. If iterator I does not have any more items, i.next() throws a StopIteration exception. Otherwise, it returns the item that comes next in the iterator. You may give permission for instances of a class to act as iterators when you write a class (see Chapter 5 for more information), and you do this by defining a method like this next. The vast majority of iterators are constructed using either implicit or explicit calls to the built-in function known as iter, which is discussed in Chapter 8. As we'll see in the following section of this chapter, calling a generator results in the return of an iterator. The iter function is implicitly called by the for statement in order to obtain an iterator. This entails the following assertion: for x in c: statement(s) 249 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook is equivalent to: _temporary_iterator = iter(c) while True: try: x = _temporary_iterator.next( ) except StopIteration: break statement(s) Therefore, if iter(c) produces an iterator I in such a way that i.next() never raises StopIteration (which indicates an infinite iterator), the loop for x in c: never finishes running (unless the statements in the loop body contain suitable break or return statements or propagate exceptions). iter(c), on the other hand, makes a call to a specialised method called c. iter__() in order to retrieve and return an iterator on c. Python 2.2 was the version that initially included iterators. for x in S: required that S be a sequence that was indexable with progressively bigger indices 0, 1,..., and produced an IndexError if it was indexed with a too-large index. This requirement was included in older versions of the software. It is now possible to use the for statement on a container that is not a sequence, such as a dictionary, as long as the container is iterable. This means that the container must define a __iter__ special method in order for the function iter to be able to accept the container as an argument and return an iterator on the container. Built-in functions that previously only accepted sequences as an input are now allowed to take any kind of iterable. range and xrange Since it is a typical activity, Python has built-in methods called range and xrange that may construct and return integer sequences. These functions are used for looping through sequences of numbers. Python's most straightforward and natural approach of looping n times is as follows: for i in xrange(n): statement(s) range(x) will provide a list with entries that are all consecutive integers starting at 0 and going all the way up to x. (excluded). range(x,y) is a function that, when called, returns a list whose elements are successive integers ranging from x (which is included) to y. (excluded). In the event if x is larger than or equal to y, the output will be an empty list. range(x,y,step) provides a list of integers starting at x (which are included) and going all the way up to y (which are not included) with a difference of step between each pair of adjacent items in the list. In the event that step is less than 0, range will begin counting from x to y. When x is more than or equal to y and step is greater than 0, range returns the empty list. When x is less than or equal to y and step is less than 0, range also returns the empty list. In the event that step is equal to zero, range will throw an exception. While range provides a regular list object that may be used for any purpose, xrange returns a specialpurpose object that is designed to be used only in iterations, similar to how the for statement was used in the example that was shown earlier. When it comes to this particular application, xrange is more memory efficient than range. Aside from the memory usage, you may use range in any situation where xrange would be appropriate. 250 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Exercise Answer the following questions: 1. A function is a group of related statements which designed specifically to perform a ___. a) Write code b) Specific task c) Create executable file d) None of the mentioned above 2. Amongst which of the following is a proper syntax to create a function in Python? a) def function_name(parameters): ... Statements ... b) def function function_name: ... Statements ... c) def function function_name(parameters): ... Statements ... d) None of the mentioned above 3. Once we have defined a function, we can call it? a) Trueb) False 4. Amongst which of the following shows the types of function calls in Python? a) Call by value b) Call by reference c) Both A and B d) None of the mentioned above 5. What will be the output of the following Python code? def show(id,name): print("Your id is :",id,"and your name is :",name) show(12,"deepak") a) Your id is: 12 and your name is: deepak b) Your id is: 11 and your name is: Deepak c) Your id is: 13 and your name is: Deepak d) None of the mentioned above 6. Amongst which of the following is a function which does not have any name? a) Del functionb) Show function c) Lambda function d) None of the mentioned above 251 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 7. Can we pass List as an argument in Python function? a) Yesb) No 8. A method refers to a function which is part of a class? a) Trueb) False 9. The return statement is used to exit a function? a) Trueb) False 10. Scope and lifetime of a variable declared in a function exist till the function exists? a) Trueb) False 3.3.18 List comprehensions The inspection of each individual item in a sequence may be accomplished with the help of a for loop, which can then be used to construct a new list by attaching the results of an expression that was computed using some or all of the items that were examined. This popular phrase may be coded in a manner that is succinct and straightforward by using an expression form that is known as a list comprehension. Due to the fact that a list comprehension is an expression (as opposed to a collection of statements), you may use it directly in any context in which you require an expression (e.g., as an actual argument in a function call, in a return statement, or as a subexpression for some other expression). The following syntax is utilised when talking about list comprehensions: [ expression for target in iterable lc-clauses ] Both the target and the iterable remain the same as they are in a regular for statement. In the event that the expression refers to a tuple, you are obligated to wrap it in parentheses. lc-clauses are a collection of zero or more clauses, each of which can take on one of the following forms: for target in iterable if expression target and iterable in each for clause of a list comprehension have the same syntax as those in a regular for statement, and the expression in each if clause of a list comprehension has the same syntax as the expression in a regular if statement. In addition, the expression in the last for clause of a list comprehension has the same syntax as the expression in the first for clause of a regular for statement. A for loop that creates the same list by repeatedly using the append method of the resultant list is the same as a list comprehension. A list comprehension is equal to a for loop. For instance (for the sake of explanation, I'll assign the result of the list comprehension to a variable): result1 = [x+1 for x in some_sequence] is the same as the for loop: result2 = [ ] for x in some_sequence: result2.append(x+1) 252 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Here’s a list comprehension that uses an if clause: result3 = [x+1 for x in some_sequence if x>23] which is the same as a for loop that contains an if statement: result4 = [ ] for x in some_sequence: if x>23: result4.append(x+1) And here’s a list comprehension that uses a for clause: result5 = [x+y for x in alist for y in another] which is the same as a for loop with another for loop nested inside: result6 = [ ] for x in alist: for y in another: result6.append(x+y) These examples demonstrate that the order of the for and if statements in a list comprehension is the same as the order of those statements in an analogous loop; nevertheless, the nesting remains implicit in the list comprehension. Break Statement Only within the body of a loop is the break statement permitted to be used. The loop will be finished when the break instruction is executed. Only the deepest level of nested loop is ended by the break statement if many loops are contained within each other. When a break statement is used practically, it is almost often nested within some clause of an if statement in the body of the loop so that it may be executed conditionally. One frequent application of break is in the construction of a loop that, in the middle of each iteration of the loop, chooses whether or not it should continue looping while True: # this loop can never terminate naturally x = get_next( ) y = preprocess(x) if not keep_looping(x, y): break process(x, y) Continue Statement Only within the body of a loop is the continue statement permitted to be used. When the continue instruction is carried out, the currently-running iteration of the loop body is finished, and processing moves on to the subsequent iteration of the loop. In many applications, a continue statement is tucked away within some subclause of an if statement in the body of the loop to ensure that it only runs under certain circumstances. 253 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Inside of a loop, you can substitute the use of many nested if statements with the continue statement instead. Take, for instance: for x in some_container: if not seems_ok(x): continue lowbound, highbound = bounds_to_test( ) if x<lowbound or x>=highbound: continue if final_check(x): do_processing(x) This equivalent code does conditional processing without continue: for x in some_container: if seems_ok(x): lowbound, highbound = bounds_to_test( ) if lowbound<=x<highbound: if final_check(x): do_processing(x) Since there is no discernible difference between the two it comes down to personal preference as to which one you employ. Else Clause on Loop Statements The while and for statements each have the possibility of having a trailing otherwise clause attached to them. The statement or statements that follow the otherwise clause are only carried out when the loop finishes executing normally (when the for iterator reaches its conclusion or when the while loop condition is satisfied), but not when the loop finishes executing prematurely (via break, return, or an exception). Whenever a loop contains one or more break statements, it is typically necessary to examine whether or not the loop exits early or normally. For this particular reason, you may implement the loop with an otherwise clause: for x in some_container: if is_ok(x): break # item x is satisfactory, terminate loop else: print "Warning: no satisfactory item was found in container" x = None Pass Statement It is not possible to have an empty body in a Python compound statement; the body must always include at least one statement. When you need to include a statement in your code but don't have anything in particular to say or do, you may use the pass statement, which doesn't really accomplish anything, as a stand-in for the real thing. The following is an illustration of the use of the pass operator in a conditional statement as part of fairly complicated reasoning, with conditions that are mutually incompatible being tested: 254 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer if condition1(x): process1(x) elif x>23 or condition2(x) and x<5: pass # nothing to be done in this case elif condition3(x): process3(x) else: process_default(x) Try Statement The try statement, which can be found in Python, allows for the management of exceptions and contains the try, except, finally, and else clauses. With the raise statement, a program has the ability to expressly cause an exception to be thrown. When an exception is thrown in Python, the regular flow of control through the program is halted. 3.3.19 Create expressions and statements to implement, core Python elements This chapter explains the meaning of the elements of expressions in Python. Notes on Syntax: The extended BNF notation will be used to express syntax in this chapter and the ones that follow. Lexical analysis will not be covered. When (one of several possible forms of) a syntactic rule takes the form name ::= othername because there is no indication of the semantics, we may assume that the semantics of this version of the name are the same as those of othername. Arithmetic conversions When you see the line "the numeric parameters are transformed to a common type" in the description of an arithmetic operator below, this indicates that the operator implementation for built-in types functions as follows: If one of the arguments is already a complex number, then the other one will be transformed to complex as well; • • • If neither parameter is a number with a fixed-point format, the value of the other argument is changed to floating point format. If this is not the case, then both values must be integers, and a conversion will not be required. There are also supplementary guidelines that apply to particular operators, such as using a string as the left parameter to the "percent" operator. Each extension is responsible for defining its own unique conversion behaviour. 255 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Atoms Expressions may be broken down into their most fundamental atoms. Identifiers and literals are the most fundamental building blocks of an atom. Atoms are a category that may also be applied syntactically to forms that are surrounded by parentheses, brackets, or braces. The following is the syntax for atoms:atom ::= identifier | literal | enclosure enclosure ::= parenth_form | list_display | dict_display | set_display | generator_expression | yield_atom Identifiers (Names) A name is an identifier that appears in the form of an atom. For documentation on naming and binding, see the section titled "Naming and binding." The lexical definition may be found in the section titled "Identifiers and keywords." When a name is associated with a specific item, the evaluation of the atom will result in the production of that object. Any attempt to evaluate a name that has not been bound results in the generation of a NameError exception. Literals Python supports string and bytes literals and various numeric literals: literal ::= stringliteral | bytesliteral | integer | floatnumber | imagnumber When a literal is evaluated, it produces an object of the provided type (string, bytes, integer, floating point number, or complex number) with the value that was specified. It is possible to provide an approximation of the value when dealing with floating point and imaginary (complex) literals. For more information, please refer to the Literals section. Because there is a one-to-one correspondence between literals and immutable data types, the value of the object takes precedence over its identity. It is possible for several evaluations of literals with the same value (either the same occurrence in the program language or a different occurrence) to yield the same object or a different object with the same value. This is because literals are evaluated in sequence. Parenthesized forms A parenthesized form is an optional expression list enclosed in parentheses: parenth_form ::= "(" [starred_expression] ")" If the expression list contains at least one comma, the result is a tuple; if the list does not contain at least one comma, the result is the single expression that constitutes the expression list. The result of an expression list that is parenthesized is the same as the result of the expression list itself. The result of a pair of empty parentheses is a tuple object that is empty. Since tuples cannot be changed, the same restrictions that apply to literals must be followed (i.e., two occurrences of the empty tuple may or may not yield the same object). It is important to keep in mind that tuples are not created by the usage of parentheses but rather the comma. The empty tuple is the only exception to this rule; it must always be enclosed in parentheses. If "nothing" could be used in expressions without being enclosed in parentheses, it would lead to ambiguity and enable frequent errors to go unnoticed. 256 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Displays for lists, sets and dictionaries Python has a specialised syntax known as "displays" for the purpose of building lists, sets, and dictionaries. Each of these constructs comes in two flavours: • • either the contents of the container are described in detail, or otherwise. They are computed using something that is called a comprehension, which is a collection of instructions for looping and filtering. Common syntax elements for comprehensions are: comprehension ::= assignment_expression comp_for comp_for ::= ["async"] "for" target_list "in" or_test [comp_iter] comp_iter ::= comp_for | comp_if comp_if ::= "if" or_test [comp_iter] List displays A list display is a succession of expressions that may or may not be empty and are enclosed in square brackets: list_display ::= "[" [starred_list | comprehension] "]" A new list object is produced when a list is shown. The contents of the new list may be supplied using either a comprehension or a list of expressions. When a list of expressions that is separated by commas is provided, the items of that list are evaluated from left to right and then inserted into the list object in the order that they were evaluated. When a comprehension is provided, the list that is generated is composed of the items that are produced as a result of the comprehension. Set displays Curly braces are used to indicate a set display, which may be differentiated from dictionary displays by the absence of colons that are used to separate the keys and values: set_display ::= "{" (starred_list | comprehension) "}" A set display results in the creation of a new mutable set object, the contents of which can be given by either a comprehension or a series of expressions. When you provide a list of expressions that are separated by commas, the items of that list are evaluated from left to right, and the results are added to the set object. When a comprehension is provided, the set that is being formed will use the components that are produced as a result of the comprehension. It is not possible to build an empty set using the notation; instead, an empty dictionary is created using this literal. Dictionary display A dictionary display is a possibly empty series of key/datum pairs enclosed in curly braces: dict_display key_datum_list key_datum ::= "{" [key_datum_list | dict_comprehension] "}" ::= key_datum ("," key_datum)* [","] ::= expression ":" expression | "**" or_expr dict_comprehension ::= expression ":" expression comp_for 257 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook A new dictionary object is produced whenever a dictionary is shown. If a sequence of key/datum pairs is provided, they are evaluated from left to right to define the entries of the dictionary. Each key object is used as a key into the dictionary to store the corresponding datum. If a sequence of key/datum pairs is provided, the entries are evaluated from left to right to define the entries. This indicates that you can specify the same key many times in the key/datum list; however, the value that is assigned to that key in the final dictionary will be the one that was specified most recently. The phrase "dictionary unpacking" is indicated with a double asterisk (**). It is required that the operand be a mapping. The new vocabulary is expanded with each individual mapping item. Later values take the place of older ones that had already been established by earlier key/datum combinations and earlier unpackings of the dictionary. Unpacking into dictionary displays, which was initially proposed by PEP 448, is now available in version 3.5. In contrast to list and set comprehensions, dict comprehensions need two expressions, each of which must be separated by a colon. These expressions are then followed by the customary "for" and "if" clauses. When the comprehension is executed, the key and value components that were formed as a result of it are added into the new dictionary in the order in which they were generated. Generator expressions A generator expression is a compact generator notation in parentheses: generator_expression ::= "(" expressioncomp_for ")" A new generator object is produced whenever a generator expression is evaluated. Its syntax is identical to that of comprehensions, with the exception that it is encased in parentheses rather than being contained in brackets or curly braces. When the __next__() method of the generator object is invoked, the variables that are being utilised in the generator expression are evaluated in a delayed way (in the same fashion as normal generators). However, because the iterable expression in the first for clause is immediately evaluated, any error that it causes will be thrown at the place in the code where the generator expression is declared rather than at the point in the code where the first item is received. Because they may depend on the values received from the leftmost iterable, subsequent for clauses and any filter condition contained inside the leftmost for clause are unable to be evaluated within the scope of the enclosing statement. As an illustration: (x*y for x in range(10) for y in range(x, x+10)When there is only one parameter to a call, the parenthesis can be left out. Details may be found in the section labelled Calls. In order to prevent unexpected side effects from occurring during the normal execution of the generator expression, the use of yield and yield from expressions is not permitted in the implicitly specified generator. An expression is said to be asynchronous if it contains async for clauses or await expressions. This type of expression is known as an asynchronous generator expression. A new asynchronous generator object, also known as an asynchronous iterator, is what is returned when an asynchronous generator expression is evaluated (see Asynchronous Iterators). Yield expressions yield_atom ::= "(" yield_expression ")" yield_expression ::= "yield" [expression_list | "from" expression] Since the yield expression is required for the definition of a generator function or an asynchronous 258 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer generator function, it is permissible to utilise it only inside the context of the body of a function declaration. When you put a yield expression inside the body of a function, it transforms the function into a generator function. When you put a yield expression inside the body of an async def function, it transforms the coroutine function into an asynchronous generator function. Take, for instance: def gen(): # defines a generator function yield 123 async def agen(): # defines an asynchronous generator function yield 123 3.3.20 Fruitful functions We write functions that return values, which we will call fruitful functions. We have seen the return statement before, but in a fruitful function the return statement includes a return value. This statement means: "Return immediately from this function and use the following expression as a return value." (or) Any function that returns a value is called Fruitful function. A Function that does not return a value is called a void function Return values: The Keyword return is used to return back the value to the called function. # returns the area of a circle with the given radius: def area(radius): temp = 3.14 * radius**2 return temp print(area(4)) (or) def area(radius): return 3.14 * radius**2 print(area(2)) Sometimes it is useful to have multiple return statements, one in each branch of a conditional: def absolute_value(x): if x < 0: return -x else: return x 259 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Since these return statements are in an alternative conditional, only one will be executed. As soon as a return statement executes, the function terminates without executing any subsequent statements. Code that appears after a return statement, or any other place the flow of execution can never reach, is called dead code. In a fruitful function, it is a good idea to ensure that every possible path through the program hits a return statement. For example: def absolute_value(x): if x < 0: return -x if x > 0: return x This function is incorrect because if x happens to be 0, both conditions is true, and the function ends without hitting a return statement. If the flow of execution gets to the end of a function, the return value is None, which is not the absolute value of 0. >>> print absolute_value(0) None By the way, Python provides a built-in function called abs that computes absolute values. # Write a Python function that takes two lists and returns True if they have at least one common member. def common_data(list1, list2): for x in list1: for y in list2: if x == y: result = True return result print(common_data([1,2,3,4,5], [1,2,3,4,5])) print(common_data([1,2,3,4,5], [1,7,8,9,510])) print(common_data([1,2,3,4,5], [6,7,8,9,10])) Output: C:\Users\CET\AppData\Local\Programs\Python\Python38-32\pyyy\fu1.py True True None 260 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer def area(radius): b = 3.14159 * radius**2 return b Parameters: Parameters are passed during the definition of function while Arguments are passed during the function call. Example: #here a and b are parameters def add(a,b): #//function definition return a+b #12 and 13 are arguments #function call result=add(12,13) print(result) Output: C:/UsersAppData/Local/Programs/Python/Python3832/pyyy/paraarg.py 25 # To display vandemataram by using function use no args no return type #function defination def display(): print("vandemataram") print("i am in main") #function call display() print("i am in main") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py i am in main vandemataram i am in main #Type1 : No parameters and no return type def Fun1() : 261 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print("function 1") Fun1() Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py function 1 #Type 2: with param with out return type def fun2(a) : print(a) fun2("hello") Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py Hello #Type 3: without param with return type def fun3(): return "welcome to python" print(fun3()) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py welcome to python #Type 4: with param with return type def fun4(a): return a print(fun4("python is better then c")) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py python is better then c Local and Global scope: Local Scope: A variable which is defined inside a function is local to that function. It is accessible from the point at which it is defined until the end of the function, and exists for as long as the function is executing Global Scope: A variable which is defined in the main body of a file is called a global variable. It will be visible throughout the file, and also inside any file which imports that file. 262 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer • The variable defined inside a function can also be made global by using the global statement. def function_name(args): ............. global x #declaring global variable inside a function .............. # create a global variable x = "global" def f(): print("x inside :", x) f() print("x outside:", x) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py x inside : global x outside: global # create a local variable def f1(): y = "local" print(y) f1() Output: local If we try to access the local variable outside the scope for example, def f2(): y = "local" f2() print(y) Then when we try to run it shows an error, 263 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Traceback (most recent call last): File "C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py", line 6, in <module> print(y) NameError: name 'y' is not defined The output shows an error, because we are trying to access a local variable y in a global scope whereas the local variable only works inside f2() or local scope. # use local and global variables in same code x = "global" def f3(): global x y = "local" x = x * 2 print(x) print(y) f3() Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py global global local • • In the above code, we declare x as a global and y as a local variable in the f3(). Then, we use multiplication operator * to modify the global variable x and we print both x and y. After calling the f3(), the value of x becomes global global because we used the x * 2 to print two times global. After that, we print the value of local variable y i.e local. # use Global variable and Local variable with same name x = 5 def f4(): x = 10 print("local x:", x) f4() print("global x:", x) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/fu1.py local x: 10 global x: 5 Function Composition: Having two (or more) functions where the output of one function is the input for another. So for example if you have two functions FunctionA and FunctionB you compose them by doing the following. FunctionB(FunctionA(x)) 264 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Here x is the input for FunctionA and the result of that is the input for FunctionB. Example 1: #create a function compose2 >>> def compose2(f, g): return lambda x:f(g(x)) >>> def d(x): return x*2 >>> def e(x): return x+1 >>> a=compose2(d,e) # FunctionC = compose(FunctionB,FunctionA) >>> a(5) # FunctionC(x) 12 In the above program we tried to compose n functions with the main function created. Example 2: >>> colors=('red','green','blue') >>> fruits=['orange','banana','cherry'] >>> zip(colors,fruits) <zip object at 0x03DAC6C8> >>> list(zip(colors,fruits)) [('red', 'orange'), ('green', 'banana'), ('blue', 'cherry')] Exercise Answer the following questions: 1. File handling in Python refers the feature for reading data from the file and writing data into a file? a) Trueb) False 2. Amongst which of the following is / are the key functions used for file handling in Python? a) open() and close() b) read() and write() 265 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook c) append() d) All of the mentioned above 3. Amongst which of the following is / are needed to open an existing file? a) filename b) mode c) Both A and B d) None of the mentioned above 4. Binary files are stored in the form of 0s and 1s? a) Trueb) False 5. The function file_object.close() is used to ___. a) To open the existing file c) To close an opened file b) To append in an opened file d) None of the mentioned above 3.3.21 Fruitful functions Recursion is the process of defining something in terms of itself. Python Recursive Function • • • We know that in Python, a function can call other functions. It is even possible for the function to call itself. These type of construct are termed as recursive functions. Factorial of a number is the product of all the integers from 1 to that number. For example, the factorial of 6 (denoted as 6!) is 1*2*3*4*5*6 = 720. Following is an example of recursive function to find the factorial of an integer. # Write a program to factorial using recursion def fact(x): if x==0: result = 1 else : result = x * fact(x-1) return result print("zero factorial",fact(0)) print("five factorial",fact(5)) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/rec.py zero factorial 1 five factorial 120 def calc_factorial(x): 266 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer """This is a recursive function to find the factorial of an integer""" if x == 1: return 1 else: return (x * calc_factorial(x-1)) num = 4 print("The factorial of", num, "is", calc_factorial(num)) Output: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/rec.py The factorial of 4 is 24 3.3.22 Python arrays Array is a container which can hold a fix number of items and these items should be of the same type. Most of the data structures make use of arrays to implement their algorithms. Following are the important terms to understand the concept of Array. • • Element− Each item stored in an array is called an element. Index − Each location of an element in an array has a numerical index, which is used to identify the element. Array Representation Arrays can be declared in various ways in different languages. Below is an illustration. Elements Int array [10] = {10, 20, 30, 40, 50, 60, 70, 80, 85, 90} Type Name Size Index 0 As per the above illustration, following are the important points to be considered. • • • Index starts with 0. Array length is 10 which means it can store 10 elements. Each element can be accessed via its index. For example, we can fetch an element at index 6 as 70 267 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Basic Operations Following are the basic operations supported by an array. • • • • • Traverse − print all the array elements one by one. Insertion − Adds an element at the given index. Deletion − Deletes an element at the given index. Search − Searches an element using the given index or by the value. Update − Updates an element at the given index. Array is created in Python by importing array module to the python program. Then the array is declared as shown below. from array import * arrayName=array(typecode, [initializers]) Typecode are the codes that are used to define the type of value the array will hold. Some common typecodes used are: Typecode b B c i I f d Value Represents signed integer of size 1 byte/td> Represents unsigned integer of size 1 byte Represents character of size 1 byte Represents signed integer of size 2 bytes Represents unsigned integer of size 2 bytes Represents floating point of size 4 bytes Represents floating point of size 8 bytes Creating an array: from array import * array1 = array('i', [10,20,30,40,50]) for x in array1: print(x) Output: >>> RESTART: C:/UsersAppData/Local/Programs/Python/Python38-32/arr.py 10 20 30 40 50 268 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.3.22.1 Access the elements of an Array Accessing Array Element We can access each element of an array using the index of the element. from array import * array1 = array('i', [10,20,30,40,50]) print (array1[0]) print (array1[2]) Output: RESTART: C:/UsersAppData/Local/Programs/Python/Python38-32/pyyy/arr2.py 10 30 Array methods: Python has a set of built-in methods that you can use on lists/arrays. Method append() clear() copy() count() extend() index() insert() pop() remove() reverse() sort() Description Adds an element at the end of the list Removes all the elements from the list Returns a copy of the list Returns the number of elements with the specified value Add the elements of a list (or any iterable), to the end of the current list Returns the index of the first element with the specified value Adds an element at the specified position Removes the element at the specified position Removes the first item with the specified value Reverses the order of the list Sorts the list Note: Python does not have built-in support for Arrays, but Python Lists can be used instead. Example: >>> college=["CET","it","cse"] >>> college.append("autonomous") >>> college ['CET', 'it', 'cse', 'autonomous'] >>> college.append("eee") >>> college.append("ece") >>> college ['CET', 'it', 'cse', 'autonomous', 'eee', 'ece'] 269 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook >>> college.pop() 'ece' >>> college ['CET', 'it', 'cse', 'autonomous', 'eee'] >>> college.pop(4) 'eee' >>> college ['CET', 'it', 'cse', 'autonomous'] >>> college.remove("it") >>> college ['CET', 'cse', 'autonomous'] Exercise Answer the following questions: 1. Python always makes sure that any unwritten or unsaved data is written to the file before it is closed? a) Trueb) False 2. The write() method takes a string as an argument and ___. a) writes it to the text file b) read from the text file c) append in a text file d) None of the mentioned above 3. The seek() method is used to _________. a) Saves the file in secondary storage b) Position the file object at a particular position in a file c) Deletes the file form secondary storage d) None of the mentioned above 4. Amongst which of the following function is / are used to create a file and writing data? a) append()b) open() c) close() d) None of the mentioned above 5. The readline() is used to read the data line by line from the text file. a) Trueb) mFalse 6. The module Pickle is used to ___. a) Serializing Python object structure b) De-serializing Python object structure 270 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer c) Both A and B d) None of the mentioned above 7. Amongst which of the following is / are the method of convert Python objects for writing data in a binary file? a) set() methodb) dump() method c) load() method d) None of the mentioned above 8. Amongst which of the following is / are the method used to unpickling data from a binary file? a) load()b) set() method c) dump() method d) None of the mentioned above 9. A text file contains only textual information consisting of ___. a) Alphabetsb) Numbers c) Special symbols d) All of the mentioned above 10. The writelines() method is used to write multiple strings to a file? a) Trueb) False 3.3.23 Python App package: Packaging Python Projects This guide shows you how to package a straightforward Python project. It will demonstrate how to construct the package, how to add the required files and structure, and how to post it to the Python Package Index (PyPI). Windows: py -m pip install --upgrade pip A simple project This tutorial uses a simple project named example_package_YOUR_USERNAME_HERE. If your username is me, then the package would be example_package_me; this ensures that you have a unique package name that doesn’t conflict with packages uploaded by other people following this tutorial. We recommend following this tutorial as-is using this project, before packaging your own project. Create the following file structure locally: packaging_tutorial/ └── src/ └── example_package_YOUR_USERNAME_HERE/ ── __init__.py └── example.py The directory containing the Python files should match the project name. This simplifies the configuration and is more obvious to users who install the package. 271 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook __init__.py is required to import the directory as a package, and should be empty. example.py is an example of a module within the package that could contain the logic (functions, classes, constants, etc.) of your package. Open that file and enter the following content: def add_one(number): return number + 1 If you are unfamiliar with Python’s modules and import packages, take a few minutes to read over the Python documentation for packages and modules. Once you create this structure, you’ll want to run all of the commands in this tutorial within the packaging_tutorial directory. Creating the package files You will now add files that are used to prepare the project for distribution. When you’re done, the project structure will look like this: packaging_tutorial/ ├── LICENSE ├── pyproject.toml ├── README.md ├── src/ │ └── example_package_YOUR_USERNAME_HERE/ │ ├── __init__.py │ └── example.py └── tests/ Creating a test directory tests/ is a placeholder for test files. Leave it empty for now. Creating pyproject.toml pyproject.toml tells “frontend” build tools like pip and build what “backend” tool to use to create distribution packages for your project. You can choose from a number of backends; this tutorial uses Hatchling by default, but it will work identically with setuptools, Flit, PDM, and others that support the [project] table for metadata. Note Some build backends are part of larger tools that provide a command-line interface with additional features like project initialization and version management, as well as building, uploading, and installing packages. This tutorial uses single-purpose tools that work independently. Open pyproject.toml and enter one of these [build-system] tables: 272 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Hatchling [build-system] requires = ["hatchling"] build-backend = "hatchling.build" setuptools Flit PDM requires is a list of packages that are needed to build your package. You don’t need to install them; build frontends like pip will install them automatically in a temporary, isolated virtual environment for use during the build process. build-backend is the name of the Python object that frontends will use to perform the build. Configuring metadata Open pyproject.toml and enter the following content. Change the name to include your username; this ensures that you have a unique package name that doesn’t conflict with packages uploaded by other people following this tutorial. [project] name = "example_package_YOUR_USERNAME_HERE" version = "0.0.1" authors = [ { name="Example Author", email="author@example.com" }, ] description = "A small example package" readme = "README.md" requires-python = ">=3.7" classifiers = [ "Programming Language :: Python :: 3", "License :: OSI Approved :: MIT License", "Operating System :: OS Independent", ] [project.urls] "Homepage" = "https://github.com/pypa/sampleproject" "Bug Tracker" = "https://github.com/pypa/sampleproject/issues" 273 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook name is the distribution name of your package. This can be any name as long as it only contains letters, numbers, ., _ , and -. It also must not already be taken on PyPI. Be sure to update this with your username for this tutorial, as this ensures you won’t try to upload a package with the same name as one which already exists. version is the package version. See the version specifier specification for more details on versions. Some build backends allow it to be specified another way, such as from a file or a git tag. authors is used to identify the author of the package; you specify a name and an email for each author. You can also list maintainers in the same format. description is a short, one-sentence summary of the package. readme is a path to a file containing a detailed description of the package. This is shown on the package detail page on PyPI. In this case, the description is loaded from README.md (which is a common pattern). There also is a more advanced table form described in the project metadata specification. requires-python gives the versions of Python supported by your project. Installers like pip will look back through older versions of packages until it finds one that has a matching Python version. classifiers gives the index and pip some additional metadata about your package. In this case, the package is only compatible with Python 3, is licensed under the MIT license, and is OS-independent. You should always include at least which version(s) of Python your package works on, which license your package is available under, and which operating systems your package will work on. For a complete list of classifiers, see https://pypi.org/classifiers/. urls lets you list any number of extra links to show on PyPI. Generally this could be to the source, documentation, issue trackers, etc. See the project metadata specification for details on these and other fields that can be defined in the [project] table. Other common fields are keywords to improve discoverability and the dependencies that are required to install your package. Creating README.md Open README.md and enter the following content. You can customize this if you’d like. # Example Package This is a simple example package. You can use [Github-flavored Markdown](https://guides.github.com/features/mastering-markdown/) to write your content. Creating a LICENSE It’s important for every package uploaded to the Python Package Index to include a license. This tells users who install your package the terms under which they can use your package. For help picking a license, see https://choosealicense.com/. Once you have chosen a license, open LICENSE and enter the license text. For example, if you had chosen the MIT license: Including other files The files listed above will be included automatically in your source distribution. If you want to include 274 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer additional files, see the documentation for your build backend. Generating distribution archives The next step is to generate distribution packages for the package. These are archives that are uploaded to the Python Package Index and can be installed by pip. Make sure you have the latest version of PyPA’s build installed: Windows:py -m pip install --upgrade build Tip If you have trouble installing these, see the Installing Packages tutorial. Now run this command from the same directory where pyproject.toml is located: Windows:py -m build This command should output a lot of text and once completed should generate two files in the dist directory: dist/ ├── example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl └── example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz The tar.gz file is a source distribution whereas the .whl file is a built distribution. Newer pip versions preferentially install built distributions, but will fall back to source distributions if needed. You should always upload a source distribution and provide built distributions for the platforms your project is compatible with. In this case, our example package is compatible with Python on any platform so only one built distribution is needed. Uploading the distribution archives Finally, it’s time to upload your package to the Python Package Index! The first thing you’ll need to do is register an account on TestPyPI, which is a separate instance of the package index intended for testing and experimentation. It’s great for things like this tutorial where we don’t necessarily want to upload to the real index. To register an account, go to https://test.pypi.org/ account/register/ and complete the steps on that page. You will also need to verify your email address before you’re able to upload any packages. For more details, see Using TestPyPI. To securely upload your project, you’ll need a PyPI API token. Create one at https://test.pypi.org/ manage/account/#api-tokens, setting the “Scope” to “Entire account”. Don’t close the page until you have copied and saved the token — you won’t see that token again. Now that you are registered, you can use twine to upload the distribution packages. You’ll need to install Twine: Windows:py -m pip install --upgrade twine Once installed, run Twine to upload all of the archives under dist: 275 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Windows:py -m twine upload --repository testpypi dist/* You will be prompted for a username and password. For the username, use __token__. For the password, use the token value, including the pypi- prefix. After the command completes, you should see output similar to this: Uploading distributions to https://test.pypi.org/legacy/ Enter your username: __token__ Uploading example_package_YOUR_USERNAME_HERE-0.0.1-py3-none-any.whl 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 8.2/8.2 kB • 00:01 • ? Uploading example_package_YOUR_USERNAME_HERE-0.0.1.tar.gz 100% ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 6.8/6.8 kB • 00:00 • ? Once uploaded, your package should be viewable on TestPyPI; for example: https://test.pypi.org/ project/example_package_YOUR_USERNAME_HERE. Installing your newly uploaded package You can use pip to install your package and verify that it works. Create a virtual environment and install your package from TestPyPI: Windows:py -m pip install --index-url https://test.pypi.org/simple/ --no-deps example-package-YOURUSERNAME-HERE Make sure to specify your username in the package name! pip should install the package from TestPyPI and the output should look something like this: Collecting example-package-YOUR-USERNAME-HERE Downloading https://testfiles.pythonhosted.org/packages/.../example_package_YOUR_USERNAME_HERE_0.0.1py3-none-any.whl Installing collected packages: example_package_YOUR_USERNAME_HERE Successfully installed example_package_YOUR_USERNAME_HERE-0.0.1 Note This example uses --index-url flag to specify TestPyPI instead of live PyPI. Additionally, it specifies --no-deps. Since TestPyPI doesn’t have the same packages as the live PyPI, it’s possible that attempting to install dependencies may fail or install something unexpected. While our example package doesn’t have any dependencies, it’s a good practice to avoid installing dependencies when using TestPyPI. You can test that it was installed correctly by importing the package. Make sure you’re still in your virtual environment, then run Python: 276 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Windows:py and import the package: from example_package_YOUR_USERNAME_HERE import example example.add_one(2) 3 Next steps Congratulations, you’ve packaged and distributed a Python project! Keep in mind that this tutorial showed you how to upload your package to Test PyPI, which isn’t a permanent storage. The Test system occasionally deletes packages and accounts. It is best to use TestPyPI for testing and experiments like this tutorial. When you are ready to upload a real package to the Python Package Index you can do much the same as you did in this tutorial, but with these important differences: Choose a memorable and unique name for your package. You don’t have to append your username as you did in the tutorial, but you can’t use an existing name. Register an account on https://pypi.org - note that these are two separate servers and the login details from the test server are not shared with the main server. Use twine upload dist/* to upload your package and enter your credentials for the account you registered on the real PyPI. Now that you’re uploading the package in production, you don’t need to specify --repository; the package will upload to https://pypi.org/ by default. Install your package from the real PyPI using python3 -m pip install [your-package]. We organize a large number of files in different folders and subfolders based on some criteria, so that we can find and manage them easily. In the same way, a package in Python takes the concept of the modular approach to next logical level. As you know, a module can contain multiple objects, such as classes, functions, etc. A package can contain one or more relevant modules. Physically, a package is actually a folder containing one or more module files. Let's create a package named mypackage, using the following steps: Create a new folder named D:\MyApp . Inside MyApp , create a subfolder with the name 'mypackage'. Create an empty __init__.py file in the mypackage folder. Using a Python-aware editor like IDLE, create modules greet.py and functions.py with the following code: greet.py def SayHello(name): print("Hello ", name) functions.py 277 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook def sum(x,y): return x+y def average(x,y): return (x+y)/2 def power(x,y): return x**y That's it. We have created our package called mypackage. The following is a folder structure: Package Folder Structure: Importing a Module from a Package Now, to test our package, navigate the command prompt to the MyApp folder and invoke the Python prompt from there. D:\MyApp>python Import the functions module from the mypackage package and call its power() function. >>> from mypackage import functions >>> functions.power(3,2) 9 It is also possible to import specific functions from a module in the package. >>> from mypackage.functions import sum >>> sum(10,20) 30 >>> average(10,12) Traceback (most recent call last): File "<pyshell#13>", line 1, in <module> NameError: name 'average' is not defined __init__.py The package folder contains a special file called __init__.py , which stores the package's content. It serves two purposes: 1. The Python interpreter recognizes a folder as the package if it contains __init__.py file. 2. __init__.py exposes specified resources from its modules to be imported. An empty __init__.py file makes all functions from the above modules available when this package is imported. Note that __init__.py is essential for the folder to be recognized by Python as a package. You can optionally define functions from individual modules to be made available. Note: We shall also create another Python script in the MyApp folder and import the mypackage package in it. It should be at the same level of the package to be imported. The __init__.py file is normally kept empty. However, it can also be used to choose specific functions 278 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer from modules in the package folder and make them available for import. Modify __init__.py as below: __init__.py Copy from .functions import average, power from .greet import SayHello The specified functions can now be imported in the interpreter session or another executable script. Create test.py in the MyApp folder to test mypackage. test.py Copy from mypackage import power, average, SayHello SayHello() x=power(3,2) print("power(3,2) : ", x) Note that functions power() and SayHello() are imported from the package and not from their respective modules, as done earlier. The output of the above script is: D:\MyApp>python test.py Hello world power(3,2) : 9 Install a Package Globally Once a package is created, it can be installed for system-wide use by running the setup script. The script calls setup() function from the setuptools module. Let's install mypackage for system-wide use by running a setup script. Save the following code as setup.py in the parent folder MyApp . The script calls the setup() function from the setuptools module. The setup() function takes various arguments such as name, version, author, list of dependencies, etc. The zip_safe argument defines whether the package is installed in compressed mode or regular mode. Example: setup.py Copy from setuptools import setup setup(name='mypackage', version='0.1', description='Testing installation of Package', url='#', author='auth', author_email='[email protected]', license='MIT', packages=['mypackage'], 279 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook zip_safe=False) Now execute the following command to install mypackage using the pip utility. Ensure that the command prompt is in the parent folder, in this case D:\MyApp . D:\MyApp>pip install mypackage Processing d:\MyApp Installing collected packages: mypack Running setup.py install for mypack ... done Successfully installed mypackage-0.1 Now mypackage is available for system-wide use and can be imported in any script or interpreter. D:\>python >>> import mypackage >>>mypackage.average(10,20) 15.0 >>>mypackage.power(10,2) 100 3.3.24 Python File Handling / Data Streams Sometimes, it is not enough to only display the data on the console. The data to be displayed may be very large, and only a limited amount of data can be displayed on the console since the memory is volatile, it is impossible to recover the programmatically generated data again and again. The file handling plays an important role when the data needs to be stored permanently into the file. A file is a named location on disk to store related information. We can access the stored information (non-volatile) after the program termination. The file-handling implementation is slightly lengthy or complicated in the other programming language, but it is easier and shorter in Python. In Python, files are treated in two modes as text or binary. The file may be in the text or binary format, and each line of a file is ended with the special character. Hence, a file operation can be done in the following order. • • • Open a file Read or write - Performing operation Close the file Opening a file Python provides an open() function that accepts two arguments, file name and access mode in which the file is accessed. The function returns a file object which can be used to perform various operations like reading, writing, etc. 280 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Syntax: file object = open(<file-name>, <access-mode>, <buffering>) The files can be accessed using various modes like read, write, or append. The following are the details about the access mode to open a file. SN Access mode 1 R 2 Rb 3 r+ 4 rb+ 5 W 6 Wb 7 w+ 8 wb+ 9 A 10 Ab 11 a+ 12 ab+ Description It opens the file to read-only mode. The file pointer exists at the beginning. The file is by default open in this mode if no access mode is passed. It opens the file to read-only in binary format. The file pointer exists at the beginning of the file. It opens the file to read and write both. The file pointer exists at the beginning of the file. It opens the file to read and write both in binary format. The file pointer exists at the beginning of the file. It opens the file to write only. It overwrites the file if previously exists or creates a new one if no file exists with the same name. The file pointer exists at the beginning of the file. It opens the file to write only in binary format. It overwrites the file if it exists previously or creates a new one if no file exists. The file pointer exists at the beginning of the file. It opens the file to write and read both. It is different from r+ in the sense that it overwrites the previous file if one exists whereas r+ doesn't overwrite the previously written file. It creates a new file if no file exists. The file pointer exists at the beginning of the file. It opens the file to write and read both in binary format. The file pointer exists at the beginning of the file. It opens the file in the append mode. The file pointer exists at the end of the previously written file if exists any. It creates a new file if no file exists with the same name. It opens the file in the append mode in binary format. The pointer exists at the end of the previously written file. It creates a new file in binary format if no file exists with the same name. It opens a file to append and read both. The file pointer remains at the end of the file if a file exists. It creates a new file if no file exists with the same name. It opens a file to append and read both in binary format. The file pointer remains at the end of the file. Let's look at the simple example to open a file named "file.txt" (stored in the same directory) in read mode and printing its content on the console. Example #opens the file file.txt in read mode fileptr = open("file.txt","r") if fileptr:print("file is opened successfully") 281 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Output: <class '_io.TextIOWrapper'> file is opened successfully In the above code, we have passed filename as a first argument and opened file in read mode as we mentioned r as the second argument. The fileptr holds the file object and if the file is opened successfully, it will execute the print statement The close() method Once all the operations are done on the file, we must close it through our Python script using the close() method. Any unwritten information gets destroyed once the close() method is called on a file object. We can perform any operation on the file externally using the file system which is the currently opened in Python; hence it is good practice to close the file once all the operations are done. The syntax to use the close() method is given below. Syntax fileobject.close() Consider the following example. # opens the file file.txt in read mode fileptr = open("file.txt","r") if fileptr: print("file is opened successfully") #closes the opened file fileptr.close() After closing the file, we cannot perform any operation in the file. The file needs to be properly closed. If any exception occurs while performing some operations in the file then the program terminates without closing the file. We should use the following method to overcome such type of problem. try: fileptr = open("file.txt") # perform file operations finally: fileptr.close() The with statement The with statement was introduced in python 2.5. The with statement is useful in the case of manipulating the files. It is used in the scenario where a pair of statements is to be executed with a block of code in between. The syntax to open a file using with the statement is given below. with open(<file name>, <access mode>) as <file-pointer>: #statement suite The advantage of using with statement is that it provides the guarantee to close the file regardless of how the nested block exits. It is always suggestible to use the with statement in the case of files because, if the break, return, or exception occurs in the nested block of code then it automatically closes the file, we don't need to write the close() function. It doesn't let the file to corrupt. Consider the following example. Example with open("file.txt",'r') as f: content = f.read(); print(content) 282 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Writing the file To write some text to a file, we need to open the file using the open method with one of the following access modes. w: It will overwrite the file if any file exists. The file pointer is at the beginning of the file. a: It will append the existing file. The file pointer is at the end of the file. It creates a new file if no file exists. Consider the following example. Example # open the file.txt in append mode. Create a new file if no such file exists. fileptr = open("file2.txt", "w") # appending the content to the file fileptr.write('''Python is the modern day language. It makes things so simple. It is the fastest-growing programing language''') # closing the opened the file fileptr.close() Output: File2.txt Python is the modern-day language. It makes things so simple. It is the fastest growing programming language. Snapshot of the file2.txt We have opened the file in w mode. The file1.txt file doesn't exist, it created a new file and we have written the content in the file using the write() function. Example 2 #open the file.txt in write mode. fileptr = open("file2.txt","a") #overwriting the content of the file fileptr.write(" Python has an easy syntax and user-friendly interaction.") #closing the opened file fileptr.close() Output: Python is the modern day language. It makes things so simple. It is the fastest growing programing language Python has an easy syntax and user-friendly interaction. 283 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Snapshot of the file2.txt We can see that the content of the file is modified. We have opened the file in a mode and it appended the content in the existing file2.txt. To read a file using the Python script, the Python provides the read() method. The read() method reads a string from the file. It can read the data in the text as well as a binary format. The syntax of the read() method is given below. Syntax: fileobj.read(<count>) Here, the count is the number of bytes to be read from the file starting from the beginning of the file. If the count is not specified, then it may read the content of the file until the end. Consider the following example. Example #open the file.txt in read mode. causes error if no such file exists. fileptr = open("file2.txt","r") #stores all the data of the file into the variable content content = fileptr.read(10) # prints the type of the data stored in the file print(type(content)) #prints the content of the file print(content) #closes the opened file fileptr.close() Output: <class 'str'> Python is In the above code, we have read the content of file2.txt by using the read() function. We have passed count value as ten which means it will read the first ten characters from the file. If we use the following line, then it will print all content of the file. content = fileptr.read() print(content) Output: Python is the modern-day language. It makes things so simple. It is the fastest-growing programing language Python has easy an syntax and user-friendly interaction. 284 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Read file through for loop We can read the file using for loop. Consider the following example. #open the file.txt in read mode. causes an error if no such file exists. fileptr = open("file2.txt","r"); #running a for loop for i in fileptr: print(i) # i contains each line of the file Output: Python is the modern day language. It makes things so simple. Python has easy syntax and user-friendly interaction. Read Lines of the file Python facilitates to read the file line by line by using a function readline() method. The readline() method reads the lines of the file from the beginning, i.e., if we use the readline() method two times, then we can get the first two lines of the file. Consider the following example which contains a function readline() that reads the first line of our file "file2.txt" containing three lines. Consider the following example. Example 1: Reading lines using readline() function #open the file.txt in read mode. causes error if no such file exists. fileptr = open("file2.txt","r"); #stores all the data of the file into the variable content content = fileptr.readline() content1 = fileptr.readline() #prints the content of the file print(content) print(content1) #closes the opened file fileptr.close() Output: Python is the modern day language. It makes things so simple. We called the readline() function two times that's why it read two lines from the file. Python provides also the readlines() method which is used for the reading lines. It returns the list of the lines till the end of file(EOF) is reached. Example 2: Reading Lines Using readlines() function #open the file.txt in read mode. causes error if no such file exists. fileptr = open("file2.txt","r"); #stores all the data of the file into the variable content content = fileptr.readlines() #prints the content of the file print(content) #closes the opened file fileptr.close() Output: ['Python is the modern day language.\n', 'It makes things so simple.\n', 'Python has easy syntax and user-friendly interaction.'] Creating a new file The new file can be created by using one of the following access modes with the function open(). 285 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook x: it creates a new file with the specified name. It causes an error a file exists with the same name. a: It creates a new file with the specified name if no such file exists. It appends the content to the file if the file already exists with the specified name. w: It creates a new file with the specified name if no such file exists. It overwrites the existing file. Consider the following example. Example 1 #open the file.txt in read mode. causes error if no such file exists. print(fileptr) if fileptr: print("File created successfully") fileptr = open("file2.txt","x") Output: <_io.TextIOWrapper name='file2.txt' mode='x' encoding='cp1252'> File created successfully File Pointer positions Python provides the tell() method which is used to print the byte number at which the file pointer currently exists. Consider the following example. # open the file file2.txt in read mode fileptr = open("file2.txt","r") #initially the filepointer is at 0 print("The filepointer is at byte :",fileptr.tell()) #reading the content of the file content = fileptr. read(); #after the read operation file pointer modifies. tell() returns the location of the fileptr. print("After reading, the filepointer is at:",fileptr.tell()) Output: The filepointer is at byte : 0 After reading, the filepointer is at: 117 Modifying file pointer position In real-world applications, sometimes we need to change the file pointer location externally since we may need to read or write the content at various locations. For this purpose, the Python provides us the seek() method which enables us to modify the file pointer position externally. The syntax to use the seek() method is given below. Syntax: <file-ptr>.seek(offset[, from) The seek() method accepts two parameters: offset: It refers to the new position of the file pointer within the file. from: It indicates the reference position from where the bytes are to be moved. If it is set to 0, the beginning of the file is used as the reference position. If it is set to 1, the current position of the file 286 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer pointer is used as the reference position. If it is set to 2, the end of the file pointer is used as the reference position. Consider the following example. Example # open the file file2.txt in read mode fileptr = open("file2.txt","r") #initially the filepointer is at 0 print("The filepointer is at byte :",fileptr.tell()) #changing the file pointer location to 10. fileptr. seek(10); #tell() returns the location of the fileptr. print("After reading, the filepointer is at:",fileptr. tell()) Output: The filepointer is at byte : 0 After reading, the filepointer is at: 10 Python OS module Renaming the file The Python os module enables interaction with the operating system. The os module provides the functions that are involved in file processing operations like renaming, deleting, etc. It provides us the rename() method to rename the specified file to a new name. The syntax to use the rename() method is given below. Syntax: rename(current-name, new-name) The first argument is the current file name and the second argument is the modified name. We can change the file name bypassing these two arguments. Example 1: import os #rename file2.txt to file3.txt os.rename("file2.txt","file3.txt") Output: The above code renamed current file2.txt to file3.txt Removing the file The os module provides the remove() method which is used to remove the specified file. The syntax to use the remove() method is given below. remove(file-name) Example 1 import os; #deleting the file named file3.txt os.remove("file3.txt") 287 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Creating the new directory The mkdir() method is used to create the directories in the current working directory. The syntax to create the new directory is given below. Syntax: mkdir(directory name) Example 1 import os #creating a new directory with the name new os.mkdir("new") The getcwd() method This method returns the current working directory. The syntax to use the getcwd() method is given below. Syntax os.getcwd() Example import os os.getcwd() Output: 'C:\\Users\\NAME Changing the current working directory The chdir() method is used to change the current working directory to a specified directory. The syntax to use the chdir() method is given below. Syntax chdir("new-directory") Example import os # Changing current directory with the new directiory os.chdir("C:\\Users\\NAME\\ Documents") #It will display the current working directory os.getcwd() Output: 'C:\\Users\\NAME\\Documents' 288 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Deleting directory The rmdir() method is used to delete the specified directory. The syntax to use the rmdir() method is given below. Syntax os.rmdir(directory name) Example 1 import os #removing the new directory os.rmdir("directory_name") It will remove the specified directory. Writing Python output to the files In Python, there are the requirements to write the output of a Python script to a file. The check_call() method of module subprocess is used to execute a Python script and write the output of that script to a file. The following example contains two python scripts. The script file1.py executes the script file.py and writes its output to the text file output.txt. Example file.py temperatures=[10,-20,-289,100] def c_to_f(c): if c< -273.15: return "That temperature doesn't make sense!" else: f=c*9/5+32 return f for t in temperatures: print(c_to_f(t)) file.py import subprocess py"], stdout=f) with open("output.txt", "wb") as f: subprocess.check_call(["python", "file. The file related methods The file object provides the following methods to manipulate the files on various operating systems. SN Method 1 file.close() 2 File.fush() 3 File.fileno() 4 File.isatty() 5 6 File.next() File.read([size]) Description It closes the opened file. The file once closed, it can't be read or write anymore. It flushes the internal buffer. It returns the file descriptor used by the underlying implementation to request I/O from the OS. It returns true if the file is connected to a TTY device, otherwise returns false. It returns the next line from the file. It reads the file for the specified size. 289 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook SN Method 7 File.readline([size]) 8 9 10 11 12 13 File. readlines([sizehint]) File. seek(offset[,from) File.tell() File.truncate([size]) File.write(str) File.writelines(seq) Description It reads one line from the file and places the file pointer to the beginning of the new line. It returns a list containing all the lines of the file. It reads the file until the EOF occurs using readline() function. It modifies the position of the file pointer to a specified offset with the specified reference. It returns the current position of the file pointer within the file. It truncates the file to the optional specified size. It writes the specified string to a file It writes a sequence of the strings to a file. 290 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer UNIT 3.4: Testing and Execution Unit Objectives By the end of this unit, the participants will be able to: 1. Execute, test, and debug the Python program 2. Describe various frameworks/ methods used in testing a Python program 3. Explain the steps involved in debugging a Python program 4. Explain various exceptions and exception handling methods 5. Discuss coding standards and best practices related to Python 6. Create suitable test cases to identify bugs in a Python program 7. Demonstrate how to debug a Python program 8. Demonstrate the ways to execute a Python app and deploy it 9. Implement exception handling methods in Python 10. Demonstrate python app deployment using Git and GitHub 3.4.1 Describe various frameworks/ methods used in testing a Python program Within the realm of testing, the concept of automated testing is rather well-known. It is the place where the test plans are being carried out by a script rather than a human individual. Python comes included with the tools and modules necessary to facilitate automated testing of your system. Writing test cases in Python is a rather straightforward process. Python-based test automation frameworks are becoming increasingly popular as the use of Python in the workplace increases. List Of Python Testing Frameworks You should be familiar with the following Python testing frameworks, which are listed below. 1. 2. 3. 4. 5. 6. 7. 8. Robot Framework Pytest TestProject PyUnit (Unittest) Nose2 Behave Lettuce Testify 1. Robot Framework An open-source test automation framework designed for acceptance testing, acceptance testdriven development (ATDD), and robotic process automation is known as Robot Framework (RF) (RPA). Python is used for the majority of its code, although it may also be run on Jython, which is a Java-based implementation of Python, and IronPython (Python for .NET framework). Installing Python version 2.7.14 or a later version is necessary in order to run it. 291 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Pros • • • • • • Based on the Keyword-driven testing (KDT) methodology, which makes it possible for us to quickly construct test cases by utilizing terms that are readable by humans (no coding experience required). It is compatible with any operating system, whether it be Windows, Linux, or MacOS, as well as any application (web, mobile and desktop apps). Offers HTML reporting information that is easy to understand and work with (including screenshots). Rich ecosystem that includes a large number of application programming interfaces (APIs), which makes it a highly expandable framework and enables it to interact with any other thirdparty tool. Beginning with RF version 4.0, support for the if/else syntax is included. Excellent assistance from the community as well as internet resources. Cons • • • • Although simultaneous testing is not enabled out of the box, it is possible to do with the use of Selenium Grid or Pabot (a parallel executor for RF). You are required to operate in accordance with a predetermined approach, which has both positive and negative implications. For novices, there is a possibility that the first learning curve will be lengthier than usual. It's possible that developing generic keywords will take more time than just writing coding tests. It is difficult to personalize the reports. In conclusion, RF is the solution for you if you are looking to implement a keyword-driven framework approach that will allow manual testers and business analysts to create automation tests. It provides a variety of extensions and libraries and is simple to use. If this is something you are interested in, continue reading. If, on the other hand, you are interested in designing more complicated scenarios, you should be aware that the framework does not come pre-configured with any of the necessary adaptations. 2. Pytest Pytest is a Python testing framework that is available as open source and is thought to be one of the most popular Python testing frameworks currently available. Pytest is capable of supporting unit testing, functional testing, and API testing, among other types of testing. Python version 3.5 or a later version is required to execute this program. Pros • • • • • enables the creation of test suites that are condensed and straightforward. enables a great deal of customization through the utilisation of plugins, some examples of which are pytest-randomly, pytest-cov, pytest-django, and pytest-bdd. You also have the option of including the pytest html plugin in your project in order to print HTML reports using a single straightforward command-line option. Can execute tests in parallel using a Pytest plugin pytest-xdist. You may learn further more about it by reading it here. possesses a sizable and active community. 292 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer • Supports fixtures are an excellent method to keep context between stages, in addition to assisting you in covering all possible parameter combinations without having to rewrite your test cases. Cons • Pytest does not place a high priority on compatibility since, despite the fact that it is simple to build test cases with Pytest, you won't be able to use those test cases in any other testing framework because Pytest makes use of its own unique routines. In a nutshell, if you want to design unit tests—that is, tiny and simple tests—that enable complicated scenarios, then this well-developed and feature-rich framework is for you. 3. TestProject TestProject is an absolutely free and comprehensive automation platform that includes HTML reports in both the cloud and locally. With TestProject's Python open-source software development kit (SDK), it is simple to create test automation for mobile, web, or general uses using Python. Pytest and Unittest, two different testing frameworks, are both supported together with Python versions 3.6 and above (you can read more about it here). TestProject incorporates all of the necessary dependencies into a single executable that is compatible with several platforms (You can watch this webinar recording to get started). Pros • • • • • • • • Executable of a single Agent that contains all of the third-party libraries required to execute and design test automation for mobile, web, and generic tests. Automatic reports available for FREE in HTML and PDF format (including screenshots). The history of the execution may be accessed using a RESTful API. Constantly current with the most recent and reliable versions of the Selenium and Appium drivers. A single SDK that can be used for testing on the web, Android, and iOS. Integrated capability for running tests and reporting results. Support for several platforms, including Mac OS X, Windows, Linux, and Docker. Large community as well as assistance, including built-in live chat, a forum, and a blog. Cons • • Since the agent can only execute one test at a time, you will need to make use of Docker Agents in order to perform parallel testing. When working in the offline mode, the capabilities of the features that enable team communication and are activated as part of the hybrid cloud are restricted. Therefore, in contrast to the smooth collaboration on the hybrid cloud, while utilizing the local "on-prem" option, you will be required to implement the collaboration on your own, storing tests on a shared network drive or git repository. The bottom line is that if you are looking for a single framework that covers your complete automation efforts end to end, then TestProject is surely the one for you. It is also an excellent fit for teams with various skill sets, including novices as well as seasoned automation gurus. 293 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 4. PyUnit (Unittest) PyUnit, sometimes known as Unittest, is a framework for doing unit tests in Python that was modelled after JUnit. Because it is the Python testing framework that is installed by default alongside the Python package, it is the one that the majority of developers begin their testing with. Pros • • • Because it is a component of the standard Python library, there is no need to install any additional modules; rather, it is included in its entirety with the Python distribution out of the box. Provides straightforward and adaptable execution of test cases. Rapid creation of test results, including XML reports and unittest-sml-reporting as well as other types. Cons • • • Due to the fact that it enables abstraction, the test code might sometimes make its intended purpose obscure. There is a significant quantity of repetitive code that must be written. Because it is based on Junit, the camelCase naming mechanism is used rather than the snake case name convention that Python use. In conclusion, if you are familiar with xUnit frameworks and are searching for simple unit testing, you will discover that getting started with PyUnit is quite straightforward, and it will probably be the most comfortable one for you, as it does not require any additional dependencies. 5. Nose2 Nose2 is the successor of Nose. At its core, it is similar to PyUnit (Unittest), but it also supports plugins. The capability of PyUnit is expanded upon by Nose2 through the use of a variety of plugins that provide support for test execution, test discovery, decorators, fixtures, parameterization, and other similar features. Pros • • • • Easy to get started with due to the fact that it extends the PyUnit (Unittest) framework that is already included with the Python library by default. Includes a huge number of pre-installed plugins that, when used, may make testing more simpler and more efficient. Allows for parallel testing to be performed by utilising the mp plugin. Automatically collects tests as long as you adhere to some basic recommendations for arranging your library and test code. Cons • • Lack of comprehensive documentation, which might act as a barrier for progress when you are just getting started. Compared to other frameworks, it does not receive as much active maintenance. 294 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer In conclusion, if you are currently utilising the PyUnit, you may as well give Nose2 a try and investigate the ways in which it expands the functionality of PyUnit. 6. Behave Behave is a popular Python testing framework for behavior-driven development (BDD), which stands for behavior-driven development. Despite the fact that it is not an official component of the Cucumber project, it performs in a manner that is quite comparable to that of Cucumber frameworks. Pros • • • • The ability to write test cases in a language that is legible makes it easier for teams working on related features to collaborate with one another. It is possible to get started with the assistance of a substantial quantity of material as well as support. Full support for the Gherkin programming language; generating feature files does not require any prior experience or specialised expertise. Has Django and Flask integrations. Cons • • There is no capability for running several processes in parallel. Just for the testing of black boxes. In conclusion, if your team uses a BDD approach, you have previous understanding of BDD (such as Cucumber or SpecFlow, for example), and you are seeking for black box testing, then you should check out Behave. You should also investigate several Python BDD frameworks, such as Pytest-bdd, Lettuce (which will be explained further down), Radish, and others that are mentioned in this post that compares Python BDD testing frameworks. If you require testing for more than just a black box, then you should search in other places. 7. Lettuce Lettuce is yet another Python-based behavior-driven development (BDD) framework. It is derived upon Cucumber. Python version 2.7.14 or a higher version is required. Pros • • Supports the Gherkin language, which makes it possible for even members of the team who are not technically minded to readily build tests using normal language. It is quite similar to Behave and is mostly used for black-box testing, although it may also be used for other sorts of testing. Lettuce, for instance, enables users to test a variety of server behaviours in addition to database interactions. Cons • Because it does not have as many features as some other frameworks, it is better suited for use on less ambitious applications. 295 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook It does not appear that its support and documentation are being maintained. • In order to guarantee that the implementation will be effective, it is necessary for all of the project's stakeholders, including developers, quality assurance specialists, and managers, to maintain open lines of communication. In a nutshell, if you have a relatively modest Behavior Driven Development (BDD) project, Lettuce is an excellent choice for the easy and natural language test generation among all members of the team. 8. Testify The common Unittest and Nose frameworks are intended to be replaced by Testify, which also has additional functionality in comparison to the typical Unittest. Pros • • • • • Utilized for testing at the unit, integration, and system levels respectively. Those who are already familiar with Unittest will find that learning how to use Testify is fairly straightforward. Has extensive plugins. Testify facilitates test discovery in a manner analogous to that of Nose2. A straightforward syntax for the fixture method. Cons • • Due to the lack of detailed documentation, newcomers may have to spend some time and effort discovering resources that are pertinent to their needs. Executing several tests in parallel is not a simple task. In a conclusion, if you have previous experience with Unittest, adapting your current tests to work with Testify will be rather simple for you to do, thus it is unquestionably something you should look into 3.4.2 Explain the steps involved in debugging a Python program Debugging refers to exercising full control over the way in which a program is run. Debugging is the process that software developers undertake to rid a program of any errors. Therefore, debugging is a method that is healthy for the program and keeps the sickness bugs at a safe distance. Programs written in Python may also be debugged by their creators with the help of the pdb module, which is included with the default installation of Python. In the Python script, all that is required of us is to import the pdb module. We are able to inspect the program's current status by using the breakpoints that we established using the pdb module. By utilising jump and continue statements, we are able to alter the flow of the program's execution. Debugging a Python application is something that has to be understood. Python's built-in pdb module, often known as the Python Debugger, makes it easier to debug programs written in Python. This module is part of the Python standard library. In reality, it is specified as the 296 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer class Pdb, which uses the bdb (basic debugger functions) and cmd (support for line-oriented command interpreters) modules on the inside. The fact that pdb operates only through the command line is its most significant benefit. As a result, it is an excellent tool for debugging code on remote servers, particularly when we do not have access to a GUI-based debugger. pdb supports: • • • • Setting breakpoints Stepping through code Source code listing Viewing stack traces Starting Python Debugger There are a few different approaches to starting up a debugger. • To begin debugging the program, just put the statements import pdb and pdb.settrace() into the appropriate places. If you run your script in the regular manner, the execution will pause at the breakpoint that we have created. Therefore, in its most basic form, we are manually inserting a breakpoint on a line below the one in which we use set trace (). In Python versions 3.7 and beyond, there is a built-in method named breakpoint () that performs the identical actions as the original breakpoint command. You may learn how to insert the set trace () method by referring to the following example. Example1: Using the Python pdb module to debug a straightforward Python program that adds some integers together Intentional error:The application is unable to do multiplication on strings since the input() function returns string. As a result, it will throw a ValueError. import pdb def addition(a, b): answer = a * b return answer pdb.set_trace() x = input("Enter first number: ") y = input("Enter second number: ") sum = addition(x, y) print(sum) Output: 297 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook After the angle bracket, the first line of output contains the directory path of our file, the line number where our breakpoint is situated, and the word "module." At the module level, the message is essentially stating that there is a breakpoint located in the exppdb.py file on line number 10. If the breakpoint is introduced while the function is being executed, then its name will show within the brackets (>). The line that follows displays the point in the code where our execution has been halted. That line has not yet been put into action. After that, there is the pdb prompt. Now, in order to move about within the code, we may make use of the following commands: Command help where next step Function To display all commands Display the stack trace and line number of the current line Execute the current line and move to the next line ignoring function calls Step into functions called at the current line Simply writing whatis followed by the name of the variable is all that is required to determine the type of the variable. The following illustration shows that the output of type x is returned in the class string format. Therefore, changing the type of the string in our application to an integer would fix the issue. Example 2: Checking variable type using pdb ‘whatis’ command Python3 a = 20 b = 10 s=0 for i in range(a): # This line will raise ZeroDivision error s += a / b b -= 1 From the Command Line: Using a debugger in this manner is the most straightforward approach. In order to proceed, open terminal and type in the following command. 298 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer python -m pdb exppdb.py (put your file name instead of exppdb.py) our source code is loaded, however execution is halted on the first line of code because of this sentence. Example 3: Navigating in pdb prompt In the pdb prompt, we may browse with the letters n (next), u (up), and d. (down). We may use the commands that were stated before to debug and explore all of the Python code by utilising this navigation method. a = 20 b = 10 s=0 for i in range(a): s += a / b b -= 1 Output: Example 4: Post-mortem debugging using Python pdb module Entering the debug mode after the program has completed the execution process is what is meant by the term "post-mortem debugging" (failure has already occurred). Through the use of the pm() and post mortem() routines, pdb is able to offer post-mortem debugging. These routines will search for active trace back and then begin the process of starting the debugger at the point in the call stack where the exception was thrown. If you look at the output of the example that was provided, you will see that the word pdb appears whenever the program runs into an error. def multiply(a, b): answer = a * b return answer x = input("Enter first number : ") y = input("Enter second number : ") result = multiply(x, y) print(result) Output: 299 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Checking variables on the Stack The stack is used to store all of the program's variables, including those that are local to the function that is now being performed in the program as well as those that are global. When we want to publish all of the arguments that are being used by a function that is now active, we may use args (or use a). The p command takes an expression as a parameter and outputs the result once it has been evaluated. This section will walk you through the process of checking for variables by putting Example 4 of this article through its paces in debug mode. Python pdb Breakpoints When dealing with complex programs, it is common practice to wish to insert a number of breakpoints at locations where we are aware that mistakes may occur. Use of the break command is all that is required to do this. The debugger will give each breakpoint a number, beginning with 1, when you enter it into the program. You may get a list of all the breakpoints in the program by using the break command. Syntax: break filename: lineno, condition The implementation of adding breakpoints to a program, which will be utilised in example 4, is presented below. 300 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Managing Breakpoints After adding breakpoints and assigning them numbers, we may control the breakpoints by using the enable, disable, and delete commands, respectively. This is done after adding the breakpoints. While disabling a breakpoint instructs the debugger to continue running when the point is reached, enabling a breakpoint causes it to be active again. The implementation of Example 4's breakpoint management is included below for your reference. Example: # Program to print Multiplication # table of a Number n=5 for x in range(1,11): print(n , '*', x, '=', n*x ) Output: 5*1=5 5 * 2 = 10 5 * 3 = 15 5 * 4 = 20 5 * 5 = 25 5 * 6 = 30 5 * 7 = 35 301 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 5 * 8 = 40 5 * 9 = 45 5 * 10 = 50 Example: # Python Program to print Multiplication Table # We want to debug the for loop so we use # set_trace() call to pdb module import pdb # It means , the Start of Debugging Mode pdb.set_trace() n=5 for x in range(1,11) : print( n , '*' , x , '=' , n*x ) Output: Basic Commands to use Python Debugger list command to see entire program. list 3 and 6 to view only the lines of the program that are between 3 and 5. 302 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer break is a command that may be used to halt the execution of a program at a certain line. Using the continue command will take you to the next stage of the loop. The jump command enables us to move to a certain line inside the program at any given point. pp command that displays the value of a variable at the current place in the program. We may use the continue command to go on to the next line in the program, and the disable command will turn off the output of the current line. We use quit or exit command to enter outside the debugging mode . Debugging is useful for developers because it allows them to examine programs line by line. When programs are run in debugging mode, developers are able to view every line that is interpreted. Python includes its own built-in debugger, which can be imported and used with relative ease. When you are perplexed about the execution of huge loops, the values of current variables, and everything else, a good place to start is using the debugger. 303 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Explain various exceptions and exception handling methods Python has two extremely useful features that may be used to manage any unexpected mistake that may occur in your Python programs and to add debugging capabilities to those applications. • • Handling of Exceptions Assertions List of Standard Exceptions − Sr.No. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Exception Name & Description Exception Class that all other exceptions inherit from. StopIteration Thrown when an iterator's next() function does not point to any item in the current collection. SystemExit Result of the sys.exit() method throwing an exception. StandardError Except for StopIteration and SystemExit, all built-in exceptions inherit from this base class. ArithmeticError The fundamental category for any and all mistakes that might arise when doing a numerical computation. OverflowError An exception is thrown if a computation results in a value that is greater than the type's maximum limit. FloatingPointError Raised whenever a computation with floating points is unsuccessful. ZeroDivisionError All numeric types see an increase if there is a division or modulo by zero operations. AssertionError Raise in the event that the Assert statement is not successful. AttributeError In the event that an attempt to reference or assign an attribute fails, this exception will be raised. EOFError Raises its head when the end of the file has been reached and neither the raw input() function nor the input() function has received any input. ImportError Raised when an import statement fails. KeyboardInterrupt Raises itself whenever the user manually pauses the execution of the application, often by hitting the Ctrl+c key simultaneously. LookupError Base class for all lookup errors. IndexError Raised when an index is not found in a sequence. KeyError Raised when the specified key is not found in the dictionary. 304 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Sr.No. 17 18 19 20 21 22 23 24 25 26 27 28 29 Exception Name & Description NameError Raised when an identifier is not found in the local or global namespace. UnboundLocalError Raised when trying to access a local variable in a function or method but no value has been assigned to it. EnvironmentError Base class for all exceptions that occur outside the Python environment. IOError Error that is generated if an input or output action fails, such as the print statement or the open() function when it attempts to open a file that does not exist. IOError Raised for operating system-related errors. SyntaxError Raised when there is an error in Python syntax. IndentationError Raised when indentation is not specified properly. SystemError Error that is thrown when the interpreter discovers a fault within itself; nonetheless, when this error occurs, the Python interpreter does not quit the program. SystemExit Raises itself whenever the sys.exit() method is used to terminate the Python interpreter. The interpreter will close down if the situation is not handled in the code. TypeError Thrown if an operation or function is tried that cannot be performed on the data type that has been supplied. ValueError Error that is thrown when a built-in function for a data type has the correct type of arguments, but those arguments have been given with erroneous values. RuntimeError Raised when a generated error does not fall into any category. NotImplementedError Error that is thrown when an inherited class does not have an abstract method that is required to be implemented but does not have that method implemented. Error that is thrown when an inherited class does not have an abstract method that is required to be implemented but does not have that method implemented. Assertions in Python A sanity check is known as an assertion, and once you have finished testing the software, you have the option of either turning it on or turning it off. An analogy between a raise-if statement and an assertion is the most straightforward way to think about an assertion (or to be more accurate, a raise-if-not statement). An expression is put through its paces, and an exception is thrown if the evaluation reveals that the expression produced an incorrect result. 305 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook The assert statement, which is Python's newest keyword and was introduced in version 1.5, is what's responsible for carrying out assertions. Assertions are often placed at the beginning of a function by programmers in order to check for legitimate input, and assertions are typically placed at the end of a function call in order to check for proper output. The assert statement Python will evaluate the expression that comes along with an assert statement, which should be accurate if the statement is being used correctly. Python will throw an exception labelled AssertionError if the expression is found to be invalid. The syntax for assert is − assert Expression[, Arguments] Python will utilise the ArgumentExpression that you provided as the argument for the AssertionError if the assertion fails. Using the try-except statement, you may catch and handle AssertionError errors just as you would any other exception; but, if you don't manage them, they will cause the program to crash and create a traceback. Example The following is a function that converts a temperature that is given in degrees Kelvin to the equivalent temperature in degrees Fahrenheit. Because 0 degrees Kelvin is the absolute lowest temperature that may be reached, the function will abort if it detects a temperature that is below zero. #!/usr/bin/python def KelvinToFahrenheit(Temperature): assert (Temperature >= 0),"Colder than absolute zero!" return ((Temperature-273)*1.8)+32 print KelvinToFahrenheit(273) print int(KelvinToFahrenheit(505.78)) print KelvinToFahrenheit(-5) The following effect is brought about when the code shown above is put into action. 32.0 451 Traceback (most recent call last): File "test.py", line 9, in <module> print KelvinToFahrenheit(-5) File "test.py", line 4, in KelvinToFahrenheit assert (Temperature >= 0),"Colder than absolute zero!" AssertionError: Colder than absolute zero! 306 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 3.4.3 What is Exception? An occurrence that occurs during the execution of a program that disturbs the usual flow of the instructions being carried out by the program is referred to as an exception. Whenever a Python script is presented with a circumstance that it is unable to handle, it will, as a general rule, throw an exception. In Python, an object called an exception is used to express a problem. If a Python script throws an exception, it has two options: either it should address the exception right away, or else it should end its execution and quit. Handling an exception You may protect your application if it contains potentially malicious code by enclosing the code in a try block. This will prevent the code from causing an exception to be thrown. Include an except: statement after the try: block, then a block of code that deals with the issue in the most aesthetically pleasing manner possible after that. Syntax Here is simple syntax of try....except...else blocks − try: You do your operations here; ...................... except ExceptionI: If there is ExceptionI, then execute this block. except ExceptionII: If there is ExceptionII, then execute this block. ...................... else: If there is no exception then execute this block. The following are some key considerations about the syntax that was just discussed: • • • • It's possible to have numerous except statements within a single try statement. When the try block contains statements that might potentially throw a variety of exceptions, it is helpful to do this. You also have the option of providing a general except clause that may accommodate any exception. You have the option of inserting an otherwise clause after any applicable except clauses. The code included in the else-block is carried out if the code contained in the try: block does not result in the production of an exception. A excellent place to put code that does not require the security provided by the try: block is in the else-block. Example This example begins by opening a file, then writes some content to that file, and then exits without incident due to the absence of any issues. 307 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook #!/usr/bin/python try: fh = open("testfile", "w") fh.write("This is my test file for exception handling!!") except IOError: print "Error: can\'t find file or read data" else: print "Written content in the file successfully" fh.close() This produces the following result – Written content in the file successfully Example The following demonstration throws an error because it attempts to open a file for which the user does not have permission to write. #!/usr/bin/python try: fh = open("testfile", "r") fh.write("This is my test file for exception handling!!") except IOError: print "Error: can\'t find file or read data" else: print "Written content in the file successfully" This produces the following result − Error: can't find file or read data The except Clause with No Exceptions You could alternatively use the except statement with no exceptions declared in the following manner: try: You do your operations here; ...................... except: If there is any exception, then execute this block. 308 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer ...................... else: If there is no exception then execute this block. This particular form of a try-except statement is able to capture any and all exceptions that may arise. The use of a try-except statement of this type, however, is not regarded as an example of good programming practise. This is due to the fact that while it does a good job of catching exceptions, it does not force the programmer to determine the underlying cause of any potential issues that may arise. The except Clause with Multiple Exceptions You may also use the same except statement to handle several exceptions in the manner that is described below: try: You do your operations here; ...................... except(Exception1[, Exception2[,...ExceptionN]]]): If there is any exception from the given exception list, then execute this block. ...................... else: If there is no exception then execute this block. The try-finally Clause A finally: block can be used in conjunction with a try: block if desired. In the finally block, you can add any code that really has to be executed, regardless of whether or not the try block encountered an error. This is how the syntax of the try-finally statement should look: try: You do your operations here; ...................... Due to any exception, this may be skipped. finally: This would always be executed. ...................... You cannot use else clause as well along with a finally clause. Example #!/usr/bin/python try: 309 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook fh = open("testfile", "w") fh.write("This is my test file for exception handling!!") finally: print "Error: can\'t find file or read data" If you do not have authorization to open the file in writing mode, the following outcome will occur as a direct consequence of your actions: Error: can't find file or read data Same example can be written more cleanly as follows – #!/usr/bin/python try: fh = open("testfile", "w") try: fh.write("This is my test file for exception handling!!") finally: print "Going to close the file" fh.close() except IOError: print "Error: can\'t find file or read data" The finally block is the next one to be executed in the program after the try block in the event that an exception is thrown within the try block. The exception is thrown once more after all of the statements in the finally block have been carried out, and it is dealt with by the except statements, if any of those statements are present in the try-except statement's subsequent higher layer. Argument of an Exception An argument is a value that provides more information about the issue that triggered the exception. Exceptions can include arguments. The specifics of the argument change depending on the specific exception. You can catch the argument of an exception by specifying a variable in the unless clause in the format shown below: try: You do your operations here; ...................... except ExceptionType, Argument: You can print value of Argument here... You can have a variable follow the name of the exception in the except statement if you build the code to handle only a single exception. This is possible if you write the code to handle just one exception. In 310 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer the event that you are catching numerous exceptions, you have the option of having a variable follow the tuple of the exception. This variable is assigned the value of the exception, which will often include an explanation of what caused the error. A single value or a tuple containing several values can be assigned to the variable in the form of an expression. In most cases, the error message, the error number, and an error location are contained within this tuple. Example: Following is an example for a single exception − #!/usr/bin/python # Define a function here. def temp_convert(var): try: return int(var) except ValueError, Argument: print "The argument does not contain numbers\n", Argument # Call above function here. temp_convert("xyz"); This produces the following result − The argument does not contain numbers invalid literal for int() with base 10: 'xyz' Raising an Exceptions By utilising the raise statement in a variety of contexts, you may cause exceptions to be thrown. The following is an example of the general syntax for the raise statement: Syntax raise [Exception [, args [, traceback]]] In this context, "exception" refers to the category of the error that was encountered (such as "NameError"), and "argument" is a value for the "exception argument." This argument is not required, and if it is not provided, the value of the exception argument will be None. The third input, traceback, is similarly optional (and is utilised in reality only very infrequently). If it is present, it is the traceback object that is used for the exception. 311 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example A text, a class, or an object can all constitute an exception. The majority of the exceptions that are thrown by the Python core are instances of classes, with the argument being another instance of the class. The process of defining new exceptions is quite straightforward and may be done in the following ways: def functionName( level ): if level < 1: raise "Invalid level!", level # The code below to this would not be executed # if we raise the exception Please take note that in order to "catch" an exception, a "except" clause must refer to the exact same exception that was thrown, whether it a class object or a plain text. For instance, in order to account for the aforementioned exception, we need to rewrite the unless clause as follows: try: Business Logic here... except "Invalid level!": Exception handling here... else: Rest of the code here... User-Defined Exceptions You may also make your own exceptions in Python by deriving classes from the built-in standard exceptions. This capability is available to you. The following is an example that pertains to the RuntimeError. In this step, a class that inherits its behavior from RuntimeError is created. When you need to display more precise information when an exception is encountered, this comes in handy. The user-defined exception will be thrown within the try block, and it will be captured within the except block. A new instance of the class Networkerror is instantiated by making use of the variable e. class Networkerror(RuntimeError): def __init__(self, arg): self.args = arg So once you defined above class, you can raise the exception as follows − try: raise Networkerror("Bad hostname") except Networkerror,e: print e.args 312 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Exercise Answer the following questions: 1. What will be the output of the following Python code? g = (i for i in range(5)) type(g) a) class <’loop’> b) class <‘iteration’> c) class <’range’> d) class <’generator’> 2. What will be the output of the following Python code? int('65.43') a) ImportErrorb) ValueError c) TypeErrord) NameError 3. Which of the following statements is true? a) The standard exceptions are automatically imported into Python programs b) All raised standard exceptions must be handled in Python c) When there is a deviation from the rules of a programming language, a semantic error is thrown d) If any exception is thrown in try block, else block is executed 4. Which of the following is not a standard exception in Python? a) NameErrorb) IOError c) AssignmentErrord) ValueError 5. Syntax errors are also known as parsing errors. a) TRUEb) FALSE 6. An exception is ____________ a) an object c) a standard module b) a special function d) a module 7. _______________________ exceptions are raised as a result of an error in opening a particular file. a) ValueErrorb) TypeError c) ImportErrord) IOError 8. Which of the following blocks will be executed whether an exception is thrown or not? a) exceptb) else c) finallyd) assert 313 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 3.4.4 Discuss coding standards and best practices related to Python Python coding standards 1. The Code Layout: Indentation, the maximum line length that should be utilised, line breaks and blank lines, imports in Python, and dunder names are all components of this. Let's talk about them using some real-world instances. a) Imports, Blank Lines, and the Indentations: It is important that the import be done in a specific order. It is recommended that the local libraries be imported last, following the importation of the standard libraries and any third-party libraries. Doing an absolute import is the best option to take if you only require one method or class from the import. Your code will be significantly cleaner, more accurate, and easier to recognise as a result. Remember that you need to put a space in between each distinct kind of import. Classes and top-level functions ought to be surrounded by two blank lines on both sides. The only thing that should surround the methods included within the class is a single blank line. Even though tab indentation is more common, the space technique of indentation is the one that is recommended. However, the indentation with four spaces is recognised and considered correct. Indentation should be done exclusively with tabs; please do not combine the use of spaces and tabs. # then,the third party imports import third_party_import_a import third_party_import_b import third_party_import_c # at the last, local library import from local_library import local_a, local_b from local_library_two import local_c # two blank lines for top level functions def top_level_function(argument): # A standard four space indent print(argument) b) The length of the Line and the Line Breaks The line shouldn't be more than 79 characters; that's the maximum it should be. When it comes to docstrings and comments, where a huge chunk of material may be included, the maximum number of characters allowed is 72. Backslashes are allowed in lengthy multiple case statements if they are used appropriately. Python recommends splitting the formula line before the binary operator to make it easier to understand when using log statements in conjunction with binary operators. This 314 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer is done to improve readability. For Example: def sample_function(arg1, arg2): ''' The document string length for a single line should be less than 72 characters. So that long texts should be adjusted in a single window ''' # code has maximum lengths of 79 characters, can use backslash # to break the line list_of_subjects = [ 'Physics', 'Chemistry', 'Mathematics', 'Biology', ‘Bio’, \ ] 2. Whitespaces, Trailing Commas, and String Quotes One should try to avoid adding excessive white spaces, and there should be one white space on each sides of an operator, one after the comma, and none inside the opening or closing parenthesis of a sentence. When developing websites using Python, you may use either single quotes or double quotes. If you require quotations inside quotes, you should use both types of quotes to prevent making a syntax error and adding an extra backslash. # Examples of commas and whitespaces x, y = 30, "text inside quotes" z = 'text inside quotes' if x == 30: print(x, y, z) # how to use quotes inside quotes text = "This text is using 'the single quote' inside double quote" print(text) 3. Naming Conventions Make sure you use variable names that are free of grammatical errors, and remember that class names must begin with a capital letter and adhere to the camel case rule. If there are going to be more than two words utilised. In the same manner, a function name ought to have an underscore appended to it, and it ought to be written in lowercase. When declaring an instance variable in the parameters for a method, you should always use self as the first argument. In a similar fashion, "cls" should be used as the first parameter when calling the class method. If the name of the function conflicts with the name of a reserved parameter, use an underscore rather than the incorrect spelling. Constants are expressed in all capital letters. 315 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Example: # class name follows camelcase convention class StudentDetails: def __init__(self, first_name, last_name): self.first_name = first_name self.last_name = last_name # Method name, variable names in lowercase joined with an underscore def grade(self, marks_obtained): # constants in capital GRACE = 2 marks_obtained = GRACE + marks_obtained if marks_obtained> 90: self.student_grade = 'A' elifmarks_obtained> 70: student_grade = 'B' else: student_grade = 'C' Some Other Coding Recommendations: 1. Exception Handling for every critical situation There are a few coding tips that have to be kept in mind at all times in order to produce code that is both error-free and of high quality. First, I will jot down the points, and then, farther on in the code, I will explain them. For Example:try: file = open('filename.txt') file.write('Hello World') except Exception as e: print('Cannot open the file :', e) finally: # Make sure to close the file after file.close() 316 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 2. Documentation of a Method Providing detailed documentation for each method, including a specification of its data types, return type, and argument types. It is best to avoid having several returns from a single function and instead use a single generic return. For Example:# documenting a function def get_grades(marks): """ Summary: getting grades from marks Description: This function takes marks as an argument and returns grades params: marks(int) : marks obtained : grade(string) : grade achieved """ if marks > 90: grade = 'A' elif marks > 70: grade = 'B' else: grade = 'C' return grade 3. Use DRY (Don’t Repeat Yourself): When reusing code, the DRY principle should always be followed. Utilizing different functions and classes is going to be the most effective method. In order to avoid having to repeatedly create functions that are very similar to one another, the common functions can be saved in a separate file called utils.py and then utilised several times. In the event that you need to read three different files, rather than writing code for file read three times, you may read it as a function to save yourself some time. For Example: # function to read the file read def file_read(filename): with open(filename, 'r') as f: return f.read() 317 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook qualities = file_read('quality.txt') description = file_read('description.txt') summary = file_read('summary.txt') 4. What to use? Tuples, Lists of Dictionaries You should make use of dictionaries when you need to map things, tuples when the data cannot be changed, and lists when the data may be changed in the future. # tuples are used when data is constant colors_of_rainbow = ('V', 'I', 'B', 'G', 'Y', 'O', 'R') # lists where data can be mutated movies_to_watch = ['Inception', 'Iron Man', 'Wonder Woman'] # Using lists in mapping is wrong # O(n) time would be taken to extract marks marks_obtained = [['History', 30], ['English', 35], ['Physics', 45]] # dicts when mapping is needed # dicts take O(1) time to get key value marks_obtained = {'History': 30, 'English': 35, 'Physics': 45} Use the ‘with’ statement while opening a file, the ‘with’ statement closes the file even if there is an exception raised. For Example: import csv # opening a file, with statement is used with open('filename.csv', 'r') as file: csv_reader = csv.reader(file) for line in csv_reader: print(line) A piece of code is considered to be of high quality if it is properly documented, well structured, and thoroughly explained using comments. The higher the quality of what we write, the greater the readability it offers, and the simpler it is to both recall and comprehend what we have written. Keeping the code in line with PEP8 may be accomplished using a number of different IDEs and editors. Pycharm is the editor that I use for coding because it has linters already built in. Depending on your tastes, you could opt to use Atom, VS Code, or Sublime Text as your text editor. Every one of them features an integrated plugin system for their linters. You can use PyLint or PyFlakes if the integrated linters in the IDE that you are using are not sufficient for your needs. In my opinion, 318 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer these integrated development environments (IDEs) can only assist us in becoming better coders; it is still up to you to decide whether or not you are willing to produce decent code. 5. Create suitable test cases to identify bugs in a Python program Python is a programming language that is interpreted. This indicates that the code is compiled behind the scenes right before being executed, which takes place during runtime. In point of fact, the built Python modules will appear as.pyc files next to the Python modules that you have installed. Developers whose background is in a compiled language such as C++ are accustomed to the following development process: • • • • write code run the compiler fix compilation errors, catching a lot of issues like syntax errors, wrong types, etc. run the program The most common and initial criticism that these programmers have about Python is that it does not have a compiler, which prohibits them from utilising this workflow and, as a result, from writing code that is dependable. However, this is not a problem at all because a procedure that is functionally equivalent may be replicated, at least in part, using Python. The following is an example of what a developer would do: • • • write code run the program fix runtime exceptions, to catch a lot of issues like syntax errors, wrong types, etc. The one and only drawback of the Python procedure described above is that errors will only be discovered in the portion of the code that is actually executed by the program. For instance, if your application does not make use of a certain function, you will be unable to locate and solve any issues that may exist inside that function. Because of this, when developing in Python, it is necessary to execute the entire program while it is still being worked on, and this is where unit tests come in. Unit tests are an absolute necessity for any significant development work done in compiled languages. They are an essential necessary part of the Python language. The most basic test I would like to make a few remarks regarding the most fundamental type of testing that you may perform before we go on to the unit testing. Let's imagine you want to develop a lesson that discusses circles and how they work. You might begin with the following: circle.py: import math class Circle(object): def __init__(self, center=(0.,0.), radius=1.): self.center = center 319 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook self.radius = radius def area(self): return math.pi * self.radius**2 Your first order of business should be to give your brand-new class a whirl and see how it performs. You may accomplish this by include a primary section at the very end of the module, such as this one: if __name__ == '__main__': c = Circle() print(c.center,c.radius) print (c.area()) c.radius = 2. print (c.area()) When the module is being directly run, as opposed to when it is being imported in another module, the main section is the one that is being performed. You may now execute your script, and you get: (0.0, 0.0) 1.0 3.141592653589793 12.566370614359172 That's great news; now we can visually see that the default parameters have been saved in the circle object in the right format, and that the area method appears to be operating as intended. The testing of your code can be done in this manner, which is entirely appropriate, and I do make use of this method on occasion. But: • • • • The Circle class's primary section will get increasingly difficult to understand the more features that are added to it. As soon as you begin to incorporate a number of different modules into your project, you need to give consideration to the fact that every time you want to test, you will need to run all of those modules. Because we rely on visual interpretation of the data, the amount of time required to validate the results increases proportionally with the number of tests conducted. As we are about to discover today, utilising unit tests is a lot simpler solution. It’s much easier to use unit tests, as we will see now. First unit test Unit test is the primary framework for conducting unit tests in Python. 320 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer We begin with a test that is guaranteed to pass in order to get a feel for the unittest framework. test_alwaysok.py: import unittest class TestAlwaysOk(unittest.TestCase): def test_true(self): self.assertTrue(True) def test_false(self): self.assertFalse(False) if __name__ == '__main__': unittest.main() See? It's quite simple. The time required to write this is at most ten seconds. You may run the tests contained in this module in one of two ways: python test_alwaysok.py .. ----------------------------------------------------Ran 2 tests in 0.000s OK Doing the following is another another option for running all of the tests contained within a directory and its subdirectories: python -m unittest discover Development with unit testing What I do, with the possible exception of projects that just involve a single module, is create the tests as I'm creating the software. I'm putting the tests to use by running the pieces of code that I'm currently creating. And after I'm done, the tests will still there, which means I can run them again at a later time if I want to make any kind of adjustment. In point of fact, unit testing might significantly boost your self-assurance. You are certain that you may safely engage in a significant reworking of the source code without any worries. If all of the 321 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook individual tests pass. There is no need to worry about anything at all. In most cases, I position the test modules directly next to the code that they validate, with names that begin with the test_ prefix. Nevertheless, you are at liberty to act in a different manner. Just make sure that all of your test modules adhere to the naming convention that you've chosen for them. Let's begin by constructing the test module, and we'll pretend for a moment that our Circle class has not yet been created. The function Object() { [native code] } is the first method that has to be developed for the Circle class. Therefore, we will compose the test before even beginning to compose the function Object() { [native code] }: test_circle.py: import unittest from circle import Circle class TestCircle(unittest.TestCase): def test_constructor(self): '''simply tests that a circle can be built''' c = Circle( center=(0,0), radius=2) if __name__ == '__main__': unittest.main() You may execute this test. I'm going to start skipping over all of the boilerplate code and simply talk about the new test methods that are being implemented from now on. Can you think of a situation in which a circle might become useless or unclearly defined? A straightforward solution presents itself to me here: if the radius is negative. Most likely, the Circle class ought to be guarded against radii that are less than zero. Therefore, we make the following change to the function Object() { [native code] } of the Circle class: circle.py: class Circle(object): def __init__(self, center=(0.,0.), radius=1.): if radius < 0: raise ValueError('radius must be >= 0') self.center = center 322 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer self.radius = radius In addition to this, we make some changes to our test function in order to verify that the exception is thrown in the correct manner. To begin, we will create a test that is unsuccessful (the exception is not raised). test_circle.py: def test_constructor(self): '''tests that a circle can be built, and that negative radii are disallowed''' c = Circle( center=(0,0), radius=2) with self.assertRaises(ValueError): Circle(radius=1) Run again. You must ensure that the examination is successful this time (the exception is indeed raised). Exercise: Create a test to validate the results of calling the Circle.area method with a variety of different input values. The following is a list of the many assert methods that are available. Hint: You will need to compare floats, however the comparison of floats to determine whether or not they are equal is unreliable. Therefore, you should employ the procedure known as assertAlmostEqual. Unit test tricks You already have sufficient knowledge to utilize unit tests efficiently in the projects you are working on. In this part of the article, I'd merely want to provide a few helpful hints and tips. Ordering tests There are occasions when you need to pay attention to the sequence in which testing are carried out. For instance, you could wish to begin with the examinations that require the least effort and the shortest amount of time. In this scenario, it is important to keep in mind that the tests are executed in the order that is determined by the lexicographical order of the method names. This is a demonstration that can be seen. test_order.py: import unittest class TestOrder(unittest.TestCase): def test_1(self): 323 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print('i run first') def test_2(self): print('i run second') if __name__ == '__main__': unittest.main() The test should be run. test 1 is executed before test 2 because, lexicographically speaking, test 1 comes before test 2. Initializing and finalizing tests An initialization is necessary for several of the tests. For illustration's sake, let's say you want to construct a test input file that you can use throughout all of your tests. You may do this action within the setUp method, which is accessed before each test. In addition, you may make use of the tearDown function in the event that you wish to do some action after each test. Here is an example of a common pattern: test_setup.py: import unittest import os class TestSetup(unittest.TestCase): def setUp(self): self.testfname = 'testfile.txt' if not os.path.isfile(self.testfname): with open(self.testfname, 'w') as ifile: print('creating test file') testlines = ['first line\n', 'second line\n'] ifile.writelines(testlines) def test_nlines(self): with open(self.testfname) as ifile: self.assertEqual(len(ifile.readlines()),2) def test_lines(self): with open(self.testfname) as ifile: self.assertListEqual(ifile.readlines(), ['first line\n', 'second line\n']) 324 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer if __name__ == '__main__': unittest.main() It is important to remember that setup is invoked before each test. However, only one copy of the test file is made in the event that a copy of the test file does not already exist. Since the file is already present, it will not be produced again even if you run these tests several times. This may not appear to be particularly beneficial in this straightforward example; nevertheless, generating test data or downloading it might take a considerable amount of time. This type of strategy is really necessary to employ at that point. Skipping tests You might wish to turn off some tests in certain circumstances. For instance, testing some aspects of your code can be contingent on the presence of an external package: if the package is there, you test the aspects of your code that are dependent on this package. On the other hand, in the event that it is absent, you are excused from these examinations. A decorator, which may be used to adorn either a Testcase class or a test function, will allow you to turn off testing in the following manner: test_skip.py import unittest import datetime import getpass now = datetime.datetime.now().time() noon = datetime.time(12,0) evening = datetime.time(19,0) user = getpass.getuser() class TestSkip1(unittest.TestCase): @unittest.skipIf(now<noon or now>evening, 'only testing in the afternoon') def test_1(self): '''tested in the afternoon only''' self.assertTrue(True) @unittest.skipIf(user!='cbernet',"these are colin's private tests") class TestSkip2(unittest.TestCase): def test_1(self): 325 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook self.assertTrue(True) def test_2(self): self.assertTrue(True) if __name__=='__main__': unittest.main() Writing a test suite Instead of depending on the automated discovery that occurs when you run tests, you may design a test suite if you want to have greater control over the tests that are executed. discover using python —m unittest Additionally, this will make it possible for you to launch your tests using a Python script if that becomes necessary. Here is a straightforward illustration: suite.py import unittest from test_circle import TestCircle from test_skip import TestSkip1, TestSkip2 from test_alwaysok import TestAlwaysOk testcases = [ TestAlwaysOk, TestCircle, TestSkip1, TestSkip2 ] suite = unittest.TestSuite() loader = unittest.TestLoader() for test_class in testcases: tests = loader.loadTestsFromTestCase(test_class) suite.addTests(tests) if __name__ == '__main__': import sys runner = unittest.TextTestRunner(verbosity=2) runner.run(suite) 326 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Debugging with pdb If you give your unit tests the attention they deserve, you will have no trouble locating bugs. But how exactly can you comprehend and correct them? For the purpose of debugging, it is quite simple to merely add printouts to the code in Python because the language does not need compilation. This antiquated approach of debugging is acceptable to a large number of users, particularly those with experience in the field of research. The difficulty with using this approach is that it is quite time consuming and not very efficient: • • • You are compelled to make changes to the code, maybe across a number of distinct modules, in order to print out the information you want. When you execute the software, you will likely discover that you want a greater quantity of printouts. When you are finished debugging, you should give some thought to deleting all of the printouts from the system. Here is a little script that has a few errors. bugged.py: a = list(range(10)) for val in a: if val % 2 == 0: # replacing all even values in a by 0 val = 0 print(val) print(a) This script is designed to substitute a zero for every value in a that is an even number. But if you run it, you get [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ! That is such a timeless! Can you make a guess as to what the issue is? We are going to make use of the debugger in our investigation. You might begin with the following: python -m pdb bugged.py You also have the option of inserting a debugging anchor into the code at the point where you would like the debugging process to begin. For instance, you might place the anchor after the if statement by doing the following: a = list(range(10)) for val in a: 327 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook if val % 2 == 0: # replacing all even values in a by 0 import pdb; pdb.set_trace() #<<<< anchor val = 0 print(val) print(a) After that, you may proceed with running the script as you normally would. In what follows, I will presume that you are utilising the first way. Therefore, after launching the script in debug mode, you will arrive at the pdb prompt, which indicates that the execution has just begun: a = list(range(10)) (Pdb) You are now standing on a line that has not yet been put into action. The following are the primary pdb commands: • • • • • • l: list the code around your position b: set a breakpoint n: go to next line c: continue until next break point p: print something + most python commands List the code. You should get: (Pdb) l -> a = list(range(10)) 2 for val in a: if val % 2 == 0: # replacing all even values in a by 0 val = 0 print(val) print(a) [EOF] Add a breakpoint on line 6, and continue to this breakpoint: (Pdb) b 6 328 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Breakpoint 1 at /Users/cbernet/Google Drive/Colab Notebooks/maldives/bugs/test/bugged.py:6 (Pdb) c /Users/cbernet/Google Drive/Colab Notebooks/maldives/bugs/test/bugged.py(6)<module>() ->val = 0 We can see that val is equal to zero even before the line above: (Pdb) val 0 That is perfectly typical given that the array a that we are looping through begins with 0. Let's keep going till we reach the identical stopping spot once again: (Pdb) c 0 >/Users/cbernet/GoogleDrive/ColabNotebooks/maldives/bugs/test/bugged.py(6)<module>() ->val = 0 (Pdb) val 2 Since our breakpoint is located under the if, it is obvious that we did not observe val = 1. First, let's find out some information on the array a. (Pdb) p a[2] 2 That's expected since we haven’t assigned val to 0 yet. let’s go to the next line: (Pdb) n >/Users/cbernet/GoogleDrive/ColabNotebooks/maldives/bugs/test/bugged.py(7)<module>() print(val) (Pdb) p val 0 (Pdb) p a[2] 2 So we have set val to 0 but a[2] is still equal to 2! My only objective in this post was to demonstrate how to work with the Python debugger. Here is an explanation, though, in case you were wondering why a[2] was not already set to 0 when we 329 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook started. Python's notion of variables can be compared to that of labels. When we do val=0, it means: take label val and put it (we call bind it) to value 0. The following is what we have done in the instance of our problematic program: • loop through the array a and attach the label val to the elements in an in the correct order. • If the value is an even number, the label val should be bound to the value 0. To put it another way, all we did was switch the location of a label from one value to another, and there is absolutely no explanation for why this should have affected a[2]. Now that we have the addresses of val, a[2], and 0 written down, let's output them in the debugger: (Pdb) print(id(val), id(a[2]), id(0)) 4326745488 4326745552 4326745488 Given that val is connected to this value, we may deduce that it use the same address as 0. a different address corresponds to a different value in the a[2] array, and vice versa. Attitude: You need to come to terms with the fact that, just like everyone else, you are going to write bugs. Never put your faith in yourself, test extensively, and test frequently. unittest: In Python, specifically, unit tests are an absolute must. We have shown how simple it is to construct unit tests, as well as how easily they can be included into the workflow of software development. You are free to put them to use at this point in time! pdb: The Python debugger is incredibly user-friendly and will help you save a significant amount of time by preventing you from having to clutter your code with debug prints. 6. Demonstrate how to debug a Python program Do you still recall the formula for a quadratic from your math class? This formula, which may also be referred to by its first letters, A, B, and C, is employed in the resolution of a straightforward quadratic equation of the form ax2 + bx + c = 0. Let's use a script to solve quadratic equations instead of doing it by hand because it will get tedious very soon. Example: import math class Solver: def demo(self, a, b, c): d = b ** 2 - 4 * a * c if d > 0: disc = math.sqrt(d) root1 = (-b + disc) / (2 * a) 330 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer root2 = (-b - disc) / (2 * a) return root1, root2 elif d == 0: return -b / (2 * a) else: return "This equation has no roots" if __name__ == '__main__': solver = Solver() while True: a = int(input("a: ")) b = int(input("b: ")) c = int(input("c: ")) result = solver.demo(a, b, c) print(result) As you can see, this sentence contains the primary clause. It indicates that the execution will start with it, then wait for you to input the values that you want for the variables a, b, and c, and then it will enter the method demo. Placing breakpoints To set breakpoints, you need to click the gutter that is located next to the line at which you want your program to pause: 331 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Starting the debugger session Okay, at this point, with the breakpoints that we've inserted, everything is prepared to be debugged. PyCharm gives users many options on how to initiate the debugger session. Let's select one: To begin, pick the Debug 'Solver' command from the popup menu that appears after you click the Run button in the gutter. The debugger will begin to run, will display the Console tab of the Debug tool window, and will give you the opportunity to input the following values: In case you were wondering, the following Python instructions may be entered in the Debug Console: The program is then halted where the first breakpoint is located by the debugger. It indicates that the code in the line containing the breakpoint has not been run yet. The line takes on a blue hue: To go to the next breakpoint, click the button labelled "Resume" that is located on the stepping toolbar of the Debugger tab. 332 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Inline debugging When you look in the editor, you will notice the following text written in grey next to the lines of code: What exactly does it signify? This is the outcome of something that is known as inline debugging. The first lines display the address of the Solver object as well as the values that you have supplied for the variables a, b, and c respectively. The inline debugging feature can be disabled if desired. Take note that this is something that may be done while the debugger is running! Let's step! After clicking the button labelled "Resume," you should now observe that the blue pointer has moved to the following line that contains the breakpoint. If you make use of the buttons on the stepping toolbar, you will advance to the next line. For instance, you may click the option labelled Step Over. Because the inline debugging feature has been turned on, the editor will now display the values of the variables in italic. After the line a = int(input("a: ")), the debugger will move into the file parse.py if you click the button that says Step into. You can see this if you click the button that says Step into. 333 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook If, on the other hand, you continue to use the buttonStep over, you will notice that your program just advances to the following loop: Use the button labelled "Step Into My Code" if you wish to avoid stepping into library classes so that you may focus on your own code instead. This will allow you to use the "Step into" button. Watching You are able to keep an eye on a variable using PyCharm. Simply choose the Variables tab, click the Watch button that is located on its toolbar, and then input the name of the variable that you want to keep an eye on. Please take note that there is code completion available: In the beginning, you will see an error, which indicates that the variable has not yet been defined: On the other hand, when the execution of the program moves on to the scope that defines the variable, the watch obtains the view that is described here: 334 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Evaluating expressions Last but not least, you have the ability to evaluate any phrase at any moment. If you wish to view the value of a variable, for instance, you may do so by clicking the button labelled "Evaluate expression," and then in the dialogue box that displays, you can click the button labelled "Evaluate:" PyCharm provides you with the capability to evaluate any expression you choose. Take, for instance: In order to see the values of the variables, you may use the Debug Console to input certain instructions. (the Python prompt icon may be used to change between the two modes). For instance, you have the ability to alter the a variable. This modification will reflect itself in the code that corresponds to it within the Editor. 335 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Changing format of the decimal variables You have the option, while using the debugger in PyCharm, to preview int variables in either the hexadecimal or binary format. When you are debugging network programs that contain binary protocols, this may be of considerable use to you. Right-clicking on one or more int variables in the Variables list, then selecting View as | Hex from the context menu, will allow you to alter the format that is shown on the screen. Both the list of variables and the editor have their respective formats altered to reflect the new format of the variables. 336 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer 7. Demonstrate the ways to execute a Python app and deploy it Three ways to deploy a Python app into an OpenShift cluster You will learn how to deploy a Python application into an OpenShift cluster in the cloud by following the steps in this tutorial. The approach that is discussed in this article may also be used to deploy apps or microservices that were created on different runtime environments. The examples shown here make use of Red Hat® OpenShift® while hosted on IBM CloudTM. This lesson goes through three different deployment scenarios that may be used to create and deploy apps to an OpenShift cluster hosted on IBM Cloud: After an existing Docker image has been deployed, it must first be pushed to the OpenShift cluster that is hosted on IBM Cloud. In the case at hand, an already-created Docker image is located in a non-public registry. It is necessary to install the image into the OpenShift cluster hosted on IBM Cloud. For the sake of illustration, you may employ this deployment scenario in a "lift and shift" strategy while you are modernising your application. Due to the fact that you do not have access to the sources, there is no system for continuous integration or delivery that has been created. There is a repository on GitHub that contains the sources, as well as a Dockerfile that provides the assembly instructions for the image: When you want full control and freedom to construct the image with only the necessary dependencies and versions, this scenario is appropriate to use. Because you identify the dependencies, the code is guaranteed to be compatible with them at all times. In this situation, you are responsible for maintaining the Dockerfile, which is a process that, at times, may be rather difficult. In this case, continuous integration and delivery to the OpenShift cluster are both possible, which makes it easier to maintain the most recent version of the code that is deployed. There is a repository on GitHub that contains the sources: For this particular use case, you will want to make use of the OpenShift Source to Image (S2I) toolkit in order to generate a Docker image. OpenShift S2I will construct a brand new Docker image by utilising the sources as well as a builder image. The source code language is automatically determined whenever the oc new-app... command is executed, even if the repository does not have a Dockerfile for the application. The principles for language detection are outlined in this section. According to the OpenShift blog, 337 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook the benefits of using S2I include increased speed, increased patchability, increased user efficiency, and an increased ecosystem. This scenario also makes it possible to do continuous integration and delivery to the OpenShift cluster, which helps ensure that the version of the code that is deployed is always up to date. Prerequisites You need an IBM Cloud Account, the OpenShift CLI and Docker. Estimated time Completing this tutorial should take about 30 minutes. Step 1. Create an OpenShift cluster instance Make a copy of an existing OpenShift cluster at a new location. Choose the right plan, then click the Create button. Step 2. Deploy the application using a Docker image in a local registry Source code and a Dockerfile may be found in the IBM repository for the deploy Python OpenShift tutorial, which can be found at github.com/IBM/deploy-python-openshift-tutorial. This tutorial will utilise these examples to construct a Docker image, and then it will show you how to deploy that image to an OpenShift cluster. 1. By using the following command, you may clone the GitHub repository: $ git clone https://github.com/IBM/deploy-python-openshift-tutorial.git 2. Create a Docker image of the application that will later be deployed to an OpenShift cluster by following these steps: $ cd deploy-python-openshift-tutorial $ docker build -t helloworldpython:latest . 3. Open the OpenShift web console: 4. Log in to OpenShift using the CLI and create a new project: $ oc login https://c100-e.us-east.containers.cloud.ibm.com:30682 –token=xxxxxxxxxxxxxxx $ oc new-project exampleproject 5.Create a route for the Docker registry: $ oc project default 338 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer $ oc get svc The output looks like the following example: NAME TYPE CLUSTER-IP EXTERNAL-IP docker-registry ClusterIP 172.21.xxx.xx <none> kubernetes ClusterIP 172.21.x.x <none> myfirstosdeploy registry-console ClusterIP ClusterIP <none> <none> router LoadBalancer 172.21.xx.xxx 172.21.xxx.xxx 172.21.xx.x PORT(S) 5000/TCP 443/TCP,53/ UDP,53/TCP 5000/TCP 9000/TCP AGE 18h 18h 17h 18h 169.47.xxx.xxx 6. To establish a path to the Docker registry, build the following route using the following command: $ oc create route reencrypt --service=docker-registry 7. Verify the following details on the create route: $ oc get route docker-registry It is expected that the output will be something similar to the following example: 8. Docker-registry-default is the format you should observe for the url of the registry. <cluster_name>-<ID_string>. <region>.containers.appdomain.cloud. Take a note of the web address of the Docker registry. It is necessary for the actions that come after it. 9. Utilizing the Docker command line interface, log in to the Docker registry. Take note: the Docker registry URL mentioned before should be used. docker login -u $(ocwhoami) -p $(ocwhoami -t) docker-registry-default.<cluster_name>-<ID_ string>.<region>.containers.appdomain.cloud 10.Mark the Docker image with the appropriate tags, as demonstrated in the following example: docker tag helloworldpython:latest docker-registry-default.<cluster_name>-<ID_string>.<region>. containers.appdomain.cloud/exampleproject/helloworldpython:latest 339 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook 11. Push the Docker image to the OpenShift Docker registry: docker pushdocker-registry-default.<cluster_name>-<ID_string>.<region>.containers.appdomain. cloud/exampleproject/helloworldpython 12. Docker image should be pushed to the OpenShift registry before proceeding: $ oc project exampleproject $ oc new-app --image-stream=helloworldpython --name=helloworldpython $ oc expose svc/helloworldpython 13. To access the helloworldpython application, navigate to the OpenShift interface and click the button labelled "Open Url." Hello, world! is displayed in the browser window: Step 3. Deploy the application using a GitHub repo with sources and a Dockerfile This step uses the same GitHub repository that was used for the deployment, which can be found at github.com/IBM/deploy-python-openshift-tutorial. The image may be assembled based on the instructions provided in the Dockerfile. In this step's examples, you will utilise the exampleproject that you established in an earlier phase. $ oc project exampleproject Run the following command to deploy the application: $ oc new-app https://github.com/IBM/deploy-python-openshift-tutorial $ oc expose svc/deploy-python-openshift-tutorial 340 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer To access the deploy-python-openshift-tutorial application, navigate to the OpenShift interface and click the button labelled Open Url. Hello, world! is displayed in the browser window: Step 4. Deploy the application using a GitHub repo with sources This step uses the same GitHub repository that was used for the deployment, which can be found at github.com/IBM/deploy-python-openshift-tutorial. During this step, the OpenShift S2I makes use of an existing Builder image as well as its sources in order to generate a new Docker image. This image is then sent to the OpenShift cluster. $ oc new-app https://github.com/IBM/deploy-python-openshift-s2i-tutorial $ oc expose svc/deploy-python-openshift-s2i-tutorial To access the deploy-python-openshift-s2i-tutorial application, navigate to the OpenShift interface and click the button labelled "Open Url." Hello, world! is displayed in the browser window: 8. Implement exception handling methods in Python It is feasible to design programs that can handle specific exceptions if given the opportunity. Take 341 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook a look at the following example, which prompts the user for input until a valid integer has been entered, but also gives the user the option to interrupt the program (by pressing Control-C or whatever other method the operating system supports). Take note that a user-initiated interruption is indicated by the raising of the KeyboardInterrupt exception. >>> while True: ... try: ... x = int(input("Please enter a number: ")) ... break ... ... except ValueError: print("Oops! That was no valid number. Try again...") The try statement operates as described below. First, the statements included in the try clause—which are denoted by the terms try and except— are carried out. In the event that no exceptions are thrown, the try statement's except clause is bypassed, and the program is then finished executing. The remainder of the try clause will not be carried out if an unexpected condition arises while it is being executed. The execution then proceeds after the try/except block if the exception's type matches the one stated after the except keyword. If the exception's type does not match, the except clause is not carried out. If an exception occurs that does not correspond to the exception that is named in the except clause, it is forwarded to the outer try statements. If an appropriate handler cannot be located, the exception is considered to be unhandled, and the execution of the program is halted with the message shown above. ... except (RuntimeError, TypeError, NameError): ... pass If a class in an except clause is the same class or a base class of an exception, then the two classes are considered compatible with one another. However, the converse is not true; an except clause that lists a derived class is not compatible with a base class. As an illustration, the code below will print the letters B, C, and D in that order: class B(Exception): pass class C(B): pass 342 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer class D(C): pass for cls in [B, C, D]: try: raise cls() except D: print("D") except C: print("C") except B: print("B") It is important to keep in mind that if the except clauses were flipped around (with except B coming first), it would have written B, B, B since it is triggered by the first matching except clause. As a result of the fact that all exceptions derive from BaseException, it is possible to employ it in a "wildcard" capacity. Utilize with great caution due to the ease with which a true programming fault may be concealed by using this method! It is also possible to use it to print an error message and then re-raise the exception, which enables the caller to additionally handle the exception: import sys try: f = open('myfile.txt') s = f.readline() i = int(s.strip()) except OSError as err: print("OS error: {0}".format(err)) except ValueError: print("Could not convert data to an integer.") except BaseException as err: print(f"Unexpected {err=}, {type(err)=}") raise Alternately, the exception name(s) might be omitted from the last except clause. In this case, however, the exception value has to be acquired via the sys.excinfo()[1] function. The try...except statement can have an optional else clause, which, if it is used, must come after all the except clauses in the statement. It is helpful for code that has to be performed regardless of 343 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook whether or not the try clause throws an exception. Take, for instance: for arg in sys.argv[1:]: try: f = open(arg, 'r') except OSError: print('cannot open', arg) else: print(arg, 'has', len(f.readlines()), 'lines') f.close() If you use the otherwise clause instead of adding further code to the try clause, you won't inadvertently catch an exception that wasn't thrown by the code that's being protected by the try... except sentence. This is a significant improvement over the alternative of adding code to the try clause. When an exception is thrown, it may have a value associated with it; this value is referred to as the argument for the exception. The kind of exception determines both the presence of the argument and the type of argument that can be sent. After the exception name, the except clause permits the specification of a variable. The variable is associated with an instance of an exception, and the arguments are saved in the instance's args property. The Exception instance specifies the __str__() function so that the arguments may be written directly without having to refer to theargs variable. This is done for the sake of convenience. It is also possible to initially create an exception before raising it, after which one may add any properties to the exception as required. >>> try: ... raise Exception('spam', 'eggs') ... except Exception as inst: ... print(type(inst)) # the exception instance ... print(inst.args) ... print(inst) ... # arguments stored in .args # __str__ allows args to be printed directly, # but may be overridden in exception subclasses ... x, y = inst.args ... print('x =', x) ... print('y =', y) # unpack args ... <class 'Exception'> ('spam', 'eggs') ('spam', 'eggs') 344 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer x = spam y = eggs If an exception includes arguments, they will be printed as the final portion of the message for unhandled exceptions, which is referred to as the "detail." Exception handlers are responsible for handling exceptions not just when they happen immediately in the try clause, but also when they happen within functions that are called (even indirectly) in the try clause. Take, for instance: >>> def this_fails(): ... x = 1/0 ... >>> try: ... this_fails() ... except ZeroDivisionError as err: ... print('Handling run-time error:', err) ... Handling run-time error: division by zero Raising Exceptions The raise statement gives the programmer the ability to coerce the occurrence of a particular exception. Take, for instance: >>> raise NameError('HiThere') Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: HiThere The one and only argument to bring up points to the exception that should be brought up. This is required to be either an instance of an exception or an exception class (a class that derives from Exception). In the event that an exception class is supplied, the class will be implicitly constructed by executing its function Object() { [native code] } with no further parameters: raise ValueError # shorthand for 'raise ValueError()' If you need to determine if an exception was raised but don't plan to handle it, you may re-raise the exception by using a shorter form of the raise statement, which gives you the ability to do so: >>> try: 345 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook ... raise NameError('HiThere') ... except NameError: ... print('An exception flew by!') ... raise ... An exception flew by! Traceback (most recent call last): File "<stdin>", line 2, in <module> NameError: HiThere Exception Chaining In the event that an unhandled exception occurs within an except section, the exception that is being handled will be associated to it and included in the error message as follows: >>> try: ... open("database.sqlite") ... except OSError: ... raise RuntimeError("unable to handle error") ... Traceback (most recent call last): File "<stdin>", line 2, in <module> FileNotFoundError: [Errno 2] No such file or directory: 'database.sqlite' During handling of the above exception, another exception occurred: Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError: unable to handle error The raise statement has the option of using a from clause, which can be used to indicate that one exception is the direct result of another: # exc must be exception instance or None. raise RuntimeError from exc When you are altering exceptions, this can come in handy for you. Take, for instance: >>> def func(): 346 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer ... raise ConnectionError ... >>> try: ... func() ... except ConnectionError as exc: ... raise RuntimeError('Failed to open database') from exc ... Traceback (most recent call last): File "<stdin>", line 2, in <module> File "<stdin>", line 2, in func ConnectionError The above exception was the direct cause of the following exception: Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError: Failed to open database In addition to that, it enables the use of the phrase "from None" to disable automatic exception chaining: >>> try: ... open('database.sqlite') ... except OSError: ... raise RuntimeError from None ... Traceback (most recent call last): File "<stdin>", line 4, in <module> RuntimeError Check out the Built-in Exceptions if you want to learn more about the chaining mechanisms. Defining Clean-up Actions There is a second optional phrase that may be added to the try statement. This clause is used to indicate clean-up operations that must be carried out regardless of the situation. Take, for instance: >>> try: ... raise KeyboardInterrupt 347 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook ... finally: ... print('Goodbye, world!') ... Goodbye, world! KeyboardInterrupt Traceback (most recent call last): File "<stdin>", line 2, in <module> If there is a finally clause, and that clause is present, then the finally clause will be carried out as the final job before the try statement is finished. The finally clause is executed regardless of whether or not an exception was produced by the try statement. The following items address more complicated situations that may trigger an exception: • • • • • An except clause may be used to manage an exception that arises during the execution of a try clause if the try clause throws an exception. After the finally clause has been carried out, the exception will be thrown again if the exception is not handled by an except clause. It is possible for an exception to arise while an except or else clause is being executed. The exception is thrown once more once the finally clause has been carried out of its duties. Exceptions are not re-thrown after the finally clause has been executed if it performs a break, continue, or return statement. If the try statement navigates its way to a break, continue, or return statement, the finally clause will run just before the relevant sentence is carried out. If a finally clause contains a return statement, the value that is returned will be the one from the return statement of the finally clause. The value that is returned will not be the one from the return statement of the try clause. For example: >>> >>> def bool_return(): ... try: ... ... return True finally: ... return False ... >>>bool_return() False A more complicated example: >>> 348 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer >>> def divide(x, y): ... ... ... ... ... ... ... ... try: result = x / y except ZeroDivisionError: print("division by zero!") else: print("result is", result) finally: print("executing finally clause") ... >>>divide(2, 1) result is 2.0 executing finally clause >>>divide(2, 0) division by zero! executing finally clause >>>divide("2", "1") executing finally clause Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 3, in divide TypeError: unsupported operand type(s) for /: 'str' and 'str' As shown, the finally clause is carried out after everything else has been completed. The TypeError that was thrown because of the division of two strings is not handled by the unless clause, and as a result, it is thrown again after the finally clause has been carried out. In programs that are used in the real world, the finally clause is helpful for releasing external resources (such as files or network connections) after they have been used, regardless of whether or not the usage of the resource was successful. Predefined Clean-up Actions Certain objects specify the standard clean-up activities that must be carried out after the item is no longer required. These actions must be carried out regardless of whether or not the operation that used the object was successful. Take a look at the following example, which demonstrates how to attempt to open a file and print the contents of that file on the screen. for line in open("myfile.txt"): 349 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook print(line, end="") The problematic aspect of this code is that once this section of the code has completed executing, it continues to keep the file open for a period of time whose length cannot be determined. In straightforward scripts, this is not an issue; however, more complex programs may run across this difficulty. Using the with statement makes it possible to work with things like files in a manner that guarantees they will always be cleaned up in a timely and accurate manner. with open("myfile.txt") as f: for line in f: print(line, end="") Following is the execution of the statement, the file denoted by f is always closed, regardless of whether or not an error occurred during the processing of the lines. Objects that, similar to files, have specified clean-up operations will reflect this fact in the documentation that accompanies them. 9. Demonstrate python app deployment using Git and GitHub This article takes a two-pronged approach to solving the problem that was outlined earlier: packaging and distribution. To begin, we will concentrate on converting your work into a Python package so that it can be effortlessly installed by other people. After that, we will make the package available to users by uploading it to a repository (such as Github or Bitbucket), where it will be stored. You will find that, towards the conclusion of this article: • • • • gaining an understanding of the prerequisites for installing a Python package. are able to either construct a Python package from scratch or convert an existing project into a package. are able to install the custom-built package from the repository using the pip command. are able to bring your package up to date. Goals and preparations Our organizationspecializes in providing analytical services to the restaurant industry. The proprietor of a restaurant often keeps track of information on customers, menu items, and prices. They offer us a data file with precise questions such as "What sort of visitor consumes the canard a l'orange?" and "Is our pumpkin soup overpriced?" They also ask, "Do we observe an increase in consumers since we've decreased pricing on deserts?" Throughout the years that I've spent working here, I've realized that I tend to reuse a lot of the same code, just copying it over from past projects. The "Toolbox" package that we want to develop will, as its name suggests, include a number of extremely generalized snippets of code that both my coworkers and I will be able to pip-install with relative ease. Then, if any one of us comes up with an additional useful feature, we will be able to add it and bring our package up to date. In order for us to accomplish this, the first step will be to encapsulate the code that we already have in a Python package. After that, our attention will be focused on delivering the present to each of my employees so that they may use it. 350 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer Putting our code into packages To begin, we will compile all of our routines into their own separate Python package. If you plan on using pip to complete the installation, you will need to do this first. Within this repository, you have access to all of the folders and files that I have created. In the following phases, we will walk through the process of building one: • Create a venv. If you don't build a virtual environment and add a gitignore, we'll end up with a package that's far larger than it has to be. • Create package folder Make a folder and give it the name of the package you are creating. In my instance, we're talking about the "toolbox." This will be the package that is installed on your computer. In the folder for the package, we will generate the following files: 1. toolbox/functions.py The functionalities that we intend to make available to others will be stored in this file. I have incorporated the following three functions: report, listChunker, and weirdCase. 2. toolbox/ init .py Python will be informed that the toolbox folder has a python package when you do this. This file may also be used to import functions, allowing us to import listChunker from toolbox in addition to importing it from toolbox. This is possible since this file supports several import formats. listChunker is imported by functions. The creation of this file is mandatory, but the content is completely up to you. • Create setup.py The information contained in this file must be provided to pip before the package can successfully be installed. Let's have a look at the setup.py file that I've been utilizing, shall we? import setup tools with open("README.md", "r", encoding="utf-8") as fh: long_description = fh.read() setuptools.setup( name='toolbox', version='0.0.3', author='Mike Huls', author_email='mike_huls@hotmail.com', description='Testing installation of Package', 351 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook long_description=long_description, long_description_content_type="text/markdown", url='https://github.com/mike-huls/toolbox', project_urls = { "Bug Tracker": "https://github.com/mike-huls/toolbox/issues" }, license='MIT', packages=['toolbox'], install_requires=['requests'], ) In the following, we will go through the lines in the setup file that require a little bit more explanation. a) On line 3, import the contents of the README.md file into a variable known as long description. This is not required at all. b) Line 7 requests that a name be given to our package. Must be the same as the name of your package folder c) Line 8. Which version of our program are you referring to? Pip checks to determine if the packages it manages need to be updated using this version; therefore, if you want users to be able to update, you must ensure that it is kept current. d) Lines 12 and 13 are responsible for loading the README.md file, which can be found at line 3. Line 13 also specifies the structure of the readme file. e) Line 14 contains the URL of your repository. f) On line 15, you may want to provide a few useful URLs. g) The 18th line asks how end users may make use of your program. Visit the website choosealicense. com. h) Line 19 contains a list of all of the required packages to be built: Check to ensure that this matches the nameof your package folder. i) At line 20, you should identify all of the other packages that your own package depends on. In spite of the fact that none of my functions make use of requests, I have chosen to add it for the sake of demonstration. By include a package in this location, you ensure that requests will be installed ahead of time during the pip installation of the toolbox package so that toolbox may make use of it. • Other optional files I have made the decision to add a README.md file as well as a LICENSE file. These are just plain text files, and while their inclusion is not strictly necessary, it is certainly appreciated. Our archival system is now complete! Let's figure out how to make it available to everyone! Distributing our code via GitHub Since our package has been generated at this point, we are able to utilise a repository for distribution. To begin, we will create the repository, and then we will utilise it to install our program using pip. After we have finished making changes to the source code, we will finally update our package. 352 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Software Programmer To begin, a repository has to be created. You may accomplish this on any system that makes use of Git (GitHub, BitBucket, etc). After that, add all of your files, making sure to gitignore any files that aren't essential, and push your changes to the repository. Pip install Make a copy of your repository's web address (URL). You may install your package using pip with this URL in the following format: pip install git+https://github.com/mike-huls/toolbox.git That wraps it up! It's not hard, is it? Also, keep in mind that you have the option of installing from either a public repository (such as toolbox) or a private repository! Update your package Imagine that one of my co-workers has developed a brand new function and is going to determine whether or not to add it to the repository. I can bring my package up to date by using pip. pip verifies the version number in the setup.py file each time I use the command pip install git+https://github. com/mike-huls/toolbox.git. My package is updated if my co-worker remembers to increment the version number. Easy! Including our package into a Docker container Docker supports your application through the use of a simple workaround. You may get a more indepth explanation by reading this article. Other advantages GitHub provides a location for documenting concerns, has a great readme on the 'home page,' and even provides a wiki for those times when your package needs even more explanation. As we've shown in this post, the strength of Python packaging combined with the power of Git gives a number of advantages, including the following: • • • • Distribution, installation, and upgrades may all be performed quickly and easily from a single point of origin (one source of the truth) Control over previous versions of our product and the capacity to work together The capability to do an update on the package once it has been modified Install and update packages from a local repository using the pip package manager 353 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Notes __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ __________________________________________________________________________________ Scan the QR codes or click on the link to watch the related videos https://youtu.be/Z2kcG7gvmoI https://youtu.be/zpt0J-QachU https://youtu.be/0hp3WK3b-Fs Pythn Memory Allocation Packages/Standard Libraries in Python Python Operations List 354 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Employability Skills DGT/VSQ/N0102 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Employability Skills is available at the following location https://www.skillindiadigital.gov.in/content/list Employability Skills 356 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Annexure Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Participant Handbook Module No. Module 3: Develop, Test and Execute Software Programs as per Specifications using Python Unit No. UNIT 3.1: Introduction to Python Topic Name Page No Link for QR Code (s) 3.1.1 Outline the evolution of programming languages 354 https://youtu.be/ Z2kcG7gvmoI 3.1.1 Outline the evolution of programming languages 354 3.1.1 Outline the evolution of programming languages 354 QR code (s) Pythn Memory Allocation https://youtu.be/ zpt0J-QachU Packages/ Standard Libraries in Python https://youtu. be/0hp3WK3b-Fs Python Operations List 358 Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime IT – ITeS Sector Skill Council NASSCOM Address: Plot No. – 7, 8, 9 & 10 Sector – 126, Noida, U�ar Pradesh – 201303 New Delhi – 110049 Website: www.sscnasscom.com e-mail: ssc@nasscom.com Phone: 0120 4990111 – 0120 4990172 Price: ` Training content licensed to Chunnu Kumar, issued on 09-11-2023, edition 2023 by FutureSkills Prime Published By NASSCOM