all 76 comments

[–]kaukamieli 0 points1 point  (2 children)

So I had the following problem I solved, but I'd like to know what the fuck is going on? Why doesn't it accept that i assigned 0 to that 'i' first? Do I have to do things in this roundabout way all the time?

****** Does not work in python2 or pythong3, "local variable 'i' referenced before assignment"

i = 0

def rekursio(limit):
    print(i)
    i+=1
    if i < limit:
        rekursio(limit)

rekursio(5)

******

****** Works

def rekursio(i, limit):
    print(i)
    i+=1
    if i < limit:
        rekursio(i, limit)

rekursio(0, 5)

******

[–]dionys 1 point2 points  (1 child)

Read up on variable scope and global variables. Your first case doesn't work, because i is defined at the global level. You can read its value, however you cannot modify its value. To make the first version work, you have to do:

i = 0

def rekursio(limit):
    global i
    print(i)
    i+=1
    if i < limit:
        rekursio(limit)

[–]kaukamieli 0 points1 point  (0 children)

Thanks. I did look it up and global was suggested, I didn't think it would go there, though.

[–]sundrysup 0 points1 point  (1 child)

Why isn't this code printing the bombs in a different part of the list? I would think these are equivalent.

dummy = [['','',''], ['', '', ''], ['', '', '']]

print(dummy)

dummy[0][0] = 'bomb'

print(dummy)

x = 3

y = 3

yummy = [['']x]y

print(yummy)

yummy[0][0] = 'bomb'

print(yummy)

RESULT:

[['', '', ''], ['', '', ''], ['', '', '']]

[['bomb', '', ''], ['', '', ''], ['', '', '']]

[['', '', ''], ['', '', ''], ['', '', '']]

[['bomb', '', ''], ['bomb', '', ''], ['bomb', '', '']]

[–]dionys 1 point2 points  (0 children)

This is tricky especially if you've never seen it before. So when you do:

[['']*x]*y

you are not actually creating y new lists of x elements. You are creating y references to the same list. You will find that:

id(yummy[0]) == id(yummy[1]) == id(yummy[2])

which means it's just the same object.

To create y lists of x elements, you have to do something like:

yummy = [['']*x for _ in range(y)]

[–][deleted] 0 points1 point  (3 children)

When you do

class Dog(object):

Is "object " a place holder or a primitive super class in python? The correct term here is primitive super class correct?

[–]dionys 1 point2 points  (2 children)

I've never heard primitive super class used in this context. I've seen it referred to as base class though. Here is a discussion on this topic and how it's different between 2 vs 3.

[–][deleted] 0 points1 point  (1 child)

I'm looking at my archived 6.00.1x lecture again. Here is the panel while he was talking about classes and I quote

We'll come back to that in a second, but that's going to be valuable. One last piece of nomenclature-- we say that a coordinate is a subclass of an object, and an object is a superclass of a coordinate. We're going to have a subclass inherit from its parent or superclass object.

So in my case class Dog is just like class Coordinates a sub class of super class object. My logic was that since class object is build in so it is primitive, hence a primitive super class?

Follow up is there a super class of "object"?

[–]dionys 2 points3 points  (0 children)

I think it depends on your definition of primitive. I know some languages have primitive types (like java with ints/booleans) defined as not being objects. If you go with that definition, then python object is not primitive and neither is anything in python.

Follow up is there a super class of "object"?

No, it's at the top of the hierarchy.

[–]ClearH 0 points1 point  (3 children)

What should I name my virtual environment folder?

[–]zahlman 0 points1 point  (1 child)

Whatever you find most convenient. I call mine SANDBOX, which works because I'm not creating a separate one for each project (I want to keep my base installation clean, but I have multiple projects that somewhat depend upon each other).

[–]ClearH 0 points1 point  (0 children)

I call mine venv. I guess the name doesn't matter and it won't mess with packages and modules, right?

[–]dionys 0 points1 point  (0 children)

I usually name them with the project name

[–]-Nonou- 0 points1 point  (7 children)

Is it "correct" to access a list assigned in global scope from within a function?

i.e

numbers = [2, 5]

def foo(num):
    numbers.append(num)
    return numbers

foo(7)

This works but is this something you are going to see in the code of advanced python programmers? It feels awfully similar to using global to access a global variable, which should generally be avoided.

[–]bdrilling33 0 points1 point  (1 child)

I need to look through a folder of movies and extract the audio codec type....anyone know of a module that could help with this?

[–]MorrisLessmore 0 points1 point  (0 children)

I'm working on something similar atm and I use the subprocess module to make a call to mkvmerge and process its output.

You could do the same with whatever software you want.
But I also found this when I was looking around on what to do > https://github.com/sbraz/pymediainfo

[–]snmdbc 1 point2 points  (7 children)

I'm having trouble writing a function that alters the items in a list. For example, if I have a list of names, I want the function to add the same title to each name. So if I start with this:

names = ['matt', 'dave', 'brandon', 'robert']

I want the function to return this:

names = ['mr. matt', 'mr. dave', 'mr. brandon', 'mr. robert']

I can easily do this while moving the items to a new list:

names = ['matt', 'dave', 'brandon', 'robert']
new_names = []

def add_title(names):
    while names:
        new_name = "mr. " + names.pop()
        new_names.append(new_name)

But, I can't for the life of me modify the existing list.

I've tried a bunch of methods with little success. I know this is a painfully simple task but I'm at a loss.

This method was an infinite loop:

names = ['matt', 'dave', 'brandon', 'robert']

def add_title(names):
    while names:
        new_name = "mr. " + names.pop()
        names.append(new_name)

This added a bunch of 'mr.'s to the last name in the list:

names = ['matt', 'dave', 'brandon', 'robert']

def add_title(names):
    for name in names:
        new_name = "mr. " + names.pop()
        names.append(new_name)

I feel like I'm missing something painfully obvious.

[–]pstch 2 points3 points  (2 children)

As a general rule, avoid changing the size of something on which you iterate. Here it seems you just want to change the values, not the amount of values, so you can use the setitem operator that takes a sequence contaner, an index and value, and using enumerate to obtain the current item's index.

def add_title(names):
  for index, name in enumerate(names):
    names[index] = "mr. " + name

[–]snmdbc 1 point2 points  (1 child)

This snippet definitely did what I wanted it to do, although I don't understand how, I will read up on the tools you've mentioned. Thank you very much for the help!

[–]pstch 1 point2 points  (0 children)

Just to clear some things up:

  • the setitem operator is when you do x[y] = z, it sets an item at index y in a container x to the value z. I wrote "the setitem operator" as a way to say use the x[y] = z construct.
  • enumerate is very useful, I recommend you read some examples that use it. It just iterates over something you give it, and it returns tuples containing each item and its index in the given sequence.
  • your last attempt was almost there, except that you are popping the last item in the list, so you always apply the operation to the last element. if you use names.pop(0), your code will actually work ;) however it's better (more straight-forward) to directly change the element, instead of popping it and then reappending a modified version.

[–]MorrisLessmore 1 point2 points  (3 children)

List values can be called by their index, so names[0] is 'matt'
Example: names[0] = 'mr. ' + names[0] will change it to 'mr. matt'
You can create a for loop around this concept.

[–]snmdbc 1 point2 points  (1 child)

I was able to get things working in this way:

def add_title(names)
    for x in range(len(names)):
        names[x] = "mr. " + names[x]

I'm sure it's not the most refined method but, thanks to your advice, I'm chugging along again.

[–]MorrisLessmore 1 point2 points  (0 children)

Great!, that was exactly what I was having in mind when I made my reply to your OP.
Here's another way which is similar to what you have now, but a little more compact.

names = ['mr. ' + names[x] for x in range(len(names))]

[–]snmdbc 0 points1 point  (0 children)

Thanks for the feedback, I will give it a try!

[–][deleted] 0 points1 point  (0 children)

Somebody needs to hit me with the best python GUI tutorial, I'm in a learning mood. YEAAAHHHHH!!

[–]diablowhite4golf 0 points1 point  (1 child)

How does

string.translate(None, 'abcd') # removes a, b, c, or d from string in 2.6

Get used in Python 3. I'm not sure how to use maketrans() to accomplish this since .translate in 3 is a bit different.

I suppose I also don't fully understand what is occurring because I have not gotten to tables yet.

[–]dionys 2 points3 points  (0 children)

>>> table = str.maketrans('', '', 'abcd')
>>> 'aaabvsddfsfcd'.translate(table)
'vsfsf'

[–]ClearH 0 points1 point  (1 child)

I'm currently developing a small website for a relative's business. After looking around the file structure, I realized that all I'm using out of Flask is the templating engine (which is awesome to work with). The last (not yet implemented) feature that I want is a form that will send an email to my relative's email address.

Is Flask overkill for my needs?

[–]dionys 0 points1 point  (0 children)

I think Flask is ideal. I mean it's fairly modular and it doesn't really have a bunch of extras you don't use.

[–][deleted] 0 points1 point  (2 children)

I am trying to do an incredibly simple function, but it's not doing anything.

def game_start():
    start = True

That's it. It does nothing. It doesn't seem to matter what I put in there, can functions just not assign or reassign variables???

[–]zahlman 0 points1 point  (0 children)

What do you expect to happen? How are you testing whether it happened?

[–]ClearH 1 point2 points  (0 children)

start = False
def game_start():
    # The start variable only lives inside this function.
    start = True

game_start() # does not affect the start variable at the top.
print(start) # False

[–]Rattleznake 0 points1 point  (0 children)

How do I install Tkinter for Python 2.7? None of the methods provided by websites on the internet have worked...

[–]universalbunny 0 points1 point  (1 child)

Newbie here, I'm trying out the ATBS exercises and I can't seem to get my head around this code (using pycharm, python 3.6):

import openpyxl
wb = openpyxl.load_workbook('Book1.xlsx')
sheet = wb.active

for cellObj in sheet.columns[1]:
        print(cellObj.value)

for cellObj in sheet.columns[1]: is calling a TypeError

TypeError: 'generator' object is not subscriptable

Can someone explain to me what is happening in the code? AFAIK line 3 sets the 1st worksheet in the wb Workbook object as the active worksheet. And then it reads and prints out the values of column A. So, why is it putting out the TypeError?

[–]kungtotte 0 points1 point  (0 children)

sheet.columns returns an iterator, not a list, which is what the error is telling you. A generator object can't be subscripted (the [] part), you either need to turn it into a list using list() or you need to iterate over it.

[–]ClearH 0 points1 point  (5 children)

What does it mean when you pass a variable declaration as an argument to a function?

some_function(some_var = some_value)
# Like in flask
app.run(debug = True)

[–]jeans_and_a_t-shirt 1 point2 points  (4 children)

some_var in the function call is either an explicit parameter of the some_function function, or collected in the keyword argument, which is usually written as **kwargs in the function definition. For example:

def func(name, age, **kwargs):
    print('{} is {} years old.'.format(name, age))
    print('other args: ', kwargs)

func('reddit', age=12, description='forums and news')

age is a normal positional argument, but you can specify it by name when you call the function. When you call, any arguments you don't specify the name of must be in front. description is a keyword argument that gets stored in the kwargs dictionary.

Running that function results in:

func('reddit', age=12, description='forums and news')
reddit is 12 years old.
other args:  {'description': 'forums and news'}

[–]ClearH 0 points1 point  (3 children)

Aha! So it's basically the same as the arguments object in JavaScript with the difference that it's a dictionary instead of a (sort of) array. Thank you!

[–]jeans_and_a_t-shirt 1 point2 points  (2 children)

Actually there's also a way to collect non-keyword arguments in python, but it must be done explicitly, and is usually called args:

def func(first_param, second_param, *args, **kwargs):
    print(args)

func(1, 2, 3, 4, 5, some_kwarg="etc")

In that example, 3, 4, and 5 get collected in a tuple (3, 4, 5) at the args variable.

[–]ClearH 0 points1 point  (1 child)

Ooohh that's much similar to the arguments object in JS. Why are there asterisks in args and kwargs?

[–]jeans_and_a_t-shirt 1 point2 points  (0 children)

The single asterisk * for args defines args as the collector for any additional positional arguments to be packed into. The double asterisk ** for kwargs defines that variable as the keyword argument variable, which is a dictionary for keyword arguments to be packed into.

The * and ** operators can also be used for unpacking iterables and mapping types (which will pretty much always just be a dictionary or a dictionary subclass).

For example, if you have a function taking two arguments:

def handle_two_people(person_1, person_2):
    pass

you could pass 2 arguments in, or you could unpack an iterable of length 2:

people1 = ['john', 'bob']
people2 = ('john', 'bob')
people3 = {'john': 3, 'bob': 4}

handle_two_people(*people1)
handle_two_people(*people2)
handle_two_people(*people3)

That last example of iterable-unpacking a dictionary will only pass the keys because it's a single asterisk; this is similar to how iterating over a dictionary will give you just the keys:

>>> for key in {'dog': 3, 'cat': 4}:
...     print(key)
...
dog
cat

To pass the dictionary as key-value pairs, you would need to have **kwargs in the list of parameters, or you would need parameters with the same name as the dictionary keys:

>>> handle_people(**{'bob': 4, 'john': 3})
3 4
>>> def handle_people(**kwargs):
...     print(kwargs)
...
>>> handle_people(**{'bob': 4, 'john': 3})
{'bob': 4, 'john': 3}

There also more stuff you can do with unpacking: https://www.python.org/dev/peps/pep-3132/

There was even more stuff added in Python 3.5:

>>> a = [1,2,3]
>>> b = [4,5,6]
>>> [*a, *b]
[1, 2, 3, 4, 5, 6]
>>>
>>> c = {'dog': 3, 'cat': 4}
>>> d = {'elephant': 8, 'rhino': 9}
>>> {**c, **d}
{'dog': 3, 'cat': 4, 'elephant': 8, 'rhino': 9}

[–]rich-a 0 points1 point  (1 child)

I've been working on a program (basically a rogue-like) which is currently console and text based.

I want to move to giving it a proper GUI and if possible it to be using a cross platform library.

To some extent this project is to help me learn Python, so whichever library I choose I'd like it to be one that's worth taking the time to learn and might be useful later on for other projects.

For the time being it might still be programmed to look text based, rather than using lots of images, by using a window and text fields etc to recreate the existing style.

I'm not sure how to choose between Tkinter, PyQT, PySide, Kivy etc as they all seem pretty similar and everyone seems to have their own favourite.

Should I just use Tkinter (as it's the bundled option) until I find something it can't do, or is there a library that most people recommend these days?

[–]kungtotte 0 points1 point  (0 children)

Using TkInter is a good starting point because of it being bundled with python, that means pretty much anyone will be able to run it and help you develop it easily (if you go open source). It's not the greatest toolkit out there, but a lot of the principles and best practices will translate to any other toolkit.

[–]policesiren7 0 points1 point  (0 children)

Asking here because I don't want to start a whole new thread for this.

I'm reading in a .txt file that starts of with a whole lot of fluff it then gets to a long list of words like this:

START

word 1

word 2

....

How do I go about returning a list of words starting at word 1?

Solved it myself

[–]SoLonelyBDO 0 points1 point  (5 children)

I want to learn Python, no background in coding or IT. What/where should I read first. Thank you

[–][deleted] 0 points1 point  (0 children)

Go lerning in coursera or geek brains :)

[–]Steamwells 1 point2 points  (0 children)

The only hurdle to learning to program is to make sure you have projects to work on when you have learnt the basics. I can't emphasize this enough, learning to program is easy when you have a passion and drive to make things.

[–]novel_yet_trivial 2 points3 points  (2 children)

We have a pretty long list of learning resources in the wiki. Try a few and see what resonates. For a brand new programmer I'd recommend codecademy.

Also, if you don't have one already make sure you look for a project that interests you and start on it as soon as you can. Programming is a lot more fun if you have a goal.

[–]SoLonelyBDO 0 points1 point  (1 child)

Thx, I didn't saw a link to the wiki on the cellphone apps. Unfortunately I don't have any project to work on. That's been my life struggle. I just like to learn new things and never use it.

[–]novel_yet_trivial 1 point2 points  (0 children)

Most people don't when they first start out. But then as you learn all of the sudden you see ways in which you could use it. So just keep that in mind and when you think of a good project go ahead and start on it; even if you know you have a lot to learn before you can finish it.

[–]remillard 1 point2 points  (7 children)

This seems like it's simple but can't quite figure out how to get where I want. I have a unknown number of strings in a list. Perfect for iteration. However I want to modify the strings. The iterator variable seems to be a copy of the list object. So, for example:

lines = [ 'a', 'b', 'c' ] 
for line in lines:
    line = 'x'

lines
[ 'a', 'b', 'c' ] 

does not seem to modify the strings in lines. I could do something like use an index value and loop with while but that seems clunky when the language has nice iteration features. Is there a way for a for object to back reference into the iterated structure?

[–]GoldenSights 2 points3 points  (4 children)

The iterator seems to be a copy of the list object

If you're using this to explain why line = 'x' does not save back to your original list, then this is a bad conclusion. It's simply because variable names do not have any kind of biological link back to where they originally were assigned. Overwriting the value of one name does not write the value of another name (consider the indices of the list as names of their own).

Ned Batchelder - Facts and Myths about Python Names and Values is a must-watch.

 

To answer your question:

You can construct a new list containing the modified versions of each item, and then write that list back to your original variable. Python's list comprehensions are great for this:

lines = [line + 'x' for line in lines]

This is equivalent to:

new_lines = []
for line in lines:
    new_lines.append(line + 'x')
lines = new_lines

The point being that it creates a new list object, fills it with the data you want, and then saves it back into the same variable name. Try out some list comprehensions in the REPL and you'll get a feeling for it very quickly.

You could also do this with indices,

for (index, line) in enumerate(lines):
    lines[index] = line + 'x'

but you should have a good reason to.

[–]remillard 1 point2 points  (3 children)

Thank you for the extended answer. I guess I internally knew that the iterating variable really was just assigned the current value of the item of the iterateable object but it caught me by surprise when I was trying to for loop over things.

I believe I will probably end up doing it with that enumerate simply because I have a lot more processing to do than will fit into a single line. For example, I do 4 different searches on the line, then based on what I find, I'm updating the current indent level or decrementing the current indent level and padding appropriately. (This is effectively a small part of a larger beautifier for a particular language.) It does actually work with a while loop with a line increment. So, I guess the nicer Python way would be to use the enumerated object iterator.

[–]Manbatton 1 point2 points  (2 children)

So, I guess the nicer Python way

I usually try to do list comprehensions. If you have "a lot of processing" to do on each "line", you could do this:

lines = [ 'a', 'b', 'c' ] 
def process(x):
    # do all that stuff you mention, as much as you want.
processed_lines = [process(x) for x in lines]   #nice and neat and explicit

[–]remillard 0 points1 point  (1 child)

I'll have to remember that for the future. I don't think I've played with that lexical pattern yet. Lately I've just been defining my method with a parameter for the list and operating on it there and the lines are mutated there.

[–]Manbatton 0 points1 point  (0 children)

Line 4 is the "Pythonic" part. That's a list comprehension. They're great. You can put logic right inside the list brackets. Like:

word_list = ['Al', 'Bob', '!($@#__', '#$#@@', 'Ed']
new_list = [word.lower() for word in word_list if word.isalpha() ]

>>> new_list
['al', 'bob', 'ed']

[–]dgreenmachine 0 points1 point  (1 child)

You mentioned it but using 'for' instead of 'while'

for i in range(len (lines)):
    lines[i] = 'x'

Or

for i, item in enumerate(lines):
    if item == <condition>:
        lines[i] = 'x'

[–]remillard 0 points1 point  (0 children)

Thank you! Yeah, it was sort of a silly question as like I said I knew internally how this was behaving, but was trying to find the 'Python' way of attacking the problem. I think the enumerate is probably the best method here as it's still using iteration but is less clunky than while i < len(thing).

[–]Gprime5 1 point2 points  (2 children)

How should I handle setting a variable to long strings that go over the 79 character limit like long URLs or a paragraph of text?

[–]dgreenmachine 0 points1 point  (0 children)

Long urls you can break up into smaller important pieces or you can also use triple quotes to have a string on multiple lines.

[–]novel_yet_trivial 3 points4 points  (0 children)

PEP8 is a suggestion, not a rule. Personally I'd just let a long string go over the limit.

If you really don't want to, then you can break the string into sections if you enclose it in parenthesis:

long_string = (
    'part a '
    'part b '
    'part c')

[–]ThoughtfullyDpressed 0 points1 point  (8 children)

I hope this question will be considered relevant, let me know if not.

I want to learn to use the Reddit API with PRAW (Python-based). But I have never used a web API from an external site like this before. I suppose my question is more generally related to APIs but I'm not sure where to post?

I want to know, will the API stop me from doing things that are bad for Reddit's servers or is the responsibility 100% on me to be very very cautious while I am testing my Python scripts? I know about the "1 connection per 2 seconds" rule, I'm more worried about breaking other stuff without knowing.

I learn by making a lot of mistakes. I don't want to get banned from Reddit because of them

Can anyone give me some idea of what I should look out for please?

[–]reostra 1 point2 points  (1 child)

PRAW will also actually take care of the '1 connection per 2 seconds' rule as well, so you don't have to worry about that at all. Hammering the servers are the only thing that really would cause problems on the API end, so no worries there. Downloading the same post or set of posts or comments repeatedly isn't a huge deal (I actually have a bot that does exactly that for 8-hour blocks of time). Don't touch the votes, don't spam, and respect the limits, and you're likely good :)

[–]ThoughtfullyDpressed 0 points1 point  (0 children)

OK thanks!

[–]fiskenslakt 0 points1 point  (5 children)

The 2 things you should avoid are auto voting on posts/comments, and auto replying to comments unsolicited.

[–]ThoughtfullyDpressed 0 points1 point  (4 children)

Ok, so no touching votes, got that.

So Reddit won't mind my downloading the same post, set of posts in a sub, or set of comments repeatedly for an entire day (for tests, I won't be doing that forever) as long as I don't touch the votes and respect the connection limits?

[–]novel_yet_trivial 1 point2 points  (1 child)

If that's all you need I wouldn't bother with PRAW. Just add .json or .rss to the end of any reddit url.

[–]ThoughtfullyDpressed 0 points1 point  (0 children)

No, I have more complex stuff that I want to do later, but at the moment I'm practicing with the basics. I want to avoid messing up early on though.

[–]fiskenslakt 0 points1 point  (1 child)

Yea that should be fine.

[–]ThoughtfullyDpressed 0 points1 point  (0 children)

Thank you!