I was called a language lawyer the other day, because I attempted to be precise about the state of play with some code. Initially I was taken aback, but eventually concluded that the phrase "language lawyer" was not being used precisely. It was used in the sense of, "Saying exactly what you mean." If I had clarified this the self-reference may have meant I got lost down a rabbit hole, so I left it.
The situation came about because a co-worker is changing some code in a repo which has a few unit tests, but due to circumstance I won't bore you with the code is in two repos - one has the tests and the other doesn't. I have been tasks with getting tests round any code changes he makes. I am therefore working in the repo with the tests. He, of course, has decided to work in the repo without tests so doesn't know if his code changes break any existing tests.
/head-desk
It's like pair-programming but we have to talk in words rather than code.
I cannot manage to guess what his code changes might do to the tests. This would be so much easier if he ran the tests as he changed the code. In fact, by definiton, refactoring should involve running the tests as you go. Trying to ask questions like "Have you deleted the isValid function or changed its behaviour?" in order to try to get the tests to match his changes have resulted in answers like "No, well a bit, but I haven't decided yet."
My attempted to print off the test names so we could discuss how the code actually behaved before the changes have been met with ,"I haven't looked at the tests yet - I'd need to look at the code to see what they test." I think the tests have really clear names - like FooWithDefaultDateIsNotValid, He could look at the test code but I was rather hoping this was clear enough. I tried asking what new test *names* we might need, but got no-where. He did suggest I check the private container didn't contain any default dates - and offered to add a getter so I could verify this from outside the object in test code. I muttered something about encapsulation and seppuku and encapsulation.
I'm not sure if this is happening because people are used to function names making no sense and figuring out one line at a time in a debugger, or if some people genuinely don't think in words. It's very difficult to communicate if people assume you aren't saying what you mean, realise you are and then call you out for trying to be clear.
Wednesday, 26 August 2015
Sunday, 14 June 2015
Eulogy for my Dad
My Dad loved many
things and it therefore falls to me to mention mathematics. Non-geeks tend to
say things like “He had a gift for that,” as though geeks know a magic
incantation or are “naturally clever”. My Dad was clever. However, one of my
lecturers at University frequently reminded me that “Genius is 1% inspiration
and 99% perspiration.” David loved maths and was willing to spend many hours
learning more, usually in order to teach his students or to share the latest
puzzle he was thinking about with anyone willing to listen. Recently the
puzzles had tended to be the Sunday Times Puzzler. After showing him how to
program in Python he submitted a few that were accepted. You can still see them
on the internet if you search. He has left ripples in the ether.
He cared about
sharing results and ideas, and instilled in me the joy of someone moving from
disbelief to confusion to understanding and conviction. The world is often a
bigger and more amazing place than we first assume. I recall him getting a
paper published he had written with some students. Not only did he credit the
students, he also persuaded the publishers to include the negative results –
things they tried that went wrong. Many academic papers avoid doing this, but
he felt it is important to stop others from going down the same blind alleys
and to learn from your mistakes.
I know he inspired
many people. In my brief career as a teacher I met many who had been his
students at Christchurch and they always spoke highly of him. He had a knack
for explaining things and making sure you had understood. He was also willing
to listen to me trying to explain things to him – including how to code in
python and what I was trying to do with my “new work” chapter in my PhD thesis.
He was willing to ask “Why?” and allowed me to ask as well. I have never grown
out of this and that leaves me with an unsatisfiable curiosity. That makes it
OK to ask “Why?” about his unexpected death. Not being a mathematical question,
we are unlikely to get a clear and compelling answer, but it’s ok to ask.
The day after he
died, I saw a nine digit number in large neon on the top of a building-front.
It had all the digits except the number “1” – I forget which was repeated. I
have no idea what the number meant, but I know if he’d been there he would have
noticed it as well. Whenever I notice symmetries in tiles or paving slabs, or
broken symmetries, curious numbers or patterns I will think of him. And have
been doing for years. His excitement and curiosity about mathematics could be infectious
if you were prone to it. Some people might say “Stop being a geek,” others just
raise an eyebrow. Once in a while you’ll find someone else who’s noticed it too
or looks when you point and wonders with you at the patterns and meaning that
point to something greater in an otherwise chaotic seeming world.
I have no idea why the digit 1 was missing from the number on the building, let alone what the number was trying to convey, but having spotted a surprising number of physics books on the bookshelves of a man who claimed physics is just watered-down maths, I am reminded of a quote attributed to Feynman:
"I would rather have questions that can’t be answered than answers that can’t be questioned."
I have no idea why the digit 1 was missing from the number on the building, let alone what the number was trying to convey, but having spotted a surprising number of physics books on the bookshelves of a man who claimed physics is just watered-down maths, I am reminded of a quote attributed to Feynman:
"I would rather have questions that can’t be answered than answers that can’t be questioned."
It’s always ok to
ask “Why?” We may never really know but we may discover beautiful and
interesting things on the way. Or perhaps I should end with another actual Feynman
quote
“The most important thing I found out from [my father] is that if you asked any question and pursued it deeply enough, then at the end there was a glorious discovery of a general and beautiful kind.”
“The most important thing I found out from [my father] is that if you asked any question and pursued it deeply enough, then at the end there was a glorious discovery of a general and beautiful kind.”
Friday, 29 May 2015
Testing legacy code by adding singletons
This is not a good idea: Michael Feathers says "STOP IT NOW"
My team has lots of legacy code, that is code without tests. We want to get it under test and I want these tests to run on our Jenkins box. I want any quick running tests to run on each checkin and email us if the build got broken and whoever broke it fix it. A girl can dream.
We seem to be developing a "pattern" whereby we introduce singletons in order to make our code testable. Yes, I just said introduce singletons in order to make the code testable.
I think this is happening because "we" (well, they) want to use gmock because it's brilliant. I could be wrong. Perhaps it doesn't matter why it is happening we just need to stop this and do something different.
Suppose you have some code like this (C++).
class Asset
{
//miles and miles of public functions and comments
double Value(std::string logMessage, double someIrrelevantNumberToLog);
};
double Asset::Value(std::string logMessage, double someIrrelevantNumberToLog)
{
ENTERPRISE_INHOUSE_LOG_FRAMEWORK_THAT_PULLS_IN_THE_WORLD(info, logMessage, someIrrelevantNumberToLog);
double value = 0.0;
if (isSpot)
value = spotValue(m_notional, m_exchangeRate);
else
value = futureValue(m_notional, m_exchangeRate);
return value;
}
spotValue and futureValue are C functions that may or may not call COBOL or FORTRAN or similar.
We have ended up with some tests. Yay! Which use singletons. Boo!!
(Hope you like the comment being in red - as a warning rather than the odd convention of making them green in many IDEs).
#include <gmock>
class MockSpotValue
{
public:
MOCK_CONST_METHOD(spotValue, double(double, double));
void rest()
{
Mock::VerifyAndClear(this);
}
};
/**
* Singleton
* /
MockSpotValue & mockSpotValue();
Let's not point out this isn't a singleton. I'll leave the "mockSpotValue" instance create factory builder method as an exercise for the reader too. Making comments in red reminds me of being a teacher. It's the future. Or spot on. Depending on a boolean.
Now we use a linker seam to make our very own spotValue we can call in a test on a dev box.
double spotValue(double x, double y)
{
mockSpotValue().(x,y);
}
TEST_F(ValueTest, testGetSpotValueWithZeroNotional)
{
MockSpotValue & valueApi = mockSpotValue();
valueApi,reset();
Asset asset;
asset.makeSpot();//or something mad like that
EXPECT_CALL(valueApi, spotValue(_, _)).WillOnce(Return(42));
I have simplified this. In order to get something like this Asset into a test we did some things with a sprout. This may require another blog post.
I have seen worse. I saw one call "testDefaultIsValid" which asserted that a thing constructed with defaults IS NOT valid. I digress.
So, testGetSpotValueWithZeroNotional. What are we testing? Can we make this test name clearly express what is tests?
The best I can come up with is testThatSpotAssetValueReturnsTheValueIToldTheMockToReturn or more simply
testThatGMockDoesWhatItIsSupposedToCosYouCannotTrustThesePeople
I feel like banning mocks until we have written a few characterisation tests. At least there will be fewer singletons that way. Who ever heard of adding singletons in order to test code?
Testing legacy code
Many people have read Mike Feather's excellent book, "Working effectively with legacy code." including people on my team. Some people like Mocks. Watch this space - Overload 127 will contain an article asking if mocks are always the right thing to use.My team has lots of legacy code, that is code without tests. We want to get it under test and I want these tests to run on our Jenkins box. I want any quick running tests to run on each checkin and email us if the build got broken and whoever broke it fix it. A girl can dream.
Stop it - you're doing it wrong
We seem to be developing a "pattern" whereby we introduce singletons in order to make our code testable. Yes, I just said introduce singletons in order to make the code testable.
I think this is happening because "we" (well, they) want to use gmock because it's brilliant. I could be wrong. Perhaps it doesn't matter why it is happening we just need to stop this and do something different.
Why does gmock make you write singletons?
Let's look at an example, with the names changed to protect the guilty.Suppose you have some code like this (C++).
class Asset
{
//miles and miles of public functions and comments
double Value(std::string logMessage, double someIrrelevantNumberToLog);
};
double Asset::Value(std::string logMessage, double someIrrelevantNumberToLog)
{
ENTERPRISE_INHOUSE_LOG_FRAMEWORK_THAT_PULLS_IN_THE_WORLD(info, logMessage, someIrrelevantNumberToLog);
double value = 0.0;
if (isSpot)
value = spotValue(m_notional, m_exchangeRate);
else
value = futureValue(m_notional, m_exchangeRate);
return value;
}
spotValue and futureValue are C functions that may or may not call COBOL or FORTRAN or similar.
We have ended up with some tests. Yay! Which use singletons. Boo!!
(Hope you like the comment being in red - as a warning rather than the odd convention of making them green in many IDEs).
No, but, HOW?
In order to test this, and armed with gmock we have something like mockSpotValue.h (namespaces and include guards left as an exercise for the reader for brevity)#include <gmock>
class MockSpotValue
{
public:
MOCK_CONST_METHOD(spotValue, double(double, double));
void rest()
{
Mock::VerifyAndClear(this);
}
};
/**
* Singleton
* /
MockSpotValue & mockSpotValue();
Let's not point out this isn't a singleton. I'll leave the "mockSpotValue" instance create factory builder method as an exercise for the reader too. Making comments in red reminds me of being a teacher. It's the future. Or spot on. Depending on a boolean.
Now we use a linker seam to make our very own spotValue we can call in a test on a dev box.
double spotValue(double x, double y)
{
mockSpotValue().(x,y);
}
And where's the test(s)?
Ah. Tests. Yes, having done this we should write some. Or maybe just one for brevity.TEST_F(ValueTest, testGetSpotValueWithZeroNotional)
{
MockSpotValue & valueApi = mockSpotValue();
valueApi,reset();
Asset asset;
asset.makeSpot();//or something mad like that
EXPECT_CALL(valueApi, spotValue(_, _)).WillOnce(Return(42));
EXPECT_THAT(asset.Value(), DoubleEq(42.0));
}I have simplified this. In order to get something like this Asset into a test we did some things with a sprout. This may require another blog post.
BUT that's a B(ad) U(nit) T(est)
How do we know this is a bad test? Because we have seen the singleton? Even without that the name smells. "testGetSpotValueWithZeroNotional"I have seen worse. I saw one call "testDefaultIsValid" which asserted that a thing constructed with defaults IS NOT valid. I digress.
So, testGetSpotValueWithZeroNotional. What are we testing? Can we make this test name clearly express what is tests?
The best I can come up with is testThatSpotAssetValueReturnsTheValueIToldTheMockToReturn or more simply
testThatGMockDoesWhatItIsSupposedToCosYouCannotTrustThesePeople
Help
I like that we are trying to get tests round legacy code. I just have a few qualms about how we are doing this. Please comment with suggestions on how to test this better.I feel like banning mocks until we have written a few characterisation tests. At least there will be fewer singletons that way. Who ever heard of adding singletons in order to test code?
Thursday, 21 May 2015
Eigenfaces FTW or the "Zebra/non-zebra decision boundary."
Yesterday I attended the Karen Spärck Jones lecture at the BCS in London Dr Cordelia Schmid talked about computer vision, giving an overview of it's history through to the current state of the art. This is a tall order to get into an hour or so.
Let's see if I can summarise what she covered.
Still pictures and moving pictures need different techniques. For still pictures, we start with attempting to recognise objects or classes of objects. For moving pictures we might be spotting actions, as well as objects; maybe tuning a stringed instrument or celebrating a birthday. For still pictures, spotting a known chair in pictures is slightly easier than getting a program to spot any chair in pictures. How do you generalise the definition of chair anyway?
For the simpler case of a specific chair, or other object, you still need to deal with problems such as the different viewpoints, or different scales. The pixels of a bridge/chair/object close up will be completely different to the same bridge further away, or at a slightly different angle. Techniques started with edge detection, then moved on to projective invariants (and geometric and photometric invariants - light levels affect the pixel). I regarded this as akin to the difference between bitmaps and scalable vector graphics.
A milestone in the move away from edge detection to feature selection came with "Eigenfaces" - see Turk and Pentland. This uses principal component analysis.. In essence you find the line of best fit through the points, plotted in n-dimensional space, if you have n features. This is the first eigenvector. It's a vector, as it has direction. It's "eigen" as it is a peculiar, singular or *characteristic* - etymology slightly uncertain. If you project the data onto this, you will have lost lots of information. You then find a perpendicular line - the 2nd best fit line. And continue until you've captured enough information. This allows you to summarise datasets and is sometimes known as a feature reduction technique. Have you ever wonder how facebook recognises faces? Or how football programmes track how far a footballer has run? Actually the latter is more moving pictures, so I am ahead of myself.
These approaches look at the global scale - the whole picture. Next came local greyscale invariants, using a voting system to spot things. This can deal with photometric problems - varying light levels. Next we have SIFT - scale-invariant feature transform.
Mention was then made of wavelet filters and boosting feature selection, trained on positive and negative examples, such as pictures with a given object, say a car, and pictures without the object. The code is in OpenCV. I wonder if this is similar to AdaBoost.
Mention was then made of histograms of orientation - see Datal and Triggs. This is related to support vector machines, SVM, which finds a hyperplane between positive and negative examples. Some example still pictures were shown wherein this technique could be used to detect a, and I quote, "Zebra/non-zebra decision boundary." This may not seem like a day-to-day problem many of us face, but made the important point that you need training data near the boundary - for example other animals with stripes, and other things with a similar profile, like a motorbike. In a more general setting I was thinking about flushing out edge-cases in unit tests. The importance of a good set of representative training data was made - you need more than just edge cases, you want many cases away from the edges too. This also applies to automated testing. But I digress.
Finally we move on to the current state of the art - convolution neural networks (CNN), which I have not met before. The find "high-dimensional aggregated descriptors" - they have a huge number of nodes and several layers and require some serious computing power - GPU etc etc. As always there is a trade-off between speed and accuracy. I presume the hand-tuned network may be incomprehensible afterwards. I have worked on "feature extraction" from feed-forward neural networks before which represent a trained network as a decision tree so a human can understand what the program has discovered. I presume for CNNs this is neither possible nor desirable. It just needs to get the job done and find Wally^H^H^H^H^H zebras. I previous mentioned python to find Wally on El Reg. Aren't computers amazing?
Could a machine automatically tag things in a still picture? "Dog 1: Terror", "Man: John Smith". I wonder if we end up with CCTV automatically sending out Robocop to arrest people. Big brother is watching you and figuring out what you're doing.
This leads to the action recognition, mentioned at the start. Having got to a point where we tag things in a still picture, can we set the machines lose to do "weak supervised learning" - find an interesting thing in this video. We were shown examples of a programming picking out a bird or person etc moving in a video, Sometimes it worked, sometimes it didn't. Supervised learning involves giving training examples as input and getting the trained algo to find the same things in other inputs. For moving pictures describing the data - giving positive and negative examples would take hours. Would you go through frame by frame and label features? It would take far too long. Instead let it learn as it goes, setting it off with a few clues - here's a robin. Is there one in this movie? Or spot and label a moving thing - which happened to be a car moving very quickly so seeming to get much smaller - it didn't find that. It seems slow movements are easier to track than fast jerky ones. Though an algo did manage to draw a rectangle around a cat rolling about in another video. The two main techniques involved were dense trajectory features (Wang) and CNN features for optical flow (Simonyan). These made the front page in the last year or so.
A compelling throw away comment at the end was that hand-crafted models are NOT machine learning (ML).Most ML I have attempted before has left me to chose some parameters - how many iterations, how fast to move towards a solution, how many layers in my neural network. The machine has learnt nothing - it just did what it was told. True ML would let the machine find its own parameters. Of course, I have seen a few people trying to do this. It's all very exciting.
Somebody asked, "How come I don't see any of this in my day to day life?" I presume the usual - this is all so academic. Pay attention at the back, I say...
My Dad once asked me how on earth the sports program he was watching could tell him how far a specific footballer had run in the course of a football match. This involves image recognition, including the optical flow - tracking an individual player over the course of a game, from various different angles, so captures many of the specific problems we mentioned above. Unless they just use a pedometer.
Fascinating stuff. I wonder if the machines could spot things we haven't spotted. For example, speckles or shadows in medical scans or even x-ray machines at passport control/baggage checks, that people might miss. Or imagine facebook looked at your holiday snaps and sent you an advert for a clinic dealing with skin cancer, having spotted the stirrings of a carcinoma in your holiday tan. Would you want this?
Further extensions including pairing up audio information, so we can find youtube videos of tuning a guitar - made much easier if the spoken commentary says "tuning" and "guitar" as well as just having the pictures to go on. Combine this with smell and haptics and the machines will soon be writing their own drivel all over the internet. Welcome Skynet.
Let's see if I can summarise what she covered.
Still pictures and moving pictures need different techniques. For still pictures, we start with attempting to recognise objects or classes of objects. For moving pictures we might be spotting actions, as well as objects; maybe tuning a stringed instrument or celebrating a birthday. For still pictures, spotting a known chair in pictures is slightly easier than getting a program to spot any chair in pictures. How do you generalise the definition of chair anyway?
For the simpler case of a specific chair, or other object, you still need to deal with problems such as the different viewpoints, or different scales. The pixels of a bridge/chair/object close up will be completely different to the same bridge further away, or at a slightly different angle. Techniques started with edge detection, then moved on to projective invariants (and geometric and photometric invariants - light levels affect the pixel). I regarded this as akin to the difference between bitmaps and scalable vector graphics.
A milestone in the move away from edge detection to feature selection came with "Eigenfaces" - see Turk and Pentland. This uses principal component analysis.. In essence you find the line of best fit through the points, plotted in n-dimensional space, if you have n features. This is the first eigenvector. It's a vector, as it has direction. It's "eigen" as it is a peculiar, singular or *characteristic* - etymology slightly uncertain. If you project the data onto this, you will have lost lots of information. You then find a perpendicular line - the 2nd best fit line. And continue until you've captured enough information. This allows you to summarise datasets and is sometimes known as a feature reduction technique. Have you ever wonder how facebook recognises faces? Or how football programmes track how far a footballer has run? Actually the latter is more moving pictures, so I am ahead of myself.
These approaches look at the global scale - the whole picture. Next came local greyscale invariants, using a voting system to spot things. This can deal with photometric problems - varying light levels. Next we have SIFT - scale-invariant feature transform.
Mention was then made of wavelet filters and boosting feature selection, trained on positive and negative examples, such as pictures with a given object, say a car, and pictures without the object. The code is in OpenCV. I wonder if this is similar to AdaBoost.
Mention was then made of histograms of orientation - see Datal and Triggs. This is related to support vector machines, SVM, which finds a hyperplane between positive and negative examples. Some example still pictures were shown wherein this technique could be used to detect a, and I quote, "Zebra/non-zebra decision boundary." This may not seem like a day-to-day problem many of us face, but made the important point that you need training data near the boundary - for example other animals with stripes, and other things with a similar profile, like a motorbike. In a more general setting I was thinking about flushing out edge-cases in unit tests. The importance of a good set of representative training data was made - you need more than just edge cases, you want many cases away from the edges too. This also applies to automated testing. But I digress.
Finally we move on to the current state of the art - convolution neural networks (CNN), which I have not met before. The find "high-dimensional aggregated descriptors" - they have a huge number of nodes and several layers and require some serious computing power - GPU etc etc. As always there is a trade-off between speed and accuracy. I presume the hand-tuned network may be incomprehensible afterwards. I have worked on "feature extraction" from feed-forward neural networks before which represent a trained network as a decision tree so a human can understand what the program has discovered. I presume for CNNs this is neither possible nor desirable. It just needs to get the job done and find Wally^H^H^H^H^H zebras. I previous mentioned python to find Wally on El Reg. Aren't computers amazing?
Could a machine automatically tag things in a still picture? "Dog 1: Terror", "Man: John Smith". I wonder if we end up with CCTV automatically sending out Robocop to arrest people. Big brother is watching you and figuring out what you're doing.
This leads to the action recognition, mentioned at the start. Having got to a point where we tag things in a still picture, can we set the machines lose to do "weak supervised learning" - find an interesting thing in this video. We were shown examples of a programming picking out a bird or person etc moving in a video, Sometimes it worked, sometimes it didn't. Supervised learning involves giving training examples as input and getting the trained algo to find the same things in other inputs. For moving pictures describing the data - giving positive and negative examples would take hours. Would you go through frame by frame and label features? It would take far too long. Instead let it learn as it goes, setting it off with a few clues - here's a robin. Is there one in this movie? Or spot and label a moving thing - which happened to be a car moving very quickly so seeming to get much smaller - it didn't find that. It seems slow movements are easier to track than fast jerky ones. Though an algo did manage to draw a rectangle around a cat rolling about in another video. The two main techniques involved were dense trajectory features (Wang) and CNN features for optical flow (Simonyan). These made the front page in the last year or so.
A compelling throw away comment at the end was that hand-crafted models are NOT machine learning (ML).Most ML I have attempted before has left me to chose some parameters - how many iterations, how fast to move towards a solution, how many layers in my neural network. The machine has learnt nothing - it just did what it was told. True ML would let the machine find its own parameters. Of course, I have seen a few people trying to do this. It's all very exciting.
Somebody asked, "How come I don't see any of this in my day to day life?" I presume the usual - this is all so academic. Pay attention at the back, I say...
- Have you ever been issued with an automatic speeding ticket? How did it find you?
- Have you ever uploaded a picture to facebook and found little boxes around faces (and the odd random tree, but what do you expect?)
My Dad once asked me how on earth the sports program he was watching could tell him how far a specific footballer had run in the course of a football match. This involves image recognition, including the optical flow - tracking an individual player over the course of a game, from various different angles, so captures many of the specific problems we mentioned above. Unless they just use a pedometer.
Fascinating stuff. I wonder if the machines could spot things we haven't spotted. For example, speckles or shadows in medical scans or even x-ray machines at passport control/baggage checks, that people might miss. Or imagine facebook looked at your holiday snaps and sent you an advert for a clinic dealing with skin cancer, having spotted the stirrings of a carcinoma in your holiday tan. Would you want this?
Further extensions including pairing up audio information, so we can find youtube videos of tuning a guitar - made much easier if the spoken commentary says "tuning" and "guitar" as well as just having the pictures to go on. Combine this with smell and haptics and the machines will soon be writing their own drivel all over the internet. Welcome Skynet.
Wednesday, 22 October 2014
Prove it - n factorial is bigger than 2^n
I've been doing the scala coursera and wanted to write down the proof that
factorial(n) ≥ 2n when n ≥ 4
since it uses induction and I am out of practise.Base case
For n = 4factorial(4) = 4*3*2*1 = 24
and 24 = 2*2*2*2 = 16
furthermore 24 ≥ 16
Induction step
For n >= 4 assume we havefactorial(n) >= 2n
and consider
factorial(n+1) = factorial(n) × (n+1)
≥ 2n × (n+1)
≥ 2n × 2 since (n+1) ≥ 2 when n ≥ 4
= 2n+1
Wednesday, 9 July 2014
Remote debugging python in Visual Studio
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)
"""
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.
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.
Wednesday, 5 February 2014
Mutable structs in C#
We know what this does, right?
struct Pricer
{
public double Price;
public long Size;
public void AddExecution(long lastSize, double lastPrice)
{
Price = (Price * Size + lastSize * lastPrice) / (Size + lastSize);
Size += lastSize;
}
}
class PriceData
{
public Pricer pricer;
}
{
Pricer price = new Pricer{Price = 0.0, Size = 0};
for (int i = 0; i < 5; ++i)
{
Console.WriteLine("{0} {1}", price.Price, price.Size);
price.AddExecution(1, 2.5 * (i + 1));
}
for (int i = 0; i < 5; ++i)
{
Console.WriteLine("{0} {1}", price.Price, price.Size);
price.Price= 2.5 * (i + 1);
}
PriceData priceData = new PriceData();
priceData.pricer = price;
for (int i = 0; i < 5; ++i)
{
Console.WriteLine("{0} {1}", price.Price, price.Size);
priceData.pricer.AddExecution(1, 2.5 * (i + 1));
}
struct Pricer
{
public double Price;
public long Size;
public void AddExecution(long lastSize, double lastPrice)
{
Price = (Price * Size + lastSize * lastPrice) / (Size + lastSize);
Size += lastSize;
}
}
class PriceData
{
public Pricer pricer;
}
class Program
{
static void Main(string[] args){
Pricer price = new Pricer{Price = 0.0, Size = 0};
for (int i = 0; i < 5; ++i)
{
Console.WriteLine("{0} {1}", price.Price, price.Size);
price.AddExecution(1, 2.5 * (i + 1));
}
for (int i = 0; i < 5; ++i)
{
Console.WriteLine("{0} {1}", price.Price, price.Size);
price.Price= 2.5 * (i + 1);
}
PriceData priceData = new PriceData();
priceData.pricer = price;
for (int i = 0; i < 5; ++i)
{
Console.WriteLine("{0} {1}", price.Price, price.Size);
priceData.pricer.AddExecution(1, 2.5 * (i + 1));
}
}
}
Eric Lippert tells us about mutating *readonly* structs: http://blogs.msdn.com/b/ericlippert/archive/2008/05/14/mutating-readonly-structs.aspx but even non-readonly structs can get us in a mess.
Subscribe to:
Posts (Atom)