We now have access to new powerful tools like ChatGPT that can help us write code. There are a number of potential issues with this:
- The ethics of using models trained by web scrapping.
- The security issues of asking an external bot about internal code.
- The correctness and quality of code produced.
So far I haven’t found this useful for situations at work. Every time I had asked for some source there were fundamental flaws with the code. It did sometimes give me ideas that I could then persue by myself but nothing to use directly.
Listening to other stories about people using these tools it seems better to treat them as a process rather than a one stop shop. They may not give you the “right” answer immediately, or indeed ever, but they are endlessly patient.
Closest distance between point and line
Like this:
Give me C++ source to calculate the distance between a point and a line.
#include <iostream> #include <cmath> // Structure to represent a point struct Point { double x, y; }; // Function to calculate the distance between two points double distance(Point p1, Point p2) { return sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2)); } // Function to calculate the distance between a point and a line defined by two points double distancePointLine(Point point, Point lineStart, Point lineEnd) { double lineLength = distance(lineStart, lineEnd); if (lineLength == 0) // If the line has zero length return distance(point, lineStart); // Return distance from the point to the line start // Calculate the perpendicular distance from the point to the line double distance = fabs((lineEnd.x - lineStart.x) * (lineStart.y - point.y) - (lineStart.x - point.x) * (lineEnd.y - lineStart.y)) / lineLength; return distance; } int main() { Point point = {1.0, 2.0}; // Point coordinates Point lineStart = {0.0, 0.0}; // Line start coordinates Point lineEnd = {3.0, 4.0}; // Line end coordinates double dist = distancePointLine(point, lineStart, lineEnd); std::cout << "Distance between point and line: " << dist << std::endl; return 0; }
Not bad but not great either. For me this seems overly cluttered.
I’d prefer it to follow my naming guidelines but the model doesn’t have internet access. I’d have to repeat them all here so I’ll not worry about that for the moment.
Update this code following this code review:
- There are a lot of comments but they aren’t adding a lot of value.
- We know structs are structures.
- We know functions are functions.
- We know points are coordinates.
- If an identifier can already tells us everything the comment is unnecessary.
- Comments are just telling us what not why.
- Adding a
struct Line
could be better in the long run.- The identifiers could be better.
- Inconsistant usage,
dist
anddistance
.- Using
distanceBetween
emphasises the purpose and removes need for comment.- Return values directly rather than transfering them via a variable (unless required to understand code).
#include <iostream> #include <cmath> struct Point { double x, y; }; struct Line { Point start, end; }; double calculateDistance(Point p1, Point p2) { return sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2)); } double distanceBetween(Point point, Line line) { double lineLength = calculateDistance(line.start, line.end); if (lineLength == 0) return calculateDistance(point, line.start); return fabs((line.end.x - line.start.x) * (line.start.y - point.y) - (line.start.x - point.x) * (line.end.y - line.start.y)) / lineLength; } int main() { Point point = {1.0, 2.0}; Line line = {{0.0, 0.0}, {3.0, 4.0}}; std::cout << "Distance between point and line: " << distanceBetween(point, line) << std::endl; return 0; }
It’s gotten rid of all the comments. I’d prefer to see some left explaining the more complex parts.
I wonder why it changed the distance
function to calculateDistance
?
I did ask. To summarise,
it said that re-using function names could cause confusion and calculateDistance
was more descriptive.
I don’t think that’s really true.
It feels more like an explaination you’d come up with after the fact to justify a change.
I’ll start combining queries rather than showing almost the same code every time.
C++ allows function overloading so that the same function name can be distinguished just by types. Re-write the code using that.
Use
distanceBetween
instead.
Add short comments to explain the maths heavy lines.
#include <iostream> #include <cmath> struct Point { double x, y; }; struct Line { Point start, end; }; // Calculate the Euclidean distance between two points double distanceBetween(Point p1, Point p2) { return sqrt(pow(p2.x - p1.x, 2) + pow(p2.y - p1.y, 2)); } // Calculate the distance between a point and a line double distanceBetween(Point point, Line line) { double lineLength = distanceBetween(line.start, line.end); // If the line has zero length, return the distance between the point and the line start if (lineLength == 0) return distanceBetween(point, line.start); // Calculate the perpendicular distance from the point to the line using the formula for a point-to-line distance return fabs((line.end.x - line.start.x) * (line.start.y - point.y) - (line.start.x - point.x) * (line.end.y - line.start.y)) / lineLength; } int main() { Point point = {1.0, 2.0}; Line line = {{0.0, 0.0}, {3.0, 4.0}}; // Calculate and print the distance between the point and the line std::cout << "Distance between point and line: " << distanceBetween(point, line) << std::endl; return 0; }
Oh dear. General comments have re-appeared rather than just explaining the maths.
Can you go back to the previous version of the code before those comments were added.
Add comments immediately before the maths on lines containing sqrt and fabs.
It can’t see to help itself with the extra comments. The “steering” for ChatGPT seems to be incredibly sensitive. Each time I ask for a change it swerves violently in the new direction.
Much easier to take the first version and just update it myself. I can change the identifiers and comments at the same time and get exactly what I want.
#include <iostream> #include <cmath> struct Point { double x, y; }; struct Line { Point start, end; }; double DistanceBetween(Point point, Point other) { return sqrt(pow(other.x - point.x, 2) + pow(other.y - point.y, 2)); } double DistanceBetween(Point point, Line line) { double lineLength = DistanceBetween(line.start, line.end); // Use a special case for an empty line to avoid divide by zero. if (lineLength == 0) { return DistanceBetween(point, line.start); } // Calculate the perpendicular distance from the point to the line. return fabs((line.end.x - line.start.x) * (line.start.y - point.y) - (line.end.y - line.start.y) * (line.start.x - point.x)) / lineLength; } int main() { Point point = { 1.0, 2.0 }; Line line = {{ 0.0, 0.0 , { 3.0, 4.0 }}; std::cout << "Distance between point and line: " << DistanceBetween(point, line) << std::endl; return 0; }
This still isn’t perfect. As part of a larger project I’d like to have my own library of maths routines. That would provide Square
and DotProduct
functions which would make this clearer.
On balance
Some people are very excited by these new tools. I’m wary. These models know a lot but are still limited in how they use that knowledge. Given the legal, ethical and quality issues of using this code I wouldn’t recommend it. They may be able to give you ideas but I don’t think they should be used to directly do coding for you.
Leave a Reply