Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
unixbeard
Dec 29, 2004

raymond posted:

It sort of makes sense to me but I can't really explain it. Remove the property decorator and it will act as you initially expected. When you access a property, it runs the method. If an AttributeError is raised within that method, it is caught and then __getattr__ is called.

yeah it's pretty borderline but that behaviour is contrary to the docs on __getattr__

quote:

Called when an attribute lookup has not found the attribute in the usual places (i.e. it is not an instance attribute nor is it found in the class tree for self). name is the attribute name. This method should return the (computed) attribute value or raise an AttributeError exception.

if it is found it should be able to handle the found attribute raising AttributeError and not call __getattr__

Adbot
ADBOT LOVES YOU

tef
May 30, 2004

-> some l-system crap ->

unixbeard posted:

what do you guys think of this:

it seems like __getattribute__ is interpreting the AttributeError raised in bar() as a failed lookup for foo and calling __getattr__, which in theory shouldn't happen.

__getattribute__ calls the __get__ method on foo which throws an AttributeError, which then falls back to __getitem__


this is documented " If the class also defines __getattr__(), the latter will not be called unless __getattribute__() either calls it explicitly or raises an AttributeError. "

unixbeard
Dec 29, 2004

yah but its not __getattribute__ raising AttributeError, it's finding the attribute fine and the attribute just so happens to be raising AttributeError. This is where my knowledge of python internals falls flat. Two questions:

1: Couldn't it go like this:

attempt to access .foo attribute
__getattribute__ does its thing, finds it, returns a callable
the callable is evaluated after getattribute returns, so AttributeError isn't taken as attribute lookup failure.

it's like __getattribute__ is doing its lookup, and evaluating the callable within its own scope/context and returning the result of that rather than returning the result of the lookup.

2:

I thought there was a bunch of stuff in __dict__ or something and if it was found there it wouldn't even get to the stage of __getattribute__ being called.

tef
May 30, 2004

-> some l-system crap ->

unixbeard posted:

yah but its not __getattribute__ raising AttributeError

it is __getattribute__

quote:

it's like __getattribute__ is doing its lookup, and evaluating the callable within its own scope/context and returning the result of that rather than returning the result of the lookup.

because foo is a @property. when you do A().foo, you are calling foo() to find out the attribute value.

unixbeard posted:

This is where my knowledge of python internals falls flat. Two questions:

1: no, as mentioned it is a @property, so it is not a plain old method lookup.

2. no, as mentioned it is a @propery, so if __get__ is called and fails, it will try another means

code:
>>> class A(object):
...     def foo(self):
...             return bar()
...     @property
...     def baz(self):
...             return bar()
...     def __getattr__(self, a):
...             print 'balls'
... 
>>> A().foo
<bound method A.foo of <__main__.A object at 0x100431090>>
>>> A().foo()
oioi
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in foo
  File "<stdin>", line 3, in bar
AttributeError: 'NoneType' object has no attribute 'x'
>>> A().baz
oioi
balls
>>> 
here we can see normal method lookup & property access


i.e, the call chain is looking up, then calling __get__ on the result returned, which in turn calls foo(), which raises AttributeError

FoiledAgain
May 6, 2007

I'm self-taught in Python and I don't know anything about memory, gc, etc., so sorry ahead of time if this is a dumb question.

I'm writing an iterative learning simulation where a population of agents talk to each other and name objects. The goal is look at how lexicons emerge. Agents die and are born to keep the population changing. I have a Population class that keeps track of all the living agents in a list; when they die they're just removed from the list. My question is this: what happens to the agent objects which are no longer on the list? Do I need to worry about deleting them, or will that get taken care of automatically? The population can quickly reach thousands of agents, so I feel like this is something I might need to be concerned about.

Lurchington
Jan 2, 2003

Forums Dragoon
CPython, which you're probably using, uses reference counting, so presumably, once you delete the agent from your list, there's no references remaining to that agent, and there are 0 references to it remaining. So the agent will be garbage collected.

If you're specifically tuning for keeping the smallest possible memory usage, there will probably need to be some optimizations here and there, but for the 95% case, deleting the object from list will be fine.

FoiledAgain
May 6, 2007

Lurchington posted:

CPython, which you're probably using, uses reference counting, so presumably, once you delete the agent from your list, there's no references remaining to that agent, and there are 0 references to it remaining. So the agent will be garbage collected.

Great. Thank you!

quote:

If you're specifically tuning for keeping the smallest possible memory usage, there will probably need to be some optimizations here and there, but for the 95% case, deleting the object from list will be fine.

I don't actually delete the object in the sense of using del. Instead, there's a list called marks which has all the agents who will die this turn. Then I filter out all the marks this way:
survivors = [agent for agent in self.population if agent not in marks], and later self.population = survivors

Lurchington
Jan 2, 2003

Forums Dragoon
so, in this situation, when marks falls out of scope or is re-set to a new list of agents who will die, all the agents that were in marks will (presumably) no longer have any references to them and they will be garbage collected

FoiledAgain
May 6, 2007

Why is this happening?

code:
>>> i, j = 2,3
>>> n = list()
>>> n.append([[i+n,j] for n in [-1,0,+1]])
>>> print n
1
>>> n = list()
>>> n = [[i+n,j] for n in [-1,0,+1]]
>>> print n
[[1, 3], [2, 3], [3, 3]]

brosmike
Jun 26, 2009

FoiledAgain posted:

Why is this happening?

code:
>>> i, j = 2,3
>>> n = list()
>>> n.append([[i+n,j] for n in [-1,0,+1]])
>>> print n
1
>>> n = list()
>>> n = [[i+n,j] for n in [-1,0,+1]]
>>> print n
[[1, 3], [2, 3], [3, 3]]

The behavior is weird, but documented (see footnote 1 of the Python expressions reference). It evidently behaves as you want in Python 3.0 and above.

e: In case it wasn't clear: The n in the list comprehension gets leaked in both cases, overriding n being set to the list. In the second case, n is immediately reset to be a list again once the comprehension is done - in the first case, no such luck.

Gothmog1065
May 14, 2009
I'm back! The book is making me make Asteroids, but in python. The book is using Pygame through livewires, and random/math.

I'm getting this error:

pre:
Exception AttributeError: "'Ship' object has no attribute '_gone'" in <bound method Ship.__del__ of <__main__.Ship object at 0x02A88730>> ignored
Traceback (most recent call last):
  File "C:\Users\shortymog\Desktop\Python\AstroCrash\Astrocrash.py", line 171, in <module>
    main()
  File "C:\Users\shortymog\Desktop\Python\AstroCrash\Astrocrash.py", line 164, in main
    y = games.screen.height/2)
TypeError: __init__() got an unexpected keyword argument 'image'
Here is my main() method and Ship() class:

pre:
class Ship(games.Sprite):
    """ The Ship"""
    image = games.load_image("ship.bmp")
    sound = games.load_sound("thrust.wav")
    ROTATION_STEP = 3
    VELOCITY_STEP = .03
    MISSILE_DELAY = 25

    def __init__(self, x, y):
        """ Initialize ship sprite. """
        super(Ship, self).__init__(image = Ship.image, x = x, y = y)
        self.missile_wait = 0

    def update(self):
        """ Rotate by keys pressed """
        # Rotation
        if games.keyboard.is_pressed(games.K_LEFT):
            self.angle -= Ship.ROTATION_STEP
        if games.keyboard.is_pressed(games.K_RIGHT):
            self.angle += Ship.ROTATION_STEP
        # Thrust
        if games.keyboard.is_pressed(games.K_UP):
            Ship.sound.play()
            
        # Velocity depending on angle
        angle = self.angle * math.pi /180 # HOLY poo poo IT IS TRIG
        self.dx += Ship.VELOCITY_STEP * math.sin(angle)
        self.dy += Ship.VELOCITY_STEP * -math.cos(angle)
        
        # Ship wrapping
        if self.top > games.screen.height:
            self.bottom = 0
            
        if self.bottom < 0:
            self.top = games.screen.height
            
        if self.left > games.screen.width:
            self.right = 0

        if self.right < 0:
            self.left = games.screen.width

        # Missles!
        if games.keyboard.is_pressed(games.K_SPACE) and self.missile_wait == 0:
            new_missile = Missile(self.x, self.y, self.angle)
            games.screen.add(new_missile)
            self.missile_wait = Ship.MISSILE_DELAY

        # Missile Wait time
        if self.missle_wait > 0:
            self.missile_wait -= 1

def main():
    # Background
    nebula_image = games.load_image("nebula.jpg")
    games.screen.background = nebula_image

    # Create 8 asteroids
    for i in range(8):
        x = random.randrange(games.screen.width)
        y = random.randrange(games.screen.height)
        size = random.choice([Asteroid.SMALL, Asteroid.MEDIUM, Asteroid.LARGE])
        new_asteroid = Asteroid(x = x, y = y, size = size)
        games.screen.add(new_asteroid)

    # Ship Creation
    the_ship = Ship(image = Ship.image,
                    x = games.screen.width/2,
                    y = games.screen.height/2)
    games.screen.add(the_ship)
    

    games.screen.mainloop()
What am I missing/doing wrong (Other than the fact I can't ever spell 'missile' correctly)?

Hughlander
May 11, 2005

Gothmog1065 posted:

I'm back! The book is making me make Asteroids, but in python. The book is using Pygame through livewires, and random/math.

I'm getting this error:

pre:
Exception AttributeError: "'Ship' object has no attribute '_gone'" in <bound method Ship.__del__ of <__main__.Ship object at 0x02A88730>> ignored
Traceback (most recent call last):
  File "C:\Users\shortymog\Desktop\Python\AstroCrash\Astrocrash.py", line 171, in <module>
    main()
  File "C:\Users\shortymog\Desktop\Python\AstroCrash\Astrocrash.py", line 164, in main
    y = games.screen.height/2)
TypeError: __init__() got an unexpected keyword argument 'image'
Here is my main() method and Ship() class:

pre:
class Ship(games.Sprite):
    """ The Ship"""
    def __init__(self, x, y):
        """ Initialize ship sprite. """
        super(Ship, self).__init__(image = Ship.image, x = x, y = y)
        self.missile_wait = 0

def main():
    # Ship Creation
    the_ship = Ship(image = Ship.image,
                    x = games.screen.width/2,
                    y = games.screen.height/2)
What am I missing/doing wrong (Other than the fact I can't ever spell 'missile' correctly)?

The constructor for ship just takes x/y, it doesn't take an image. The superclass takes an image, but you're passing it in statically. Either update Ship to take image, or remove image from the call to Ship.

TOO SCSI FOR MY CAT
Oct 12, 2008

this is what happens when you take UI design away from engineers and give it to a bunch of hipster art student "designers"

Gothmog1065 posted:

What am I missing/doing wrong (Other than the fact I can't ever spell 'missile' correctly)?
In addition to Hughlander's solution, I recommend you use "self" instead of "Ship" when possible. This lets subclasses and tests override attributes more easily, so it's a good habit to get into.

For example:

code:
class Ship(games.Sprite):
    """ The Ship"""
    image = games.load_image("ship.bmp")
    sound = games.load_sound("thrust.wav")
    ROTATION_STEP = 3
    VELOCITY_STEP = .03
    MISSILE_DELAY = 25

    def __init__(self, x, y):
        """ Initialize ship sprite. """
        super(Ship, self).__init__(image = self.image, x = x, y = y)
        self.missile_wait = 0

    def update(self):
        """ Rotate by keys pressed """
        # Rotation
        if games.keyboard.is_pressed(games.K_LEFT):
            self.angle -= self.ROTATION_STEP
        if games.keyboard.is_pressed(games.K_RIGHT):
            self.angle += self.ROTATION_STEP
        # Thrust
        if games.keyboard.is_pressed(games.K_UP):
            self.sound.play()
        
        # ... and so on ...

Gothmog1065
May 14, 2009

Janin posted:

In addition to Hughlander's solution, I recommend you use "self" instead of "Ship" when possible. This lets subclasses and tests override attributes more easily, so it's a good habit to get into.

For example:

code:
class Ship(games.Sprite):
    """ The Ship"""
    image = games.load_image("ship.bmp")
    sound = games.load_sound("thrust.wav")
    ROTATION_STEP = 3
    VELOCITY_STEP = .03
    MISSILE_DELAY = 25

    def __init__(self, x, y):
        """ Initialize ship sprite. """
        super(Ship, self).__init__(image = self.image, x = x, y = y)
        self.missile_wait = 0

    def update(self):
        """ Rotate by keys pressed """
        # Rotation
        if games.keyboard.is_pressed(games.K_LEFT):
            self.angle -= self.ROTATION_STEP
        if games.keyboard.is_pressed(games.K_RIGHT):
            self.angle += self.ROTATION_STEP
        # Thrust
        if games.keyboard.is_pressed(games.K_UP):
            self.sound.play()
        
        # ... and so on ...

Yeah, a lot of that code was consolidated with some other classes. I'll be working on modifying the code after the book finishes, like putting a cap on the velocity (How I'm going to work that, I don't know yet), and maybe do some other stuff (Setting sizes, rotation sensitivity, maybe even putting "brakes" on the down key. I'm still in the learning process, and I"m sure I'll be asking plenty more really stupid questions. I just don't like moving forward if something is broke and I don't know why.

German Joey
Dec 18, 2004
Hey, does anyone know if there's anything like Perl's POE for Python?

http://poe.perl.org

I'm trying to write some code that:
  • Starts off a bunch of processes/threads (flows happening in parallel) instantiated off a particular class, which should run indefinitely as if it were a little server
  • Each of these parallel executions will share data through a read-only manner
  • Within each of these parallel executions, child thread/processes will need to be started, which also run indefinitely - like little child servers
  • These Child threads are synchronized via a message-passing scheme

The easiest way to code this would actually be to make all these processes into little daemons and communicate via TCPIP, but unfortunately that would be way slower for what I want to do. So, I've been dealing with threading.Thread, trying to figure out synchronization using Conditions. How do I block? Why can't you just loving sit there until someone else tells you to wake up? Its all so frustrating.

But, I figure someone else has built some kind of easy way to deal with all of this? What I want to do seems so generic. Someone must have figured all this out before and put it in a module. Any ideas?

German Joey
Dec 18, 2004
AHA, thought of a different way to search and THAT'S A BINGO! ooo what fun! THIS, this is what I want, pretty much exactly:

http://twistedmatrix.com/trac/wiki/DeferredGenerator

Has anyone used this Twisted (:twisted:) framework before?

DirtyDiaperMask
Aug 11, 2003

by Ozmaugh

German Joey posted:

The easiest way to code this would actually be to make all these processes into little daemons and communicate via TCPIP, but unfortunately that would be way slower for what I want to do. So, I've been dealing with threading.Thread, trying to figure out synchronization using Conditions. How do I block? Why can't you just loving sit there until someone else tells you to wake up? Its all so frustrating.

You can use Condition or Event(calling wait() should block until another thread calls notify or set) to synchronize threads, but if you're looking for a more straightforward way to synchronize threads, try Barrier? It's new to 3.3 however you could just yank the code out of the threading library if you can't run that. And 3.2 has concurrent.futures, which has the same functionality of Twisted's DeferredGenerator. And while I haven't used Twisted much myself, the general opinion seems to be the documentation is ultra-bad

DirtyDiaperMask fucked around with this message at 21:36 on Jun 11, 2011

Profane Obituary!
May 19, 2009

This Motherfucker is Dead
The Twisted framework docs are pretty bad, and a lot of the code is written to be more javaesque then Python, but all in all it's not the worst bit of code in the world.

Grabulon
Jul 25, 2003

I'm writing a game in Pygame, and I currently have an enemy class and a level class. Is it good OOP design to pass a reference to the level instance in the enemy constructor, like this:

code:
class Level:
    ...

class Enemy:
    def __init__(self, level_instance):
          self.level_instance = level_instance

level = Level()
enemy = Enemy(level)

It makes it easy to access the level's is_wall() method, but maybe there's a better way?

German Joey
Dec 18, 2004

DirtyDiaperMask posted:

You can use Condition or Event(calling wait() should block until another thread calls notify or set) to synchronize threads, but if you're looking for a more straightforward way to synchronize threads, try Barrier? It's new to 3.3 however you could just yank the code out of the threading library if you can't run that. And 3.2 has concurrent.futures, which has the same functionality of Twisted's DeferredGenerator. And while I haven't used Twisted much myself, the general opinion seems to be the documentation is ultra-bad

man, Barrier was just what I needed. Thank you! This was a real lifesaver considering, like you said, Twisted's documentation was a complete disaster. I gave it a few hours until I gave up and realized that I'd be way better off (in terms of my own sanity) just figuring out how to synchronize my drat threads.

Clandestine!
Jul 17, 2010
So I just started with Python last night. This is my first foray into programming languages; I have some understanding of HTML and CSS from highschool, but that doesn't mean much :downs: My first objective was to code a lottery number simulator. Easy, right?

code:
import random

numberz = []
x = 0

while x < 6 :
    numberz.append(random.randint(1, 49))
    x += 1

numberz.sort()
print numberz
Now, instead of the lotto 649 generator I made before, I'm trying to make one that allows you to specify how many numbers you want, and the minimum and maximum values you want. And I am doing something horrifically wrong.

code:
import random

def numberlist(a, b, c):
    numbers()
    x = 0
    
    while x < a:
        numbers.append(random.randint(int(b), int (c))
        x += 1

        return numbers

a = raw_input("How many numbers do you need?")
b = raw_input("What's the highest possible value?")
c = raw_input("What's the lowest possible value?")     


numberlist(a, b, c)
:downsgun:

Anyone wanna teach me how to not code bad, please and thank you? Sorry for the textwall.

Bazanga
Oct 10, 2006
chinchilla farmer
Anyone know of a good Python application deployment system? I've been googling around for one but it seems like most of them are either abandoned or really lacking in functionality. It doesn't help that I know fuckall about application deployment. I'm not a coder by trade and can't remember the last time I did any serious application packaging or deployment.

I ask because I'm working on a project to create a p2p number cruncher similar to Prime95 except in Python. The project is mainly just to learn about Python but I'd like to eventually be able to turn the application into an installable form that I can just pop onto fresh machines without having to have Python and the libraries installed beforehand.

Similarly, are there any particularly good secure networking libraries out there for Python?

THANKS PYTHON BROS :glomp:

alltoohuman
Jul 26, 2007

Shut up, Marx.

Clandestine! posted:

def numberlist(a, b, c):
numbers()
x = 0

while x < a:
numbers.append(random.randint(int(b), int (c))
x += 1

return numbers

a = raw_input("How many numbers do you need?")
b = raw_input("What's the highest possible value?")
c = raw_input("What's the lowest possible value?")


numberlist(a, b, c)[/code]

:downsgun:

Anyone wanna teach me how to not code bad, please and thank you? Sorry for the textwall.

Couple of things. The first is that you want to create your list like so:
code:
numbers = []
"raw_input" will return a string, which will do weird things to the condition on your while loop. For example:
code:
>>> 3 < "3"
True
>>> 3 < 3
False
If you use just plain "input" instead, it will work, or you can call int() on what raw_input gives you.

Also, the "return" statement should be on the same indentation level as the "while".

Edit: Oh, you also have b and c in the wrong order in your random.randint call.

alltoohuman fucked around with this message at 22:08 on Jun 13, 2011

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe
There is also another problem with your algorithm that I guess you haven't run into yet. The call to randint could return the same number which is not supposed to happen in the lottery!

What you really want is to create a list of all the possible numbers, select a random number from the list, remove it and finally add it to the list of winning numbers that you are constructing. The next time you go to remove a number at random from the list you'll be guaranteed that it will be different since the old one was already removed.

Computer viking
May 30, 2011
Now with less breakage.

MEAT TREAT posted:

There is also another problem with your algorithm that I guess you haven't run into yet. The call to randint could return the same number which is not supposed to happen in the lottery!

What you really want is to create a list of all the possible numbers, select a random number from the list, remove it and finally add it to the list of winning numbers that you are constructing. The next time you go to remove a number at random from the list you'll be guaranteed that it will be different since the old one was already removed.

That's incidentally a good use for random.sample(). Given more sensible variable names, you can do something like this:
pre:
numbers = random.sample(range(minval, maxval), numbercount)
That's sort of counterproductive from a learning POV, but if you ever want to pick random numbers later on it's better to use the existing tools. :)

Lurchington
Jan 2, 2003

Forums Dragoon

Bazanga posted:

The project is mainly just to learn about Python but I'd like to eventually be able to turn the application into an installable form that I can just pop onto fresh machines without having to have Python and the libraries installed beforehand.

this isn't strictly deployment, but on windows, you have py2exe: http://www.py2exe.org/
and if you develop with python 2.4 as your base version, (at least) that already comes packaged with Macs and Linux

Gothmog1065
May 14, 2009
Dumb general question, but I've finished my python book. Is there a site out there that has some simple "challenge" programs to do to help learn? I've gone one that should be easy enough to do, but I'm really lovely with coming up with ideas.

Captain Capacitor
Jan 21, 2008

The code you say?

Gothmog1065 posted:

Dumb general question, but I've finished my python book. Is there a site out there that has some simple "challenge" programs to do to help learn? I've gone one that should be easy enough to do, but I'm really lovely with coming up with ideas.

Project Euler!

Profane Obituary!
May 19, 2009

This Motherfucker is Dead

German Joey posted:

man, Barrier was just what I needed. Thank you! This was a real lifesaver considering, like you said, Twisted's documentation was a complete disaster. I gave it a few hours until I gave up and realized that I'd be way better off (in terms of my own sanity) just figuring out how to synchronize my drat threads.

There are other options then Twisted btw, gevent, Circuits, eventlet etc.

Clandestine!
Jul 17, 2010
You folks are lifesavers, thanks. I didn't think about randint returning the same number, which I guess is something I should've considered. :v: EDIT: Now I'm running into trouble finishing my code. When I try to run it, I get a message saying "invalid syntax" and the 'x' in 'x += 1' is highlighted. I hope I'm not trying anybody's patience here, but I really cannot get a grasp on this stupid bit of programming.

Clandestine! fucked around with this message at 05:41 on Jun 14, 2011

Pivotal Lever
Sep 9, 2003

Clandestine! posted:

You folks are lifesavers, thanks. I didn't think about randint returning the same number, which I guess is something I should've considered. :v: EDIT: Now I'm running into trouble finishing my code. When I try to run it, I get a message saying "invalid syntax" and the 'x' in 'x += 1' is highlighted. I hope I'm not trying anybody's patience here, but I really cannot get a grasp on this stupid bit of programming.

If your current code is similar to the sample you posted above, you're missing a closing parethesis on this line:
code:
numbers.append(random.randint(int(b), int (c))
Change it to this and it should work:
code:
numbers.append(random.randint(int(b), int (c)))
Python has implicit line continuation inside brackets, which allows you to do things like this without throwing an error:
code:
numbers.append(random.randint(int(b), 
               int (c)))
Whenever python throws a syntax error and gives the first non-whitespace character in a line as the reason, check the previous line to make sure you have all your closing brackets.

Here's where this is explained in the python docs: http://docs.python.org/reference/lexical_analysis.html#implicit-line-joining

Using an editor that highlights the matching parenthesis makes these errors much easier to spot. Most 'programmer's editors' will highlight the matching bracket when the cursor is placed over either the opening, or closing bracket. If nothing is highlighted, you're missing a bracket.

Here's what it looks like in vim:

The green parens is under the cursor, and the blue parens is the matching one. I moved my cursor over the parens after 'number.append', and nothing was highlighted, which quickly showed me that a closing parens was missing. x += 1 is highlighted in red because I have the pyflakes.vim plugin installed, which highlights syntax errors as you code. Bracket highlighting is built into vim, so you don't have to mess around with plugins to get that working. My .vim directory is up on github [https://github.com/bobmurder/dotvim] if you'd like to see one way to set up vim for python programming.

Also, you should probably cast a, b and c to int on the raw_input lines instead of casting to int when passing them as arguments to functions. I'm not 100% sure about this, so if someone else knows, let both of us know.

The rest of my post is about editors, and people have strong opinions about them. Take your time, and find one you like.

My editor of choice is vim. It does have a steep learning curve, but I think it's worth it. Emacs is the other big name in programming editors. The big difference is that vim uses modal editing, which means that depending on which mode you are in, different keys do different things.

Emacs is always in what vim calls 'insert mode', so when you type, text is entered. With vim, you must explicitly enter insert mode by pressing i to enter text, and Esc to exit insert mode. The nice thing about vim is you don't need to use Ctrl+<key> or Alt+<key> to use hotkeys, like in emacs. When you are in normal mode in vim, the keys themselves are used to move the cursor around. This may not sound useful now, but if you get to know all the movement keys, you can move around in a file and perform editing tasks much faster than you ever could with a mouse.

I tried both vim and emacs before I settled on vim. It seemed more efficient and natural to me. Both editors have an astounding amount of plugins/scripts to extend their functionality. I'd try both before settling on one of them.

There are also a number of other programming editors out there. Off the top of my head, there's geany, kate, gedit, notepad++, SciTE, pico, and if you use OS X and like paying for things, I hear TextMate is pretty good. Try out a bunch and pick one you like. Notepad and IDLE are alright for the first couple days of programming, but once you use and learn a real editor, you won't go back.

Pivotal Lever fucked around with this message at 09:45 on Jun 14, 2011

Lurchington
Jan 2, 2003

Forums Dragoon
for general text editing on Mac, I like TextWrangler and it's free.

But for python stuff, I'm an IDE guy, so:
Eclipse with PyDev - http://pydev.org/ - free and perfectly fine
PyCharm - http://www.jetbrains.com/pycharm/ - has certain free licenses, and is greater than everything ever

tripwire
Nov 19, 2004

        ghost flow

Lurchington posted:

PyCharm - http://www.jetbrains.com/pycharm/ - has certain free licenses, and is greater than everything ever
If they don't start listening to my furious rants about the code formatter gobbling up all of your whitespace on blank lines I'm going to suicide bomb something.

MaberMK
Feb 1, 2008

BFFs
sorry guys, vim still blows everything else away

http://sontek.net/turning-vim-into-a-modern-python-ide

Profane Obituary!
May 19, 2009

This Motherfucker is Dead

tripwire posted:

If they don't start listening to my furious rants about the code formatter gobbling up all of your whitespace on blank lines I'm going to suicide bomb something.

Can't you turn that off?

tripwire
Nov 19, 2004

        ghost flow

Profane Obituary! posted:

Can't you turn that off?

Nope.

Profane Obituary!
May 19, 2009

This Motherfucker is Dead

tripwire posted:

Nope.



This option doesn't stop it from doing that?

tripwire
Nov 19, 2004

        ghost flow

Profane Obituary! posted:



This option doesn't stop it from doing that?

Haha, you'd think it did, but you'd be wrong!

That only prevents it from stripping your blank lines when you save. Nothing prevents it from stripping them when you reformat :)

Profane Obituary!
May 19, 2009

This Motherfucker is Dead
Oh I see, well then carry on your furious rage!

Adbot
ADBOT LOVES YOU

German Joey
Dec 18, 2004
Wait, what does it do? I just gave this IDE a try and it seemed pretty kewl so far...

  • Locked thread