Skip to content

Commit 7b921b0

Browse files
committed
Production ready: eliminate print statements.
1 parent ac38e5e commit 7b921b0

File tree

13 files changed

+99
-59
lines changed

13 files changed

+99
-59
lines changed

CHANGELOG

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
This is a hand generated changelog for versions, not very accurate.
3+
Use >git log for every commit.
4+
5+
6+
Version 0.0.2
7+
=============
8+
9+
SegmentString, Segment, ControlPoint classes.
10+
Explicitly model the abstractions of a SegmentString.
11+
This more cleanly separates freehandTool from what it produces.
12+
Demonstrates editing a SegmentString by manipulation of its ControlPoints.
13+
(Although editing is not graphical, just crude demo via keystrokes.)
14+
15+
16+
Version 0.0.3
17+
=============
18+
19+
- Relations between ControlPoints defines actions (behavior of user manipulations.)
20+
- Cusps known by SegmentString
21+
- Actions defined as a Strategy/Policy
22+
- An API that can be cleanly hooked to a GUI editor.
23+
24+
Version 0.1
25+
===========
26+
27+
A production version?
28+
29+
Add exception for generated null segments, catch the exception internally, and handle it gracefully.
30+
I don't expect the algorithm to generate null segments, but if it does they are handled.
31+
32+
Improve ghosting of the head of the generated curve: path instead of straight line.
33+
34+
Clarify use of input, view (int pixel) coords and internal, scene (float) coords.
35+
Eliminate rounding errors by not converting in the back direction.
36+
37+
Reraise StopIteration. If the tool fails, it will generate this exception.
38+
A caller might be able to rescue.
39+
40+
Remove all print statements.

README

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44
Copyright 2012 L. Konneker
55
-------------------------
66

7-
1. About
8-
========
7+
About
8+
=====
99

1010
A freehand drawing tool.
1111
Where a tool is a user interface object, something a user uses.
@@ -34,34 +34,23 @@ References:
3434
See much more technical discussion in the code.
3535

3636

37-
2. Version 0.0.2
38-
================
39-
40-
SegmentString, Segment, ControlPoint classes.
41-
Explicitly model the abstractions of a SegmentString.
42-
This more cleanly separates freehandTool from what it produces.
43-
Demonstrates editing a SegmentString by manipulation of its ControlPoints.
44-
(Although editing is not graphical, just crude demo via keystrokes.)
37+
Versions
38+
========
4539

40+
See CHANGELOG.
4641

47-
3. Version 0.0.3
48-
================
4942

50-
- Relations between ControlPoints defines actions (behavior of user manipulations.)
51-
- Cusps known by SegmentString
52-
- Actions defined as a Strategy/Policy
53-
- An API that can be cleanly hooked to a GUI editor.
43+
Serialize/Deserialize
44+
======================
5445

46+
The output SegmentString, a QGraphicsPathItem, does not pickle.
47+
But QPainterPath implements << for serializing, and it's not hard to do (it's not in this package.)
5548

56-
4. Serialize/Deserialize
57-
========================
58-
TODO
59-
Calculate cuspness geometrically.
6049
Cuspness is not currently serializable/deserializable, only exists just after SegmentString creation.
6150

6251

63-
5. Directory structure and distribution
64-
=======================================
52+
Directory structure and distribution
53+
====================================
6554
The top directory freehandTool includes a demo app, freehandApp.py.
6655
It also include other distribution artifacts e.g. setup.py.
6756

@@ -74,17 +63,19 @@ The directory freehandTool.freehandTool.generator is a Python package that the t
7463
The Python distribution (a zipped archive) includes only the package freehandTool.freehandTool and subpackages,
7564
but not the demo app.
7665

77-
6. The demo app
78-
===============
66+
67+
The demo app
68+
============
7969

8070
Draw with the mouse left button down.
8171
Any key modifies an arbitrary control point (the second one?)
8272
A key with control key also down modifies said control point while maintaining cuspness.
8373

8474
A real app would have an alternate user interface for editing (dragging?) control points.
8575

86-
7. Installing
87-
==============
76+
77+
Installing
78+
==========
8879

8980
If you clone the git repository, you can change directory to the project directory and simply execute freehandApp.py.
9081

alternatePaintingQGPI.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ def paint(self, painter, styleOption, widget):
2424
while True:
2525
try:
2626
element = path.elementAt(i)
27-
# print type(element), element.type
27+
#print type(element), element.type
2828
if element.isMoveTo():
2929
pathEnd = QPointF(element.x, element.y)
3030
i+=1

dist/freehandTool-0.1.tar.gz

-67 Bytes
Binary file not shown.

freehandTool/freehand.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -331,14 +331,21 @@ def pointerMoveEvent(self, pointerEvent):
331331
except StopIteration:
332332
'''
333333
While user is moving pointer with pointer button down, we don't expect pipe to stop.
334-
If programming error stops pipe, quit app so we can see error trace.
334+
For debugging, call exitAbnormally().
335+
If a component of large app, raise.
336+
A caller might catch it and rescue by ending and restarting the tool?
335337
'''
336-
print "Abnormal pointerMoveEvent, exiting"
337-
sys.exit()
338+
raise
338339
else:
339340
self.pathHeadGhost.updateEnd(FreehandPoint(pointerEvent.scenePos))
340341

341342

343+
def exitAbnormally(self):
344+
" For debugging: quit app so we can see error trace. "
345+
print "Abnormal pointerMoveEvent, exiting"
346+
sys.exit()
347+
348+
342349
def pointerPressEvent(self, pointerEvent):
343350
'''
344351
Start freehand drawing.
@@ -351,7 +358,7 @@ def pointerReleaseEvent(self, pointerEvent):
351358
self.closeFilterPipe()
352359
self.pathHeadGhost.hide()
353360
self._createFinalSegment(pointerEvent)
354-
print "Final segment count", self.path.countSegments()
361+
#print "Final segment count", self.path.countSegments()
355362

356363

357364
def _createFinalSegment(self, pointerEvent):
@@ -374,7 +381,7 @@ def _createFinalSegment(self, pointerEvent):
374381
# Only create final segment if pointer was NOT released at exact end of current path
375382
# For example when ending on a timed cusp??
376383
if currenPathEnd != currentPointerPos:
377-
print "Created final line segment"
384+
#print "Created final line segment"
378385
finalLineSegment = LineSegment(startPoint=currenPathEnd, endPoint=currentPointerPos)
379386
self.path.appendSegments( [finalLineSegment], segmentCuspness=[False])
380387

freehandTool/freehandHead.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ def __init__(self, **kwargs):
4747

4848

4949
def showAt(self, initialPosition):
50-
# print "showAt"
50+
#print "showAt"
5151
self.start = initialPosition
5252
self.end = initialPosition
5353
self.path.moveTo(initialPosition)
@@ -71,7 +71,7 @@ def updateEnd(self, point):
7171
'''
7272
Update current path by appending lineTo new end point.
7373
'''
74-
# print "updateEnd"
74+
#print "updateEnd"
7575
assert isinstance(point, FreehandPoint)
7676
self.end = point
7777
self.path.lineTo(point)
@@ -95,7 +95,7 @@ def floatSceneFromIntViewPoint(self, pointVCS):
9595
def updateStart(self, pointVCS):
9696
'''
9797
'''
98-
print "updateStart"
98+
#print "updateStart"
9999
# !!! start point from FreehandTool is in View CS.
100100
pointViewInt = QPoint(pointVCS.x(), pointVCS.y())
101101
pointSceneFloat = self.scene().views()[0].mapToScene(pointViewInt)
@@ -120,7 +120,7 @@ def _findFirstElementAt(self, point):
120120
assert self.path.elementCount() > 1 # moveTo, lineTo
121121
for elementIndex in range(1, self.path.elementCount()):
122122
element = self.path.elementAt(elementIndex)
123-
print element.x, element.y, point
123+
#print element.x, element.y, point
124124
if element.x == point.x() and element.y == point.y() :
125125
return elementIndex
126126
assert False, 'New start point must be on existing path.'

freehandTool/generator/constraints.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,11 +43,11 @@ def update(self, v):
4343
If you take out turnGenerator, this might make sense.
4444
4545
if abs(v.x())<=1 and abs(v.y())<=1 :
46-
print "No constraints."
46+
#print "No constraints."
4747
pass
4848
else:
4949
'''
50-
# print "Updating constraints"
50+
#print "Updating constraints"
5151
offset = PointerPoint( v.x() + (1 if v.y() >= 0 and (v.y()>0 or v.x()<0) else -1 ),
5252
v.y() + (1 if v.x() <= 0 and (v.x()<0 or v.y()<0) else -1 ) )
5353
if self.constraintLeft.crossProduct(offset) >= 0 :

freehandTool/generator/curveGenerator.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,8 @@ def CurveGenerator(self, startLine):
8080
GeneratorExit exception is still in effect after finally, but caller does not see it,
8181
and Python does NOT allow it to return a value.
8282
'''
83-
print "closed curve generator"
83+
#print "closed curve generator"
84+
pass
8485

8586

8687

@@ -142,7 +143,7 @@ def segmentsFromLineMidToEnd(self, line1, line2):
142143
'''
143144
midToMidsegments, endOfMidToMid, cuspness = self.segmentsFromLineMidToMid(line1, line2)
144145
finalEndPoint = FreehandPoint(self.mapFromDeviceToScene(line2.p2())) # line2.p2()
145-
print "Mid to end"
146+
#print "Mid to end"
146147
midToEnd = LineSegment(endOfMidToMid, finalEndPoint)
147148
return midToMidsegments + [midToEnd], finalEndPoint, cuspness + [True]
148149

@@ -160,7 +161,7 @@ def segmentsForCusp(self, cuspPoint, endPoint):
160161
Note we already generated segment to first midpoint,
161162
and will subsequently generate segment from second midpoint.
162163
'''
163-
print "cusp <<<"
164+
#print "cusp <<<"
164165
try:
165166
# !!! Here is where we use cache
166167
firstSegment = LineSegment(self.lastEndPointGenerated, cuspPoint)

freehandTool/generator/lineGenerator.py

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def LineGenerator(self, startPosition):
3636
while True:
3737
turn, positionElapsedTime = (yield)
3838
#turnElapsedTime = turnClock.restart()
39-
# print "Turn elapsed", turnElapsedTime
39+
#print "Turn elapsed", turnElapsedTime
4040
#line = self.smallestLineFromPath(previousTurn, turn) # TEST
4141
line = self._lineFromPath(startTurn, previousTurn, turn, constraints) # ,directions)
4242
if line is not None: # if turn not satisfied by vector
@@ -54,24 +54,25 @@ def LineGenerator(self, startPosition):
5454
startTurn = previousTurn # !!! current turn is part of next PathLine
5555
didLastEmitCusp = True
5656
else:
57-
print "Skipping consecutive cusps"
57+
#print "Skipping consecutive cusps"
58+
pass
5859
# else current path (all turns) still satisfied by a PathLine: wait
5960

6061
previousTurn = turn # Roll forward !!! Every turn, not just on send()
6162
except Exception:
6263
# !!! GeneratorExit is a BaseException, not an Exception
6364
# Unexpected programming errors, which are obscured unless caught
64-
print "Exception in LineGenerator"
65+
#print "Exception in LineGenerator"
6566
traceback.print_exc()
6667
raise
6768
except GeneratorExit:
68-
print "closing line generator"
69+
#print "closing line generator"
6970
if previousTurn != startTurn:
70-
print "closing line generator"
71+
#print "closing line generator"
7172
#print "startTurn, previousTurn", startTurn, previousTurn
7273
''' Have turn not sent. Fabricate a PathLine and send() it now. '''
7374
self.curveGenerator.send((PathLine(startTurn, previousTurn), False))
74-
print "closed line generator"
75+
#print "closed line generator"
7576

7677

7778

@@ -112,7 +113,7 @@ def _lineFromPath(self, startTurn, previousTurn, currentTurn, constraints, direc
112113
if len(directions) > 3:
113114
# a path with four directions can't be approximated with one vector
114115
# end point is starting pixel of segment ???
115-
print "Four directions"
116+
#print "Four directions"
116117
self.resetLineFittingFilter()
117118
# Note end is previousTurn, not current Turn
118119
return PathLine(startTurn, previousTurn)
@@ -122,7 +123,7 @@ def _lineFromPath(self, startTurn, previousTurn, currentTurn, constraints, direc
122123
vectorViaAllTurns = currentTurn - startTurn
123124

124125
if constraints.isViolatedBy(vector=vectorViaAllTurns):
125-
# print "Constraint violation", constraints, "vector", vectorViaAllTurns
126+
#print "Constraint violation", constraints, "vector", vectorViaAllTurns
126127
result = self._interpolateConstraintViolating(startTurn=startTurn,
127128
lastSatisfyingTurn=previousTurn,
128129
firstNonsatisfingTurn=currentTurn)
@@ -144,11 +145,11 @@ def _forceLineFromPath(self, startTurn, previousTurn, currentTurn, constraints,
144145

145146
if startTurn == currentTurn:
146147
''' A reversal. A line from start to current would be Null. '''
147-
print "Reversal"
148+
#print "Reversal"
148149
assert previousTurn != startTurn
149150
return PathLine(startTurn, previousTurn)
150151
else:
151-
## print "Force PathLine", startTurn, currentTurn
152+
##print "Force PathLine", startTurn, currentTurn
152153
return PathLine(startTurn, currentTurn)
153154

154155

freehandTool/generator/turnGenerator.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ def TurnGenerator(self, startPosition):
3535
positionClock = QTime.currentTime() # note restart returns elapsed
3636
positionClock.restart()
3737
# I also tried countPositionsSinceTurn to solve lag for cusp-like
38-
# print "init turn"
38+
#print "init turn"
3939

4040
try:
4141
while True:
@@ -49,12 +49,12 @@ def TurnGenerator(self, startPosition):
4949
pass
5050
# Not catching general exceptions, have not found a need for it.
5151
except GeneratorExit:
52-
print "Closing turn generator"
52+
#print "Closing turn generator"
5353
# assert position is defined
5454
if previousPosition != position:
5555
''' Have position not sent. Fabricate a turn (equal to position) and send() '''
5656
self.lineGenerator.send((position, 0))
57-
print "Closed turn generator"
57+
#print "Closed turn generator"
5858

5959

6060

0 commit comments

Comments
 (0)