Pete Goodliffe from Pete Goodliffe

My latest**Becoming a Better Programmer**column is published in the July issue of CVu magazine (26.3). It called

*Nothing is Set in Stone*. It talks about the

*soft*nature of software, and how to make fearless changes.

Skip to content
## Posts

### Writing: Nothing is Set in Stone

**Becoming a Better Programmer** column is published in the July issue of CVu magazine (26.3). It called* Nothing is Set in Stone*. It talks about the *soft* nature of software, and how to make fearless changes.
### Writing: Becoming a Better Programmer

*Becoming a Better Programmer* with the excellent folks at O'Reilly.

You can find out more about the book from it's catalogue page at http://shop.oreilly.com/product/0636920033929.do.

We have now made an early access version available with a number of the chapters. It's already looking excellent, and I can't wait to get the final version out.
### Remote debugging python in Visual Studio

The additional lines are highlighted in the following script:

#!/usr/bin/python

"""

You will need to insert both these in your script

The remote box requires the ptvsd package (otherwise the import fails)

**"""**

**import ptvsd**

**ptvsd.enable_attach(secret = 'joshua')**

#use None instead of joshua but that is not secure

#The secret can be any string - but this is not properly secure

def say_it(it):

"""

This inserts a breakpoint

but you can add new breakpoints in Visual Studio

if required too/instead

"""

**ptvsd.break_into_debugger()**

print(it)

if __name__ == "__main__":

#pause this script til we attach to it

**ptvsd.wait_for_attach()**

say_it("Hello world")

See https://pytools.codeplex.com/wikipage?title=Remote%20Debugging%20for%20Windows%2C%20Linux%20and%20OS%20X for more details and be wary of line ending in VS which may be inappropriate for linux.

Install the ptvs from the relevant msi for your version of Visual Studio.

Start the script on the linux box:

$python VSPyNoodle.py

It will hang, since it has a wait_for_attach call in main.

ctrl-Z will stop it on the remote box if something goes wrong.

Select "Attach to process" in the Debug menu on Visual Studio

Change the "Transport" to "Python remote debugging (unsecured)"

Add the secret (joshua in this script) @ hostname to Qualifier

e.g. joshua@hostname

Hit "Refresh"

It should find the process running on the linux box and add the port it uses to the Qualifier

Select your process in the list box and hit "Attach"

then debug as you are used to in VS.

If it complains about stack frames and not being able to see the code you may need to make a VS project from a local version of the code. having made sure it exactly matches the remote code.

### Rational Computational Geometry in Python

### Business of Software Conference Europe

### Business of Software Conference Europe

### Business of Software Conference Europe

### Resolving strong references between Swift and Objective-C classes – Using unowned and weak references from Swift to Objective-C classes

Rather than derive game objects from SKSpriteNode with each derived class containing the code for handling collisions with the other types of game objects I'm following something akin to a Component-Entity model.

I have per-game-object handler classes of which an instance of each is stored in the actual SKSpriteNode's userData dictionary. In turn each handler instance has a reference to the SKSpriteNode that references it. Given ARC is used this is a classical strong-reference chain which will prevent memory from being freed. The usual solution to this in Objective-C is to have one of the references be weak. In Swift there are two types of weak references: weak which is the same as in Objective-C and unowned (which I think is new). The difference is that an unowned reference can never be**nil**, i.e. it's optional whether a weak pointer reference an object but an unowned pointer must always reference something. As such the member variable is always defined using let and must be initialized, i.e. an init method is required.

The following code shows how I was intending to implement this. There is the strong reference from node.UserData to PhysicsActions and then the unowned reference back again from PhysicsActions.

However, when I went to use this code it crashed within the onContact method when it attempted to use the node. Changing this the reference type from unowned to weak fixed this, e.g.

weak let node : SKSpriteNode?

This verified that the rest of the code was ok so this seemed to look like another Swift/Objective-C interoperability issue. Firstly, I made a pure Swift example which is a simplified version from the The Swift Programming Language book.

**foo:C14XXXUnownedTest3Foo (has 1 child)**

**Foo2.h**

**Foo2.m**

**main.swift**

### Beware: Despite the docs SKNode userData is optional

**Declaration**

**fatal error: Can't unwrap Optional.None**

**node.userData = NSMutableDictionary()**
### Rename Selected Jenkins Jobs

Pete Goodliffe from Pete Goodliffe

My latestPete Goodliffe from Pete Goodliffe

I am delighted to announce that I have signed a contract to publish my latest book,You can find out more about the book from it's catalogue page at http://shop.oreilly.com/product/0636920033929.do.

We have now made an early access version available with a number of the chapters. It's already looking excellent, and I can't wait to get the final version out.

Frances Buontempo from BuontempoConsulting

Suppose you have a script you want to run on linux and you only know how to drive the Visual Studio debugger. By installing an add-in for Visual Studio locally, installing the python tools for Visual Studio debugging on the remote machine, e.g. with pip install ptvsd==2.0.0pr1 and adding a (minimum of) a couple of lines to your script you can debug in Visual Studio even if the remote machine is running linux.The additional lines are highlighted in the following script:

#!/usr/bin/python

"""

You will need to insert both these in your script

The remote box requires the ptvsd package (otherwise the import fails)

#use None instead of joshua but that is not secure

#The secret can be any string - but this is not properly secure

def say_it(it):

"""

This inserts a breakpoint

but you can add new breakpoints in Visual Studio

if required too/instead

"""

print(it)

if __name__ == "__main__":

#pause this script til we attach to it

say_it("Hello world")

See https://pytools.codeplex.com/wikipage?title=Remote%20Debugging%20for%20Windows%2C%20Linux%20and%20OS%20X for more details and be wary of line ending in VS which may be inappropriate for linux.

Install the ptvs from the relevant msi for your version of Visual Studio.

Start the script on the linux box:

$python VSPyNoodle.py

It will hang, since it has a wait_for_attach call in main.

ctrl-Z will stop it on the remote box if something goes wrong.

Select "Attach to process" in the Debug menu on Visual Studio

Change the "Transport" to "Python remote debugging (unsecured)"

Add the secret (joshua in this script) @ hostname to Qualifier

e.g. joshua@hostname

Hit "Refresh"

It should find the process running on the linux box and add the port it uses to the Qualifier

Select your process in the list box and hit "Attach"

then debug as you are used to in VS.

If it complains about stack frames and not being able to see the code you may need to make a VS project from a local version of the code. having made sure it exactly matches the remote code.

Rob Smallshire from Good With Computers

In the previous article,
we looked at how a standard technique for determining the collinearity of
points, based on computing the sign of the area of the triangle formed by two
points on the line and a third query point. We discovered, that when used with
Python's `float` type [1] the routine was unreliable in a region close to the
line. This shortcoming has nothing to do with Python specifically and everything
to do with the finite precision of the `float` number type. This time, we'll
examine the behaviour of the algorithm more systematically using the following
program:

```
def sign(x):
"""Determine the sign of x.
Returns:
-1 if x is negative, +1 if x is positive or 0 if x is zero.
"""
return (x > 0) - (x < 0)
def orientation(p, q, r):
"""Determine the orientation of three points in the plane.
Args:
p, q, r: Two-tuples representing coordinate pairs of three points.
Returns:
-1 if p, q, r is a turn to the right, +1 if p, q, r is a turn to the
left, otherwise 0 if p, q, and r are collinear.
"""
d = (q[0] - p[0]) * (r[1] - p[1]) - (q[1] - p[1]) * (r[0] - p[0])
return sign(d)
def main():
"""
Test whether points immediately above and below the point (0.5, 0.5)
lie above, on, or below the line through (12.0, 12.0) and (24.0, 24.0).
"""
px = 0.5
pys = 0.49999999999999,
0.49999999999999006,
0.4999999999999901,
0.4999999999999902,
0.49999999999999023,
0.4999999999999903,
0.49999999999999034,
0.4999999999999904,
0.49999999999999045,
0.4999999999999905,
0.49999999999999056,
0.4999999999999906,
0.4999999999999907,
0.49999999999999073,
0.4999999999999908,
0.49999999999999084,
0.4999999999999909,
0.49999999999999095,
0.499999999999991,
0.49999999999999106,
0.4999999999999911,
0.4999999999999912,
0.49999999999999123,
0.4999999999999913,
0.49999999999999134,
0.4999999999999914,
0.49999999999999145,
0.4999999999999915,
0.49999999999999156,
0.4999999999999916,
0.4999999999999917,
0.49999999999999173,
0.4999999999999918,
0.49999999999999184,
0.4999999999999919,
0.49999999999999195,
0.499999999999992,
0.49999999999999206,
0.4999999999999921,
0.4999999999999922,
0.49999999999999223,
0.4999999999999923,
0.49999999999999234,
0.4999999999999924,
0.49999999999999245,
0.4999999999999925,
0.49999999999999256,
0.4999999999999926,
0.4999999999999927,
0.49999999999999273,
0.4999999999999928,
0.49999999999999284,
0.4999999999999929,
0.49999999999999295,
0.499999999999993,
0.49999999999999306,
0.4999999999999931,
0.49999999999999317,
0.4999999999999932,
0.4999999999999933,
0.49999999999999334,
0.4999999999999934,
0.49999999999999345,
0.4999999999999935,
0.49999999999999356,
0.4999999999999936,
0.49999999999999367,
0.4999999999999937,
0.4999999999999938,
0.49999999999999384,
0.4999999999999939,
0.49999999999999395,
0.499999999999994,
0.49999999999999406,
0.4999999999999941,
0.49999999999999417,
0.4999999999999942,
0.4999999999999943,
0.49999999999999434,
0.4999999999999944,
0.49999999999999445,
0.4999999999999945,
0.49999999999999456,
0.4999999999999946,
0.49999999999999467,
0.4999999999999947,
0.4999999999999948,
0.49999999999999484,
0.4999999999999949,
0.49999999999999495,
0.499999999999995,
0.49999999999999506,
0.4999999999999951,
0.49999999999999517,
0.4999999999999952,
0.4999999999999953,
0.49999999999999534,
0.4999999999999954,
0.49999999999999545,
0.4999999999999955,
0.49999999999999556,
0.4999999999999956,
0.49999999999999567,
0.4999999999999957,
0.4999999999999958,
0.49999999999999584,
0.4999999999999959,
0.49999999999999595,
0.499999999999996,
0.49999999999999606,
0.4999999999999961,
0.49999999999999617,
0.4999999999999962,
0.4999999999999963,
0.49999999999999634,
0.4999999999999964,
0.49999999999999645,
0.4999999999999965,
0.49999999999999656,
0.4999999999999966,
0.49999999999999667,
0.4999999999999967,
0.4999999999999968,
0.49999999999999684,
0.4999999999999969,
0.49999999999999695,
0.499999999999997,
0.49999999999999706,
0.4999999999999971,
0.49999999999999717,
0.4999999999999972,
0.4999999999999973,
0.49999999999999734,
0.4999999999999974,
0.49999999999999745,
0.4999999999999975,
0.49999999999999756,
0.4999999999999976,
0.49999999999999767,
0.4999999999999977,
0.4999999999999978,
0.49999999999999784,
0.4999999999999979,
0.49999999999999795,
0.499999999999998,
0.49999999999999806,
0.4999999999999981,
0.49999999999999817,
0.4999999999999982,
0.4999999999999983,
0.49999999999999833,
0.4999999999999984,
0.49999999999999845,
0.4999999999999985,
0.49999999999999856,
0.4999999999999986,
0.49999999999999867,
0.4999999999999987,
0.4999999999999988,
0.49999999999999883,
0.4999999999999989,
0.49999999999999895,
0.499999999999999,
0.49999999999999906,
0.4999999999999991,
0.49999999999999917,
0.4999999999999992,
0.4999999999999993,
0.49999999999999933,
0.4999999999999994,
0.49999999999999944,
0.4999999999999995,
0.49999999999999956,
0.4999999999999996,
0.49999999999999967,
0.4999999999999997,
0.4999999999999998,
0.49999999999999983,
0.4999999999999999,
0.49999999999999994, # The previous representable float < 0.5
0.5,
0.5000000000000001, # The next representable float > 0.5
0.5000000000000002,
0.5000000000000003,
0.5000000000000004,
0.5000000000000006,
0.5000000000000007,
0.5000000000000008,
0.5000000000000009,
0.500000000000001,
0.5000000000000011,
0.5000000000000012,
0.5000000000000013,
0.5000000000000014,
0.5000000000000016,
0.5000000000000017,
0.5000000000000018,
0.5000000000000019,
0.500000000000002,
0.5000000000000021,
0.5000000000000022,
0.5000000000000023,
0.5000000000000024,
0.5000000000000026,
0.5000000000000027,
0.5000000000000028,
0.5000000000000029,
0.500000000000003,
0.5000000000000031,
0.5000000000000032,
0.5000000000000033,
0.5000000000000034,
0.5000000000000036,
0.5000000000000037,
0.5000000000000038,
0.5000000000000039,
0.500000000000004,
0.5000000000000041,
0.5000000000000042,
0.5000000000000043,
0.5000000000000044,
0.5000000000000046,
0.5000000000000047,
0.5000000000000048,
0.5000000000000049,
0.500000000000005,
0.5000000000000051,
0.5000000000000052,
0.5000000000000053,
0.5000000000000054,
0.5000000000000056,
0.5000000000000057,
0.5000000000000058,
0.5000000000000059,
0.500000000000006,
0.5000000000000061,
0.5000000000000062,
0.5000000000000063,
0.5000000000000064,
0.5000000000000066,
0.5000000000000067,
0.5000000000000068,
0.5000000000000069,
0.500000000000007,
0.5000000000000071,
0.5000000000000072,
0.5000000000000073,
0.5000000000000074,
0.5000000000000075,
0.5000000000000077,
0.5000000000000078,
0.5000000000000079,
0.500000000000008,
0.5000000000000081,
0.5000000000000082,
0.5000000000000083,
0.5000000000000084,
0.5000000000000085,
0.5000000000000087,
0.5000000000000088,
0.5000000000000089,
0.500000000000009,
0.5000000000000091,
0.5000000000000092,
0.5000000000000093,
0.5000000000000094,
0.5000000000000095,
0.5000000000000097,
0.5000000000000098,
0.5000000000000099,
0.50000000000001]
q = (12.0, 12.0)
r = (24.0, 24.0)
for py in pys:
p = (px, py)
o = orientation(p, q, r)
print("orientation(({p[0]:>3}, {p[1]:<19}) q, r) -> {o:>2}".format(
p=p, o=o))
if __name__ == '__main__':
main()
```

The program includes definitions of our `sign()` and `orientation()`
functions, together with a `main()` function which runs the test. The
main function includes a list of the 271 nearest representable
\(y\)-coordinate values to 0.5. We haven't included the code
to generate these values successive float values because it's somewhat
besides the point; we're referenced the necessary technique in the
previous article.

The program iterates over these `py` values and performs the
orientation test each time, printing the result. The complex format
string is used to get readable output which lines up in columns. When we
look at that output we see an intricate pattern of results emerge, which
isn't even symmetrical around the central 0.5 value:

orientation((0.5, 0.50000000000001 ) q, r) -> 1 orientation((0.5, 0.5000000000000099 ) q, r) -> 1 orientation((0.5, 0.5000000000000098 ) q, r) -> 1 orientation((0.5, 0.5000000000000097 ) q, r) -> 1 orientation((0.5, 0.5000000000000095 ) q, r) -> 1 orientation((0.5, 0.5000000000000094 ) q, r) -> 1 orientation((0.5, 0.5000000000000093 ) q, r) -> 1 orientation((0.5, 0.5000000000000092 ) q, r) -> 1 orientation((0.5, 0.5000000000000091 ) q, r) -> 1 orientation((0.5, 0.500000000000009 ) q, r) -> 1 orientation((0.5, 0.5000000000000089 ) q, r) -> 1 orientation((0.5, 0.5000000000000088 ) q, r) -> 1 orientation((0.5, 0.5000000000000087 ) q, r) -> 1 orientation((0.5, 0.5000000000000085 ) q, r) -> 1 orientation((0.5, 0.5000000000000084 ) q, r) -> 1 orientation((0.5, 0.5000000000000083 ) q, r) -> 1 orientation((0.5, 0.5000000000000082 ) q, r) -> 1 orientation((0.5, 0.5000000000000081 ) q, r) -> 1 orientation((0.5, 0.500000000000008 ) q, r) -> 1 orientation((0.5, 0.5000000000000079 ) q, r) -> 1 orientation((0.5, 0.5000000000000078 ) q, r) -> 1 orientation((0.5, 0.5000000000000077 ) q, r) -> 1 orientation((0.5, 0.5000000000000075 ) q, r) -> 1 orientation((0.5, 0.5000000000000074 ) q, r) -> 1 orientation((0.5, 0.5000000000000073 ) q, r) -> 1 orientation((0.5, 0.5000000000000072 ) q, r) -> 1 orientation((0.5, 0.5000000000000071 ) q, r) -> 1 orientation((0.5, 0.500000000000007 ) q, r) -> 1 orientation((0.5, 0.5000000000000069 ) q, r) -> 1 orientation((0.5, 0.5000000000000068 ) q, r) -> 1 orientation((0.5, 0.5000000000000067 ) q, r) -> 1 orientation((0.5, 0.5000000000000066 ) q, r) -> 1 orientation((0.5, 0.5000000000000064 ) q, r) -> 1 orientation((0.5, 0.5000000000000063 ) q, r) -> 1 orientation((0.5, 0.5000000000000062 ) q, r) -> 1 orientation((0.5, 0.5000000000000061 ) q, r) -> 1 orientation((0.5, 0.500000000000006 ) q, r) -> 1 orientation((0.5, 0.5000000000000059 ) q, r) -> 1 orientation((0.5, 0.5000000000000058 ) q, r) -> 1 orientation((0.5, 0.5000000000000057 ) q, r) -> 1 orientation((0.5, 0.5000000000000056 ) q, r) -> 1 orientation((0.5, 0.5000000000000054 ) q, r) -> 1 orientation((0.5, 0.5000000000000053 ) q, r) -> 1 orientation((0.5, 0.5000000000000052 ) q, r) -> 1 orientation((0.5, 0.5000000000000051 ) q, r) -> 1 orientation((0.5, 0.500000000000005 ) q, r) -> 1 orientation((0.5, 0.5000000000000049 ) q, r) -> 1 orientation((0.5, 0.5000000000000048 ) q, r) -> 1 orientation((0.5, 0.5000000000000047 ) q, r) -> 1 orientation((0.5, 0.5000000000000046 ) q, r) -> 1 orientation((0.5, 0.5000000000000044 ) q, r) -> 0 orientation((0.5, 0.5000000000000043 ) q, r) -> 0 orientation((0.5, 0.5000000000000042 ) q, r) -> 0 orientation((0.5, 0.5000000000000041 ) q, r) -> 0 orientation((0.5, 0.500000000000004 ) q, r) -> 0 orientation((0.5, 0.5000000000000039 ) q, r) -> 0 orientation((0.5, 0.5000000000000038 ) q, r) -> 0 orientation((0.5, 0.5000000000000037 ) q, r) -> 0 orientation((0.5, 0.5000000000000036 ) q, r) -> 0 orientation((0.5, 0.5000000000000034 ) q, r) -> 0 orientation((0.5, 0.5000000000000033 ) q, r) -> 0 orientation((0.5, 0.5000000000000032 ) q, r) -> 0 orientation((0.5, 0.5000000000000031 ) q, r) -> 0 orientation((0.5, 0.500000000000003 ) q, r) -> 0 orientation((0.5, 0.5000000000000029 ) q, r) -> 0 orientation((0.5, 0.5000000000000028 ) q, r) -> 0 orientation((0.5, 0.5000000000000027 ) q, r) -> 0 orientation((0.5, 0.5000000000000026 ) q, r) -> 0 orientation((0.5, 0.5000000000000024 ) q, r) -> 0 orientation((0.5, 0.5000000000000023 ) q, r) -> 0 orientation((0.5, 0.5000000000000022 ) q, r) -> 0 orientation((0.5, 0.5000000000000021 ) q, r) -> 0 orientation((0.5, 0.500000000000002 ) q, r) -> 0 orientation((0.5, 0.5000000000000019 ) q, r) -> 0 orientation((0.5, 0.5000000000000018 ) q, r) -> 1 orientation((0.5, 0.5000000000000017 ) q, r) -> 1 orientation((0.5, 0.5000000000000016 ) q, r) -> 1 orientation((0.5, 0.5000000000000014 ) q, r) -> 1 orientation((0.5, 0.5000000000000013 ) q, r) -> 1 orientation((0.5, 0.5000000000000012 ) q, r) -> 1 orientation((0.5, 0.5000000000000011 ) q, r) -> 1 orientation((0.5, 0.500000000000001 ) q, r) -> 1 orientation((0.5, 0.5000000000000009 ) q, r) -> 0 orientation((0.5, 0.5000000000000008 ) q, r) -> 0 orientation((0.5, 0.5000000000000007 ) q, r) -> 0 orientation((0.5, 0.5000000000000006 ) q, r) -> 0 orientation((0.5, 0.5000000000000004 ) q, r) -> 0 orientation((0.5, 0.5000000000000003 ) q, r) -> 0 orientation((0.5, 0.5000000000000002 ) q, r) -> 0 orientation((0.5, 0.5000000000000001 ) q, r) -> 0 orientation((0.5, 0.5 ) q, r) -> 0 orientation((0.5, 0.49999999999999994) q, r) -> 0 orientation((0.5, 0.4999999999999999 ) q, r) -> 0 orientation((0.5, 0.49999999999999983) q, r) -> 0 orientation((0.5, 0.4999999999999998 ) q, r) -> 0 orientation((0.5, 0.4999999999999997 ) q, r) -> 0 orientation((0.5, 0.49999999999999967) q, r) -> 0 orientation((0.5, 0.4999999999999996 ) q, r) -> 0 orientation((0.5, 0.49999999999999956) q, r) -> 0 orientation((0.5, 0.4999999999999995 ) q, r) -> 0 orientation((0.5, 0.49999999999999944) q, r) -> 0 orientation((0.5, 0.4999999999999994 ) q, r) -> 0 orientation((0.5, 0.49999999999999933) q, r) -> 0 orientation((0.5, 0.4999999999999993 ) q, r) -> 0 orientation((0.5, 0.4999999999999992 ) q, r) -> 0 orientation((0.5, 0.49999999999999917) q, r) -> 0 orientation((0.5, 0.4999999999999991 ) q, r) -> 0 orientation((0.5, 0.49999999999999906) q, r) -> -1 orientation((0.5, 0.499999999999999 ) q, r) -> -1 orientation((0.5, 0.49999999999999895) q, r) -> -1 orientation((0.5, 0.4999999999999989 ) q, r) -> -1 orientation((0.5, 0.49999999999999883) q, r) -> -1 orientation((0.5, 0.4999999999999988 ) q, r) -> -1 orientation((0.5, 0.4999999999999987 ) q, r) -> -1 orientation((0.5, 0.49999999999999867) q, r) -> -1 orientation((0.5, 0.4999999999999986 ) q, r) -> -1 orientation((0.5, 0.49999999999999856) q, r) -> -1 orientation((0.5, 0.4999999999999985 ) q, r) -> -1 orientation((0.5, 0.49999999999999845) q, r) -> -1 orientation((0.5, 0.4999999999999984 ) q, r) -> -1 orientation((0.5, 0.49999999999999833) q, r) -> -1 orientation((0.5, 0.4999999999999983 ) q, r) -> -1 orientation((0.5, 0.4999999999999982 ) q, r) -> -1 orientation((0.5, 0.49999999999999817) q, r) -> 0 orientation((0.5, 0.4999999999999981 ) q, r) -> 0 orientation((0.5, 0.49999999999999806) q, r) -> 0 orientation((0.5, 0.499999999999998 ) q, r) -> 0 orientation((0.5, 0.49999999999999795) q, r) -> 0 orientation((0.5, 0.4999999999999979 ) q, r) -> 0 orientation((0.5, 0.49999999999999784) q, r) -> 0 orientation((0.5, 0.4999999999999978 ) q, r) -> 0 orientation((0.5, 0.4999999999999977 ) q, r) -> 0 orientation((0.5, 0.49999999999999767) q, r) -> 0 orientation((0.5, 0.4999999999999976 ) q, r) -> 0 orientation((0.5, 0.49999999999999756) q, r) -> 0 orientation((0.5, 0.4999999999999975 ) q, r) -> 0 orientation((0.5, 0.49999999999999745) q, r) -> 0 orientation((0.5, 0.4999999999999974 ) q, r) -> 0 orientation((0.5, 0.49999999999999734) q, r) -> 0 orientation((0.5, 0.4999999999999973 ) q, r) -> 0 orientation((0.5, 0.4999999999999972 ) q, r) -> 0 orientation((0.5, 0.49999999999999717) q, r) -> 0 orientation((0.5, 0.4999999999999971 ) q, r) -> 0 orientation((0.5, 0.49999999999999706) q, r) -> 0 orientation((0.5, 0.499999999999997 ) q, r) -> 0 orientation((0.5, 0.49999999999999695) q, r) -> 0 orientation((0.5, 0.4999999999999969 ) q, r) -> 0 orientation((0.5, 0.49999999999999684) q, r) -> 0 orientation((0.5, 0.4999999999999968 ) q, r) -> 0 orientation((0.5, 0.4999999999999967 ) q, r) -> 0 orientation((0.5, 0.49999999999999667) q, r) -> 0 orientation((0.5, 0.4999999999999966 ) q, r) -> 0 orientation((0.5, 0.49999999999999656) q, r) -> 0 orientation((0.5, 0.4999999999999965 ) q, r) -> 0 orientation((0.5, 0.49999999999999645) q, r) -> 0 orientation((0.5, 0.4999999999999964 ) q, r) -> 0 orientation((0.5, 0.49999999999999634) q, r) -> 0 orientation((0.5, 0.4999999999999963 ) q, r) -> 0 orientation((0.5, 0.4999999999999962 ) q, r) -> 0 orientation((0.5, 0.49999999999999617) q, r) -> 0 orientation((0.5, 0.4999999999999961 ) q, r) -> 0 orientation((0.5, 0.49999999999999606) q, r) -> 0 orientation((0.5, 0.499999999999996 ) q, r) -> 0 orientation((0.5, 0.49999999999999595) q, r) -> 0 orientation((0.5, 0.4999999999999959 ) q, r) -> 0 orientation((0.5, 0.49999999999999584) q, r) -> 0 orientation((0.5, 0.4999999999999958 ) q, r) -> 0 orientation((0.5, 0.4999999999999957 ) q, r) -> 0 orientation((0.5, 0.49999999999999567) q, r) -> 0 orientation((0.5, 0.4999999999999956 ) q, r) -> 0 orientation((0.5, 0.49999999999999556) q, r) -> 0 orientation((0.5, 0.4999999999999955 ) q, r) -> -1 orientation((0.5, 0.49999999999999545) q, r) -> -1 orientation((0.5, 0.4999999999999954 ) q, r) -> -1 orientation((0.5, 0.49999999999999534) q, r) -> -1 orientation((0.5, 0.4999999999999953 ) q, r) -> -1 orientation((0.5, 0.4999999999999952 ) q, r) -> -1 orientation((0.5, 0.49999999999999517) q, r) -> -1 orientation((0.5, 0.4999999999999951 ) q, r) -> -1 orientation((0.5, 0.49999999999999506) q, r) -> -1 orientation((0.5, 0.499999999999995 ) q, r) -> -1 orientation((0.5, 0.49999999999999495) q, r) -> -1 orientation((0.5, 0.4999999999999949 ) q, r) -> -1 orientation((0.5, 0.49999999999999484) q, r) -> -1 orientation((0.5, 0.4999999999999948 ) q, r) -> -1 orientation((0.5, 0.4999999999999947 ) q, r) -> -1 orientation((0.5, 0.49999999999999467) q, r) -> -1 orientation((0.5, 0.4999999999999946 ) q, r) -> -1 orientation((0.5, 0.49999999999999456) q, r) -> -1 orientation((0.5, 0.4999999999999945 ) q, r) -> -1 orientation((0.5, 0.49999999999999445) q, r) -> -1 orientation((0.5, 0.4999999999999944 ) q, r) -> -1 orientation((0.5, 0.49999999999999434) q, r) -> -1 orientation((0.5, 0.4999999999999943 ) q, r) -> -1 orientation((0.5, 0.4999999999999942 ) q, r) -> -1 orientation((0.5, 0.49999999999999417) q, r) -> -1 orientation((0.5, 0.4999999999999941 ) q, r) -> -1 orientation((0.5, 0.49999999999999406) q, r) -> -1 orientation((0.5, 0.499999999999994 ) q, r) -> -1 orientation((0.5, 0.49999999999999395) q, r) -> -1 orientation((0.5, 0.4999999999999939 ) q, r) -> -1 orientation((0.5, 0.49999999999999384) q, r) -> -1 orientation((0.5, 0.4999999999999938 ) q, r) -> -1 orientation((0.5, 0.4999999999999937 ) q, r) -> -1 orientation((0.5, 0.49999999999999367) q, r) -> -1 orientation((0.5, 0.4999999999999936 ) q, r) -> -1 orientation((0.5, 0.49999999999999356) q, r) -> -1 orientation((0.5, 0.4999999999999935 ) q, r) -> -1 orientation((0.5, 0.49999999999999345) q, r) -> -1 orientation((0.5, 0.4999999999999934 ) q, r) -> -1 orientation((0.5, 0.49999999999999334) q, r) -> -1 orientation((0.5, 0.4999999999999933 ) q, r) -> -1 orientation((0.5, 0.4999999999999932 ) q, r) -> -1 orientation((0.5, 0.49999999999999317) q, r) -> -1 orientation((0.5, 0.4999999999999931 ) q, r) -> -1 orientation((0.5, 0.49999999999999306) q, r) -> -1 orientation((0.5, 0.499999999999993 ) q, r) -> -1 orientation((0.5, 0.49999999999999295) q, r) -> -1 orientation((0.5, 0.4999999999999929 ) q, r) -> -1 orientation((0.5, 0.49999999999999284) q, r) -> -1 orientation((0.5, 0.4999999999999928 ) q, r) -> -1 orientation((0.5, 0.49999999999999273) q, r) -> -1 orientation((0.5, 0.4999999999999927 ) q, r) -> -1 orientation((0.5, 0.4999999999999926 ) q, r) -> -1 orientation((0.5, 0.49999999999999256) q, r) -> -1 orientation((0.5, 0.4999999999999925 ) q, r) -> -1 orientation((0.5, 0.49999999999999245) q, r) -> -1 orientation((0.5, 0.4999999999999924 ) q, r) -> -1 orientation((0.5, 0.49999999999999234) q, r) -> -1 orientation((0.5, 0.4999999999999923 ) q, r) -> -1 orientation((0.5, 0.49999999999999223) q, r) -> -1 orientation((0.5, 0.4999999999999922 ) q, r) -> -1 orientation((0.5, 0.4999999999999921 ) q, r) -> -1 orientation((0.5, 0.49999999999999206) q, r) -> -1 orientation((0.5, 0.499999999999992 ) q, r) -> -1 orientation((0.5, 0.49999999999999195) q, r) -> -1 orientation((0.5, 0.4999999999999919 ) q, r) -> -1 orientation((0.5, 0.49999999999999184) q, r) -> -1 orientation((0.5, 0.4999999999999918 ) q, r) -> -1 orientation((0.5, 0.49999999999999173) q, r) -> -1 orientation((0.5, 0.4999999999999917 ) q, r) -> -1 orientation((0.5, 0.4999999999999916 ) q, r) -> -1 orientation((0.5, 0.49999999999999156) q, r) -> -1 orientation((0.5, 0.4999999999999915 ) q, r) -> -1 orientation((0.5, 0.49999999999999145) q, r) -> -1 orientation((0.5, 0.4999999999999914 ) q, r) -> -1 orientation((0.5, 0.49999999999999134) q, r) -> -1 orientation((0.5, 0.4999999999999913 ) q, r) -> -1 orientation((0.5, 0.49999999999999123) q, r) -> -1 orientation((0.5, 0.4999999999999912 ) q, r) -> -1 orientation((0.5, 0.4999999999999911 ) q, r) -> -1 orientation((0.5, 0.49999999999999106) q, r) -> -1 orientation((0.5, 0.499999999999991 ) q, r) -> -1 orientation((0.5, 0.49999999999999095) q, r) -> -1 orientation((0.5, 0.4999999999999909 ) q, r) -> -1 orientation((0.5, 0.49999999999999084) q, r) -> -1 orientation((0.5, 0.4999999999999908 ) q, r) -> -1 orientation((0.5, 0.49999999999999073) q, r) -> -1 orientation((0.5, 0.4999999999999907 ) q, r) -> -1 orientation((0.5, 0.4999999999999906 ) q, r) -> -1 orientation((0.5, 0.49999999999999056) q, r) -> -1 orientation((0.5, 0.4999999999999905 ) q, r) -> -1 orientation((0.5, 0.49999999999999045) q, r) -> -1 orientation((0.5, 0.4999999999999904 ) q, r) -> -1 orientation((0.5, 0.49999999999999034) q, r) -> -1 orientation((0.5, 0.4999999999999903 ) q, r) -> -1 orientation((0.5, 0.49999999999999023) q, r) -> -1 orientation((0.5, 0.4999999999999902 ) q, r) -> -1 orientation((0.5, 0.4999999999999901 ) q, r) -> -1 orientation((0.5, 0.49999999999999006) q, r) -> -1 orientation((0.5, 0.49999999999999 ) q, r) -> -1

The colour coding (added later) represents whether the algorithm reckons
the points are above the line (in blue), on the line (in yellow) or
below the line (in red). The only point which is *actually* on the line
is in green.

By this point you should at least be wary of using floating point arithmetic for geometric computation. Lest you think this can easily be solved by introducing a tolerance value, or some other clunky solution, we'll save you the bother by pointing out that doing do merely moves these fringing effects to the edge of the tolerance zone.

What to do? Fortunately, as we alluded to at the beginning of this tale,
Python gives us a solution into the form of the rational numbers,
implemented as the `Fraction` type.

Let's make a small change to our program, converting all numbers to
`Fraction`s before proceeding with the computation. We'll do this by
modifying the `orientation()` to convert each of its three arguments
from a tuple containing a pair of numeric objects into a pair of
`Fraction`s. The `Fraction` constructor accepts a selection of
numeric types, including `float`:

```
def orientation(p, q, r):
"""Determine the orientation of three points in the plane.
Args:
p, q, r: Two-tuples representing coordinate pairs of three points.
Returns:
-1 if p, q, r is a turn to the right, +1 if p, q, r is a turn to the
left, otherwise 0 if p, q, and r are collinear.
"""
p = (Fraction(p[0]), Fraction(p[1]))
q = (Fraction(q[0]), Fraction(q[1]))
r = (Fraction(r[0]), Fraction(r[1]))
d = (q[0] - p[0]) * (r[1] - p[1]) - (q[1] - p[1]) * (r[0] - p[0])
return sign(d)
```

The variable `d` will now also be a `Fraction` and the `sign()`
function will work as expected with this type since it only uses
comparison to zero.

Let's run our modified example:

orientation((0.5, 0.49999999999999 ) q, r) -> -1 orientation((0.5, 0.49999999999999006) q, r) -> -1 orientation((0.5, 0.4999999999999901 ) q, r) -> -1 orientation((0.5, 0.4999999999999902 ) q, r) -> -1 orientation((0.5, 0.49999999999999023) q, r) -> -1 orientation((0.5, 0.4999999999999903 ) q, r) -> -1 orientation((0.5, 0.49999999999999034) q, r) -> -1 orientation((0.5, 0.4999999999999904 ) q, r) -> -1 orientation((0.5, 0.49999999999999045) q, r) -> -1 orientation((0.5, 0.4999999999999905 ) q, r) -> -1 orientation((0.5, 0.49999999999999056) q, r) -> -1 orientation((0.5, 0.4999999999999906 ) q, r) -> -1 orientation((0.5, 0.4999999999999907 ) q, r) -> -1 orientation((0.5, 0.49999999999999073) q, r) -> -1 orientation((0.5, 0.4999999999999908 ) q, r) -> -1 orientation((0.5, 0.49999999999999084) q, r) -> -1 orientation((0.5, 0.4999999999999909 ) q, r) -> -1 orientation((0.5, 0.49999999999999095) q, r) -> -1 orientation((0.5, 0.499999999999991 ) q, r) -> -1 orientation((0.5, 0.49999999999999106) q, r) -> -1 orientation((0.5, 0.4999999999999911 ) q, r) -> -1 orientation((0.5, 0.4999999999999912 ) q, r) -> -1 orientation((0.5, 0.49999999999999123) q, r) -> -1 orientation((0.5, 0.4999999999999913 ) q, r) -> -1 orientation((0.5, 0.49999999999999134) q, r) -> -1 orientation((0.5, 0.4999999999999914 ) q, r) -> -1 orientation((0.5, 0.49999999999999145) q, r) -> -1 orientation((0.5, 0.4999999999999915 ) q, r) -> -1 orientation((0.5, 0.49999999999999156) q, r) -> -1 orientation((0.5, 0.4999999999999916 ) q, r) -> -1 orientation((0.5, 0.4999999999999917 ) q, r) -> -1 orientation((0.5, 0.49999999999999173) q, r) -> -1 orientation((0.5, 0.4999999999999918 ) q, r) -> -1 orientation((0.5, 0.49999999999999184) q, r) -> -1 orientation((0.5, 0.4999999999999919 ) q, r) -> -1 orientation((0.5, 0.49999999999999195) q, r) -> -1 orientation((0.5, 0.499999999999992 ) q, r) -> -1 orientation((0.5, 0.49999999999999206) q, r) -> -1 orientation((0.5, 0.4999999999999921 ) q, r) -> -1 orientation((0.5, 0.4999999999999922 ) q, r) -> -1 orientation((0.5, 0.49999999999999223) q, r) -> -1 orientation((0.5, 0.4999999999999923 ) q, r) -> -1 orientation((0.5, 0.49999999999999234) q, r) -> -1 orientation((0.5, 0.4999999999999924 ) q, r) -> -1 orientation((0.5, 0.49999999999999245) q, r) -> -1 orientation((0.5, 0.4999999999999925 ) q, r) -> -1 orientation((0.5, 0.49999999999999256) q, r) -> -1 orientation((0.5, 0.4999999999999926 ) q, r) -> -1 orientation((0.5, 0.4999999999999927 ) q, r) -> -1 orientation((0.5, 0.49999999999999273) q, r) -> -1 orientation((0.5, 0.4999999999999928 ) q, r) -> -1 orientation((0.5, 0.49999999999999284) q, r) -> -1 orientation((0.5, 0.4999999999999929 ) q, r) -> -1 orientation((0.5, 0.49999999999999295) q, r) -> -1 orientation((0.5, 0.499999999999993 ) q, r) -> -1 orientation((0.5, 0.49999999999999306) q, r) -> -1 orientation((0.5, 0.4999999999999931 ) q, r) -> -1 orientation((0.5, 0.49999999999999317) q, r) -> -1 orientation((0.5, 0.4999999999999932 ) q, r) -> -1 orientation((0.5, 0.4999999999999933 ) q, r) -> -1 orientation((0.5, 0.49999999999999334) q, r) -> -1 orientation((0.5, 0.4999999999999934 ) q, r) -> -1 orientation((0.5, 0.49999999999999345) q, r) -> -1 orientation((0.5, 0.4999999999999935 ) q, r) -> -1 orientation((0.5, 0.49999999999999356) q, r) -> -1 orientation((0.5, 0.4999999999999936 ) q, r) -> -1 orientation((0.5, 0.49999999999999367) q, r) -> -1 orientation((0.5, 0.4999999999999937 ) q, r) -> -1 orientation((0.5, 0.4999999999999938 ) q, r) -> -1 orientation((0.5, 0.49999999999999384) q, r) -> -1 orientation((0.5, 0.4999999999999939 ) q, r) -> -1 orientation((0.5, 0.49999999999999395) q, r) -> -1 orientation((0.5, 0.499999999999994 ) q, r) -> -1 orientation((0.5, 0.49999999999999406) q, r) -> -1 orientation((0.5, 0.4999999999999941 ) q, r) -> -1 orientation((0.5, 0.49999999999999417) q, r) -> -1 orientation((0.5, 0.4999999999999942 ) q, r) -> -1 orientation((0.5, 0.4999999999999943 ) q, r) -> -1 orientation((0.5, 0.49999999999999434) q, r) -> -1 orientation((0.5, 0.4999999999999944 ) q, r) -> -1 orientation((0.5, 0.49999999999999445) q, r) -> -1 orientation((0.5, 0.4999999999999945 ) q, r) -> -1 orientation((0.5, 0.49999999999999456) q, r) -> -1 orientation((0.5, 0.4999999999999946 ) q, r) -> -1 orientation((0.5, 0.49999999999999467) q, r) -> -1 orientation((0.5, 0.4999999999999947 ) q, r) -> -1 orientation((0.5, 0.4999999999999948 ) q, r) -> -1 orientation((0.5, 0.49999999999999484) q, r) -> -1 orientation((0.5, 0.4999999999999949 ) q, r) -> -1 orientation((0.5, 0.49999999999999495) q, r) -> -1 orientation((0.5, 0.499999999999995 ) q, r) -> -1 orientation((0.5, 0.49999999999999506) q, r) -> -1 orientation((0.5, 0.4999999999999951 ) q, r) -> -1 orientation((0.5, 0.49999999999999517) q, r) -> -1 orientation((0.5, 0.4999999999999952 ) q, r) -> -1 orientation((0.5, 0.4999999999999953 ) q, r) -> -1 orientation((0.5, 0.49999999999999534) q, r) -> -1 orientation((0.5, 0.4999999999999954 ) q, r) -> -1 orientation((0.5, 0.49999999999999545) q, r) -> -1 orientation((0.5, 0.4999999999999955 ) q, r) -> -1 orientation((0.5, 0.49999999999999556) q, r) -> -1 orientation((0.5, 0.4999999999999956 ) q, r) -> -1 orientation((0.5, 0.49999999999999567) q, r) -> -1 orientation((0.5, 0.4999999999999957 ) q, r) -> -1 orientation((0.5, 0.4999999999999958 ) q, r) -> -1 orientation((0.5, 0.49999999999999584) q, r) -> -1 orientation((0.5, 0.4999999999999959 ) q, r) -> -1 orientation((0.5, 0.49999999999999595) q, r) -> -1 orientation((0.5, 0.499999999999996 ) q, r) -> -1 orientation((0.5, 0.49999999999999606) q, r) -> -1 orientation((0.5, 0.4999999999999961 ) q, r) -> -1 orientation((0.5, 0.49999999999999617) q, r) -> -1 orientation((0.5, 0.4999999999999962 ) q, r) -> -1 orientation((0.5, 0.4999999999999963 ) q, r) -> -1 orientation((0.5, 0.49999999999999634) q, r) -> -1 orientation((0.5, 0.4999999999999964 ) q, r) -> -1 orientation((0.5, 0.49999999999999645) q, r) -> -1 orientation((0.5, 0.4999999999999965 ) q, r) -> -1 orientation((0.5, 0.49999999999999656) q, r) -> -1 orientation((0.5, 0.4999999999999966 ) q, r) -> -1 orientation((0.5, 0.49999999999999667) q, r) -> -1 orientation((0.5, 0.4999999999999967 ) q, r) -> -1 orientation((0.5, 0.4999999999999968 ) q, r) -> -1 orientation((0.5, 0.49999999999999684) q, r) -> -1 orientation((0.5, 0.4999999999999969 ) q, r) -> -1 orientation((0.5, 0.49999999999999695) q, r) -> -1 orientation((0.5, 0.499999999999997 ) q, r) -> -1 orientation((0.5, 0.49999999999999706) q, r) -> -1 orientation((0.5, 0.4999999999999971 ) q, r) -> -1 orientation((0.5, 0.49999999999999717) q, r) -> -1 orientation((0.5, 0.4999999999999972 ) q, r) -> -1 orientation((0.5, 0.4999999999999973 ) q, r) -> -1 orientation((0.5, 0.49999999999999734) q, r) -> -1 orientation((0.5, 0.4999999999999974 ) q, r) -> -1 orientation((0.5, 0.49999999999999745) q, r) -> -1 orientation((0.5, 0.4999999999999975 ) q, r) -> -1 orientation((0.5, 0.49999999999999756) q, r) -> -1 orientation((0.5, 0.4999999999999976 ) q, r) -> -1 orientation((0.5, 0.49999999999999767) q, r) -> -1 orientation((0.5, 0.4999999999999977 ) q, r) -> -1 orientation((0.5, 0.4999999999999978 ) q, r) -> -1 orientation((0.5, 0.49999999999999784) q, r) -> -1 orientation((0.5, 0.4999999999999979 ) q, r) -> -1 orientation((0.5, 0.49999999999999795) q, r) -> -1 orientation((0.5, 0.499999999999998 ) q, r) -> -1 orientation((0.5, 0.49999999999999806) q, r) -> -1 orientation((0.5, 0.4999999999999981 ) q, r) -> -1 orientation((0.5, 0.49999999999999817) q, r) -> -1 orientation((0.5, 0.4999999999999982 ) q, r) -> -1 orientation((0.5, 0.4999999999999983 ) q, r) -> -1 orientation((0.5, 0.49999999999999833) q, r) -> -1 orientation((0.5, 0.4999999999999984 ) q, r) -> -1 orientation((0.5, 0.49999999999999845) q, r) -> -1 orientation((0.5, 0.4999999999999985 ) q, r) -> -1 orientation((0.5, 0.49999999999999856) q, r) -> -1 orientation((0.5, 0.4999999999999986 ) q, r) -> -1 orientation((0.5, 0.49999999999999867) q, r) -> -1 orientation((0.5, 0.4999999999999987 ) q, r) -> -1 orientation((0.5, 0.4999999999999988 ) q, r) -> -1 orientation((0.5, 0.49999999999999883) q, r) -> -1 orientation((0.5, 0.4999999999999989 ) q, r) -> -1 orientation((0.5, 0.49999999999999895) q, r) -> -1 orientation((0.5, 0.499999999999999 ) q, r) -> -1 orientation((0.5, 0.49999999999999906) q, r) -> -1 orientation((0.5, 0.4999999999999991 ) q, r) -> -1 orientation((0.5, 0.49999999999999917) q, r) -> -1 orientation((0.5, 0.4999999999999992 ) q, r) -> -1 orientation((0.5, 0.4999999999999993 ) q, r) -> -1 orientation((0.5, 0.49999999999999933) q, r) -> -1 orientation((0.5, 0.4999999999999994 ) q, r) -> -1 orientation((0.5, 0.49999999999999944) q, r) -> -1 orientation((0.5, 0.4999999999999995 ) q, r) -> -1 orientation((0.5, 0.49999999999999956) q, r) -> -1 orientation((0.5, 0.4999999999999996 ) q, r) -> -1 orientation((0.5, 0.49999999999999967) q, r) -> -1 orientation((0.5, 0.4999999999999997 ) q, r) -> -1 orientation((0.5, 0.4999999999999998 ) q, r) -> -1 orientation((0.5, 0.49999999999999983) q, r) -> -1 orientation((0.5, 0.4999999999999999 ) q, r) -> -1 orientation((0.5, 0.49999999999999994) q, r) -> -1 orientation((0.5, 0.5 ) q, r) -> 0 orientation((0.5, 0.5000000000000001 ) q, r) -> 1 orientation((0.5, 0.5000000000000002 ) q, r) -> 1 orientation((0.5, 0.5000000000000003 ) q, r) -> 1 orientation((0.5, 0.5000000000000004 ) q, r) -> 1 orientation((0.5, 0.5000000000000006 ) q, r) -> 1 orientation((0.5, 0.5000000000000007 ) q, r) -> 1 orientation((0.5, 0.5000000000000008 ) q, r) -> 1 orientation((0.5, 0.5000000000000009 ) q, r) -> 1 orientation((0.5, 0.500000000000001 ) q, r) -> 1 orientation((0.5, 0.5000000000000011 ) q, r) -> 1 orientation((0.5, 0.5000000000000012 ) q, r) -> 1 orientation((0.5, 0.5000000000000013 ) q, r) -> 1 orientation((0.5, 0.5000000000000014 ) q, r) -> 1 orientation((0.5, 0.5000000000000016 ) q, r) -> 1 orientation((0.5, 0.5000000000000017 ) q, r) -> 1 orientation((0.5, 0.5000000000000018 ) q, r) -> 1 orientation((0.5, 0.5000000000000019 ) q, r) -> 1 orientation((0.5, 0.500000000000002 ) q, r) -> 1 orientation((0.5, 0.5000000000000021 ) q, r) -> 1 orientation((0.5, 0.5000000000000022 ) q, r) -> 1 orientation((0.5, 0.5000000000000023 ) q, r) -> 1 orientation((0.5, 0.5000000000000024 ) q, r) -> 1 orientation((0.5, 0.5000000000000026 ) q, r) -> 1 orientation((0.5, 0.5000000000000027 ) q, r) -> 1 orientation((0.5, 0.5000000000000028 ) q, r) -> 1 orientation((0.5, 0.5000000000000029 ) q, r) -> 1 orientation((0.5, 0.500000000000003 ) q, r) -> 1 orientation((0.5, 0.5000000000000031 ) q, r) -> 1 orientation((0.5, 0.5000000000000032 ) q, r) -> 1 orientation((0.5, 0.5000000000000033 ) q, r) -> 1 orientation((0.5, 0.5000000000000034 ) q, r) -> 1 orientation((0.5, 0.5000000000000036 ) q, r) -> 1 orientation((0.5, 0.5000000000000037 ) q, r) -> 1 orientation((0.5, 0.5000000000000038 ) q, r) -> 1 orientation((0.5, 0.5000000000000039 ) q, r) -> 1 orientation((0.5, 0.500000000000004 ) q, r) -> 1 orientation((0.5, 0.5000000000000041 ) q, r) -> 1 orientation((0.5, 0.5000000000000042 ) q, r) -> 1 orientation((0.5, 0.5000000000000043 ) q, r) -> 1 orientation((0.5, 0.5000000000000044 ) q, r) -> 1 orientation((0.5, 0.5000000000000046 ) q, r) -> 1 orientation((0.5, 0.5000000000000047 ) q, r) -> 1 orientation((0.5, 0.5000000000000048 ) q, r) -> 1 orientation((0.5, 0.5000000000000049 ) q, r) -> 1 orientation((0.5, 0.500000000000005 ) q, r) -> 1 orientation((0.5, 0.5000000000000051 ) q, r) -> 1 orientation((0.5, 0.5000000000000052 ) q, r) -> 1 orientation((0.5, 0.5000000000000053 ) q, r) -> 1 orientation((0.5, 0.5000000000000054 ) q, r) -> 1 orientation((0.5, 0.5000000000000056 ) q, r) -> 1 orientation((0.5, 0.5000000000000057 ) q, r) -> 1 orientation((0.5, 0.5000000000000058 ) q, r) -> 1 orientation((0.5, 0.5000000000000059 ) q, r) -> 1 orientation((0.5, 0.500000000000006 ) q, r) -> 1 orientation((0.5, 0.5000000000000061 ) q, r) -> 1 orientation((0.5, 0.5000000000000062 ) q, r) -> 1 orientation((0.5, 0.5000000000000063 ) q, r) -> 1 orientation((0.5, 0.5000000000000064 ) q, r) -> 1 orientation((0.5, 0.5000000000000066 ) q, r) -> 1 orientation((0.5, 0.5000000000000067 ) q, r) -> 1 orientation((0.5, 0.5000000000000068 ) q, r) -> 1 orientation((0.5, 0.5000000000000069 ) q, r) -> 1 orientation((0.5, 0.500000000000007 ) q, r) -> 1 orientation((0.5, 0.5000000000000071 ) q, r) -> 1 orientation((0.5, 0.5000000000000072 ) q, r) -> 1 orientation((0.5, 0.5000000000000073 ) q, r) -> 1 orientation((0.5, 0.5000000000000074 ) q, r) -> 1 orientation((0.5, 0.5000000000000075 ) q, r) -> 1 orientation((0.5, 0.5000000000000077 ) q, r) -> 1 orientation((0.5, 0.5000000000000078 ) q, r) -> 1 orientation((0.5, 0.5000000000000079 ) q, r) -> 1 orientation((0.5, 0.500000000000008 ) q, r) -> 1 orientation((0.5, 0.5000000000000081 ) q, r) -> 1 orientation((0.5, 0.5000000000000082 ) q, r) -> 1 orientation((0.5, 0.5000000000000083 ) q, r) -> 1 orientation((0.5, 0.5000000000000084 ) q, r) -> 1 orientation((0.5, 0.5000000000000085 ) q, r) -> 1 orientation((0.5, 0.5000000000000087 ) q, r) -> 1 orientation((0.5, 0.5000000000000088 ) q, r) -> 1 orientation((0.5, 0.5000000000000089 ) q, r) -> 1 orientation((0.5, 0.500000000000009 ) q, r) -> 1 orientation((0.5, 0.5000000000000091 ) q, r) -> 1 orientation((0.5, 0.5000000000000092 ) q, r) -> 1 orientation((0.5, 0.5000000000000093 ) q, r) -> 1 orientation((0.5, 0.5000000000000094 ) q, r) -> 1 orientation((0.5, 0.5000000000000095 ) q, r) -> 1 orientation((0.5, 0.5000000000000097 ) q, r) -> 1 orientation((0.5, 0.5000000000000098 ) q, r) -> 1 orientation((0.5, 0.5000000000000099 ) q, r) -> 1 orientation((0.5, 0.50000000000001 ) q, r) -> 1

Using `Fraction`s internally, our `orientation()` function gets
the full benefit of exact arithmetic with effectively infinite precision
and consequently produces an *exact* result with only one position of
`p` being reported as collinear with `q` and `r`.

In the next article, we'll more fully explore the behaviour of the
*non*-robust `float`-based version of this function based graphically,
to get an impression of how lines are 'seen' by floating-point geometric
functions.

[1] | Python's float is an IEEE-754 double precision 64-bit float. |

Products, the Universe and Everything from Products, the Universe and Everything

Our founder Anna attended the Business of Software Europe Conference in Cambridge last week, and it was quite something indeed.

Although the Business of Software Conference has been running for several years in the USA, this is the first year an event has been held in Europe (and what better a place than Cambridge?). The conference covered everything from live Python telephony to the psychology of the internet and the organisation and management of sales teams, so it was pretty diverse.

If you are interested in more than just coding, this is an event we can strongly recommend. Photos and videos from the conference should be online soon, so if you are interested please stay tuned.

Products, the Universe and Everything from Products, the Universe and Everything

Our founder Anna attended the Business of Software Europe Conference in Cambridge last week, and it was quite something indeed.

Although the Business of Software Conference has been running for several years in the USA, this is the first year an event has been held in Europe (and what better a place than Cambridge?). The conference covered everything from live Python telephony to the psychology of the internet and the organisation and management of sales teams, so it was pretty diverse.

If you are interested in more than just coding, this is an event we can strongly recommend. Photos and videos from the conference should be online soon, so if you are interested please stay tuned.

Products, the Universe and Everything from Products, the Universe and Everything

Our founder Anna attended the Business of Software Europe Conference in Cambridge last week, and it was quite something indeed. Although the Business of Software Conference has been running for several years in the USA, this is the first year an event has been held in Europe (and what better a place than Cambridge?). The conference covered everything from live Python telephony to the psychology of the internet and the organisation and management of sales teams, so it was pretty diverse. If you are interested in more than just coding, this is an event we can strongly recommend. Photos and videos from the conference should be online soon, so if you are interested please stay tuned.Pete Barber from C#, C++, Windows & other ramblings

My Swift and SpriteKit exploration continues. At the moment I'm writing the collision handling code.Rather than derive game objects from SKSpriteNode with each derived class containing the code for handling collisions with the other types of game objects I'm following something akin to a Component-Entity model.

I have per-game-object handler classes of which an instance of each is stored in the actual SKSpriteNode's userData dictionary. In turn each handler instance has a reference to the SKSpriteNode that references it. Given ARC is used this is a classical strong-reference chain which will prevent memory from being freed. The usual solution to this in Objective-C is to have one of the references be weak. In Swift there are two types of weak references: weak which is the same as in Objective-C and unowned (which I think is new). The difference is that an unowned reference can never be

The following code shows how I was intending to implement this. There is the strong reference from node.UserData to PhysicsActions and then the unowned reference back again from PhysicsActions.

class PhysicsActions

{

unowned let node : SKSpriteNode

init(associatedNode : SKSpriteNode)

{

// Store really weak (unowned) reference

self.node = associatedNode

}

func onContact(other : PhysicsActions)

{

// Do stuff with node

}

}

class func makeNode(imageNamed name: String) -> SKSpriteNode

{

let node = SKSpriteNode(imageNamed: name)

node.userData = NSMutableDictionary()

// Store strong reference

node.userData["action"] = makeActionFn(node)

return node

}

However, when I went to use this code it crashed within the onContact method when it attempted to use the node. Changing this the reference type from unowned to weak fixed this, e.g.

weak let node : SKSpriteNode?

This verified that the rest of the code was ok so this seemed to look like another Swift/Objective-C interoperability issue. Firstly, I made a pure Swift example which is a simplified version from the The Swift Programming Language book.

class Foo

{

var bar : Bar?

func addBar(bar: Bar)

{

self.bar = bar

}

}

class Bar

{

unowned let foo : Foo

init(foo : Foo)

{

self.foo = foo

}

func f()

{

println("foo:\(foo)")

}

}

var foo : Foo? = Foo()

var bar = Bar(foo: foo!)

foo!.Ã§(bar)

bar.f()

Which works and results in:

Ok, not a fundamental problem but let's try having an unowned reference to an Objective-C class which is just like the real case as that's what SKSpriteNode is.

@interface Foo2 : NSObject

@end

@implementation Foo2

-(id)init

{

return [super init];

}

@end

class Bar2

{

unowned let foo2 : Foo2

init(foo2 : Foo2)

{

self.foo2 = foo2

}

func f()

{

println("foo2:\(foo2)")

}

}

var foo2 = Foo2()

var bar2 = Bar2(foo2: foo2)

bar2.f()

Which when foo2.f() is invoked results in:

libswift_stdlib_core.dylib`_swift_abortRetainUnowned:

0x100142420: pushq %rbp

0x100142421: movq %rsp, %rbp

0x100142424: leaq 0x17597(%rip), %rax ; "attempted to retain deallocated object"

0x10014242b: movq %rax, 0x348be(%rip) ; gCRAnnotations + 8

0x100142432: int3

0x100142433: nopw %cs:(%rax,%rax)

Again, changing unowned let foo2 : Foo2 to weak var foo2 : Foo2? works.

I can't explain what the actual problem is but it looks like the enhanced weak reference support (unowned) only works with pure Swift classes. If you have cyclic references to Objective-C classes from Swift then don't use unowned. In fact writing the previous sentence led me to try the following:

let orig = Foo2()

unowned let other = orig

println("other:\(other)")

println("orig:\(orig)")

No cyclic references, just an ordinary reference counted instance of Foo2 (the Objective-C class) which is then assigned to an unowned reference. The final call to println will keep the instance around until the end. This crashes as per the previous example when the other variable is accessed. Changing the type assigned to orig from Foo2 (Objective-C) to Foo (Swift) make it work.

Therefore it seems unowned should not be used to refer to Objective-C classes, just Swift classes.

Pete Barber from C#, C++, Windows & other ramblings

In the Swift documentation for SKNode the userData member (a dictionary) is defined as follows:userData

A dictionary containing arbitrary data.

SWIFT

var userData: NSMutableDictionary!

OBJECTIVE-C

However, in Objective-C the userData member is initially nil. Given that this is the same class then it should also be in Swift and using it, e.g.

let node = SKSpriteNode(imageNamed: name)

node.userData["action"] = Action() // custom class

causes a crash:

This is because the it is in fact nil despite the '!' following the Swift definition. This must be a documentation bug. The correct code is:

let node = SKSpriteNode(imageNamed: name)

node.userData["action"] = Action() // custom class

Using jenkinsapi it is easy to rename some jobs:

`from jenkinsapi.jenkins import Jenkins`

J = Jenkins('http://localhost:8080')

for j in J.keys():

if (j.startswith('bad-prefix')):

n = j.replace('bad-prefix', 'good-prefix')

J.rename_job(j, n)