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
neosloth
Sep 5, 2013

Professional Procrastinator
If I want my class to be modular what would be the best way to go about appending more variables to it? I was thinking about keeping a dict of all the custom variables but that seems like a bad idea.

Adbot
ADBOT LOVES YOU

Dominoes
Sep 20, 2007

Cingulate posted:

I actually do that - not much, but sometimes.
Learn the functools, itertools, and collections modules.

Nippashish
Nov 2, 2005

Let me see you dance!

Cingulate posted:

Things I know I don't do:
- classes and objects

What's the next concept I should focus on learning and understanding so as to become slightly less awful at Python?

Learn how to make effective use of classes and objects. There's a reason they're so ubiquitous in modern computing.

QuarkJets
Sep 8, 2008

superstepa posted:

If I want my class to be modular what would be the best way to go about appending more variables to it? I was thinking about keeping a dict of all the custom variables but that seems like a bad idea.

If you want to add more variables to a class, you can create a new class that inherits from it or just edit the original class. Maybe I'm missing what your goal is

EAT THE EGGS RICOLA
May 29, 2008

QuarkJets posted:

If you want to add more variables to a class, you can create a new class that inherits from it or just edit the original class. Maybe I'm missing what your goal is

It sounds like he wants to pass a number of variables that might be unwieldly, and is worried about just having tons of them.

(Rather than just passing kwargs or somehing, maybe?)

EAT THE EGGS RICOLA fucked around with this message at 02:37 on Jul 19, 2015

Cingulate
Oct 23, 2012

by Fluffdaddy

Dominoes posted:

Learn the functools, itertools, and collections modules.


Nippashish posted:

Learn how to make effective use of classes and objects. There's a reason they're so ubiquitous in modern computing.
Thanks!

Badly Jester
Apr 9, 2010


Bitches!

Cingulate posted:

Things I do:
- few, usually medium-length, loops
- list and dict comprehensions - a lot, often nested
- functions small and large, even sometimes recursive
- a common pattern is to create a function or a dict for the purpose of using it for a list or dict comprehension

Things I know I don't do:
- classes and objects
- decorators

Things I don't know I don't do:
- ...

Most of what I do is scientific python, so usually numpy and scipy based, with a lot of pandas and matplotlib. I also operate with strings (e.g., cleaning up text input) a lot. So nothing exciting.

What's the next concept I should focus on learning and understanding so as to become slightly less awful at Python?

I'm just now getting into the whole programming game, but since you're also a linguist: did you learn Python using the NLTK book? If so, would you recommend it?

Cingulate
Oct 23, 2012

by Fluffdaddy

Badly Jester posted:

I'm just now getting into the whole programming game, but since you're also a linguist: did you learn Python using the NLTK book? If so, would you recommend it?
I'm more of a neuro guy than a linguist really (the idea that I might actually be a linguist to the degree that I'm a functionalist just shows how dumb whoever bought that thing is ...). I started out using Python to handle things like experimental log files, which is string parsing, but not especially linguist-y in nature. And for basically every task I've ever considered using NLTK for, there are vastly superior individual packages. So I don't know much about NLTK, and never read the book.

I know a bunch of other peopel in the linguistics thread are also pretty good at Python, I think at least foiled is much better than I am actually.

Hammerite
Mar 9, 2007

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

superstepa posted:

If I want my class to be modular what would be the best way to go about appending more variables to it? I was thinking about keeping a dict of all the custom variables but that seems like a bad idea.

If you want multiple "versions" of a class that do the same "sort of thing" but do it slightly differently, there are two main ways to achieve that: inheritance (creating a subclass that overrides aspects of the base class's behaviour or makes the base class's behaviour more specific to a particular use case) and composition (attaching sub-objects to your class that implement specific functionality, letting you customise your class's behaviour by choosing what you attach to it)

Like QuarkJets I'm not sure what you're aiming to do.

neosloth
Sep 5, 2013

Professional Procrastinator

QuarkJets posted:

If you want to add more variables to a class, you can create a new class that inherits from it or just edit the original class. Maybe I'm missing what your goal is

Hammerite posted:

If you want multiple "versions" of a class that do the same "sort of thing" but do it slightly differently, there are two main ways to achieve that: inheritance (creating a subclass that overrides aspects of the base class's behaviour or makes the base class's behaviour more specific to a particular use case) and composition (attaching sub-objects to your class that implement specific functionality, letting you customise your class's behaviour by choosing what you attach to it)

Like QuarkJets I'm not sure what you're aiming to do.

What I want is to have one main class that only defines a few very basic methods and variables and then have a large bulk of extra methods/variables appended to an instance of that class post initialization. I know you can just use setattr but I was wondering if there is an "official" way to do that.

Sorry, I think I'm just making a really simple question sound really convoluted.

OnceIWasAnOstrich
Jul 22, 2006

superstepa posted:

What I want is to have one main class that only defines a few very basic methods and variables and then have a large bulk of extra methods/variables appended to an instance of that class post initialization. I know you can just use setattr but I was wondering if there is an "official" way to do that.

Sorry, I think I'm just making a really simple question sound really convoluted.

You effectively want to transform one type of object into another type of object? I'm not sure I've ever seen that done, and I'm not aware of any dedicated language feature to do that. If you are set on transforming the object itself for some reason then create some sort of method that does all your setattr calls for you in a standard way. Some sort of composition approach is probably what you want to do though.

Hammerite
Mar 9, 2007

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

superstepa posted:

What I want is to have one main class that only defines a few very basic methods and variables and then have a large bulk of extra methods/variables appended to an instance of that class post initialization. I know you can just use setattr but I was wondering if there is an "official" way to do that.

Sorry, I think I'm just making a really simple question sound really convoluted.

On the face of it there is nothing to stop you from achieving this by just assigning to the objects. Can't really give you any advice about what you should really do, though, because I have no idea what you want to achieve.

code:
Python 3.4.2 (v3.4.2:ab2c023a9432, Oct  6 2014, 22:16:31) [MSC v.1600 64 bit (AM
D64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> class c: pass
...
>>> x = c()
>>> y = c()
>>> x.a = 5
>>> print(x.a)
5
>>> print(y.a)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'c' object has no attribute 'a'
>>>

chutwig
May 28, 2001

BURLAP SATCHEL OF CRACKERJACKS

superstepa posted:

What I want is to have one main class that only defines a few very basic methods and variables and then have a large bulk of extra methods/variables appended to an instance of that class post initialization. I know you can just use setattr but I was wondering if there is an "official" way to do that.

Sorry, I think I'm just making a really simple question sound really convoluted.

This sounds a little bit like you want to create an abstract base class and then create subclasses from that. What's the underlying problem you're trying to solve?

gbut
Mar 28, 2008

😤I put the UN🇺🇳 in 🎊FUN🎉


superstepa posted:

What I want is to have one main class that only defines a few very basic methods and variables and then have a large bulk of extra methods/variables appended to an instance of that class post initialization. I know you can just use setattr but I was wondering if there is an "official" way to do that.

Sorry, I think I'm just making a really simple question sound really convoluted.

This indeed sounds like class inheritance. If your objects have completely different sets of properties (which would make them structurally unique when using classes and would have you create subclass for every object), you could store properties in dict or something in a class that describes the way they are the same. Otherwise, if you can group them based on sets of properties, sub classing is the way to go, as it was designed for that. (New to python, so I might be overlooking something)

Basically, (to use the common example) you can create class Vehicle that is a parent class of Car, Bicycle, Skateboard, Boat, Airplane, and so on. Vehicle would contain properties like speed and mass, while subclasses would contain specific stuff, like MPG for Car, or cruising altitude for Airplane. You could make intermediary classes for wheeled vehicles that share property numberOfWheels, etc...

Thermopyle
Jul 1, 2003

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

Well he's wanting to do this post-initialization so that's not really subclassing.

He wants to add properties and methods to object instances, not to classes.

You do this by just assigning to instance attributes. Also read this about methods: http://stackoverflow.com/a/2982/23972

floppo
Aug 24, 2005
I am thinking about moving from Python 2 to 3 and to change the way I work as I am starting a new job with a lot more collaboration in September. I am also moving from PC to Mac in about two weeks.

What I do now:
I use Python 2.7 and lots of data packages like scipy, numpy, pandas, statsmodels, scikitlearn, nltk, networkx. I use Ipython notebooks to mess around and generally move cleaned up chunks of code into sublime for reuse. I like to explore things in R as well, but never got Rpy2 to work. I have been really bad about learning classes and objects and just write messy functions. I'm also terrible about version control (the version1.py, version2.py approach discussed above rings true).

What I would like to do better, informed by the advice of future colleagues:
1. Learn useful Unix commands
2. Use Git
3. Write better code - more comments, start incorporating classes and objects

Questions I have for the thread:
- I've looked up the documentation for the packages I use and they all have versions for Python 3. This seems like a good a time as any to make the switch, as I will be starting a lot of new projects and leaving most of my old work behind. Are there any drawbacks? Things I should look out for?
- I will continue to do exploration and experimenting in Ipython notebook, but I would like to do more involved coding in an editor with nice features (works with git, for example?). Is there a clear winner?
-General advice for this kind of transition. ie how would you set up your system for writing code differently if you had to start over?

hope its not too vague

Cingulate
Oct 23, 2012

by Fluffdaddy
You can version control ipynbs. And I use all these packages minus networkx, exclusively under 3.
You probably want to add seaborn btw.

Dominoes
Sep 20, 2007

quote:

What I would like to do better, informed by the advice of future colleagues:
1. Learn useful Unix commands
Useful ones to learn:
  • cd
  • mkdir
  • rm
  • chmod
  • vim/nano
  • ls
  • misc things like ~, sudo, ctrl+c/ctrl+d, clear

quote:

Questions I have for the thread:
- I've looked up the documentation for the packages I use and they all have versions for Python 3. This seems like a good a time as any to make the switch, as I will be starting a lot of new projects and leaving most of my old work behind. Are there any drawbacks? Things I should look out for?
No drawbacks. Look out for unicode issues, print as a function, and builtin functions returning iterators. Given you're into numerical things and iPython Notebook, take advantage of unicode in variable names when appropriate. Ie '\alpha', tab. iPython's QT console's nice too.

quote:

- I will continue to do exploration and experimenting in Ipython notebook, but I would like to do more involved coding in an editor with nice features (works with git, for example?). Is there a clear winner?
-General advice for this kind of transition. ie how would you set up your system for writing code differently if you had to start over?
PyCharm. The free edition's great for normal Python. The pay version has features for integrating other things like web frameworks, databases, and javascript.

Note about Git: Its basic use is straightforward, but the CLI is a mess. Take advantage of PyCharm's integration, and look things up when needed.

Dominoes fucked around with this message at 19:04 on Jul 20, 2015

hooah
Feb 6, 2006
WTF?
I have dictionary whose values are lists of lists. I want to write these lists to one csv file per key. According to this Stack Overflow question, this was straight-forward in Python 2. However, I get an error about not being able to write the value to the file at writer.writerow(value) in this code:

Python code:
for key, value in output_data.items():
    with open(subject + "_" + key + ".csv") as output_file:
        writer = csv.writer(output_file, delimiter=",")
        writer.writerow(value)
What's going on?

Dominoes
Sep 20, 2007

Your code works for me, after making two modifications: setting the open file as 'w' to write instead of the default of read, and iterating over the list of lists so it splits each file into multiple rows.

Python code:
for key, value in output_data.items():
    with open(subject + "_" + key + ".csv", 'w') as output_file:
        writer = csv.writer(output_file, delimiter=",")
        for row in value:        
            writer.writerow(row)

hooah
Feb 6, 2006
WTF?

Dominoes posted:

Your code works for me, after making two modifications: setting the open file as 'w' to write instead of the default of read, and iterating over the list of lists so it splits each file into multiple rows.

Holy poo poo :doh:

Ok, how can I write to the file without the brackets for each list? I saw this post, but I got a "float not iterable" message, even though the example has floats. I've also tried using itertools.chain to flatten my lists of lists, but that results in the same type of error.

hooah fucked around with this message at 19:56 on Jul 20, 2015

Dominoes
Sep 20, 2007

hooah posted:

Ok, how can I write to the file without the brackets for each list?
See my second modification.

hooah
Feb 6, 2006
WTF?
Great. Didn't realize you'd done a ninja edit.

Ghost of Reagan Past
Oct 7, 2003

rock and roll fun
You should also add
code:
newline=''
to the open command. Here's what the documentation says about it (they are themselves not consistent on using it in the documentation!)

quote:

If csvfile is a file object, it should be opened with newline=''. [1]
...
[1] If newline='' is not specified, newlines embedded inside quoted fields will not be interpreted correctly, and on platforms that use \r\n linendings on write an extra \r will be added. It should always be safe to specify newline='', since the csv module does its own (universal) newline handling.

hooah
Feb 6, 2006
WTF?
Yeah, I figured that out after it printed list, blank line, list, blank line...

Gothmog1065
May 14, 2009
Is there a simple way to do a string comparison that is case insensitive? I'm doing the MIME comparison game thing from codingame.com.

Python code:
for x in filenames:
    file, ext = os.path.splitext(x)
    ext = ext[1:]
    if ext in types:
        print(types[ext])
    else:
        print("UNKNOWN")
Filenames is a list of, well, filenames (foo.bar, fooo.BAR, bar.Bar, etc) and types is a dictionary of known filetypes, ('bar', foo/bar) (Basically MIME types). What I"m wanting to do the if statement without regard to case. Is there a simpler way to do that?

Hammerite
Mar 9, 2007

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

Gothmog1065 posted:

Is there a simple way to do a string comparison that is case insensitive? I'm doing the MIME comparison game thing from codingame.com.

Python code:
for x in filenames:
    file, ext = os.path.splitext(x)
    ext = ext[1:]
    if ext in types:
        print(types[ext])
    else:
        print("UNKNOWN")
Filenames is a list of, well, filenames (foo.bar, fooo.BAR, bar.Bar, etc) and types is a dictionary of known filetypes, ('bar', foo/bar) (Basically MIME types). What I"m wanting to do the if statement without regard to case. Is there a simpler way to do that?

if ext.lower() in (t.lower() for t in types):

If you have a lot of places where you need to compare strings case-insensitively you might create a simple class that implements a notion of case-insensitive string.

Gothmog1065
May 14, 2009

Hammerite posted:

if ext.lower() in (t.lower() for t in types):

If you have a lot of places where you need to compare strings case-insensitively you might create a simple class that implements a notion of case-insensitive string.

Bleh, that works but that's not the solution I need, now I have to pull the keys from the dictionary with this with these case insensitivities. I could force all the keys to be lowercase, but I don't think that would work for the particular solution. Going to have to think on this.

hooah
Feb 6, 2006
WTF?
Yeah, that one ended up being trickier than I initially thought. I did end up lower-casing the keys, if that helps.

Gothmog1065
May 14, 2009

hooah posted:

Yeah, that one ended up being trickier than I initially thought. I did end up lower-casing the keys, if that helps.

Actually that does work, it's not the key, it's the value that's important for the result. Thanks guys!

e: thanks again! I ended up changing around some bits and bobs due to the way they were playing with filenames:

Python code:
for x in filenames:
    ext = x.split(".")[-1]
        
    if ext == "" or "." not in x:
        print("UNKNOWN")
    elif ext.lower() in types:
        print(types[ext.lower()])
    else:
        print("UNKNOWN")

Gothmog1065 fucked around with this message at 15:50 on Jul 21, 2015

Cingulate
Oct 23, 2012

by Fluffdaddy
NumPy question. Can I somehow do something like this:

code:
x_loc = np.asarray([1,2,3])
y_loc = np.asarray([1,5,9])
values = np.asarray([99, 11, 00])
target = np.zeros((100,100))

target[x_loc, y_loc] = values
so that it's equal to
code:
x_loc = np.asarray([1,2,3])
y_loc = np.asarray([1,5,9])
values = np.asarray([99, 11, 00])
target = np.zeros((100,100))

for x, y, v in zip(x_loc, y_loc, values):
    target[x,y] = v
but without doing loops?

Nippashish
Nov 2, 2005

Let me see you dance!
Something like
code:
target.flat[np.ravel_multi_index((x_loc, y_loc), dims=target.shape)] = values
will do it.

Cingulate
Oct 23, 2012

by Fluffdaddy
Oh thanks.

Ghost of Reagan Past
Oct 7, 2003

rock and roll fun
Suppose I wanted to run a function for a specified time period (it gathers data from the Internet and prints it to a file). I can do
Python code:
t = time.time() + 86400
while t > time.time():
    # DO THINGS
to run it for a day, but there has to be a better way to do this.

Harriet Carker
Jun 2, 2009

What's the easiest way to share some simple games I wrote in Python with non-tech savvy people? If the answer is freeze it in an .exe, what's the best current utility for doing so?

The March Hare
Oct 15, 2006

Je rêve d'un
Wayne's World 3
Buglord

dantheman650 posted:

What's the easiest way to share some simple games I wrote in Python with non-tech savvy people? If the answer is freeze it in an .exe, what's the best current utility for doing so?

Freeze 'em, but it is going to suck unless something drastic changed in the last 6 months and no one told me. You'll want to use py2exe which, I think, works on python 2 or 3 now.

Dominoes
Sep 20, 2007

This is one of Python's biggest weaknesses; there's no clean way.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Ghost of Reagan Past posted:

Suppose I wanted to run a function for a specified time period (it gathers data from the Internet and prints it to a file). I can do
Python code:
t = time.time() + 86400
while t > time.time():
    # DO THINGS
to run it for a day, but there has to be a better way to do this.

Python code:
import datetime
import time

dayFromNow = datetime.datetime.now() + datetime.timedelta(days=1)
secondsBetweenRuns = 1 #use a float to sleep for less than a second

while datetime.datetime.now() < dayFromNow:
    #do stuff here
    time.sleep(secondsBetweenRuns) #I'm assuming you don't want it to run constantly
If you want it to run less than every minute or so, just set up a cron job instead of rolling your own.

politicorific
Sep 15, 2007
It's been 6 years since I read this thread(!). Well, I'm still a lovely programmer, but am looking to fix that.


In short, I'm looking for information on running loops over lists containing lists.


I built this 7 segment LED display using shift registers to interface with my raspberry pi:
http://forums.somethingawful.com/showthread.php?threadid=2734977&pagenumber=311#post447919014

I need assistance building the "rendering engine" because the existing libraries I found, listed below, are designed as demonstrations or work with only a single digit. Is there a library out there that already works with multiple 7 segment displays? My final device will be between 9-12 digits.

https://github.com/mignev/shiftpi
https://github.com/shrikantpatnaik/Pi7SegPy
https://github.com/m01/sevensegment

Addressing the segments looks like this: 10 millions place far left, highest outputs(56-63), ones-place (0-7). Here's what 8 digits looks like, even though I only have 5 digits built at the moment.

10,000,000 1,000,000 100,000 10,000 1,000 100 10 1
[55-63] [48-55] [40-47] [32-39] [24-31] [16-23] [8-15] [0-7]

These are the pin outs from the 595 to the segments. Technically the 595 has these alphabetically labeled.
A = 1
B = 0
C = 4
D = 5
E = 6
F = 3
G = 2
DP = 7 #decimal point

Here are some examples - to get these familiar outputs bring these pins high:
patterns =
"0": [A, B, C, D, E, F],
"1": [B, C],
"2": [A, B, D, E, G],
"3": [A, B, C, D, G],
"4": [B, C, F, G],
"5": [A, C, D, F, G],
"6": [A, C, D, E, F, G],
"7": [A, B, C],
"8": [A, B, C, D, E, F, G],
"9": [A, B, C, D, F, G],
".": [DP]
}

Okay so here's my idea, I wonder if there's a better way:

Let's say I have an IP address which I want to display: "192.168.0.1" - a string with 8 digits and 3 decimal points. Let's assume I have 8 shift registers/digits so I don't have overflow/or scroll the device.


First, my rendering engine is going to split that string into a list [1,9,2,.,1,6,8,.,0,.,1]. #Note that this has 11 elements

Next, each element of the list is looked up in the patterns dictionary/truth table to find which pins to bring high.

The result being : [[B, C],[A, B, C, D, F, G],[A, B, D, E, G],[DP],[B, C],[A, C, D, E, F, G],[A, B, C, D, E, F, G],[DP],[A, B, C, D, E, F],[DP],[B, C]].

Now run a loop to combine the decimal point, [DP] with the preceding list element. This is just the lazy way I see of doing it. I could eventually make a truth table with 255 patterns.

[[B, C],[A, B, C, D, F, G],[A, B, D, E, G, DP],[B, C],[A, C, D, E, F, G],[A, B, C, D, E, F, G, DP],[A, B, C, D, E, F],[DP, B, C]]. # back to 8 elements

The numerical values of this list are:
[[0, 4],[1, 0, 4, 5, 3, 2],[1, 0, 5, 6, 2, 7],[0, 4],[1, 4, 5, 6, 3, 2],[1, 0, 4, 5, 6, 3, 2, 7],[1, 0, 4, 5, 6, 3],[7, 0, 4]]

Next, flip the list so that "1" or [0,4] or [B,C] segments are in the left side's 10 millions place.

[[7, 0, 4],[1, 0, 4, 5, 6, 3],[1, 0, 4, 5, 6, 3, 2, 7],[1, 4, 5, 6, 3, 2],[0, 4],[1, 0, 5, 6, 2, 7],[1, 0, 4, 5, 3, 2],[0, 4]] # probably good to copy this variable before going further; I guess for strings larger than 8 digits, I can pop values out and do a marquee scrolling effect

If I write this to the shift register, it will only address the "ones" place.

I need to add multiples of 8 to the values of each element in the list: [0]+0, [1]+8, [2]+16, [3]+24, [4]+32, [5]+40, [6]+48, 7[+56]

So on so that I end up with:

[[7, 0, 4],[9, 8, 12, 13, 14, 11],[17, 16, 20, 21, 22, 19, 18, 24],[25, 28, 29, 30, 27, 26],[32, 36],[41, 40, 45, 46, 42, 47],[49, 48, 52, 53, 51, 50],[56, 60]]

At this point, I need to write a loop that goes over every element in the list and sublist and turns it "high" or "on". I suppose this just turns into a string of 64 rising and falling voltages. I then latch the values, display it, and then repeat with new information.


Does this make sense?


There is a lot more I want to do: like setting PWM for individual segments. Centering/right justifying/left justifying. Building digits/characters segment by segment, have digits "fly" in from the left and right.
But for now, I just need a way to use the entire display, and not just the first digit. Does this sound like a smart way to go about it?

Adbot
ADBOT LOVES YOU

Ghost of Reagan Past
Oct 7, 2003

rock and roll fun

Munkeymon posted:

Python code:
import datetime
import time

dayFromNow = datetime.datetime.now() + datetime.timedelta(days=1)
secondsBetweenRuns = 1 #use a float to sleep for less than a second

while datetime.datetime.now() < dayFromNow:
    #do stuff here
    time.sleep(secondsBetweenRuns) #I'm assuming you don't want it to run constantly
If you want it to run less than every minute or so, just set up a cron job instead of rolling your own.
That'll work, thanks.

E: I was just hoping there was a fancy way to do it with a generator or something (you know, reflecting on it, I was just hoping for some cool new way to do this task beyond a while loop). Whatever, this way is transparent and probably better Python than anything fancy.

Ghost of Reagan Past fucked around with this message at 17:59 on Jul 22, 2015

  • Locked thread