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
Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I was reading the Flask documentation and thinking of playing with it. But I'm not clear on whether, or how, I can make something run in Flask on my shared hosting. The stuff about making it work with Apache might as well be written in Greek. Besides that I'm pretty sure the most I can do to "configure Apache" is to write a .htaccess file. Can anyone give me some pointers? I'm not used to scripts needing a great deal of configuration before they'll run, because I'm used to PHP.

Adbot
ADBOT LOVES YOU

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Baby Nanny posted:

You can always use something like http://heroku.com/ and host your static files (CSS, images, etc) on your shared hosting. Heroku is a great (and free!) way to get your python webapps on the Internet when you're learning.

I think I would rather plump for a vps than tie myself in to using something like that.

I checked with my hosting provider and it doesn't look like they are able to support WSGI setups such as are required by Flask and the like.

I'll have to put this idea on the back burner. Thanks for the suggestions.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Baby Nanny posted:

You wouldn't be tied to anything since it'll be using the same git repo that you can just deploy on to a real server or vps when you're ready. Honestly if you're just learning go with heroku there's really no downside (that is until your site gets popular then you just move it)

Well maybe I should explain my situation. I have a web application that already exists, written using PHP and MySQL. I first opened it up a little over 3 years ago. It has a small but respectable number of users, mostly as a result of doing something that's not available elsewhere (play an obscure boardgame). Some parts of it I'm reasonably proud of, some parts are grotty because I was learning as I went and/or stupid.

I would like to do a better job of maintaining and upgrading it, but I have a couple of problems. I feel like if I invest time into programming as a hobby, it would be a good idea to not stay in my comfort zone all the time with a language I am already familiar with, hence the interest in learning something other than PHP. And also, PHP as a language has its share of problems. For the most part these can be worked around, yes I know PHP makes it easy to write spaghetti code and there are a million array_* functions that all do variations on the same thing and have arguments in different orders, and there is no built-in support for unicode, but all of those things can be carefully navigated if you are familiar with the language and mindful of its shortcomings. But the thing that most motivates a move away from it I think is that the development team seems kind of unserious about producing a language that does a good job and does it securely. For example the recent thing about being able to pass command-line arguments to PHP, admittedly on an uncommon configuration. That was introduced as a regression because the PHP devs noticed their code that guarded against it, said "Was there ever a reason we had this code? Whatever" and deleted it. At the moment my hosting provider takes responsibility for keeping the server's PHP up-to-date, but if I ever chose to move to a VPS for unrelated reasons then I'd have to stay on top of it (I guess) and it sounds like it would be more of a hassle than it would need to be. In contrast to PHP's other flaws, that isn't something that there exists an easy workaround for.

So I toy with the idea of rewriting the thing in another language. This would mean I learn another language and move away from PHP, at the cost of significant duplication of effort.

The real reason I have no interest in Heroku is that if I did re-implement my existing web application in Python, and close the old one and tell everyone to move to te new one, there would be no smooth curve from zero uptake to "too much uptake to be free on Heroku". It would go straight there. Hence no point in Heroku unless I do intend to pay for it. (A 5mb database is no good.)

What I really find myself wondering is why there is no language that has the advantages of PHP without the brain damage. When I say advantages, I mean that you can write a script whatever.php and upload it, and it works straight away. And if you change something and upload it, the new version works straight away, too, you don't need to tell something at the server "pay attention, I changed something", as you apparently do with everything else.

I have no formal education in computer science or software development. By the way what is a good book for picking up Python if you are already familiar with PHP?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I'm reading through O'Reilly's "Learning Python", 4th ed. I'm reading the chapter on numeric types, specifically the pages about the decimal module. The author seems to suggest setting setcontext().prec to 2 in order to do calculations with money. But from my experiments it seems like this sets the number of significant digits used for results, rather than the number of digits used to the right of the decimal point. For example, the following example is given in the book (slightly paraphrased):

Python code:
>>> import decimal
>>> decimal.getcontext().prec = 2
>>> decimal.Decimal(str(1999 + 1.33))
Decimal('2000.33')
But you can also do something like this, and lose the fractional part of a number:

Python code:
>>> import decimal
>>> decimal.getcontext().prec = 2
>>> decimal.Decimal('1999') + decimal.Decimal('1.33')
Decimal('2.0E+3')
Have I misunderstood something, or is the book giving really bad advice?

I'm running Python 3.2.3 on 64-bit Windows 7.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
That's what I thought.

I have another question. I understand that / performs division and yields a floating-point result, in Python 3.X. So I reasoned that if the operands are too large to be converted to floats, then the interpreter should fail to do the division, even if the result is something that can be represented comfortably as a float. But this is not what happens.

Python code:
>>> x = 2 ** 1501
>>> y = 2 ** 1500
>>> float(y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OverflowError: long int too large to convert to float
>>> x / y
2.0
The division succeeds just fine even when x and y are coprime, so there are no clever factoring tricks to be done.

Python code:
>>> x = 2 ** 1500
>>> y = x + 1
>>> x / y
1.0
Is there some kind of magic happening that makes this work?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Reading about strings and their literals at the moment. Is there a reason why in raw strings, the backslash escapes the string quote character, while being preserved in the string even when used in that way? It seems baffling. I realise that raw strings are just a convenience for more easily expressing some string literals and that there are plenty of ways around it.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Suspicious Dish posted:

Because it's hard to do in the lexer otherwise, and because there's otherwise no way to insert a regular quote character.

How is it "hard to do in the lexer"? Seems like the lexer is already able to do comparable things when parsing regular string literals.

And I'm not disputing that there would be no way of inserting a regular quote character if they couldn't be escaped - I'm saying I don't understand the reasoning behind the backslash used to do the escaping being preserved in the resulting string.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I understand that there are various statements in Python that implicitly carry out assignment. So for example a def statement is just a special kind of assignment statement used for assigning a function, and the header statement of a for loop carries out assignment. But I noticed while experimenting that you can index a dictionary or list in one but not the other. Is there a particular reason for this difference in behaviour?

code:
Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {}
>>> for d['x'] in [1, 2, 3]:
...     print('butt')
...
butt
butt
butt
>>> d['x']
3
>>> def d['f'] ():
  File "<stdin>", line 1
    def d['f'] ():
         ^
SyntaxError: invalid syntax
>>>

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Suspicious Dish posted:

The def statement (and the class statement, too) takes an identifier in the grammar. The for statement takes an expression.

The for loop takes an expression because it needs to do:

Python code:
for k, v in D.iteritems():
    print k, v

I thought that dictionary and list offsets were indeed identifiers, since you can assign to them, but I guess not.

Actually, something just clicked for me, because I had been wondering what exactly the thing on the left is in a statement like

[a, b] = 'xy'

I was reluctant to think of it as a "list" because I was thinking of lists as something that contains objects, not unresolved names. But I guess really there is no reason why it can't contain unresolved names up until the point it's evaluated, or in this case, purposely contain unresolved names so as to be the target of assignment. So that makes more sense to me now.

So, the notion of the assignment target in a for loop header being in fact an expression does explain it for me. Thanks.

quote:

And while you're at it, why not allow all kinds of expressions?

I don't know. Why not indeed. That's why I was asking - you react as though you think I'm trying to argue for one behaviour or other.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
code:
Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> L = [5, 6, 7]
>>> [x ** 2 for x in L]
[25, 36, 49]
>>> x
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'x' is not defined
>>> for x in L:
...     x ** 2
...
25
36
49
>>> x
7
>>> x = [0]
>>> [x[0] ** 2 for x[0] in L]
[25, 36, 49]
>>> x
[7]
>>> [x ** 2 for x in L]
[25, 36, 49]
>>> x
[7]
>>>
I can't make sense of this behaviour. If you use a for loop, then the iteration dummy variable is visible after the loop and has its value from the last loop iteration. But if you use a list comprehension, then it is not visible (or is unchanged, if it existed). Except that for some expressions it will modify dummy variables that share a name used outside of the list comprehension? This seems rather inconsistent.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

ynohtna posted:

List comprehensions are a shorthand for lambda functions and thus create a new scope in which their variables exist.

Oh OK, so it's like I wrote a loop inside a function (or I'm running a function inside a loop) that uses the variable x or refers to x[0], and in the second case Python can't make sense of x[0] using the function's set of names so looks up into the global scope and finds x there.

I am just going to share this because I found it funny:

code:
Python 3.2.3 (default, Apr 11 2012, 07:15:24) [MSC v.1500 32 bit (Intel)] on win
32
Type "help", "copyright", "credits" or "license" for more information.
>>> [x + y for x in range(y) for y in range(10) if (x + y) % 2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'y' is not defined
>>> [x + y for y in range(10) for x in range(y) if (x + y) % 2]
[1, 3, 3, 5, 5, 7, 5, 7, 9, 7, 9, 11, 7, 9, 11, 13, 9, 11, 13, 15, 9, 11, 13, 15
, 17]
>>>
I couldn't work out what was happening until I realised that it expects the for clauses to be in a strange order.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

PiotrLegnica posted:

It's actually the same order as always, if you look at it this way:

code:
# for y in range(10) for x in range(y)
for y in range(10):
    for x in range(y):
        ...

No, it's not the same order, because if it was in that order then the "x + y" would have to go at the end of the list comprehension expression. What you posted there represents something like this:

code:
# for y in range(10) for x in range(y)
for y in range(10):
    for x in range(y):
        do a thing with x and y
That would only be in the same order if the list comprehension looked like this:

[for y in range(10) for x in range(y) do a thing with x and y]

But it doesn't, the "do a thing" appears at the start and not at the end.

The reason the order is strange to me is that the expression "x + y" is maximally general, with 2 indeterminates. It's followed by the range of y-values, which has no indeterminates, and then by the range of x-values, which is in between the two in terms of generality (it depends on one indeterminate, y). So the order (of expression clauses by number of indeterminates) goes 2, 0, 1. That's a bizarre order.

It's only a nitpick, but it is a counter-intuitive order for the clauses to have to appear in.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Jewel posted:

Naw, the order isn't strange because, I don't think? Think of it this way:

code:
array = [x + y for y in range(10) for x in range(y) if (x + y) % 2]
Is equivalent to

code:
array = []

for y in range(10):
    for x in range(y):
        if (x+y) % 2:
            array.append(x+y)

If you make a point of writing it this way then that to me represents more an argument that the "x + y" should appear at the end of the expression, after the if clause.

quote:

It's saying "put 'x+y' in the array FOR this statement IF this is true"

Whereas if you say it this way, then the ordering of the for clauses should still to me be in decreasing order in number of indeterminates (because the maximally general clause, "x + y", is furthest left). The if statement belongs after the for clause to which it applies because it's a further (optional) restriction on the set of values that make it to the "x + y" expression.

To argue by analogy: we write



we don't write

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

PiotrLegnica posted:

I only referred to the order of for components in the comprehensions. That expression goes first is just a common convention, going all the way back to math notation.

Sure, but given that the expression comes first, the nested for clauses should not appear in the same order as the header lines would in the corresponding explicit nested for loop. Rather, they should sensibly appear in the reverse order, for reasons I have expressed.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

spankweasel posted:

I do all of my python at the system level. No web stacks for me. I absolutely hate seeing try/except used as a control structure. There are functions designed for asking permission and it leads to better code, especially in a team of 20 people, 15 of which hadn't seen python before 2 years ago.

Legibility of code counts for more for me because people come and go. The code has to live for awhile and if have anything to say about, I'll try to make it as clean and well organized as I can so the other folks on my team can maintain the code after I'm gone.

I can understand the sentiment but, speaking as someone who has only just started learning python, it seems like there is an established culture of "exceptions as tools of control flow". e.g. exceptions are how you know how an iteration is finished, etc.

And what would you say in reply to the point that if you "check, then do", something could happen in between the checking and the doing? In contrast if you wrap the "do" in a try then you are free of that worry and you handle the failure case just fine.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

the posted:

So I have an array of a bunch of floats. I want to find what spot in the array that 4.25 is in there (it's in there). How do I do that?

Are we talking precisely 4.25, or just something that is 4.25 to some degree of precision? If it is the former you can just use the index() method.

As in: mylist.index(4.25)

If it needn't be precisely 4.25 but just quite close, I guess you have to do something more involved.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Suspicious Dish posted:

Yes, that's invalid syntax.

More specifically...

You need another + between name and "!" on the final line

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

huhu posted:

Oh gently caress, I think it's time for me to stop coding for the night I'm starting to lose it. Thanks for clarifying.

Edit:I swear I have a real question now.

The problem is:


Here is my code:
code:
a=0
b=0
c=0
for x in range(1,1000):
    a=x
    for y in range(1,1000):
        b=y
        for z in range(1,1000):
            c=z
            if a<b<c and a+b+c==1000:
                if a**2+b**2==c**2:
                    print(a,b,c)
It gets the answer but takes about 30 seconds to do so. What makes it so horribly inefficient? I thought that moving around the last three commands of a<b<c a+b+c==1000 and a**2+b**2==c**2 to their own if statements would make it faster but I don't think so.

There is no reason for the third, innermost loop. Once you have chosen values for a and b, the value of c is fixed (namely, it is 1000 - a - b). You are looping a factor of 1000 times more than you should be.

Since you are requiring that a < b, you could also build that requirement into the second range(). (i.e. have the range for b / y be dependent on the current value of a.)

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Example:

code:
>>> import math
>>> def f ():
...     for x in range(1, 334):
...         for y in range(x, math.floor(501 - x / 2)):
...             if x**2 + y**2 == (1000 - x - y)**2:
...                 return x * y * (1000 - x - y)
...     return 'Not found'
...
>>> f()
31875000
If you want me to explain anything, then ask.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
When you write

if selection == 'n' or 'north':

because the "==" operator has higher precedence than the "or" operator, it is equivalent to this:

if (selection == 'n') or 'north':

So you are asking: is it the case that either selection == 'n' is true, or 'north' is true?

The string 'north' always counts as True, so the value returned by "or" will always be True here.

You could change the line to

if selection in ['n', 'north']:

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

huhu posted:

Ended up with a surprisingly fast code which went through about 5000 names in less than a second. I will check out dictionaries and ord now though thanks.

code:
def score(this_name):
    sum=0
    for j in range(len(this_name)):
        if this_name[j]=='A': sum+=1
        ...
        if this_name[j]=='Z': sum+=26
    return(sum)
Edit: I've solved 14 of the first 22 problems on Project Euler. I'd like to start learning about other aspects of Python that aren't focused primarily on solving math problems similar to Project Euler. What would be the next best logical step from here?

I guess that works, but you're not really using the strengths of the language to cut down on the amount of code you have to write. See how it is possible to do the same thing in four lines of Python code, with less repetition:

Python code:
def score_character (c):
    ordc = ord(c.lower())
    return ordc - 96 if 97 <= ordc <= 122 else 0

def score (name): return sum(score_character(c) for c in name)
To answer your question, it seems like it would be worthwhile learning about Python's iterators, list generators and the like, as it could let you become more comfortable coming up with efficient solutions of your own.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I just found out that Python chokes if you do this:

code:
f(*L,)
Specifically it does not like a trailing comma after the argument-unpacking operator.

Why does it do this? I thought trailing commas in argument lists, etc. were fine.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I set out to make a Python program that interacts with the user through the command line and gives a (more-or-less) friendly interface allowing them to make changes to the contents of a database, or dump the database contents. I wasn't sure quite how to do it, but what I came up with is this: I have a class which defines a __call__() method. When the module is loaded, an object of this class is instantiated and assigned to main. As a result, the program can be launched by calling modulename.main(). The __call__() method looks like this:

Python code:
def __call__ (self, autocommit = False):
    '''See the class's docstring.'''

    self.autocommit = bool(autocommit)
    # Code goes here in which the "self" object is prepared.
    handlers = {
        self._mode_connect: self._handler_connect,
        self._mode_quit: self._handler_quit,
        self._mode_select_trainer: self._handler_select_trainer,
        ... (more) ...,
        self._mode_write: self._handler_write,
    }
    mode = self._mode_connect
    while mode:
        # When each handler returns, it tells us which mode to go to next,
        # or it returns a False-like value, in which case we are done.
        mode = handlers[mode]()
So the class also has a bunch of methods with names that follow the pattern _handler_*(), and for each one a corresponding constant _mode_*. Each one returns one of the _mode_* constants when it is done, except for _handler_quit(), which returns None.

The module also has a global dictionary "messages" (text to be output to the user) and a global dictionary "_queries" (SQL queries). Having the messages and queries inline was proving to be unwieldy.

Is this how something like this would ordinarily be done, or is it unusual? Is there a better way to implement this kind of behaviour? I found that having a set of individual handler functions let me strike a good balance between being able to keep some global state (by assigning to attributes of self) and keeping the logic of a particular handler localised. I did end up with one quite hairy handler function that is 570 lines long now that I have written a docstring and added comments to it, but the states it has to manage are so intricate I think that I would have had difficulty not making it huge.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Pangolin Poetry posted:

When I do that (give self, a as arguments and only pass a) it gives me a "fun takes exactly two arguments (1 given)" error

Basically: When you define a function within a class, that function becomes an attribute of your class. So if you do this:

Python code:
    class cat:
        def meow ():
            print('Meow')
you can then call the "meow" method by typing cat.meow() (obviously from a suitable scope). That is how it behaves if there is no actual instantiation of the class involved, only the class object itself ("cat" here).

When you create an instantiation of the class, by typing something like fluffy = cat(), you can then access the "meow" method through "fluffy" (an object of class cat) as well as through cat (a class object). However, when you type fluffy.meow(), that is treated as though you had typed cat.meow(fluffy). That is, what really happens is that the "meow" method of "cat" is called and the relevant cat object is prepended to the list of arguments that you supplied.

That is why you always include "self" as the first parameter when you define a class method, because if you don't then you cannot call it through an instantiation of the class without potentially odd things happening. This is also why the "self" object is available in the object method's scope.

(You do not have to call it "self", but it's established convention to do so.)

Hammerite fucked around with this message at 08:01 on Sep 17, 2012

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
You can write long string literals in sequence and they are automatically concatenated together.

Python code:
mylongstring = (
    'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod '
    'tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim '
    'veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea '
    'commodo consequat. Duis aute irure dolor in reprehenderit in voluptate '
    'velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint '
    'occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit '
    'anim id est laborum.'
)

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

A Fistful of Dicks posted:

I'm going through the reading list, and I'm checking out the built-in functions part of the Python Reference Library and idkwtf dude...it's incomprehensible for a nooblet like me. What do I need to read in order for this to make sense?

When I learn how to do something with a programming language, I generally like to do it by using the language in anger, i.e. I have something I want to achieve and I learn the tools I need to do it. Is there anything you are trying to work towards, or are you just trying to learn the language "in general"? Perhaps it would help to focus on a particular topic.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Carthag posted:

How would you guys go about sorting open-ended "ranges"? I have a bunch of numbers in tuples that represent ranges (start, end) and I want to sort these in a specific way.

Python code:
...

expected = [
	(None,0),
	(0,0),
	(0,2),
	(None,1),
	(1,1),
	(2,2),
	(2,None),
	(2,3),
	(3,3),
]

print sortedvals
print sortedvals == expected
I guess I'm growing old, I can't wrap my head around it.

Let me check whether I understand this. You're trying to sort open intervals, and None is a stand-in for minus infinity or infinity? And expected is the ordering you want to end up with? (I'm not sure whether this is a correct understanding. In particular, if these really are meant to be open intervals, then for example (2, 2) and (3, 3) both represent the empty set, and so given that they're equal they should surely be placed adjacent in expected.)

I can't deduce any logic behind the ordering given in expected. Is this where you are running into difficulty, or is it something else that is the problem.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
I've decided that 79 characters per line is too restrictive for me on the project I'm working on, and that 89 characters per line is more appropriate. But I'm loath to make an exception for docstrings, so I'm most likely just going to wrap them at the 89 character line as well. So some of the lines in the docstrings are going to end up longer than 79 characters after being treated by the automatic formatter. I think it is reasonable enough just to dismiss this as NMFP, but does the idea make anyone froth with rage?

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Maluco Marinero posted:

Yeah, what is that 10 characters buying you that you need so much? Is it because you're nesting too heavily?

Are you not breaking up long line statements to make them more readable, such as chained methods?

That is difficult for me to answer because I don't know what "nesting too heavily" means (to you or to anyone else). I am breaking up long statements into multiple lines, but I was finding that I had to do so a bit more frequently than I was entirely happy with. However, I have concluded that I quite like the width and readability of my code at 89 characters, so I am going to stick to it.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

baquerd posted:

Suppose I have a list of values and a list that represent the indices of the values that I want to slice:

code:
#core
values = ["Blue", "Green", "Yellow", "Red"]
indices = [1, 3]
sliced = [values[i] for i in indices]
Is this reasonable? I'm very unfamiliar with python.

I don't know anything about numpy so I won't comment on that. The above should set sliced to be ["Green", "Red"]. Since you are talking about slicing I assume what you expected was ["Green", "Yellow"]. You could do that like this:

code:
#core
values = ["Blue", "Green", "Yellow", "Red"]
indices = [1, 3]
sliced = values[slice(*indices)]

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

baquerd posted:

I was specifically looking for ["Green", "Red"], but you just taught me about the slice function. I suppose there would be a different terminology used for a discontinuous slice?

Do you mean a slice with a step parameter? It should work fine for that as well.

Python code:
values = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
indices = [1, 8, 2]
sliced = values[slice(*indices)] # [1, 3, 5, 7]

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Suspicious Dish posted:

There's nothing wrong with this. I don't know why Hammerite is trying to convince you differently. Note that it's very unusual you'll have something like this, so if you do have this exact problem, please post more context so we can lead you to a better solution for your specific problem.

Modern Pragmatist posted:

Look at his initial question. He is attempting to retrieve the elements at all positions designated by indices which has nothing to do with slicing. He just used a bad variable name.

I am aware now, after reading his second post, that he is just trying to retrieve arbitrary elements from a list of their offsets. When I responded to his first post, I misunderstood what he wanted, because he used the term "slice". In his second post, he used the term "slice" again, and I presumed that on that occasion he had used the term in that way intentionally and was asking me a follow-up question about slicing.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

Delicate Stranger posted:

Would I be better off learning PHP to start with?

Speaking as someone who learned PHP before taking up Python, I would say no - especially since you are already comfortable with Python, you are better off checking out the Python options for the web.

PHP tries to make certain things easy for you when you are starting out with web programming, but it also makes it very easy for you to do things poorly, and it has a lot of "gotchas" and poor design decisions that you don't really get fully acquainted with until you have got far enough in that it would be a pain in the rear end to drop PHP and transition to something else. Go with something more well-thought-out, like a mature Python framework. You will be glad you did, even if it holds your hand slightly less at the start.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

JetsGuy posted:

Also, thanks for the explanation as to why Python was setting ALL instance of x to the same value. That kinda seems like a 'gotcha' to me, but I guess I need to think more like a programmer :v: ? It makes sense to me now, it's just a little counter-intuitive.

Different programming languages handle assignment operations in different ways. Python's way of doing things is at least very consistent; assignment operations always create a reference to the object being assigned. This goes for mutable and immutable types alike (although you obviously don't care for immutable ones). One of the appealing things about Python is that the way it behaves is very thoroughly thought-out and consistent. But yes it can be a bit of "gotcha" if you are not used to it.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe
Does anyone have a recommendation for an IRC library that works in Python 3? I really like this library for how simple it is to get something working, but it doesn't support Python 3. I found that it is possible to get it to work in Python 3 by modifying it, but something similar that is supported might be nice.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

The Gripper posted:

I've always just used irclib, which claims to be Python 3 supported (though I've only used it with 2.7). Installs properly from pip (it's called "irc" rather than irclib though).

https://bitbucket.org/jaraco/irc

I recall looking at this, and being turned off by how complex the example bot's code looks. It seems extremely involved just for making a simple robot that responds to messages in a channel, though maybe if you need to do a lot of advanced stuff that complexity is needed. In comparison with the one I linked, you can get going just by writing methods called on_channel_message and on_private_message, which makes things exceedingly simple.

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

MeramJert posted:

Why would you call it num pee unless you also say pee thon?

I hear it as "numpee" in my internal monologue because it resembles the word "numpty" (a dimwitted or bumbling person; a muppet).

BigRedDot posted:

Why are you guys making this hard.
code:
In [7]: [(a-b) for (a, b, c) in zip(list1, list2, list3) if c]
Out[7]: [-9, -6, -4]

This is what I thought. It was said in the question that the lists are all the same length, so zip() is fine.

Surprise T Rex posted:

Can we use this thread for more specific python-related stuff? (Maya scripting, etc)?

Related to that, but still fairly general - I have a vague issue with trying to work out how to figure out if two generated squares overlap in X or Y. Any ideas? Just vague suggestions in pseudocode will do, I'm sure I can figure the rest out.

As long as it's just squares (even just rectangles) with sides orthogonal to the x- and y-axes, you can check by just seeing whether they overlap in both the x- and y-dimensions.

I don't know how you represent your squares in the program, so let's say each square is an object with the attributes left, right, top, bottom (numbers representing where these borders are located). So a square whose top-left corner is at (-2, 6) and whose bottom-right corner is at (1, 3) would have left = -2, right = 1, top = 6, bottom = 3. You have two squares, s1 and s2, and you want to know whether they overlap. I'm assuming they are deemed not to overlap if they just touch at the edges.

Python code:
def rangesoverlap (range1left, range1right, range2left, range2right):
    return range1left <= range2left < range1right or range2left <= range1left < range2right

def rectanglesoverlap (r1, r2):
    return rangesoverlap(r1.left, r1.right, r2.left, r2.right) and rangesoverlap(r1.bottom, r1.top, r2.bottom, r2.top)

overlapping = rectanglesoverlap(s1, s2)
If you need to work with more general shapes or if the rectangles are skewed, you're probably going to want to look at something more complicated & capable. Also this code assumes that your squares are sensible (non-zero width and height, left < right, top > bottom).

Hammerite fucked around with this message at 05:44 on Jan 31, 2013

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

QuarkJets posted:

In Python 2.6 I want to take a dictionary and convert all of the keys, which are strings with various cases, to lowercase strings. Right now I am doing it like this:

code:
dict_low = dict((k.lower(), v) for k, v in olddict.items()) 


I just want to change the keys to lowercase, not create a second copy of the dictionary in memory. Does this code do that, and how can I check that this is the case?

I'm pretty sure that immediately after that line both the old and new dictionaries are in memory in full, because olddict isn't being modified and is still in scope. Given you want to overwrite the old dictionary as you go, you might have to do something like this (although there might well be a builtin I'm not aware of that does the same thing)

code:
for k, v in mydict.items():
    lowerk = k.lower()
    if k != lowerk:
        mydict[lowerk] = v
        del mydict[k]

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

The Insect Court posted:

Unless you're going to be vastly increasing the number of keys, it shouldn't be an issue. That said, you can pretty easily do:
code:
for k, v in myDict:
    myDict[transform(k)] = v
    toBeDeleted.append(k)
As long as a value in the dictionary has some key attached to it, it shouldn't get GC'ed. And getting rid of the old keys means you can iterate through the dictionary without having to write code to check the case of the keys.

What is this "toBeDeleted"? Why do the deletions in a separate step? You can just do them as you go. Nothing is going out of scope within the loop, v is still a reference to the dictionary element.

Adbot
ADBOT LOVES YOU

Hammerite
Mar 9, 2007

And you don't remember what I said here, either, but it was pompous and stupid.
Jade Ear Joe

The Insect Court posted:

You could, but you'd need some way to make certain that the transformed key isn't the same as the original one, otherwise you could lose entries. So something like:

code:
for k, v in myDict:
    _k = transform(k)
    if _k != k:
        myDict[_k] = v;
        del myDict[k]

This is literally what I posted already, in slightly greater generality.

  • Locked thread