PE2 : Module 1

Réussis tes devoirs et examens dès maintenant avec Quizwiz!

Your 1st Module - an example of a Python module

#!/usr/bin/env python3 """ module.py - an example of a Python module """ __counter = 0 def suml(the_list): global __counter __counter += 1 the_sum = 0 for element in the_list: the_sum += element return the_sum def prodl(the_list): global __counter __counter += 1 prod = 1 for element in the_list: prod *= element return prod if __name__ == "__main__": print("I prefer to be a mod, but I can do tests 4 u.") my_list = [i+1 for i in range(5)] print(suml(my_list) == 15) print(prodl(my_list) == 120) ^ [Run in module.py] ^ - line starting with #! has many names - the name itself means nothing here, but as opposed to being a comment in Python, the # line in Unix / Unix-like OSs (including MacOS) instructs the OS how to execute the contents of the file (i.e. what program needs to be launched to interpret the text) >> in some environ.'s (esp. those connected with web servers) the absence of that line will cause trouble - the "doc-string" is a """string""" (maybe a multiline) placed before any mod. instruct.'s (including imports) to briefly explain purpose & contents of the mod. - the func.'s defined inside the module : (suml() & prodl()) are available for import - used the "__name__" var. to detect when the file is run stand-alone, and seized this opportunity to perform some simple tests

3rd method (w/ "as" keyword variation)

- "as" is a keyword - you may not want to use a particular modname bc it's same as an alrdy defined entity (conflict w/ qualif.) - if you use 3rd method and you have this^ issue, you can give it another name you like : this is "aliasing" Format Ex. import module as alias - "module" identifies the original module's name - "alias" is name you wish to use instead of the orig. Ex. import math as m print(m.sin(m.pi/2)) - *after successful execution of aliased import, orig. modname becomes inaccessible & must not be used Using this w/ 2nd method: Format of 2nd : from module import name Format of 2nd w/ alias : from module import name as alias - will cause the name to be replaced by alias chosen - orig. modname becomes inaccessible (don't use) "name as alias" can be repeated - use commas to separate them : Ex1. from module import n as a, m as b, o as c Ex2. (may look a bit weird, but it also works) : from math import pi as PI, sin as sine print(sine(PI/2))

Growing Code & Multiple Developers

- Codes are always growing and adjusting based on user needs and potential bugs - Large codes are very hard to maintain, and you may want to (or be forced to) divide it into many parts- implemented in parallel by a few, dozens, several dozens, or even several hundreds of developers - All of these individual developers can't just edit a singe source file all at the same time

Overview of Function / Module Analogies (Intro to Packages)

- Python Standard Lib. : Library - Packages : Shelves - Modules : Books - Entities : Chapters - a mod. is a kind of container filled with as many functions as you want that can be distributed across the world - generally a good idea not to mix functions with different application areas within one module (in a library - nobody expects scientific works to be among comic books) - group your func.'s carefully & name mod. containing them in a clear, intuitive way (don't give the name comic_books to a mod. w/ func.'s intended to partition & format hard disks) - group your modules exactly in the same way as you've previously grouped func.'s - a package, in the world of modules, plays a similar role to a folder/directory in the world of files

Your 1st Module - Variables btwn. Modules/Source Files

- Python also creates a var. called __name__ - each source file uses its OWN, separate version of the variable = it ISN'T shared between modules - when you run a file directly, its __name__ variable is set to __main__ - when a file is imported as a mod. (like on main.py) its __name__ var. is set to the file's name "module" ( excluding the .py extension ) (*^all these underscores_ are _ _ (2 underscores)^)

Python packaging ecosystem and how to use it

- Python is an interdisciplinary tool employed in countless applications / data mining uses it also - ^ it has become a leader of research on a.i. - most preferable & efficient thing is to enable all Python community members to freely exchange their codes & experiences w/out having to start from scratch (as there's a high probability that someone else has worked on the same (or similar) problem) - Python is an open-source software -invitation for all coders to maintain whole Python ecosystem as an open, friendly, & free environment - for model to work & evolve, some additional tools should be provided that help the creators to : publish, maintain, & take care of their code - programmers free to modify someone else's code in for their own needs, thus building a completely new product that can be used by another developer - For this flow^ 2 basic entities (that alrdy exist & can be used at any time) have to be est. & kept in motion: > a centralized repository of all avail. software pkg's > a tool allowing users to access the repository^

Importing a Module

- To make a module usable, you must import it (like taking a book off the shelf) - is done by an instruction named "import" <- keyword

Python Module Index

- a community-driven directory of modules available in the Python universe - if you want to find a module fitting your needs, start your search here : https://docs.python.org/3/py-modindex.html

Dependencies

- a phenomenon that appears every time you're going to use a piece of software that relies on other software [it may include (and generally does include) more than 1 level of software development ]

Modules

- a source file containing Python definitions & statements, which can be later imported & used - it's a way to divide a piece of software into separate but cooperating parts - identified by its name : to use it, you must know this - each module consists of entities (like a book consists of chapters), which can be can be functions, variables, constants, classes, and objects - if such a module^ exists & is accessible, Python imports its contents, i.e., all the names defined in the module become known... but they don't enter your code's namespace : ( so this means that you can have your own entities named sin or pi- these will be different than, and not affected by, the import ( of "pi" & "sin( )" ), in any way ) - A (rather large) # of modules are delivered together with Python itself - (you can think of them as a kind of "Python extra equipment") - Python's modules make up their own universe, in which Python itself is only a galaxy Can read about all standard Python modules here : https://docs.python.org/3/py-modindex.html

pip

- a special (free) tool to make use of PyPI's "products" - the proper cheese knife (for cheese shop's cheese) - "pip" is a recursive acronym - the acronym refers to itself, meaning explaining it is an infinite process [Bc pip means "pip installs packages", and the "pip" inside "pip installs packages" means "pip installs packages" it's on and on...etc.] (Linux is a recurs. acronym as well: "Linux is not unix")

Python Standard Library

- a special sort of library where modules play the roles of books (and folders play the role of shelves) - consists of all the modules & built-in func.'s - full list of all "volumes" collected in that library : https://docs.python.org/3/library/index.html

seed( ) function

- able to directly set the generator's seed 2 variants : seed( ) - sets the seed with the current time seed(int_value) - sets seed w/ integer value "int_value" Ex. from random import random, seed seed(0) for i in range(5): print(random()) - Sequence of generated values always looks the same bc the seed is always set with the same value NOTE : your values may be slightly different than ours if your system uses more precise or less precise floating-point arithmetic, but the difference will be seen quite far from the decimal point (>> they were)

Your 1st Module - Creation & Importing Mod.'s

- adding something to module.py to print also prints when running main.py (given it has "import module") When a module is imported, its content is implicitly executed by Python : - it gives it the chance to initialize some of its internal aspects (i.e. it may assign some var.'s w/ useful values) this takes place only once [when 1st import occurs] so assignments by the mod. aren't repeat'd unnecessarily Concept Ex. - there's a mod. named mod1 - there's a mod. named mod2 which contains the 'import mod1' instruction - there's a main file containing the 'import mod1' & 'import mod2' instructions > At first glance, you may think that mod1 will be imported twice - fortunately, only 1st import occurs > Python remembers the imported modules & silently omits all subsequent imports

Your first package - using the zip file in a role of packages

- assume that we've zipped the whole subdirectory, starting from extra folder (including it) & let's get a file named extrapack.zip - next, we put the file inside the packages folder Now we are able to use the zip file in a role of packages: Ex. from sys import path path.append('..\\packages\\extrapack.zip') import extra.good.best.sigma as sig import extra.good.alpha as alp from extra.iota import funI from extra.good.beta import funB print(sig.funS()) print(alp.funA()) print(funI()) print(funB())

Your 1st Module - One solution to locate "module" to import

- can solve our prob of accessing "module" to import being located in : C:\Users\user\py\modules by adding a folder containing the mod. to the path var. (it's fully modifiable) Ex. solution possibility : from sys import path path.append('..\\modules') import module zeroes = [0 for i in range(5)] ones = [1 for i in range(5)] print(module.suml(zeroes)) print(module.prodl(ones)) (^ backslash is used to escape other characters - if you want to get just a backslash, you have to escape it, thus we use // here) we've used relative name of the folder - this will work if you start the main.py file directly from its home folder - this won't work if the current directory doesn't fit the relative path > can always use an absolute path, like this : path.append('C:\\Users\\user\\py\\modules') - the new path will occupy the last element in the path list using append(); if you don't like the idea, you can use insert() instead

choice( ) function

- checks the uniqueness of the "drawn" numbers Format Ex. 1st variant : choice(sequence) - chooses a "random" element from the input sequence & returns it 2nd variant : sample(sequence, elements_to_choose) - builds a list (a sample) consisting of the elements_to_choose element "drawn" from the input sequence (i.e. chooses an amount of the input elements, returning a list with the choices - elements in the sample are placed in random order) NOTE : the "elements_to_choose" must not be greater than the length of the input sequence

Your 1st Module - Creation

- created 2 files in the same folder : PE2 My Mod (Folder 1) --> module.py & main.py - module.py is an empty file - the module itself - main.py is the main - contains the code using the new module : "import module" - nothing shows up when you run the main.py file - this^ means that the contents of module.py have been successfully imported - a subfolder exists in the My Mod folder: _pycache_ - pycache contains a file : module.cypython-xy.pyc > xy are the digits of the python version : (mine is 38) > module is the same as the module's name > after the first dot, the Python implementation the has created the file is mentioned (CPython here) > last part (pyc) comes from "Python" & "compiled" > the contents are completely unreadable to humans > not machine code - internal Python semi-compiled code to be executed by Python's interpreter When Python imports a mod. for the 1st time, it translates its contents into a kind of compiled shape : - this file doesn't require lots of the checks needed for pure source files (execution starts & runs faster) - so, every subsequent import will go quicker than interpreting the source text from scratch - Python's able to check if the module's source file has been modified (in this case, the pyc file will be rebuilt) or not (when the pyc file may be run at once) - this process is fully automatic & transparent

random MODULE

- delivers some mechanisms allowing you to operate with pseudorandom #s (may look random as you cannot predict their subsequent values, but are calculated using very refined algorithms that are deterministic & predictable - data produced by deterministic computers cannot be random in any way (*Only those physical processes which run completely out of our control) may be used as a source of actual random data)

Your first package - modified "path" var. to access a function

- from top of extra package - from iota module - access the funI() function [ forces us to use qualified package names (associate this with naming folders & subfolders - the conventions are very similar) ] Ex. from sys import path path.append('..\\packages') import extra.iota print(extra.iota.funI()) - modified "path" var. to make it accessible to Python - import doesn't point directly to mod. but specifies the fully qualified path from the top of the pkg - replacing import extra.iota with just iota -> error (This variant works too - Ex. 2) : from sys import path path.append('..\\packages') from extra.iota import funI print(funI())

Your first package - Creating/ accessing Python packages intro

- how do we transform a tree (actually subtree) into a real Python package ? ( i.e. convince Python that it's not just a bunch of junk files, but a set of mod.'s? ) > packages, like modules, may require initialization > Python expects a file is inside the package's folder: __init__.py. : it's presence finally makes up the package > the content is executed when any of the package's mod.'s is imported > can leave the file empty if you don't want any special initializations, but you mustn't omit it

Pyramid of Your Program's Environment

- location of your program within the greater environment of the computer (unrelated to Python) Pyramid of Your Program's Environment : - Your (running) Code --- Python('s runtime environment) ----- OS (operating system)* -------Hardware** (*Python's environment uses OS's services to provide some of its functionalities - Python is very powerful - NOT omnipotent - forced to use helpers if it's going to process files / communicate w/ physical devices) (**the processor (or processors), network interfaces, human interface devices (mice, keyboards, etc.) & all other machinery needed to make the computer run - the OS knows how to drive it, and uses lots of tricks to conduct all parts in a consistent rhythm)

"math"

- one of the most frequently used modules - it contains a rich collection of entities (not only functions) - these enable a programmer to effectively implement calculations demanding the use of mathematical functions ( ex. sin( ) or log( ) )

random( ) FUNCTION

- produces a float number x coming from the range (0.0, 1.0) ( i.e. ----> 0.0 <= x < 1.0) - a program that will produce 5 pseudorand. values : - values are determined by the current (unpredictable) seed value - can't guess them Ex. from random import random for i in range(5): print(random())

version( ) : (platform mod)

- provides OS version as a string Ex. from platform import version print(version()) --> (my) output --> #242-Ubuntu SMP Fri Apr 16 09:57:56 UTC 2021

What name takes precedence?

- redefining the meaning of pi & sin AFTER importing same-named entities - your redefined names supersede the original (imported) definitions within the code's namespace. the import yields it's respective output, and then the precedence goes to your redef. var.'s which yields it's respective output reversing the sequence of the code's operations : - we define our own pi and sin & make use of them, which yields its respective output, then carrying out the import causes the imported symbols to supersede their previous definitions within the namespace, so the precedence goes to the imports entities and yield it's respective output

platform( ) function : (platform mod)

- returns a string describing the environment - output is rather addressed to humans than auto-processing - platform(aliased = False, terse = False) : - aliased → when set to True (or any non-0), may cause the func. to present the alternative underlying layer names instead of the common ones - terse → when set to True (or any non-zero value) it may convince the func. to present a briefer form of the result (if poss.) Ex. from platform import platform print(platform()) print(platform(1)) print(platform(0, 1)) --> (my) output --> Linux-4.4.0-210-generic-x86_64-with Linux-4.4.0-210-generic-x86_64-with Linux-4.4.0-210-generic-x86_64-with

processor( ) function : (platform mod)

- returns a string filled with the real processor name (name of CPU running in your computer) (if possible) Ex. from platform import processor print(processor()) --> (my) output --> (my console was blank)

system( ) : (platform mod)

- returns the generic OS name as a string Ex. from platform import system print(system()) --> (my) output --> Linux

machine( ) function : (platform mod)

- returns the generic name of the processor which runs your OS together with Python & your code Ex. from platform import machine print(machine()) --> (my) output --> x86_64

dir( ) function

- reveals all names provided thru a particular module - the module HAS to have been previously imported as a whole using "import", NOT "from" - returns an alphabetically sorted list containing all entities' names available in the mod. (passed as arg.) Format Ex. dir(module) NOTE : if the module's name has been aliased, you must use the alias, not the original name - Using this func. inside a regular script doesn't make much sense, but is possible - you can run these to print the names of all entities w/ the math module: Ex. import math for name in dir(math): print(name, end="\t") ---> outputs all entities in math module separated by "tab"

Importing a Module - Ex. w/ 2 entities from "math" module :

- simplest way to import a particular module is to use the import instruction : Ex. import modname --> import math - this instruction may be used anywhere is the code - BUT must be placed before 1st use of any entities - can import more than one module... by repeating the "import clause" (preferred way) : Ex. import math \ import sys or by listing by listing the modnames after "import" : Ex. import math, sys - modules' list may be arbitrarily long

program's actions behind-the-scenes traveling path

- the hierarchy means than some of your (or rather your program's) actions have to travel a long way to be successfully performed : >> Code wants to create a file, so it invokes one of Python's functions >> Python accepts the order, rearranges it to meet local OS requirements & sends it down (like putting stamp of approval on a request & chain of command) >> OS checks if request is reasonable & valid (i.e. whether filename conforms to some syntax rules) & tries to create the file (this operation consists of many minor steps taken by...) >> Hardware - responsible for activating *storage devices to satisfy OS's needs (*hard disk/solid state devices, etc.)

Dependency Hell

- the process of arduously fulfilling all the subsequent requirements to trace all dependencies & manually install all needed packages - ...BUT... "pip" can discover, identify & resolve all dependencies for you instead, while cleverly avoiding unnecessary downloads & reinstalls !!

Ex. program where some elements may not be unique :

- this program very likely outputs a set of #'s in which some elements are not unique : Ex. from random import randint for i in range(10): print(randint(1, 10), end=',') --> output --> 9,4,5,4,5,8,9,4,8,4,

qualifying the entity name w/ it's original mod

- to access an entity coming from a module, you must qualify the entityname w/ the name of its original mod - using this qualification is compulsory if a module has been imported by the import module instruction - doesn't matter if any names from your code and from the module's namespace are in conflict or not (import the module, then qualify the entity names w/ their original module name -> modname.entityname) Ex. math.pi math.sin

Your 1st Module - how many times have the func.'s been invoked?

- to know how many times the func.'s have been invoked, you need a counter initialized to zero when the module is being imported ---> - can absol. introduce such a variable must be aware of the important side effects that could be caused : [Run in module.py] : counter = 0 if __name__ == "__main__": print("I prefer to be a module.") else: print("I like to be a module.") [Run in main.py] : import module print(module.counter) - main file tries to access the mod.'s counter var. - this is legal, but only safe if you trust your mod.'s users - you may not want the whole world to see your personal/private var., but python doesn't have a means to allow hiding of such a var. from mod. users -BUT, you can inform users that this is YOUR var. that can be read but not modified under any circumstance (done by preceding the var.'s name with _ (one underscore) or __ (two underscores) ) > mod. users may or MAY NOT obey this however, this is only a convention

Executing the dir( ) function

- you can execute the dir( ) function directly in the Python console (IDLE), without needing to write and run a separate script inside your code in editor Ex. (inputted in console/shell) >>> import math \ >>> dir(math) --> output --> will give a list of all the entitynames in the imported mod. separated by commas

Some functions from the "math" module

---Circular Functions --- group of "math"s func's connected w/ trig : sin(x) → the sine of x cos(x) → the cosine of x tan(x) → the tangent of x - all take 1 arg. (an angle measurement in radians) ( be careful with tan( ) - not all arg.'s are accepted ) group of "math"s func's connected w/ inverse trig : asin(x) → the arcsine of x acos(x) → the arccosine of x atan(x) → the arctangent of x - take 1 arg. (mind the domains) & return a measure of an angle in radians group of "math"s entities to effectively operate on angle measurements : pi → a constant with a value that is an approx. of π radians(x) → a func. that converts x from deg. to rad. degrees(x) → converts x in opp. direct. ( deg. to rad.) ---Hyperbolic analogues --- sinh(x) → the hyperbolic sine cosh(x) → the hyperbolic cosine tanh(x) → the hyperbolic tangent asinh(x) → the hyperbolic arcsine acosh(x) → the hyperbolic arccosine atanh(x) → the hyperbolic arctangent

Handling of Modules

2 issues : - (probably the most common) happens when you want to use an already existing module, written by someone else, or created by yourself during your work on some complex project - here, you're the user - occurs when you want to create a brand new module, either for your own use, or to make other programmers' lives easier - here, you're the supplier

PyPI (Python Package Index)

> centralized repository of all avail. software pkg's : - the repo is named (Python Package Index) PyPI [PyPI website (administered by PWG) is located at] : https://pypi.org/ - completely free - can just pick a code and use it (but must observe & obey all the licensing terms) - PyPI is not the only existing Python repository, however, it is the most important Python repo in the world - "all Python roads lead to PyPI" - some Python installations come w/ it & some don't - you can also create your own repos - PWG is the Packaging Working Group that named it [main task is supporting Python dev.'s in efficient code dissemination] : https://wiki.python.org/psf/PackagingWG - this grp is part of the Python Software Foundation

random number generator

>> takes a value (seed) >> treats seed as an input value >> calculates a "random" number based on it (the method depends on a chosen algorithm) >> produces a new seed value - length of a cycle in which all seed values are unique may be very long, but isn't infinite - sooner or later values will start repeating, and generating values will repeat, too. This is normal. - initial seed value, set during program start, determines order in which gen. values will appear - random factor of the process may be augmented by setting seed w/ a # taken from the current time....may ensure that each program launch will start from a different seed value (ergo, use different random #'s)

Your 1st Module - file locating

Assume Python "main" file ISN'T located in the same folder/directory as the module to be imported : - in Windows ® OS (file name's shape depends on it) - main Python script (named main.py) lies in : C:\Users\user\py\progs - "module" to import is located in : C:\Users\user\py\modules -> how do we deal w/ it? Python searches in locations (folders/directories) to find the mod. requested by the import instruction : a special var. "path" (actually a list) stores all of them - "path" is accessible through the module named "sys" - "path" browses these folders in the order they are arranged in the list & import fails if it can't be found - otherwise, 1st folder containing a mod. w/ the desired name will be taken into consideration (if any of the remaining folders contains a mod. of that name, it will be ignored)

Your 1st Module - use the updated Python module

Ex. from module import suml, prodl zeroes = [0 for i in range(5)] ones = [1 for i in range(5)] print(suml(zeroes)) print(prodl(ones)) ^ [Run in main.py] ^

Your 1st Module - checking "path"'s regular value

Ex. to check "path"'s regular value : import sys for p in sys.path: print(p) output (after launching in the C:\User\user folder) --> C:\Users\user C:\Users\user\AppData\Local\Programs\Python\Python36-32\python36.zip C:\Users\user\AppData\Local\Programs\Python\Python36-32\DLLs C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib C:\Users\user\AppData\Local\Programs\Python\Python36-32 C:\Users\user\AppData\Local\Programs\Python\Python36-32\lib\site-packages NOTE : (^the folder in which the execution starts is listed in the first path's element (^there is a zip file listed as one of the path's elements - this is NOT an error - python's able to treat zip files as ordinary folders - this can save lots of storage)

3rd method

Format : from module import * (entityname / list of entityname(s) is replaced w/ *) - this instruction imports ALL entities from that mod. - it's convenient as it relieves you of the duty of enumerating all the names you need ... BUT ... - it's unsafe as name conflicts may not be avoidable unless you know all the names provided by the mod. (treat this as temporary solution, not for frequent use)

Your first package - get access to the sigma and tau modules

How to get access to the sigma and tau modules : Ex. from sys import path \ path.append('..\\packages') \ import extra.good.best.sigma from extra.good.best.tau import funT \ print(extra.good.best.sigma.funS()) print(funT()) Can make your life easier by using aliasing : Ex. from sys import path \ path.append('..\\packages') \ import extra.good.best.sigma as sig import extra.good.alpha as alp \ print(sig.funS()) print(alp.funA())

2nd method

In 2nd method (selective method), "import"'s syntax precisely points out which mod's entity(s) are acceptable in the code: from math import pi Instruction consists of the following elements: - "from" keyword - modname to be (selectively) imported - "import" keyword - entityname (or list of those) being imported Instruction has this effect: - those listed entities are imported from the mod. - names of the imported entities are accessible without qualification NOTE : - no other entities are imported - you cannot import additional entities using a qualification (i.e. print(math.e) --> Error) Ex. from math import sin, pi print(sin(pi/2)) \ --> output --> 1.0

Ex. co-existing namespaces (modules' and your own)

In first method, - We've defined our own pi and sin here : Ex. import math def sin(x): if 2 * x == pi : return 0.99999999 else: return None pi = 3.14 print(sin(pi/2)) print(math.sin(math.pi/2)) output ---> 0.99999999 \ 1.0 - 2 namespaces (yours and the module's one) can coexist, & the entities don't affect each other

Decomposition

Large codes being edited by many developers : For such a software project to be completed successfully, you need to have the means to : - divide all the tasks among the developers - join all the created parts into one working whole For ex., a project can be divided into 2 main parts: - user interface ( part that communicates with the user using widgets & a graphical screen) - logic (the part processing data & producing results) - the process of each of these parts being divided up into smaller ones, and so on is *decomposition*

Your 1st Module - Using a var. to detect context of code activation

Make use of the __main__ variable in order to detect the context in which your code has been activated : if __name__ == "__main__": print("I prefer to be a module.") else: print("I am equivalent to 'module'.") [Run in module.py] : output -> I prefer to be a module. [Run in main.py] : output -> I am equiv. to 'module'. - if you write a mod. filled with a bunch of complex functions, you can use it to place a series of tests to check if the functions work properly - each time you modify any of these func.'s, you can simply run the mod. to make sure that your amendments didn't spoil the code - these tests will be omitted when the code is imported as a mod.

platform module

Sometimes you want to know more beyond just creating a file : ex. - name of the OS which hosts Python - some characteristics describing the hardware that hosts the OS - this mod. provides some means to allow you to know where you are & what components work for you - lets you access the underlying platform's data, i.e., hardware, OS, and interpreter version info

Your first package - Creating/ accessing Python packages intro2

Where do we put pkg so it's accessible to Python? - only have to ensure that Python is aware of the package's location, but can be put anywhere - __init.py__ file can be put in the root folder & inside any of its subfolders (subpackages) too - this may be useful if some subpackages require individual treatment & special kinds of initialization

Your first package - make use of your first package

Zip file containing all the files from the packages branch (tree structures in python graphics folder) : Modules and Packages ZIP file - unpack it in the folder presented in the scheme, or it won't be accessible to the code from the main file

Your first package - almost a package (tree structure)

[looks like a directory structure] (described from bottom-up) ----->>> the ugly group contains 2 modules: psi and omega the best group contains 2 modules: sigma and tau the good group contains 2 modules: alpha and beta & 1 subgroup (best) the extra group contains 1 module: iota & 2 subgroups (good and ugly) - tree shows projected dependencies btwn the mod.'s - if you assume that extra is the name of a newly created package (the package's root), it will impose a naming rule which allows you to clearly name every entity from the tree For ex. extra.good.best.tau.funT() > location of a func. named funT() from tau package extra.ugly.psi.funP() ---> comes from : > psi mod. in "ugly" subpackage of "extra" package

Package

a container which enables the coupling of several related modules under one common name - can be distributed as-is > (a batch of files deployed in a directory sub-tree) > (can be packed inside a zip file)

namespace

a space (understood in a non-physical context) in which some names exist & the names don't conflict w/ each other (i.e. meaning there are not two different objects of the same name) - in a certain namespace, names must remain unique when any other entity of an already known name enters the namespace, duplicates may dissapear*** (*** will the duplicates go, or will the name itself go?) - group tends to name each member in a unique way (i.e. how parents won't give sib's the same first names) - each social group is a namespace this uniqueness may be achieved in many ways : - by using nicknames along with the first names ( like in a small group i.e. a class in a school ) - by assigning special identifiers to all members of the group ( like a Social Security # )

choice / sample Ex.

from random import choice, sample my_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] print(choice(my_list)) print(sample(my_list, 5)) print(sample(my_list, 10)) ---> outputs ---> 4 \ [3, 1, 8, 9, 10] [10, 8, 5, 1, 6, 4, 3, 9, 7, 2]

more "math" module func.'s

group of "math"s func's connected w/ exponentiation : e → constant w/ a value that is approx. Euler's # (e) exp(x) → finding the value of e^x log(x) → the natural logarithm of x log(x, b) → the logarithm of x to base b log10(x) → decimal logarithm of x (more precise than --> log(x, 10)) log2(x) → binary logarithm of x (more precise than --> log(x, 2)) NOTE : the pow() function: pow(x, y) → finds the value of x^y (mind the domains) This is a built-in func.^ - doesn't have to be imported

more "math" module func.'s (cont.)

group of "math"s func's for general-purpose use: ceil(x) → the ceiling of x (smallest integer > or = to x) floor(x) → the floor of x (largest integer < or = to x) trunc(x) → the value of x truncated to an integer (not an equi. of ceil or floor- shaves off decimal & dec. #'s) factorial(x) → returns x! (x has to be an integral and not be a negative) hypot(x, y) → returns the length of the hypotenuse of a right-angle triangle with the leg lengths = to x & y (same as sqrt(pow(x, 2) + pow(y, 2)) but more precise) Ex. from math import ceil, floor, trunc x = 1.4 y = 2.6 print(floor(x), floor(y)) print(floor(-x), floor(-y)) print(ceil(x), ceil(y)) print(ceil(-x), ceil(-y)) print(trunc(x), trunc(y)) print(trunc(-x), trunc(-y)) outputs --> 1 2 \ -2 - 3 \ 2 3 - 1 - 2 \ 1 2 \ - 1 - 2 - this ex.^ demonstrates the fundamental differences between : ceil() floor() trunc()

1st method Ex. print the value of sin(½π)

import math print(math.sin(math.pi/2)) output --> 1.0

2 entities provided by the "math" module

pi" and "sin( )" are entities avail. thru the math module : - "pi" is a symbol (constant) representing a precise value of π (as precise as possible using double floating-point arithmetic) - (using a Greek letter to name a var. is fully possible) - (BUT the symbol is named pi bc its more convenient, esp for people that don't have/use a Greek keyboard) - sin( ) is a function - (computer equiv. of the mathematical sine function) - how the import has been done strongly affects the way in which you can use them

func.'s to check what version of Python is running your code : (platform mod)

python_implementation( ) → - returns a string denoting the Python implementation - (Expect CPython here, unless you decide to use any non-canonical Python branch) python_version_tuple( ) → - returns a three-element tuple filled with : >> the major part of Python's version >> the minor part >> the patch level number Ex. from platform \ import python_implementation, python_version_tuple print(python_implementation()) for atr in python_version_tuple(): print(atr) --> (my) output --> CPython \ 3 \ 7 \ 10

some more functions from the random module

randrange and randint functions : - for random integer values, one of the following functions would fit better : randrange(end) randrange(beg, end) randrange(beg, end, step) randint(left, right) - the first 3 invocations will generate an integer taken (pseudorandomly) from the range (respectively) : range(end) range(beg, end) range(beg, end, step) Note the implicit right-sided exclusion! (meaning no exclusion on the right side) - the last function is an equivalent of : randrange(left, right+1) - it generates the integer value i, which falls in the range [left, right] , again- includes the "right" in range - important disadvantage - these func's may produce repeating values even if # of subsequent invocations is not greater than the width of the specified range

Your first package

you & your associates write a large # of Python func.'s - your team decides to group the func.'s in separate mod.'s & this is the final result of one (out of a set*) : #! /usr/bin/env python3 """ module: alpha """ def funA(): return "Alpha" if __name__ == "__main__": print("I prefer to be a module.") ( *the set will contain other mod's looking similar (they will all contain one function named funX, where X is the first letter of the module's name) ) ( Ex. psi.py : def funP( ) : ... \ beta.py : def funB( ) : ... ) - notice these mod.'s form their own hierarchy - putting them in a flat structure isn't a good idea - the modules have to be grouped - the tree structure perfectly reflects the mutual relationships between the modules : [looks like a directory structure] (described from bottom-up) ----->>> the ugly group contains 2 modules: psi and omega the best group contains 2 modules: sigma and tau the good group contains 2 modules: alpha and beta & 1 subgroup (best) the extra group contains 1 module: iota & 2 subgroups (good and ugly)

The PyPI repo : The Cheese Shop

you want some cheese, you go to the cheese shop : you want a piece of softw., you go to the softw. shop - The Cheese Shop - one of the most famous Monty Python sketches - depicts an Englishman trying to buy some cheese - unfortunately, the shop he visits (Ye National Cheese Emporium) ironically has no cheese in stock at all - PyPI has lots of software in stock & is available 24/7 - fully entitled to identify itself as "Ye International Python Software Emporium" (but stocked...) - a very specific "shop" requiring a special (free) tool to make use of it named "pip"-the proper cheese knife


Ensembles d'études connexes

Trail Guide to The Body: Chapter 2 - Shoulder & Arm

View Set

Biology Quiz 4 - Taxonomy and Origins

View Set

Chapter 5 Personnel Planning and Recruiting

View Set

Line-of-Duty Death or Serious Injury Incident Assistance

View Set