Should I delete variables I don't plan on using anymore? - python-3.x

At first, it sounds like a no-brainer, but the more I think about it the more I feel like others' opinions would be helpful. Whenever looking at others' Python code, I never see them delete variables. Is there a reason for this, or is it just them not wanting to. I assume it has to do more with clean code vs. quick code, but I'm not sure that's the case. Plus, to be honest, I don't know for sure the impact deleting variables has on a program (I always just assumed it was good, since the courses I've taken on Python never really mentioned it).
Example of deleting a variable...
j = 'jjjjj'
for i in range(len(j)):
print(j[i], j)
del j
Not the most relatable example but you get the point.

In general, don't worry about deleting variables.
Python has garbage collection, so any objects that you can no longer access (usually because you've left their scope) will automatically be freed from memory, you don't have to worry about this at all.
The case where you might want to use del would be if you want to make it explicity clear that this variable cannot be used anymore by this part of the program.
As mentioned in the comments, this won't even necessarily delete your object.
You can read about the del keyword more here

Related

There's any way to delete objects in VB6 without getting errors?

I need to simplify a program made in VB6, so I need to delete a lot of objects but don't want to delete one, run, get an error, fix it, run, get another error, a so on for every object.
I don't created the original program, so is very annoying try to think what someone else thought.
Plus, the code is not commented and is very dirty, the objects have the default names, like Label1, Timer12. WTF?
So I can't get a clue about what a timer does until I fully read the code.
Any idea?
Perhaps the original author didn't have much thought, true. But then you're not giving it much thought either by thinking that the best approach will be to delete an object, run and see what happens, and then rinse and repeat until you have a fully working program. Given your approach, by the time you've finished deleting all the objects - you won't have much left to run anyway! (No data, No Problem!).
Look through the code in conjunction with running and debugging the application. This will give you an idea of what it is trying to do (I am under the assumption there's not really much in the way of documentation for this project?)
Time to think of a new plan! Sometimes re-writing from scratch is absolutely necessary rather than attempting to work with legacy code that is clearly hard to maintain and is far from optimum. The downside is that this will take more time, on paper - but perhaps will save time in the long run. This might be the time also to move away from VB6 and in to the .NET era. Rewriting applications can let you do this too!
If a re-write is out of the question (such a shame), then you can't go through willy-nilly deleting objects! The program functions with these objects. So they've got to stay and you need to maintain it.
See (2).
Good luck, God speed.
Or, given your comment
Rename Label1 to something more appropriate. Do a search replace within that file (Not the whole solution) to the new name, then correct any accidental errors and move on.
I would go with the last option of Moo-Juice's answer, but slightly different: I would rename a control by adding an "x" to its name and run the project.
If it runs, then remove the control, if it doesnt run, then rename the control back by removing the "x".
This should not take more than 1 hour for about 250 controls
But first you might do something else: Instead of just deleting the unused controls, you might also want to look at the controls:
If there are so many controls then it might be possible to convert series of controls into a control array: This might clean up the code a lot as well, and give you a better overview of the remaining controls
When you cleaned up the controls have a look at their names, and rename them to something useful.
After that it is time to clean up the code in the same way.
You can download MZ-Tools to help you with that.
It's a must for the lazy coder :)
Also place "Option Explicit" at the top of all code windows. This will make it easier for you to spot errors caused by not (properly) declared variables.
Do this after you have done "Review Source Code" of MZ-Tools though, as that might save you a lot of work :)

Is there a way to tell Stata to execute the whole do-file ignoring the lines producing exceptions (or even syntax errors)?

I run the time-consuming code in the background and oftentimes even the 10% of the code is not executed due to a small syntax mistake in the beginning of the do-file.
I would prefer the rest of the do-file to be executed as well since sometimes that mistake in the beginning has no effect on the computations at the end.
(version 2)
Wanting Stata to ignore mistakes can itself be mistaken.
If there is a mistake early in a do-file, it usually has implications for what follows.
Suppose you got Stata to work as you wish. How do you know whether Stata ignored something important or something trivial? If it ignored something trivial, that should be easy to fix. If it ignored something important, that was the wrong decision.
Let's now be more constructive. The help for do tells you that there is a nostop option.
You need to be very careful about how you use it, but it can help here.
The context of do, nostop is precisely that of the OP. People had do-files, often expected to take a long time because of big datasets or lots of heavy computation, and set them going, historically "overnight" or "while you went to lunch". Then they would be irritated to find that the do-file had quickly terminated on the first error, and especially irritated if the error was trivial. So, the idea of do, nostop is to do as much as you can, but as an aid to debugging. For example, suppose you got a variable name wrong in various places; you generate Y but refer to y later, which doesn't exist. You might expect to find corresponding error messages scattered through the file, which you can fix. The error messages are the key here.
The point about do files is that once they are right, you can save yourself lots of time, but no-one ever promised that getting the do-file right in the first place would always be easy.
My firm advice is: Fix the bugs; don't try to ignore them.
P.S. capture was mentioned in another answer. capture may seem similar in spirit, but used in similar style it can be a bad idea.
capture eats error messages, so the user doesn't see them. For debugging, that is the opposite of what is needed.
capture is really a programmer's command, and its uses are where the programmer is being smart on behalf of the user and keeping quiet about it.
Suppose, for example, a variable supplied could be numeric or it could be string. If it's numeric, we need to do A; if it's string we need to do B. (Either A or B could be "nothing".) There could be branches like this.
capture confirm str variable myvar
if _rc { /// it's numeric
<do A>
}
else {
<do B>
}
Otherwise put, capture is for handling predictable problems if and as they arise. It is not for ignoring bugs.
If there are only a couple commands that are hanging up and are otherwise inconsequential to your later calculations, you can always use capture (either as an inline prefix or as a block command, see help capture on use) to force the program to run through commands that stop the program.
But--echoing Nick's general comments about this way of writing and executing do-files--be similarly careful where you apply capture: generally, you should only apply it to commands you are sure would not affect later code or calculations. Or, even better, just remove from the program those lines that are giving problems and you apparently don't need anyway.

When exactly am I required to set objects to nothing in classic asp?

On one hand the advice to always close objects is so common that I would feel foolish to ignore it (e.g. VBScript Out Of Memory Error).
However it would be equally foolish to ignore the wisdom of Eric Lippert, who appears to disagree: http://blogs.msdn.com/b/ericlippert/archive/2004/04/28/when-are-you-required-to-set-objects-to-nothing.aspx
I've worked to fix a number of web apps with OOM errors in classic asp. My first (time consuming) task is always to search the code for unclosed objects, and objects not set to nothing.
But I've never been 100% convinced that this has helped. (That said, I have found it hard to pinpoint exactly what DOES help...)
This post by Eric is talking about standalone VBScript files, not classic ASP written in VBScript. See the comments, then Eric's own comment:
Re: ASP -- excellent point, and one that I had not considered. In ASP it is sometimes very difficult to know where you are and what scope you're in.
So from this I can say that everything he wrote isn't relevant for classic ASP i.e. you should always Set everything to Nothing.
As for memory issues, I think that assigning objects (or arrays) to global scope like Session or Application is the main reason for such problems. That's the first thing I would look for and rewrite to hold only single identifider in Session then use database to manage the data.
Basically by setting a COM object to Nothing, you are forcing its terminator to run deterministically, which gives you the opportunity to handle any errors it may raise.
If you don't do it, you can get into a situation like the following:
Your code raises an error
The error isn't handled in your code and therefore ...
other objects instantiated in your code go out of scope, and their terminators run
one of the terminators raises an error
and the error that is propagated is the one from the terminator going out of scope, masking the original error.
I do remember from the dark and distant past that it was specifically recommended to close ADO objects. I'm not sure if this was because of a bug in ADO objects, or simply for the above reason (which applies more generally to any objects that can raise errors in their terminators).
And this recommendation is often repeated, though often without any credible reason. ("While ASP should automatically close and free up all object instantiations, it is always a good idea to explicitly close and free up object references yourself").
It's worth noting that in the article, he's not saying you should never worry about setting objects to nothing - just that it should not be the default behaviour for every object in every script.
Though I do suspect he's a little too quick to dismiss the "I saw this elsewhere" method of coding behaviour, I'm willing to bet that there is a reason Eric didn't consider that has caused this to be passed along as a hard 'n' fast rule - dealing with junior programmers.
When you start looking more closely at the Dreyfus model of skill acquisition, you see that at the beginning levels of acquiring a new skill, learners need simple to follow recipes. They do not yet have the knowledge or ability to make the judgement calls Eric qualifies the recommendation with later on.
Think back to when you first started programming. Could you readily judge if you were "set[tting an] expensive objects to Nothing when you are done with them if you are done with them well before they go out of scope"? Did you really know which objects were expensive or when they truly went out of scope?
Thus, most entry level programmers are simply told "always set every object to Nothing when you are done with it" because it is within their grasp to understand and follow. Unfortunately, not many programmers take the time to self-educate, learn, and grow into the higher-level Dreyfus stages where you can use the more nuanced situational approach.
And then we come back to my earlier statement - even the best of us started out at that earlier stage, where we reflexively closed all objects because that was the best we were capable of. We left large bodies of code that people look at now, and project our current competence backwards to the earlier work and assume we did that for reasons we don't understand.
I've got to get going, but I hope to expand this a little futher...

Catching resource filename errors at compile time

I'm doing my first iOS App with Monotouch and I'm loading quite a lot of images from my resources directory. Every now and then I get a typo in a filename and the app will then crash on me spewing out some unintelligible error message. (I'll try adding deciphering stack traces to my skill set any day now ...)
I was thinking that there must be a smarter way to handle this. For example one could have a utility script that goes through the resources directory and constructs a list of global constants based on its contents. Each file in the resources gets an entry.
So that MyResources/Icons/HomeIcon.png will be represented by the constant MyResources.Icons.HomeIcon_png. Then one could have something like Inotify (don't know what that would be on Mac) watch the resources directory and regenerate the constants file on every change.
This would of course also give nice autocompletion for resources.
Maybe there's already something like this is already in Monodevelop or online somewhere? Otherwise how would I go about setting it up?
Or maybe there's some other smart way of mitigating the problem?
Your primary problem is typos in resource names are not caught early, and only cause crashes when the app is actually ran.
Your proposed solution of a list of global constants generated based on the available resources is kind of neat, but as far as I know this does not exist yet.
In the mean time, you could manually construct this list of global constants, and create a unit test that verifies all the elements in this list are valid resources (by looping through them automatically, of course - adding a resource to the list should not require a change to the test).
This way you can catch typos earlier (when you run the unit test rather than when you run the app), which is your primary concern. Additionally, if you ever find/write the script you envision, your application code is already prepared.
I filed an enhancement bug on Xamarin bugzilla for you: https://bugzilla.xamarin.com/show_bug.cgi?id=3760
So I spent four precious hours to cook up this little python script that sort of solves my problem. For now it's the best solution to my problem.
http://github.com/oivvio/Monodevelop-Resources-as-Constants

When is it a good use of time to refactor string literals?

I'm starting on a project where strings are written into the code most of the time. Many strings might only be used in a few places but some strings are common throughout many pages.
Is it a good use of my time to refactor the literals into constants being that the app is pretty well established and runs well? What would be the long-term benefits to doing so?
One common thing to consider would be i18n. If you (or your muckity-mucks) ever want to sell your product in Mexico or France (etc.) you're going to appreciate having those string literals not littered throughout the code base.
EDIT: I realize this doesn't directly answer your question, so I'm voting up some of the other answers re: rule of three, and the like. I understand you're talking about an existing code base, so it's a little late to talk about incorporating i18n from the start. It's so easy to do when you're in the habit from the start.
I like to apply the rule of three when refactoring. If it happens three or more times, then the code needs to be updated.
Only if this project needs to be supported into the future is this a good use of time. If you will be regularly maintaining/expanding this system; however, this is a great idea.
1) There is a large degree of risk associated with string literals as a single misspelling can usually only be detected at run time. The reduced risk of run time errors is a serious advantage as they can be embarrassing/frustrating.
2) Also, should they ever need to be changed, for example when they are used to reference another system (like table names, server names etc) they can be very difficult to update when those other system names change. Centralize them and it's a trivial issue.
If a string is used in more than one place, refactor it. If it is only used in one place, leave it alone.
If you've refactored out all your common strings, it makes it easier to internationalize/translate them. It's even easier if they're all in properties files, or whatever your language equivalent is.
Is it a good use of my time to refactor the literals into constants being that the app is pretty well established and runs well?
No, you better leave it like it is.
What would be the long-term benefits to doing so?
If no one ever touch that code, the benefits are none.
What you can do, however is avoid adding new literals. But I would pretty much leave existing the way they are.
You could probably refactor them in your free to sleep better.
Probably there are some other bugs already that need your attention. Fix those instead.
Finally, if you manage you add "refactoring" to your task list, go ahead!!!
I agree with JMD, just keep in mind that there is more to i18n than changing strings(currencies, UI must be adpated to Right-to-left languages etc)
Even if you don´t wish to 18n your application it would be useful to refactor your strings, since that string that is used today only once, maybe reused tomorrow several times, and if it´s hardcoded you may be not aware of it and star replicating string all over the place.
Best let sleeping dogs lie. If you need to change a string that's used eighteen-lumpy times, yeah, go ahead and turn it into a constant somewhere. If you find yourself working in a module that has a string that could be constant-ize, do it if you feel like it. But going through the whole app changing all strings to constants... that should be on the very bottom of the to-do list.

Resources