scipy is a specialist library for dealing with mathematical, science and engineering problems. According to their website:
The SciPy library, a collection of numerical algorithms and domain-specific toolboxes, including signal processing, optimization, statistics and much more.
The library itself is such a broad topic, so for the purposes of today’s article I just want to focus on a few items (from numpy) listed in their basic functions area covering polynomials and then finish up with the integration library.
Polynomials
A quick brush-up on some high school math (thanks wikipedia) tells us that a polynomial is an expression of more than two algebraic terms; these are normally variables (or indeterminates) and co-efficients.
Our polynomial with just one variable:
x² + 3x + 1
Let’s get scipy to represent this for us:
importnumpyasnpp1=np.poly1d([1,3,1])print(p1)
This gives us an output of:
2
1 x + 3 x + 1
Derivative
Lets derive this function, to find the formula that defines its instantaneous rate of change:
f(x) = x² + 3x + 1
f'(x) = 2x + 3
We can get scipy to this for us using the deriv function:
print(p1.deriv())
Confirming everything for us, we now receive the derivative:
2 x + 3
Integral
We’ll integrate the same function now, providing us with the ability to calculate the area under the curve that the original polynomial would provide:
f(x) = x² + 3x + 1
∫f(x) = x³ / 3 + (3x²) / 2 + x + C
We can simply use the integ function to do this for us, again:
print(p1.integ())
Providing us with the following answer:
3 2
0.3333 x + 1.5 x + 1 x
General integration
Now that we’ve done some basic calculus with polynomials, we’ll get scipy to perform the integration for us. Using quad we specify the function that produces our values a maxima and minima value and then we’re given the integrated values.
Getting your program to make simple HTTP has become a feature that is just a given these days. The python library requests makes life a lot easier.
Requests is the only Non-GMO HTTP library for Python, safe for human consumption.
Today’s post will focus on this library, to show you how you can be immediately productive.
How things were
One of the best comparisons comes directly from the requests documentation. Prior to its existence, you needed to do the following to perform a GET request with Basic Authentication:
numpy is an excellent library for dealing with array-based math problems. According to the website:
NumPy is the fundamental package for scientific computing with Python
In today’s post, I’ll go through some very basic operations of the library while piecing together the transformation segment that you might see in the back-end of a 3D rendering pipeline. We’ll focus on some vector and matrix math, but most importantly we’ll look at the creation of specialised matricies and matrix multiplication.
Vectors
All points in our 3D world is going to be re-presented by a 4D Homogenous co-ordinate. numpy provide the perfect abstraction here with the array function.
p=np.array([1,0,0,1])
There are many other construction functions available for this single dimension value series that you can find in the documentation.
Once we’ve created the array, we can start to perform arithmetic on it.
Graduating from the vector, we now need a tabular representation for our linear algebraic operations that we’ll perform. To do this, we’ll use a matrix which numpy has a direct analog for.
First of all, every math library needs a shortcut to the identity matrix:
Armed with all of these functions, we have a basic (local) co-ordinate transform pipeline. We can start to make a little more sense out of these mathematical constructs by binding the results to variables that are named by their side effects.
# the cartesian plane moves positive, to the right
move_right_by_2=create_translation(2,0,0)# make any point twice the distance away from the origin
make_twice_bigger=create_scale(2,2,2)# π radians is 180°
turn_the_other_way=create_rotate_x(math.pi)
What is interesting about the matricies that we’ve just created, is that they’re reusable for as many points as we want. We can uniformly transform a group of vectors with the same matrix.
So, if I wanted to not only move right by 2, but also make twice bigger and turn the other way; I could multiply these matricies together to form a new transformation:
We did start, pointing towards the camera 0, 0, 1 and then after moving to the right by 2 and doubling our size, we’re now at 4 on the x-axis. We turn around about the x axis and we’re now facing away from the camera; twice the distance (-2 on the z-axis). Note that the y-axis has some epsilon garbage after our multiplies.
Well, it was a quick tour; but this has been numpy in (a little bit of) action.
As web application developers, we’re given a vast array of web application development frameworks at our disposal, In today’s post, I’m going to go through three of these; all based on the Python programming language. The frameworks are:
These really are micro-frameworks for this purpose.
Pyramid
Pyramid, or the Pylons Project is a straight-forward application framework where most of the focus is placed on the application’s configuration. This isn’t an ancillary file supplied to the application, but defined in code, in module. From the web site:
Rather than focusing on a single web framework, the Pylons Project will develop a collection of related technologies. The first package from the Pylons Project was the Pyramid web framework. Other packages have been added to the collection over time, including higher-level components and applications. We hope to evolve the project into an ecosystem of well-tested, well-documented components which interoperate easily.
The Pylons project is a greater umbrella for the Pyramid-piece which is the web application framework.
Following is a “Hello, world” application using this framework.
The Configurator class holding a lot of the application’s runtime, which is where routes and views come together.
Bottle
Bottle is a no-frills framework, with four main responsibilities: routing, templates, utilities and server.
It’s actually quite amazing (from a minimalist’s perspective) exactly how much you can get accomplished in such little code. Here’s the “Hello, world” example from their site:
The simplistic feel to the framework certainly makes it very clear. template providing a direct text template with a model. run performing the job of the server and the @route attribute performing route configuration.
They’re faithful to their words:
Bottle is a fast, simple and lightweight WSGI micro web-framework for Python. It is distributed as a single file module and has no dependencies other than the Python Standard Library.
Tornado
Tornado is a web application framework that has been based around event-driven I/O. It’s going to be better suited to some of the persistent connection use-cases that some applications have (like long-polling or web sockets, etc). The following is from their site:
Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed. By using non-blocking network I/O, Tornado can scale to tens of thousands of open connections, making it ideal for long polling, WebSockets, and other applications that require a long-lived connection to each user.
In its own way, Tornado can also be quite minimalist. Here’s their example:
Network programming is a delicate mix of sending messages, waiting for events and reacting. Twisted is a python library that aims to simplify this process. From their website:
Twisted is an event-driven networking engine written in Python
Pretty straight forward.
Echo Server
The first example (lifted directly from their website) is an Echo Server:
The method dataReceived which is provided by the Protocol class is called by the reactor when a network event of interest presents itself to your program.
HTTP
Out of the box, you’re also given some tools to talk web actions. Again, lifted from the twisted website is an example web server:
fromtwisted.webimportserver,resourcefromtwisted.internetimportreactor,endpointsclassCounter(resource.Resource):isLeaf=TruenumberRequests=0defrender_GET(self,request):self.numberRequests+=1request.setHeader(b"content-type",b"text/plain")content=u"I am request #{}\n".format(self.numberRequests)returncontent.encode("ascii")endpoints.serverFromString(reactor,"tcp:8080").listen(server.Site(Counter()))reactor.run()
It’s a pretty brute-force way to deal with assembling a web server, but it’ll get the job done. The render_GET method of the Resource derived Counter class will perform all of the work when a GET request is received by the server.
Chat Server
I’ll finish up with some original content here, that is a PubSub example (which twisted website has an example of).
Getting a leg up using the LineReceiver protocol as a base, really simplifies our implementation. This allows us little gems like connectionMade, connectionLost and lineReceived . . all pieces that you’d expect in a chat server:
defconnectionMade(self):'''When a connection is made, we'll assume that the client wants to implicitly join
out chat server. They'll gain membership automatically to the conversation'''self.factory.clients.add(self)defconnectionLost(self):'''When a connection is lost, we'll take the client out of the conversation'''self.factory.clients.remove(self)
We use a really crude regular expression with some basic captures to pull apart the instruction sent by the client:
# our very crude, IRC instruction parser
irc_parser=re.compile('/(join|leave|msg|nick) ([A-Za-z0-9#]*)(| .*)')
When receiving a line, we can respond back to the client; or we can broadcast to the portfolio of connections:
deflineReceived(self,line):'''When a client sends a line of data to the server, it'll be this function that handles
the action and re-acts accordingly'''matches=irc_parser.match(line)ifmatches==None:# send an error back (to this client only)
self.sendLine('error: line did not conform to chat server requirements!')else:(act,obj,aux)=matches.groups()ifact=='join':self.broadcast(self.nick+' has joined the channel '+obj)elifact=='leave':self.broadcast(self.nick+' has left the channel '+obj)elifact=='nick':client_ip=u"<{}> ".format(self.transport.getHost()).encode("ascii")self.broadcast(client_ip+' is changing nick to '+obj)self.nick=obj
The only part left out here, is the broadcast method. Which is simply a for-loop:
fromtwisted.internetimportreactor,protocol,endpointsfromtwisted.protocolsimportbasicimportre# our very crude, IRC instruction parser
irc_parser=re.compile('/(join|leave|msg|nick) ([A-Za-z0-9#]*)(| .*)')classChatProtocol(basic.LineReceiver):'''The chat server is responsible for maintaing all client connections along with
facilitating communication between interested chat clients'''def__init__(self,factory):self.factory=factoryself.channels={}defconnectionMade(self):'''When a connection is made, we'll assume that the client wants to implicitly join
out chat server. They'll gain membership automatically to the conversation'''self.factory.clients.add(self)defconnectionLost(self):'''When a connection is lost, we'll take the client out of the conversation'''self.factory.clients.remove(self)deflineReceived(self,line):'''When a client sends a line of data to the server, it'll be this function that handles
the action and re-acts accordingly'''matches=irc_parser.match(line)ifmatches==None:# send an error back (to this client only)
self.sendLine('error: line did not conform to chat server requirements!')else:(act,obj,aux)=matches.groups()ifact=='join':self.broadcast(self.nick+' has joined the channel '+obj)elifact=='leave':self.broadcast(self.nick+' has left the channel '+obj)elifact=='nick':client_ip=u"<{}> ".format(self.transport.getHost()).encode("ascii")self.broadcast(client_ip+' is changing nick to '+obj)self.nick=objdefbroadcast(self,line):forclientinself.factory.clients:client.sendLine(line)classChatFactory(protocol.Factory):def__init__(self):self.clients=set()defbuildProtocol(self,addr):returnChatProtocol(self)endpoints.serverFromString(reactor,"tcp:1234").listen(ChatFactory())reactor.run()