I was recently reading the Lucky Basartd page on the Stone Brewery website and I remembered an (unverified) study claiming “scrambled words are legible as long as first and last letters are in place.” For grins, I whipped up a Python script to scramble a word/sentence.
Sometimes I get frustrated about that things that aren’t included in the C standard libs. Chief among my frustrations: there is no substring function! I know C is bare-bones for a reason, but they couldn’t think to include it in <string.h>?
A friend of mine recently asked me to help him with a Java GUI to demonstrate the finer points of his PhD thesis. Part of this GUI included a canvas wherein the user would “hand draw” a line, which his algorithm would use as input (which I stored as a List of line segments). Long story short, this line needed to be smoothed out to remove the inaccuracies created from its hand-drawedness.
Now, there are a number of algorithms (e.g. Bézier Curves, Spline Interpolation), but I wanted something simple enough that the user could just hand-draw the line and hit a button that said “smooth.” After a bit of searching I settled on McMaster’s Slide Averaging Algorithm, which I have implemented below:
importjava.awt.Point;
importjava.util.ArrayList;
importjava.util.List;
/**
* A method to smooth a hand-drawn line based on the McMaster
* line smoothing algorithm
*
* @author Derek Springer
*/publicclassLineSmoother {
/**
* @param lineSegments A list of line segments representing a line
* @return A list line segments representing the smoothed line
*/publicstaticList<Line> smoothLine(List<Line> lineSegments) {
if(lineSegments.size() < 4) return lineSegments;
List<Line> smoothedLine = newArrayList<Line>();
List<Point> points = getPoints(lineSegments);
smoothedLine.add(lineSegments.get(0));
Point newPoint = points.get(1);
for(int i = 2; i < points.size()-2; i++) {
Point lastPoint = newPoint;
newPoint = smoothPoint(points.subList(i-2, i+3));
smoothedLine.add(newLine(lastPoint, newPoint));
}
Line lastSegment = lineSegments.get(lineSegments.size()-1);
smoothedLine.add(newLine(
newPoint,
newPoint(lastSegment.x1, lastSegment.y1)));
smoothedLine.add(lastSegment);
return smoothedLine;
}
/**
* @param lineSegments A list of line segments representing a line
* @return A list of Points representing the points in a series of
* line segments
*/publicstaticList<Point> getPoints(List<Line> lineSegments) {
List<Point> points = newArrayList<Point>();
for(Line segment : lineSegments) {
points.add(newPoint(segment.x1, segment.y1));
}
points.add(newPoint(
lineSegments.get(lineSegments.size()-1).x2,
lineSegments.get(lineSegments.size()-1).y2));
return points;
}
/**
* Find the new point for a smoothed line segment
* @param points The five points needed
* @return The new point for the smoothed line segment
*/publicstaticPoint smoothPoint(List<Point> points) {
int avgX = 0;
int avgY = 0;
for(Point point : points) {
avgX += point.x;
avgY += point.y;
}
avgX = avgX/points.size();
avgY = avgY/points.size();
Point newPoint = newPoint(avgX, avgY);
Point oldPoint = points.get(points.size()/2);
int newX = (newPoint.x + oldPoint.x)/2;
int newY = (newPoint.y + oldPoint.y)/2;
returnnewPoint(newX, newY);
}
}
I recently needed to check to see if a file had a particular tag in it before continuing, but I didn’t want to have to read it line by line to find out.
To my astonishment, there is no simple way to read a whole file into a string in Perl. The simple solution would be to use File::Slurp, but since the script will be running in a closed system I could only use default libraries. Also, because it’s Perl, I wanted to do it in a single line to maintain maximum incomprehensibility.
After a bit of tooling around I came up with this:
#!/usr/bin/perl -w
use strict;
use warnings;
# Check the file to ensure it contains the tag before continuing
my $FILE = $ARGV[0] or die $!;
die "File is missing required TIMESTAMP tag.n" unless do { local $/; local @ARGV = $FILE; <> } =~ /TIMESTAMP/;
...
More simply, here is the code to just stick the file contents in a variable:
my $contents = do { local $/; local @ARGV = $FILE; <> };
Essentially, what’s going on here is that I’m unsetting ‘$/’, the Input Record Separator, to make <> give the whole file at once.
Props to Stack Overflow for pointing me in the right direction.
# sample Python code snippet# bonus points if you know what this isfrom__future__importgeneratorsdeffirstn(g, n):
for i inrange(n):
yield g.next()
defintsfrom(i):
while1:
yield i
i = i + 1defexclude_multiples(n, ints):
for i in ints:
if (i % n): yield i
defsieve(ints):
while1:
prime = ints.next()
yield prime
ints = exclude_multiples(prime, ints)
if __name__ == '__main__':
for i in firstn(sieve(intsfrom(2)), 400):
print i