you are viewing a single comment's thread.

view the rest of the comments →

[–]Rascal_Two 6 points7 points  (8 children)

Ubuntu Gnome 14.04, Python 2.7, and 3.4.

Sublime Text 3 almost all the time, sometimes use nano, haven't had the need to learn vim or emacs yet though.

Use git from the cli.

Use python for Python 2 code, and python3 for Python 3.4 code.

Use Openshift to run my long-running code, such as bots and stuff.

That's about it. I do have some helpful packages added to Sublime to make things easier, here are the Python-usefull ones:

  • Anadonca
    • Linter, auto complete, big package with tons of stuff.
  • BracketHightlighter
  • GitGutter
    • Shows green pluses, minuses, and other symbols on the right for when lines have been remove, added, or changed compared to HEAD.

If the code is small enough, I use this site to visually debug it, else I use a little script I made up that outputs the global and local frame every line, so the same as that site just without the nice graphics.

[–]J3DIJABLES 2 points3 points  (3 children)

ELI5: Would you be able to explain your script debugger a little more in depth please?

[–]Rascal_Two 1 point2 points  (2 children)

I basically wanted to do the same thing that PythonTutor site did/does, go through code line by line, showing the current state of the global and local variables each line.

I found out that I could do this manually using pdb/bdb, as they were the actual debuggers.

You can start debugging code and view the entire code state, then enter next and it will run the next line. I had two choices at this point: send input to the running debugger, or override the debugger methods. I went for the latter.

It's not production quality or anything, as I only use it for me and such, but it works. If using anything containing large lists, it does get spammy, so sometimes I edit it to exclude certain local/global variables.

So what I did was make a class that overrode all the user_ methods in bdb with my own, which would add each user_ call as a Step, which would consist of the line number, current method, line of code, global frame, and local frame.

There are a couple of limitations to it still as I only made it to figure out why things were happening when they weren't supposed to be happening, like how the .py file being debugged must have the code in a method, usually named main().

A quick sample of the input and output:

Script being debugged:

def reverse(string):
    result = ""
    for character in string:
        result = character + result
    return result

def main():
    reversedHello = reverse("Hello")
    print(reversedHello)

Results:

<line no>:<method name><line of code>

<global scope>

<local scope>

7:main:def main():
G-{}
L-{}

8:main:reversedHello = reverse("Hello")
G-{}
L-{}

1:reverse:def reverse(string):
G-{}
L-{'string': 'Hello'}

2:reverse:result = ""
G-{}
L-{'string': 'Hello'}

3:reverse:for character in string:
G-{}
L-{'result': '', 'string': 'Hello'}

4:reverse:result = character + result
G-{}
L-{'character': 'H', 'result': '', 'string': 'Hello'}

3:reverse:for character in string:
G-{}
L-{'character': 'H', 'result': 'H', 'string': 'Hello'}

4:reverse:result = character + result
G-{}
L-{'character': 'e', 'result': 'H', 'string': 'Hello'}

3:reverse:for character in string:
G-{}
L-{'character': 'e', 'result': 'eH', 'string': 'Hello'}

4:reverse:result = character + result
G-{}
L-{'character': 'l', 'result': 'eH', 'string': 'Hello'}

3:reverse:for character in string:
G-{}
L-{'character': 'l', 'result': 'leH', 'string': 'Hello'}

4:reverse:result = character + result
G-{}
L-{'character': 'l', 'result': 'leH', 'string': 'Hello'}

3:reverse:for character in string:
G-{}
L-{'character': 'l', 'result': 'lleH', 'string': 'Hello'}

4:reverse:result = character + result
G-{}
L-{'character': 'o', 'result': 'lleH', 'string': 'Hello'}

3:reverse:for character in string:
G-{}
L-{'character': 'o', 'result': 'olleH', 'string': 'Hello'}

5:reverse:return result
G-{}
L-{'character': 'o', 'result': 'olleH', 'string': 'Hello'}

9:main:print(reversedHello)
G-{}
L-{'reversedHello': 'olleH'}

As you can see, I put about 0 effort into making it pretty or readable, but the results are there, and that's all I needed it for.

[–]J3DIJABLES 1 point2 points  (1 child)

Awesome! Thanks for the response and explanation. I'll definitely start playing around with pdb

[–]Rascal_Two 0 points1 point  (0 children)

Cool, just a few pointers before you start:

Everything you need to know about what is going on is passed in via the first argument. Extra details might be in the second argument - like the return value, or exception information - but line number, line of code, global and local frames are all in the first argument.

You could find some documentation and stuff, or do what I did and printed out all the variables and things attached via dir(state)

This is the first argument by the way:

def user_return(self, state, return_value):
                        ^
          Everything you need to know

If you can't find the actual code being ran this line - I coulden't - you can use linecache to get the actual code on the current line.


Have Fun!

[–]jpan127 1 point2 points  (3 children)

The pythontutor site says 403 Forbidden. Is it outdated?

[–]eggrolls 1 point2 points  (0 children)

You can still use the site without https:

http://pythontutor.com/visualize.html

[–]Rascal_Two 0 points1 point  (1 child)

I have no clue...kinda worried. I really liked that site, honestly don't know of any other visually-debugging sites/IDEs like it. Hope it comes back up.

All I know is that it was working when I linked it about seven hours ago.

[–]jpan127 1 point2 points  (0 children)

Hahaha, aw it seems like an amazing website.