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
Fergus Mac Roich
Nov 5, 2008

Soiled Meat
I'm in here because I'm following a Google Python tutorial, and I have a question about an exercise. The task I'm working on right now is printing a sorted list of the top 20 words in a document along with their count. Each word gets their own line. I have a dictionary because that seems the most natural structure besides a list of tuples, but since tuples are immutable, I thought a dictionary would be more efficient(not making a new tuple every time I increment the count, etc). I'm a relatively new programmer, but I know a bit of C.

code:
   
for k, v in sorted(word_dict.items(), key=val*, reverse=True):
    print "%s %d" % (k, v)
*simply returns the value associated with the key, pardon the lovely method name

1. Am I right that there's no built-in way to slice a dictionary? I want to cut it off when it reaches 20 items, and I could easily break the loop when an iterator reaches 20, but that seems to be coming from the C center of my brain, and I'm thinking Python might have something more elegant. I'm aware I could use something like for x in range(), but I don't know how or even if that can be combined with the loop there. I was considering actually converting and saving it to a list of tuples, since I'm thinking that's what sorted(my args) does to that dictionary anyway. If I did that I could rather easily use slice notation.
2. Since a dictionary isn't guaranteed to be sorted in any particular way, is that sorted(etc etc) expression being re-evaluated for every iteration of the loop, or does it stay in memory somewhere?

Adbot
ADBOT LOVES YOU

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
I don't actually know what a lambda is(except vaguely) because it doesn't appear in K&R C so I guess I'll figure that out and throw it in there. The rest of your post makes perfect sense and answers my questions, thanks.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

baka kaba posted:

Here's a nice lambda overview
http://www.secnetix.de/olli/Python/lambda_functions.hawk

Also it doesn't really answer your general question, but There's A Library For That!
https://docs.python.org/3/library/collections.html?highlight=counter#collections.Counter


KICK BAMA KICK posted:

Lambdas are anonymous functions -- one-liners you can use exactly like a function; the key of sorted and the like is the canonical example of their use in Python.
Python code:
def val(item):
    """Get the second item of the given tuple, e.g., the value of a (key, value) pair generated by dict.items()"""
    return item[1]
or
code:
val = lambda item: item[1]
are pretty much exactly equivalent, and the latter is more Pythonic for such a simple function; inlining them anonymously like I did in the previous post is also very common as long as they're simple and don't make the resulting line unreadable.


Dominoes posted:

Of note, you can also use key=operator.itemgetter(1)

You'd use lambda or itemgetter() in this example, but you'd pass a normal function into key if you're sorting based on a more complex rule.

Thanks guys! The amount of crap I get "for free" in this language compared to writing it myself in C is pretty awesome. Especially not having to call a function just to allocate memory for a new struct or whatever.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Question about generators. I have a generator that yields lists of words(one list per call, obviously). Is there any way to use another generator expression to yield each element of each list?

I feel like the solution is staring me in the face but there's some kind of gap in my understanding of generators that prevents me from seeing it. I want to avoid writing a function if possible.

edit: Wow, I think the answer might actually be in the itertools module you guys helpfully pointed out.
double edit: Okay, I thought the answer was itertools.chain(), but I couldn't get that to work. Here's an insanely stupid construct that did work:

code:
word_lists = (words for wordslists in doc_lines for words in wordslists)
Now if I can only actually create a mental model of what's happening in that expression, because I kind of trial and error'd it out. I'm fixing my variable names to be more comprehensible.

I'm really liking generators. Check out my new function:

code:
def word_count(filename):
  f = open(filename)
  ret_word_count  = collections.Counter()
  doc_lines   = (line.lower().split() for line in f) 
  individual_words  = (w for wlists in doc_lines for w in wlists) 
  for w in individual_words:
    ret_word_count[w] += 1
  return ret_word_count
I made that from this:

code:
def word_count(filename):
  f = open(filename, 'r')
  words = {}
  for line in f:
    line = line.lower().split()
    for word in line:
      if word in words:
        words[word] += 1
      else:
        words[word] = 1
  return words
My new code might still be somewhat stupid, not sure. Obviously this is just for a beginner's exercise so pretty low stakes here but if anyone knows of anything further I could do to make it better I'm all ears. I tend to learn a lot from refactoring code over and over.

Fergus Mac Roich fucked around with this message at 02:59 on Jan 17, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

ShadowHawk posted:

What you want is equivalent to:
Python code:
def individual_words_from_wordlists(wordlists):
  for wordlist in wordlists:
    for word in wordlist:
      yield word
You called wordlists "doc_lines" and you called "word" "words", but that's the gist of it.

Yes, Python chained for loops in a single expression are a bit yodaspeak. I'm not sure why.

I kind of figured that I might be able to do it with a generator function, but in this case I decided(somewhat arbitrarily) that I preferred to be as succinct as I could - I had a strong sense that a generator expression could do it. I'll have to read the style guide to get a better sense of how variable names are supposed to look, I was just using whatever matched the concept I had in my head of what was happening with the function.


baka kaba posted:

...
(This is an amateur explanation coming up) This is a little tricky, but you see that asterisk in the first one? That unpacks a collection of arguments into in the individual elements. It turns 'hey chain, handle this box of stuff' into 'hey chain, handle this and this and also this'. The difference is that chain will treat the box (say your collection of iterables) as the -single- iterable you want it to operate on, and it will happily hand you each element inside it - but those elements are the things you actually wanted it to iterate over. So you need to unpack that collection as you hand it to chain, so it gets multiple elements instead of the container. If that makes sense!
...

Good post, thanks. I should have read the docs more closely, I made a totally wrong assumption about the asterisk and then proceeded to miss the alternate version of chain. I'll swap my solution for chain, actually, because I think it's much more clear.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
The line between brevity and incoherence is a difficult one to grasp for me, I think.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Very true. I'll think of some more apps to write and be back when I have more questions. Thank you all.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
code:
>>> 0.1 + 0.1 + 0.1 - 0.3
5.551115123125783e-17
What information am I looking up to find out why this happens? I notice it doesn't happen in C with GCC on this machine, which has an i3 M370(not sure if that's relevant).

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

JawnV6 posted:

I'd be curious how you're setting it up in C to be confident in the bolded bit. Here's a python doc on it that might be enlightening, if you really want to learn all the lies that surround FP you could start here.

As simply as possible, with printf("%f\n", 0.1+0.1+0.1-0.3). I assume there's some gotcha I'm missing?

edit: Oh, and the link to the Python docs pretty much answered my question. I guess I'll dig into the wikipedia article too, I find it pretty interesting.

Double edit: Figured it out, printf's %f truncates it; %e shows the "correct" value. Thank you guys for being so helpful with my silly questions. One day I will be a good programmer and it will be awesome.

Fergus Mac Roich fucked around with this message at 00:57 on Feb 24, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
So I'm starting to build python apps that, while still pretty small in scope(single-threaded, totally local, etc), are big enough to warrant multiple classes and the like. I'm still a beginner and my learning background is in C, so I don't really have a good grasp of object oriented programming. I understand, on a basic level, the ideas behind encapsulation, inheritance, and polymorphism, but what I'm struggling with is how to put it all together and create a program with a really good, idiomatic structure. I'm looking for Python-specific tips, concepts, or hopefully reading material on how to master this aspect of programming.

Here's an example of a challenge I'm facing with a small program.

I'm writing an application that more or less acts as a leaderboard/record for performance in a board game(I have a group that meets once weekly). I've got some idea of how I want to structure my data in terms of classes. I have a player class that contains a name and methods that take a dictionary of games(keyed with a date object that's also a member of each game object). It also has __hash__ and _eq__ methods. I have a game class that contains said date object, and also a dictionary of player objects as keys with their respective scores as values. Game objects can also tell you who won them, and maybe some other things if I can think of some cool stuff to throw in there. I'm fine up to that point; there's almost definitely ways to improve upon this arrangement, but I think I can figure them out on my own.

My issue is that, to manage it all, I've essentially created a class of which there is only ever one instance that manages dictionaries* of all the games we've played and all the players who have played by prompting the user for commands and then either returning or inserting the appropriate data. I'm concerned that in doing this, I've created a "God" class that's as bad as just a global state. Is this the violation of OOP that I perceive it to be? If so, how do I overcome it? I can't figure out what kind of structure I need to come up with that can avoid a class that sees and manages all the data.

*I will probably change the top-level dictionaries to shelves for persistence.

Fergus Mac Roich fucked around with this message at 02:05 on Feb 26, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
What's wrong with using a functional style? I don't know that much about it but from hacking around with SICP/Scheme it seems pretty intuitive(moreso than a procedural style, honestly), and it looks like the tools are there to do it in Python.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
What's the most idiomatic way to copy a list?
1. newlist = oldlist.copy()
2. newlist = list(oldlist)
3. newlist = oldlist[:](don't think I'd consider this, but you never know)

This is Python 3. Mostly an academic question, it came up in a project for my own amusement.

Fergus Mac Roich fucked around with this message at 22:58 on Apr 2, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
let's say i have a function that i want to use a particular set of values that i want to generate just once. is it appropriate to do something like this?

Python code:
def outer():
    d = {'x': 3}
    def inner():
	#let's assume I did something useful with an argument and this value instead of just returning it
        return d['x'] 
    return inner

outer = outer()
It makes sense to me, but it seems like maybe I should use a decorator?

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Yes, perhaps I should have used a more complex example, but both functions would be parameterized.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Class names are supposed to use CamelCase according to PEP8. I assume that dict and list are lowercase because they're built in types, but why collections.deque is lowercase and collections.Counter isn't is beyond me. nametuple() is a function that produces classes so that one's different.

For another CamelCase example, collections.ChainMap.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Looks like a typo. I believe it'll work if you change:
code:
c.executemany("INSERT INTO tv_shows VALUES (?,?), movieList")
to
code:
c.executemany("INSERT INTO tv_shows VALUES (?,?)", movieList)

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
So you're finding the smallest difference between any two values in the list, right? As viking_helmet was getting at, your algorithm needs to minimize the number of times it needs to "touch" its elements. Now, your new solution is better than your old one, but step back from it and think: what if you could just know where the num2 value that's most similar to num1 is in the list? There's actually a way to do it, and it's right under your nose. I'll just stick the answer in spoiler tags, because I know I didn't find the fact that this method is faster to be intuitive at first, but you might be smarter than me so make sure to think about it for a bit before looking.

So if your original algorithm takes time equivalent to N^2, most practical sorting algorithms are closer to N * log N, which is way, way faster for a large N. So much faster that you can just call the list's sort() method, THEN loop through the entire list, checking each value against only the next value in the list. Be careful you don't run off the end of the list.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

SurgicalOntologist posted:

...and it might be marginally faster using generators, with less indexing.

Python code:
horses.sort()
smallest_diff = min(second - first for first, second in zip(horses, horses[1:]))
and izip if it's python 2, I think.

Python is cool as poo poo.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
So, Python mavens, is this the most elegant way to do this?

code:
def countit(arg):
    count_sub1, count_sub2 = Counter(), Counter()
    with open(arg) as dataf:
        thing = DictReader(dataf, fieldnames=fieldnames)
	for item in thing:
	    if validate(item, is_sub1_appropriate):
	        count_sub1 += 1
	    elif validate(item, is_sub2_appropriate):
		count_sub2 += 1 
    return count_sub1, count_sub2
fieldnames is a list of strings that comes from outside the function. validate looks a bit like this, in case it's not clear what I'm doing:

code:
def validate(item, func):
    item = {key: item[key].strip() for key in item} #maybe some things have whitespace; the functions called below do string comparisons
    return meets_common_criteria(item) and func(item)
For some reason it feels like I could improve this, but I just can't get my head around how. (The variable names are made up)

edit: Well, right after posting this I figured out the obvious way I was overthinking it. The code now reflects the change I made, but if anyone has any magic suggestions, I'd love to hear 'em.

Fergus Mac Roich fucked around with this message at 00:30 on Sep 4, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

chutwig posted:

It seems like you wrote countit() the way you did so that you could use tee() to not read the file twice, but with the consequence that now everything else in the function is doubled up. If you expect to re-use the file contents over and over, read it into a buffer outside the function and pass that in. There are also some things being accessed inside countit() that look like globals, e.g., fieldnames.

Do the counts need to be done together like that? Is there a reason why they can't be done one at a time? If the state of one counter has no bearing on the other, then I would advise doing them separately instead of doubling up. Generally speaking you will want to deal with having 0 things, 1 thing, or more than 1 thing. Right now you're dealing with 2 things as 2 things, instead of dealing with them as 1 thing twice. Changing countit() to handle one counter as a time is a more generalizable solution.

What do you think of this?

Python code:
#calling code
fieldnames = #some strings
mykey = #a key from fieldnames
with open(myfile) as f:
    mydata = list(DictReader(f, fieldnames=fieldnames))
sub1 = countit(*mydata, validator=partial(validate, func=is_sub1), key=mykey)
sub2 = countit(*mydata, validator=partial(validate, func=is_sub2), key=mykey)

def countit(*args, validator, key):
    count = Counter()
    items = [item for item in args if validator(item)]
    for item in items:
        count[item[key]] += 1
    return count
This script actually does have some globals that are never modified, and yeah, that includes fieldnames. I've deemed it "okay" for this since it's just a script that runs for a second, writes all the counts to a file, and dies. However, I understand that you're right that as far as elegance and best practices, globals are generally bad design.

Fergus Mac Roich fucked around with this message at 01:37 on Sep 4, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

chutwig posted:

I think that is a lot more reasonable, yeah. Obviously there's such a thing as quick hacky scripts, but I've been burned by wackity global variable scope too much in the past and prefer to pass arguments around explicitly.

Cool, thanks. I'll take your advice about globals, too. For once I'll do the smart thing and learn from others' experience. :)

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
You don't need GitHub, you can use Git locally. It sounds like it would pretty much cover your needs with a simple local repository. With a single user, it's surprisingly easy to get everything set up. If you want remote code hosting, try Bitbucket.org, which is free for up to five users for a private repo.

You can get started here:
https://git-scm.com/book/en/v1/Git-Basics-Getting-a-Git-Repository

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

vikingstrike posted:

Indentation error technically, but really a scope problem. You define "disconnect" at a level lower (inside the for loop) than what you are calling (inside the while loop).

I feel like I'm going crazy, I thought control blocks in Python don't make a new scope?

Gothmog, you need a debugger. I'm not a very knowledgeable programmer so I'm sorry if this is wrong, but I'm pretty sure the else code path can't fail unless link_list is empty(as long as you do disconnect[0] to get the tuple and not the list of one tuple), so if the other code paths are failing, you need to use the debugger to determine why link_list doesn't contain the values that you expect.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
I don't know how codingame works but my takeaway would be that it's a lot easier to track this stuff down if you can code it so that you can use a debugger(mocking the external data) :v:

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Look into filter.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Okay so I feel kinda embarrassed about this question. It's about an early Project Euler question: question 18.

I should preface this by saying that I eventually figured out the correct solution, and it's way simpler than the solution I'm going to ask about. Here's one right way to do it:
http://codepad.org/3fwfoSrN

So there's probably much simpler/more elegant ways to write that, but it works just fine. You give it a filename, it reads the numbers in, and does its thing. The algorithm is applicable to the more difficult problem 67, as well.

Here's the thing: I don't know anything about math, and these solutions don't come easily to me, so I originally came up with the idea of computing the answer with a "longest path" algorithm. I found Dijkstra's Algorithm on Wikipedia, converted the pseudocode to Python, and came up with:
http://codepad.org/H0dHxtqN

I can't figure out where my implementation is wrong; I've never implemented Dijkstra's Algorithm before. Either that, or I can't figure out why this algorithm is not sufficient to solve the problem. It actually works on the smaller example that Project Euler gives. Can anyone give me any hints? And sorry about my crappy code, or if it's hard to read. It's not too many lines, at least.

Fergus Mac Roich fucked around with this message at 01:08 on Nov 11, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Is there a real difference between a shortest path and a longest path? You can see in the code there that I swapped the concepts around where appropriate. I suppose there's something I'm not understanding, but it seemed clear to me that the values of the numbers mapped neatly onto the concept of weights of nodes on a graph. All paths are the same number of nodes, but each node has a different weight, determined by the number the node represents in the triangle. In the first solution I linked, I did exactly what you said(okay i reread what you said and no I didn't do that but I did something that does work and is much simpler than a graph), but I am sort of a dummy and it took me a solid week to think of that. I'm just trying to make sure I have my head around why I was wrong.

Fergus Mac Roich fucked around with this message at 01:41 on Nov 11, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
Yeah... it's still not intuitive to me why this algorithm can't do this(note that my script does model the constraint you mentioned) but I guess I should have read further. There are other internet resources making it clear that this algorithm is just inapplicable to longest path in a DAG, assuming that I'm right that this problem actually can be modeled in that way. I guess I'll come back to this problem one day when I understand graph algorithms better and maybe it'll make more sense. At least I have a solution. Thanks.

Fergus Mac Roich fucked around with this message at 02:19 on Nov 11, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

Emacs Headroom posted:

I didn't check your implementation, but I think Dijkstra's would work if you set up the graph structure correctly (i.e. in the triangle every node has two children in the level below it, except for the final layer which all feeds into a "sink" node that is your target).

The solution is going to be dynamic programming of some sort; my first pass would be somethng like:

1. Assign each node in the tree DAG a weight w_n equal to the intial weight supplied

2. Starting at the lowest level and moving up, for each node n in the level, set w_n = w_n + max(w_m for m in children)

The number at the top of the node should be the number you want after this process is finished (this might be the same as the topological sorting mentioned earlier, but I'm too lazy / hung over to check)

I'm not sure if that's topological sorting because I haven't studied it yet(thanks for the heads up to whoever posted it, I am definitely going to read up), but that's actually pretty much the solution I ended up with.


baka kaba posted:

(sorry for the megapost, I couldn't see anything wrong at first so I got curious)

This post is great and I feel like it improved my understanding of the algorithm, so thank you.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

The Royal Scrub posted:

Is there a way to set variable type once and be done? Designating a variable as int(input(variable),10) every time I redefine it doesn't seem right.

If I don't do that it wants it to be a string, I guess because I'm using input but yeah.

Python uses type inference, so you aren't declaring a variable to be a specific type. What you're doing is using the int() built-in function to parse the result of the input() function(which is a string, because that's what the function returns) into an int. int() returns an int, so the variable is assigned an int, that's all. This is conceptually like using C's atoi(), and ultimately, any time you get information from standard input, you must do something like this. I believe that this is the case irrespective of the language you're using; as you can see, even C must do the same thing(though it provides a facility to make this case more convenient in the form of scanf()).

Fergus Mac Roich fucked around with this message at 05:00 on Dec 16, 2015

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
And it doesn't have tail call elimination :arghfist:

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

Pie Colony posted:

Not as a built-in language feature, but one of the "good" things about Python is you can pretty much do whatever you want, such as programmatically rewrite recursive calls in tail position for a given function's AST.

You're right, that is "good".

edit: Oops I'm posting in GBS too much. Fixed capitalization. Also yeah Python isn't perfect in terms of functional programming but I find that first class function objects and map() and stuff get me most functional-esque stuff I'd like to express in my imperative code.

Fergus Mac Roich fucked around with this message at 20:14 on Apr 4, 2016

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

drainpipe posted:

I'm just beginning to learn Python, and I was wondering what the best way to create a list of variable length filled with copies of one thing is. Specifically, I want to create the list [[],[],...,[]] where there are k empty lists. Right now, I'm looping over k and appending empty lists to my growing list of empty lists. I can't do [] * k because modifying one of the [] modified them all.

More generally, my setup is that I need k containers that I will fill with numbers. I do not know how many numbers will go in each container. Is there a better way to do this than a list of empty lists? I'm using NumPy/SciPy if that's any help.

from itertools import repeat

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
It's better if the object doesn't know how to construct its dependencies. If the dependencies are available via the API at the time you construct the object, you should make the API call somewhere in the calling code and then supply the dependencies as arguments to the constructor. Or maybe I write too much java.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

Tigren posted:

Hand... calculator? Like, you push buttons on a thing that only calculates?

You know how you prove an RCE with a screenshot of calc.exe? Well, that program was actually made into a handheld device, like a Tiger Electronics portable game but for an application.

Edit: just for clarification, I don't think handheld calculators can be used to demonstrate an RCE unless the thing you hacked is a 3D printer.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

Dominoes posted:

Would it be possible to write a Pycharm plugin to support unicode (ie greek letter) shortcuts like in Ipython/jupyter/julia ? ie type '\gamma tab' to get the letter. If this is doable, I might try.

If this isn't an explicit piece of functionality already it's definitely possible with snippets. I'm sure I've done this in a JetBrains editor.

Edit: oops there were more posts

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

LochNessMonster posted:

Another (likely dumb) question about something I don't quite understand.

I figured I'd take the following route with parsing different variations of a specific webstore template. Each dealer has a specific variation of div/span classes in which the price, milage and year info is stored. Since there are only a few options per value I'd like to scrape, I figured I'd write a loop that checks which dealer uses which variation. I store which dealersite uses which variation in dictionary with the dealername as key, and the values in a tuple.

Python code:
dealerInfo = {"alpha": "(2, 1, 2)",
	      		"bravo": "(3, 2, 3)",
	      		"charlie": "(2, 1, 2)",
	      		"delta": "(2, 1, 1)",
			}
Later on I base which beautifulsoup search should be done on the flags in this dict.

Python code:
for dealerName, flags in dealerInfo.items():

<some code>

#getPrice dependant on flag[1]
                if flags[1] == "1":
                    getPrice = vehicle.find("span", {"class": "price"})
                elif flags[1] == "2":
                    getPriceDiv = vehicle.find("div", {"class": "vehicleSpecs"})
                    getPrice = getPriceDiv.find("span", {"class": "price"})
                elif flags[1] == "3":
                    getPriceDiv = vehicle.find("div", {"class": "vehiclePrices"})
                    getPrice = getPriceDiv.find("span", {"class": "price"})
                elif flags[1] == "4":
                    getPriceDiv = vehicle.find("div", {"class": "vehiclePrice"})
                    getPrice = getPriceDiv.find("span", {"class": "price"})
This works perfectly fine , but I figured the values in the dictionary would be flag[0], flag[1] and flag[2]. That however does not return the values I'd like. It returns: "(", "2" and "," respectively. So it seems the value of the dictionary is being treated as a string instead of a tuple. Which works, as long as I take the correct position of the string, but it's not what I had in mind.

fake edit: while I'm typing this I'm realizing my error. If I don't wrap the tuple in quotes, and remove the quotes from the if flags[x] == "value" it treats the tuple as a tuple instead of a string...

:ughh:

Yep, if you put something in quotes it's a string literal(people also use this for code comments in Python). It's actually not that different from how we use quotes in regular language. To steal part of an example from The Structure and Interpretation of Computer Programs:

Chicago is the largest city in Illinois.

"Chicago" has seven letters.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

LochNessMonster posted:

Django sounds awesome, but it might be overkill for a newbie like me.

Will I be able to add other functionality (like creating graphs) to a Flask web application later on?

Yes. Flask is Just Python™ and you can use it to make just about any type of web app.

Fergus Mac Roich
Nov 5, 2008

Soiled Meat

lifg posted:

I do like this convention, but I don't see it much.

(And coming from 10 years in Perl World, the $_ variable is quite important, it's the implied default of many builtins.)

I know for sure it's used in Haskell and Rust, and I'm pretty sure it's used in Lisps as well(Scheme is the one I have in mind). Also you will notice that your linter will complain about your unused unused, but not about your unused _.

Adbot
ADBOT LOVES YOU

Fergus Mac Roich
Nov 5, 2008

Soiled Meat
I feel that half-open has been fairly universal in the languages that I've used. For example, Java's Arrays.sort() uses half-open indexing. Dijkstra essentially makes an argument for it here

  • Locked thread