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
KetchupYEAH!
Jul 25, 2011

Bap Bap Bap Bap Bap Bap Bap Bap Bap Bap Bap Bap
Got started with Python with this book: this book (think python) and i really like it so far.
What's a good book to continue learning?
I'm using 2.7, but wouldn't mind advancing to 3. I'm mostly interested in learning to make GUIs, maybe some web stuff or games, and some light mathematical use.

Adbot
ADBOT LOVES YOU

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES
Thanks for the input guys, I'm still not entirely clear though why I'd use (or import) the copy module rather than just keep a loop like before, i.e.:

code:
master = {}
for i in range(1,4,1):
    d_set = {"x": [], "x_err" : [], "y" : [], "y_err" : []}
    key = "set_"+str(i)
    master[key] = d_set
Using the copy module certainly doesn't seem to shorten the code any, but perhaps I'm missing something in the backend of this. While I generally don't have to worry about this, is it a time-saving technique to use the copy module to construct such a dictionary? Ok, with 3 data sets, it may not matter, but if it were N data sets, would it be considerably quicker to construct this dictionary with the copy module as y'all suggested? Like, I don't exactly see where the advantage of using either copy or deepcopy would give an advantage otherwise. It seems fairly clear what that loop is doing, so I don't see it as particularly more/less elegant to code it with those modules.

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.

Jewel
May 2, 2009

JetsGuy posted:

Thanks for the input guys, I'm still not entirely clear though why I'd use (or import) the copy module rather than just keep a loop like before, i.e.:

You don't. It's bad. But we told you why putting d_set outside the loop didn't work, and how to fix that if you somehow had to do it that way.

JetsGuy
Sep 17, 2003

science + hockey
=
LASER SKATES

KetchupYEAH! posted:

Got started with Python with this book: this book (think python) and i really like it so far.
What's a good book to continue learning?
I'm using 2.7, but wouldn't mind advancing to 3. I'm mostly interested in learning to make GUIs, maybe some web stuff or games, and some light mathematical use.

Personally speaking, I stick to 2.7 for a lot of reasons, not the least of which is that it is the 'consensus' Python for astrophysics right now. While some modules exist for 3, not ALL astro python libraries have been re-written for 3.

A lot of this is for the simple fact that "this works", and why bother to rewrite it until there is a clear advantage in doing so?

I don't remember where the exact hiccup is but I think a lot of it was in matplotlib for a long time. It doesn't help that a lot of people coded a lot of their processing codes for their own work in 2.* and the differences between Py2.* and Py3 are big enough to actually matter. So a lot of people in my field are kinda stuck with 2.* for a long time simply because it's a pain in the rear end to rewrite routines we know to work.

So my suggesting here is to determine what you *really* want to do with Python and then settle on a version. If you're just screwing around with it for your own purposes, go to 3.

I literally know people that still run FORTRAN code that they wrote on punch cards. There is a LOT of sentiment in the astro community of "I know this works, so I will use this". Even today, I know a lot of young physicists who are taught to use F90 because they have to in order to read all the bullshit code that their advisers write.

NASA data still has a ton of FORTRAN code used to analyze the data. :ssh:

Jewel posted:

You don't. It's bad. But we told you why putting d_set outside the loop didn't work, and how to fix that if you somehow had to do it that way.

Ahhhh. Ok. Thanks again! :)

JetsGuy fucked around with this message at 16:36 on Dec 17, 2012

BigRedDot
Mar 6, 2008

JetsGuy posted:

NASA data still has a ton of FORTRAN code used to analyze the data. :ssh:

I taught several python classes at JSC earlier this year. All the obscure and impenetrable initialisms reminded me of when I worked for Navy research lab...

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Haystack posted:

No, your question makes perfect sense.

Oh, thanks. I forgot I read that part of the documentation! Sometimes I get too immersed in my reading and with 30 tabs open kind of forget where I'm at.

But yeah, I get it now and I bet your solution works when I test it out later today.

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.

BeefofAges
Jun 5, 2004

Cry 'Havoc!', and let slip the cows of war.

Can I get some opinions on some code I wrote? To give some background, I'm developing automated tests using Robot Framework, which lets you write libraries in Python (or Java). One of the libraries I'm working on is a wrapper for a product's REST API. I've never worked with REST before, or remote function calls in general, but the product's implementation is awful as far as I can tell. I've found that every function seems to handle authentication/data input in one of seven different ways. To work around this, I wrote the following (some names and documentation removed/changed to avoid identifying the product or company):

Python code:
import copy

import requests
from requests.auth import HTTPDigestAuth

import GenericTestLibrary
reload(GenericTestLibrary)

class RestApiLibrary(GenericTestLibrary.GenericTestLibrary):
    '''
    Library with convenience methods for accessing the REST API.
    '''


    def __init__(self):
        '''
        By default,
        self.api_url = 'http://{0}/api/1.0/rest/'.format(self.ip_address)
        
        You can override this if you need to.
        '''
        super(RestApiLibrary, self).__init__()
        
        # Build the REST API URL for the test unit
        self.api_url = 'http://{0}/api/1.0/rest/'.format(self.ip_address)
        
    def _rest_url(self, function_name):
        # Return the REST API's URL for a given function
        return self.api_url + function_name
    
    def _rest_put(self, function_name, **kwargs):
        # Do a REST PUT call
        return self._rest_call(requests.put, self._rest_url(function_name), **kwargs)
    
    def _rest_get(self, function_name, **kwargs):
        # Do a REST GET call
        return self._rest_call(requests.get, self._rest_url(function_name), **kwargs)
    
    def _rest_post(self, function_name, **kwargs):
        # Do a REST POST call
        return self._rest_call(requests.post, self._rest_url(function_name), **kwargs)
    
    def _is_successful(self, result):
        return (result.status_code == 200)
    
    def _no_authentication(self, request_function, args, kwargs):
        return request_function(*args, **kwargs)

    def _HTTP_basic_authentication(self, request_function, args, kwargs):
        # default HTTP basic authentication
        temp_kwargs = copy.deepcopy(kwargs)
        temp_kwargs['auth'] = self.username, self.password
        return request_function(*args, **temp_kwargs)

    def _HTTP_digest_authentication(self, request_function, args, kwargs):
        # HTTP digest authentication
        temp_kwargs = copy.deepcopy(kwargs)
        temp_kwargs['auth'] = HTTPDigestAuth(self.username, self.password)
        return request_function(*args, **temp_kwargs)

    def _URL_authentication_Product1(self, request_function, args, kwargs):
        # URL-based authentication (Product1 style)
        temp_kwargs = copy.deepcopy(kwargs)
        temp_kwargs['params']['owner'] = self.username
        temp_kwargs['params']['pw'] = self.password
        return request_function(*args, **temp_kwargs)

    def _URL_authentication_Product2(self, request_function, args, kwargs):
        # URL-based authentication (Product2 style)
        temp_kwargs = copy.deepcopy(kwargs)
        temp_kwargs['params']['auth_username'] = self.username
        temp_kwargs['params']['auth_password'] = self.password
        return request_function(*args, **temp_kwargs)

    def _URL_authentication_Product1_json(self, request_function, args, kwargs):
        # URL-based authentication with JSON data (Product1 style)
        temp_kwargs = copy.deepcopy(kwargs)
        temp_kwargs['data'] = temp_kwargs['params']
        temp_kwargs['params'] = {'owner':self.username, 'pw':self.password}
        return request_function(*args, **temp_kwargs)

    def _URL_authentication_Product2_json(self, request_function, args, kwargs, temp_kwargs):
        # URL-based authentication with JSON data (Product2 style)
        temp_kwargs = copy.deepcopy(kwargs)
        temp_kwargs['data'] = temp_kwargs['params']
        temp_kwargs['params'] = {'auth_username':self.username, 'auth_password':self.password}
        return request_function(*args, **temp_kwargs)

    def _rest_call(self, request_function, *args, **kwargs):
        """
        Runs through the possible ways of authenticating and providing data
        to the REST API. This method is only necessary because of inconsistent
        behavior across the REST API.
        
        To use this method, pass any parameters/data you have in as a dict
        assigned to the keyword 'params'.
        
        'request_function' must be a requests call, like requests.post or requests.get
        """
        if not 'params' in kwargs:
            kwargs['params'] = {}
        funcs = [self._no_authentication,
                 self._HTTP_basic_authentication, 
                 self._HTTP_digest_authentication,
                 self._URL_authentication_Product1,
                 self._URL_authentication_Product2,
                 self._URL_authentication_Product1_json,
                 self._URL_authentication_Product2_json]
        for func in funcs:
            result = func(request_function, args, kwargs)
            if self._is_successful(result):
                return result
        raise Exception('REST call failed: ' + str(result))
The above is to allow me to quickly wrap REST calls and make them accessible to Robot:
Python code:
    def set_ssh(self, enable=True):
        """
        Modify SSH configuration.
        """
        
        if enable:
            params = {'enablessh': 'enable'}
        else:
            params = {'enablessh': 'disable'}
        return self._rest_put('ssh_configuration', params=params)
    
    def get_ssh_configuration(self):
        return self._rest_get('ssh_configuration')
Does this seem like a reasonable way of doing things? I feel like there's probably something a lot cleaner and smarter I could be doing.

Captain Capacitor
Jan 21, 2008

The code you say?
[quote="BeefofAges" post="410668431"]

Python code:
import copy

import requests
from requests.auth import HTTPDigestAuth

import GenericTestLibrary
reload(GenericTestLibrary)


Mind clarifying why there's a reload here?

BeefofAges
Jun 5, 2004

Cry 'Havoc!', and let slip the cows of war.

Captain Capacitor posted:

[quote="BeefofAges" post="410668431"]

Python code:
import copy

import requests
from requests.auth import HTTPDigestAuth

import GenericTestLibrary
reload(GenericTestLibrary)


Mind clarifying why there's a reload here?

Oh, I don't actually have a good reason for that anymore. It was left over from when I was trying to figure out a stupid mistake I made (I had a module named TestLibrary but it turned out Robot Framework has it's own module named TestLibrary, and the conflict manifested strangely so it took me a while to figure it out).

tef
May 30, 2004

-> some l-system crap ->

BeefofAges posted:

Can I get some opinions on some code I wrote? To give some background, I'm developing automated tests using Robot Framework, which lets you write libraries in Python (or Java). One of the libraries I'm working on is a wrapper for a product's REST API. I've never worked with REST before, or remote function calls in general, but the product's implementation is awful as far as I can tell.

From the looks of the api you're having to wrap, they don't seem to have much experience with REST.

fritz
Jul 26, 2003

JetsGuy posted:

I literally know people that still run FORTRAN code that they wrote on punch cards. There is a LOT of sentiment in the astro community of "I know this works, so I will use this". Even today, I know a lot of young physicists who are taught to use F90 because they have to in order to read all the bullshit code that their advisers write.

NASA data still has a ton of FORTRAN code used to analyze the data. :ssh:

Some big part of the numpy stack is fortran. Writing that kind of code is hard, and it works, and other languages can interface with it, and it works, so why would anybody want to re-do it?

BeefofAges
Jun 5, 2004

Cry 'Havoc!', and let slip the cows of war.

tef posted:

From the looks of the api you're having to wrap, they don't seem to have much experience with REST.

Yeah... I think they pretty much settled on a cool sounding buzzword and didn't bother to actually read up on what it means or how to properly use it.

I'm just trying to build a decent way to interact with their crappy API so I can test the software behind it.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe

tef posted:

From the looks of the api you're having to wrap, they don't seem to have much experience with REST.

"Oh, so we just put our function name in the URL? That's easy, then"

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Given the following SQLAlchemy models how can I query for Tenants in a specific Complex? Is there a better way to model this to allow for such queries?

I think I got this stripped down to the bare essentials.

Python code:
class Complex(Base):
	id = Column(Integer, primary_key=True)
	name = Column(String(128), nullable=False, unique=True)
	
	# relationships
	units = relationship("Unit", backref="complex")


class Unit(Base):
	id = Column(Integer, primary_key=True)
	name = Column(String(10))

	# relationships
	complex_id = Column(Integer, ForeignKey('complex.id'))
	tenants = relationship("Tenant", backref="unit")


class Tenant(Base):
	id = Column(Integer, primary_key=True)
	name = Column(String(512), nullable=False)

	# relationships
	unit_id = Column(Integer, ForeignKey('unit.id'))

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Python code:
from sqlalchemy import and_
session.query(Tenant).filter(and_(Tennant.unit_id == Unit.id, Unit.complex_id == my_complex.id))
There may be some way to use the Complex class instead of the ID: I'd expect Unit.complex == my_complex to work, but I haven't tried it.

Optimus Prime Ribs
Jul 25, 2007

If I were to write something that uses non-blocking sockets would it potentially be a bad idea to completely ignore WOULDBLOCK exceptions?
Like this:
Python code:
while True:
    try:
        client,addr = server.accept()
    except socket.error,e:
        if e.errno == errno.EWOULDBLOCK:
            pass
        else:
            # Handle other errors
Could there be a situation where you'd want to do some error handling on receiving the WOULDBLOCK exception?

Optimus Prime Ribs fucked around with this message at 11:28 on Dec 19, 2012

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Suspicious Dish posted:

Python code:
from sqlalchemy import and_
session.query(Tenant).filter(and_(Tennant.unit_id == Unit.id, Unit.complex_id == my_complex.id))

Ahh yes, thank you.

quote:

There may be some way to use the Complex class instead of the ID: I'd expect Unit.complex == my_complex to work, but I haven't tried it.

Yeah, I'd expect so too...but it doesn't work.

tef
May 30, 2004

-> some l-system crap ->

Optimus Prime Ribs posted:

If I were to write something that uses non-blocking sockets would it potentially be a bad idea to completely ignore WOULDBLOCK exceptions?
Like this:
Python code:
while True:
    try:
        client,addr = server.accept()
    except socket.error,e:
        if e.errno == errno.EWOULDBLOCK:
            pass
        else:
            # Handle other errors
Could there be a situation where you'd want to do some error handling on receiving the WOULDBLOCK exception?

Might want to leave it in as defensive code :3: (With a comment, and possibly a log/error)

Optimus Prime Ribs
Jul 25, 2007

tef posted:

Might want to leave it in as defensive code :3: (With a comment, and possibly a log/error)

I don't think it's really defensive coding since if the exception isn't handled the program blows up; don't really have any choice about doing something with the exception (even if I just end up silencing it).

And writing to a log every time that occurs would probably be a bad idea. I just ran a non-blocking socket script for 5 seconds, counted the number of exceptions I received, and then extrapolated that to an hour and got 259.2 million.
So I guess then just stick to silencing it and maybe add a comment?

tef
May 30, 2004

-> some l-system crap ->
Leave a comment, move on :3:

Optimus Prime Ribs
Jul 25, 2007

Keepin' calm and carryin' on.

Daynab
Aug 5, 2008

Can someone point me to a basic "Babby's first app packaging guide"?

For example, assuming I want to install my thing on a computer that only has python but nothing else, and that my app has one or two third party libraries?

I'm not finding anything really easily understandable as a newbie.

BeefofAges
Jun 5, 2004

Cry 'Havoc!', and let slip the cows of war.

Daynab posted:

Can someone point me to a basic "Babby's first app packaging guide"?

For example, assuming I want to install my thing on a computer that only has python but nothing else, and that my app has one or two third party libraries?

I'm not finding anything really easily understandable as a newbie.

http://stackoverflow.com/questions/5360873/how-do-i-package-a-python-application-to-make-it-pip-installable

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Pycharm, the Python IDE that people are always raving about is $25 instead of $100 for individual developers for the rest of the day.

http://www.jetbrains.com/specials/index.jsp

Daynab
Aug 5, 2008

Thermopyle posted:

Pycharm, the Python IDE that people are always raving about is $25 instead of $100 for individual developers for the rest of the day.

http://www.jetbrains.com/specials/index.jsp

Sweet. Thanks for the heads up, I wasn't going to but then I noticed licenses are permanent, which is awesome.


That... sound as if I would need pip installed in the first place on that computer, no?

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Thermopyle posted:

Pycharm, the Python IDE that people are always raving about is $25 instead of $100 for individual developers for the rest of the day.

http://www.jetbrains.com/specials/index.jsp

I'm kind of on the fence about this. Is it worth it?

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

MeramJert posted:

I'm kind of on the fence about this. Is it worth it?

Download it and dick around. 30 day free trial.

There's also videos and documentation on their site.

Hed
Mar 31, 2004

Fun Shoe
Thanks for letting us know, Thermopyle. I guess I only thought it worked on a Mac before since I only saw Mac screenshots. Snatched it up for 1.25 :20bux:

fletcher
Jun 27, 2003

ken park is my favorite movie

Cybernetic Crumb
Perfect timing for the sale! My PyCharm trial was just about to run out.

duck monster
Dec 15, 2004

MeramJert posted:

I'm kind of on the fence about this. Is it worth it?

I dont use it because i've found it unstable. However I havent actually used it since it first came out (and it DID undeniably explode alot back them). Perhaps its more stable now.

When it worked, it worked well and its code completions actually frigging worked.

Bunny Cuddlin
Dec 12, 2004

Hed posted:

Thanks for letting us know, Thermopyle. I guess I only thought it worked on a Mac before since I only saw Mac screenshots. Snatched it up for 1.25 :20bux:

did you get the confirmation email and a key and everything?

Yay
Aug 4, 2007

duck monster posted:

I dont use it because i've found it unstable. However I havent actually used it since it first came out (and it DID undeniably explode alot back them). Perhaps its more stable now.
it has gotten much better since 2.0, which finally seemed to stop many of the background tasks from hanging and causing all the actual IDE parts to cease working. It's still unnecessarily demanding of CPU and RAM, so netbooks and older laptops lag like crazy.

However, if you're using any relatively modern PC, it's brilliant.

I picked up a personal license for it, but I've not yet had the license through, I think because of the huge backlog jetbrains didn't anticipate.

Hed
Mar 31, 2004

Fun Shoe
Yes it probably took about 30 minutes but I got an email from sales@jetbrains.com with all of the information.

loose-fish
Apr 1, 2005
So, I migrated a program I wrote from PyGTK to PyGObject. Afterwards I noticed that it was noticeably slower when doing the following: User selects data -> TreeView is filled with data. So I wrote small test programs for PyGTK and PyGObject where a single TreeView with a ListStore model and six columns is filled with 100 rows of random 8 character strings.

Python code:
class MainWindow(gtk.Window):
    def __init__(self):
	[...]
        self.model = gtk.ListStore(str, str, str, str, str, str)
        self.view = gtk.TreeView(self.model)
	[...]        
        self.data = [(str(randint(100000000,999999999)),
                      str(randint(100000000,999999999)),
                      str(randint(100000000,999999999)),
                      str(randint(100000000,999999999)),
                      str(randint(100000000,999999999)),
                      str(randint(100000000,999999999))) for _ in range(100)]
	[...]

    def append_data(self):
        self.model.clear()
        for d in self.data:
            self.model.append(d)
            
    def insert_data(self):
        self.model.clear()
        for d in self.data:
            self.model.insert(-1, d)
Results of timing the append and insert functions:
code:
PyGTK
Append: 0.00200605392456
Insert: 0.0011670589447

PyGObject
Append: 0.0111100673676
Insert: 0.0110750198364
Am I missing something or is this just hosed? Python version is 2.7, PyGObject is 3.4.2.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

For some reason my brain is not working today and I'm getting impatient with myself. I can't seem to figure out how to get a list of the datetime.date's between two dates.

So, I'm wanting something like:

Python code:
start = datetime.date(2012, 2, 11)
end = datetime.date(2013, 2, 11)

print day_counter(start, end, day_of_month=7)
[datetime.date(2012, 3, 7), datetime.date(2012, 4, 7),...] # twelve datetime.dates here
The kicker is that if day_of_month is, say 31, and the month doesn't have 21 days, then return a datetime.date for the last day of the month.

I'm quite irritated that I can't come up with a function to do this right now, so I'm going to go watch Homeland.

edit: Nevermind. Used python-dateutil. It came to me right after I started watching Homeland.

Python code:
import datetime
from dateutil.relativedelta import relativedelta


def date_count(start, end, day_of_month=None):
	dates = []
	months = (end.year - start.year) * 12
	months += end.month - start.month

	if not day_of_month:
		day_of_month = start.day

	if start.day > day_of_month:
		first_date = datetime.date(start.year, start.month + 1, day_of_month)
	elif start.day == day_of_month:
		first_date = start
	else:
		first_date = datetime.date(start.year, start.month, day_of_month)

	dates.append(first_date)

	for x in range(1, months):
		dates.append(first_date + relativedelta(months=+x))

	return dates
Haven't thought through edge cases or looked over anything weird I'm doing there, but it seems to work.

Thermopyle fucked around with this message at 23:05 on Dec 21, 2012

Plorkyeran
Mar 22, 2007

To Escape The Shackles Of The Old Forums, We Must Reject The Tribal Negativity He Endorsed

loose-fish posted:

So, I migrated a program I wrote from PyGTK to PyGObject. Afterwards I noticed that it was noticeably slower when doing the following: User selects data -> TreeView is filled with data. So I wrote small test programs for PyGTK and PyGObject where a single TreeView with a ListStore model and six columns is filled with 100 rows of random 8 character strings.
Have you tried freezing the TreeView while updating the model? It may be updating the UI on every append/insert, which would be pointless and slow.

loose-fish
Apr 1, 2005

Plorkyeran posted:

Have you tried freezing the TreeView while updating the model? It may be updating the UI on every append/insert, which would be pointless and slow.

You're right, I thought detaching the model was enough to keep the UI from updating. However PyGObject is still ten times slower than PyGTK:
code:
PyGTK
Append: 0.00150084495544
Insert: 0.000877857208252

PyGObject
Append: 0.00925707817078
Insert: 0.00927495956421

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Can you give full complete programs for both?

Adbot
ADBOT LOVES YOU

loose-fish
Apr 1, 2005
Sure:
PyGObject
PyGTK

  • Locked thread