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
Haystack
Jan 23, 2005





It's simple: don't issue a redirect for the case where there's a blank or empty symbol parameter. Just let the template render on the same request.

Adbot
ADBOT LOVES YOU

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

Pollyanna posted:

So how do I handle when the page is first loaded? I'm expecting the user to load the page, attempt to search from the searchbar, and if the input is blank or none then it would put a message onscreen "please enter search terms" or something.

skip the redirect(s) on len(s) == 0

edit:

To add, the example on the flask docs is redirecting on success and some other arguments because it's a POST request they are flashing from, the GET doesn't redirect.

Jose Cuervo
Aug 25, 2004
I have a text file where each line has the following format
code:
X Y X Y X Y
where X is a 3 digit number and Y is a name (that can be more than just a single word), and the X and Y come in pairs (if there is an X there will be a Y. An example is:

code:
011  Anasco         129  San Lorenzo	069  Humacao
If I read the line in from a file, I would like to be able to split the line and extract the X Y pairs, but a regular split on white space will not work because of 'San Lorenzo'.

Any thoughts on how to accomplish this?

Dominoes
Sep 20, 2007

Jose Cuervo posted:

I have a text file where each line has the following format
code:
X Y X Y X Y
where X is a 3 digit number and Y is a name (that can be more than just a single word), and the X and Y come in pairs (if there is an X there will be a Y. An example is:

code:
011  Anasco         129  San Lorenzo	069  Humacao
If I read the line in from a file, I would like to be able to split the line and extract the X Y pairs, but a regular split on white space will not work because of 'San Lorenzo'.

Any thoughts on how to accomplish this?

Python code:
import re


text = '011  Anasco         129  San Lorenzo	069  Humacao'
x = re.findall('(\d{3})\s+([A-Z][a-z]+)\s+', text)
This gives you a list of tuples of the results. Note that this solution will have issues if the capitalization isn't like your examples.


Here's a breakdown of what that regex does:
  • \d{3} matches any 3 digits together. The parentheses around it means to return that as part of the result.
  • \s+ matches 1 or more spaces or line breaks
  • [A-Za-z]+, from viking's example below, matches one or more letters together. Parentheses applies here too.

Dominoes fucked around with this message at 20:34 on Jan 23, 2014

vikingstrike
Sep 23, 2007

whats happening, captain
Slightly expanding what you've done, you can always use [A-Za-z].

Biggz
Dec 27, 2005

There's probably a better way of doing this but I'd use regex - http://regex101.com/r/cN2aG9

code:
(?P<first>\d{3}.+)(?P<second>\d{3}.+)(?P<third>\d{3}.+)
code:
first	[0-20]	`011  Anasco         `
second	[20-37]	`129  San Lorenzo	`
third	[37-49]	`069  Humacao`

Jose Cuervo
Aug 25, 2004

Dominoes posted:

Python code:
import re


text = '011  Anasco         129  San Lorenzo	069  Humacao'
x = re.findall('(\d{3})\s+([A-Z][a-z]+)\s+', text)
This gives you a list of tuples of the results. Note that this solution will have issues if the capitalization isn't like your examples.


Here's a breakdown of what that regex does:
  • \d{3} matches any 3 digits together. The parentheses around it means to return that as part of the result.
  • \s+ matches 1 or more spaces or line breaks
  • [A-Za-z]+, from viking's example below, matches one or more letters together. Parentheses applies here too.

That does not seem to work quite right for me:

Python code:
>>> x
[('011', 'Anasco'), ('129', 'San')]
But now I know about regexs I can go read up on them and find what exactly I need the regex to be.

Dominoes
Sep 20, 2007

The spaces in the name are dorking it up. It'll get a bit messier taking them into account.

Dominoes fucked around with this message at 21:00 on Jan 23, 2014

Omnomnomnivore
Nov 14, 2010

I'm swiftly moving toward a solution which pleases nobody! YEAGGH!
Anyone know if there's a more direct way to do a vectorized substring operation than numpy.char.find?

code:
>>> jerks = numpy.array(['butthead', 'poophead', 'fartbutt'])
>>> has_butt = numpy.char.find(jerks, 'butt') != -1
>>> has_butt
array([ True, False,  True], dtype=bool)
There doesn't seem to be a numpy method that will vectorize str.__contains__ directly, unless I'm missing something.

Dren
Jan 5, 2001

Pillbug
Jose Cuervo, perhaps there are tabs between each of those X Y pairs? If so, parsing gets a lot easier because you can split on the tabs. e.g.
Python code:
# where 'line' has your input line in it
pairs = line.split('\t')
for pair in pairs:
    num = pair.split()[0]
    name = ' '.join(pair.split()[1:])
If not, this regex is a good starting point:
code:
\d+\s+[a-zA-Z\s]+
You can parse the line with almost the same code
Python code:
import re
# where 'line' has your input line in it
pairs = re.findall(r'\d+\s+[a-zA-Z\s]+', line)
for pair in pairs:
    num = pair.split()[0]
    name = ' '.join(pair.split()[1:])

Jose Cuervo
Aug 25, 2004

Dren posted:

Jose Cuervo, perhaps there are tabs between each of those X Y pairs? If so, parsing gets a lot easier because you can split on the tabs. e.g.
Python code:
# where 'line' has your input line in it
pairs = line.split('\t')
for pair in pairs:
    num = pair.split()[0]
    name = ' '.join(pair.split()[1:])
If not, this regex is a good starting point:
code:
\d+\s+[a-zA-Z\s]+
You can parse the line with almost the same code
Python code:
import re
# where 'line' has your input line in it
pairs = re.findall(r'\d+\s+[a-zA-Z\s]+', line)
for pair in pairs:
    num = pair.split()[0]
    name = ' '.join(pair.split()[1:])

Unfortunately the file did not have tabs between the X Y pairs. I ended up using
Python code:
re.findall('(\d{3})\s+([A-Za-z\-\s]+)', line)
because some of the names were hyphenated. I then used the .strip() function to remove the excess white space from around the Y name. But you all pointing me in the direction of regular expressions was exactly what I needed. Thanks.

QuarkJets
Sep 8, 2008

Omnomnomnivore posted:

Anyone know if there's a more direct way to do a vectorized substring operation than numpy.char.find?

code:
>>> jerks = numpy.array(['butthead', 'poophead', 'fartbutt'])
>>> has_butt = numpy.char.find(jerks, 'butt') != -1
>>> has_butt
array([ True, False,  True], dtype=bool)
There doesn't seem to be a numpy method that will vectorize str.__contains__ directly, unless I'm missing something.

I don't think so; I'm pretty sure that numpy.char contains all of the vectorized string operations, so your solution is probably the most direct

posting smiling
Jun 22, 2008

Jose Cuervo posted:

Unfortunately the file did not have tabs between the X Y pairs. I ended up using
Python code:
re.findall('(\d{3})\s+([A-Za-z\-\s]+)', line)
because some of the names were hyphenated. I then used the .strip() function to remove the excess white space from around the Y name. But you all pointing me in the direction of regular expressions was exactly what I needed. Thanks.

Here's one that doesn't require a .strip(), not that it's actually any better, but I couldn't resist a regex puzzle.

Python code:
In [61]: re.findall(r'(\d+)\s+(.+?)\s*(?=\d|$)', data)
Out[61]: [('011', 'Anasco'), ('129', 'San Lorenzo'), ('069', 'Humacao')]

Dren
Jan 5, 2001

Pillbug

Classicist posted:

Here's one that doesn't require a .strip(), not that it's actually any better, but I couldn't resist a regex puzzle.

Python code:
In [61]: re.findall(r'(\d+)\s+(.+?)\s*(?=\d|$)', data)
Out[61]: [('011', 'Anasco'), ('129', 'San Lorenzo'), ('069', 'Humacao')]

Lookaheads are cheating

Munkeymon
Aug 14, 2003

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



Dren posted:

Lookaheads are cheating

How about (\d{3})\s{2}(\w+(?:\s{1,2}\w+)+?) ?

JawnV6
Jul 4, 2004

So hot ...
I have a base64 string encoding a stream of bytes. I'm trying to decode that with base64.b64decode() and running afoul of character sets.

The very first byte is 0xfa. Testing (chars[0] == 0xfa) returns false. Printing chars[0] results in this lil guy: ú, 0x00fa

Is there any way to declare this as a boring array of bytes and Not A String? Some other import I should use?

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug
Python 2 or 3? What's the output of type(chars)? Does base64.b64decode succeed? What's the type(...) of what b64decode returns?

In Python 3 the base64.b64{encode, decode} methods only ever return byte strings -- b64decode can decode a sequence of Unicode code points that are in the ASCII range, but b64encode explodes with a TypeError if you give it a str.

Can you post some example data/code?

JawnV6
Jul 4, 2004

So hot ...
Python 2.7.3

>>> chars = base64.b64decode("+q8HAAAADrwAABpgG0sbXhtoGz0a9gAAAAEAAAAm")
>>> type (chars)
<type 'str'>
>>> print chars
▒▒▒`▒&
>>> base64.b64decode("+q8HAAAADrwAABpgG0sbXhtoGz0a9gAAAAEAAAAm")
'\xfa\xaf\x07\x00\x00\x00\x0e\xbc\x00\x00\x1a`\x1bK\x1b^\x1bh\x1b=\x1a\xf6\x00\x00\x00\x01\x00\x00\x00&'
>>> type(base64.b64decode("+q8HAAAADrwAABpgG0sbXhtoGz0a9gAAAAEAAAAm"))
<type 'str'>

Same thing happens with binascii.a2b_base64

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug
Python 2's str type is a sequence of bytes without any encoding; the interpreter is attempting to decode it as UTF-8 when you print it. You'd need to use ord on each element of chars to get the actual integer value of that byte:
Python code:
>>> import base64
>>> chars = base64.b64decode("+q8HAAAADrwAABpgG0sbXhtoGz0a9gAAAAEAAAAm")
>>> chars[0]
'\xfa'
>>> ord(chars[0]) == 0xfa
True
I strongly recommend that you use Python 3, where the bytes object behaves the way you want:
Python code:
>>> import base64
>>> chars = base64.b64decode("+q8HAAAADrwAABpgG0sbXhtoGz0a9gAAAAEAAAAm")
>>> type(chars)
<class 'bytes'>
>>> print(chars)
b'\xfa\xaf\x07\x00\x00\x00\x0e\xbc\x00\x00\x1a`\x1bK\x1b^\x1bh\x1b=\x1a\xf6\x00\x00\x00\x01\x00\x00\x00&'
>>> list(chars)
[250, 175, 7, 0, 0, 0, 14, 188, 0, 0, 26, 96, 27, 75, 27, 94, 27, 104, 27, 61, 26, 246, 0, 0, 0, 1, 0, 0, 0, 38]
>>> chars[0] == 0xfa
True
(maybe stealth) EDIT: I'm guessing about the UTF-8 part; that's dependent on your locale/system/etc. The actual encoding that's used isn't important, just the fact that the interpreter is trying to decode those bytes as text in some way.

Lysidas fucked around with this message at 20:07 on Jan 24, 2014

JawnV6
Jul 4, 2004

So hot ...
Ugh, that's what I needed. I had that figured out last week, apparently (values[x] = ord(chars[index])*256 + ord(chars[index+1]) shows up elsewhere)

This is an internal project, just meant for other engineers to quickly check values from a prototype. Eventually the base64 encoded string will be parsed in a much more reasonable environment. I'm not going to risk breaking all my existing, working infrastructure to make this one bit easier.

edit: Thanks!

JawnV6 fucked around with this message at 19:58 on Jan 24, 2014

Drone
Aug 22, 2003

Incredible machine
:smug:


So I'm teaching myself Python after basically everyone recommended it to me as baby's first programming language, and I'm having a lot more fun with it than I ever thought I would. I've run through a couple beginner courses (Code Academy and another really great one that I seem to have lost the URL for, basically a tutorial for people who know nothing about programming). I'm supplementing what I'm learning there with some more "practical" hands-on stuff from Youtube, since I sometimes have a hard time learning something when I can't see the practical application of it.

Anyway, I've got a goal in mind for a learning project. Without getting into too much detail since I'm not sure I'll stick with it, it's a type of fairly simple trivia game. I set out with the basic goal of creating a trivia game that enables me to store a bank of easily-editable questions in a plaintext file (right now .txt, but I think a .csv would work better). The program would then pull the questions, in random order, from the question bank file.

Thankfully there are a billion tutorials for basic trivia games in Python, and I've run through several of them. One of them is pretty great, astoundingly simple, and even has my basic plaintext storage system worked out. I understand pretty much all of the following code and why it's used, with the exception of the critical "with" command, which makes the whole thing work:

code:
from random import shuffle

with open("questions.txt") as questionBank:
    lines = questionBank.readlines()

shuffle(lines)
numRight = 0
wrong = []

numQuestions = int(input("How many questions would you like to answer? "))

for line in lines[:numQuestions]:
    question, rightAnswer = line.strip().split("\t")
    answer = input(question + " ")
    if answer.lower() == rightAnswer.lower():
        print("Right!")
        numRight += 1
    else:
        print("Wrong! The answer is", rightAnswer)
        wrong.append(question)

print("You got %d right!" % (numRight))
if (wrong):
    print("You got these wrong: ")
    for q in wrong:
        print(q)
This question probably sounds really stupid, but considering I've only got a couple days of any kind of programming experience under my belt, it's probably a least a little cute :shobon: Basically, can someone explain 'with' to me?

Other questions: if I wanted to use a different type of file (say, a .csv), how would I go about defining the 'question' and 'rightAnswer' variables instead of using line.strip().split("\t")?

Edit: note that excepting some minor changes in variable names, this is not my original code. Just a question I have from already-existing code.

Drone fucked around with this message at 23:53 on Jan 25, 2014

KICK BAMA KICK
Mar 2, 2009

In short, that's a safe way to work with files and such without worrying that the file won't get closed should an error occur. When the indented code under the with statement finishes, the file is automatically closed, and it also gracefully closes in the event of an exception. I think the term is "context manager" if you want more info. Seems a coinflip as to whether a particular tutorial covers that syntax or not. Works with more than just files too.

Dominoes
Sep 20, 2007

Anyone know what would cause text form an uploaded file to not work with a regex, or otherwise get mangled? I have a webapp that previously ran regexes on text taken from a text field. Worked fine. I switched to a django file upload. The read code looks like this: str(f.read())

I can print the text from the file and it looks normal, but my regexes are hosed. I tried looking at the printed text, then making a dead simple regex of a random word, that that didn't work either. I think this has to do with unicode/bytes/string magic. I'm using Python 3. Any ideas?

QuarkJets
Sep 8, 2008

Drone posted:

So I'm teaching myself Python after basically everyone recommended it to me as baby's first programming language, and I'm having a lot more fun with it than I ever thought I would. I've run through a couple beginner courses (Code Academy and another really great one that I seem to have lost the URL for, basically a tutorial for people who know nothing about programming). I'm supplementing what I'm learning there with some more "practical" hands-on stuff from Youtube, since I sometimes have a hard time learning something when I can't see the practical application of it.

Anyway, I've got a goal in mind for a learning project. Without getting into too much detail since I'm not sure I'll stick with it, it's a type of fairly simple trivia game. I set out with the basic goal of creating a trivia game that enables me to store a bank of easily-editable questions in a plaintext file (right now .txt, but I think a .csv would work better). The program would then pull the questions, in random order, from the question bank file.

Thankfully there are a billion tutorials for basic trivia games in Python, and I've run through several of them. One of them is pretty great, astoundingly simple, and even has my basic plaintext storage system worked out. I understand pretty much all of the following code and why it's used, with the exception of the critical "with" command, which makes the whole thing work:

code:
from random import shuffle

with open("questions.txt") as questionBank:
    lines = questionBank.readlines()

shuffle(lines)
numRight = 0
wrong = []

numQuestions = int(input("How many questions would you like to answer? "))

for line in lines[:numQuestions]:
    question, rightAnswer = line.strip().split("\t")
    answer = input(question + " ")
    if answer.lower() == rightAnswer.lower():
        print("Right!")
        numRight += 1
    else:
        print("Wrong! The answer is", rightAnswer)
        wrong.append(question)

print("You got %d right!" % (numRight))
if (wrong):
    print("You got these wrong: ")
    for q in wrong:
        print(q)
This question probably sounds really stupid, but considering I've only got a couple days of any kind of programming experience under my belt, it's probably a least a little cute :shobon: Basically, can someone explain 'with' to me?

Other questions: if I wanted to use a different type of file (say, a .csv), how would I go about defining the 'question' and 'rightAnswer' variables instead of using line.strip().split("\t")?

Edit: note that excepting some minor changes in variable names, this is not my original code. Just a question I have from already-existing code.

The with keyword has some limited by highly useful uses, basically it lets you create an instance of a variable that cleanly closes itself. This is very useful for files, as the file gets automatically closed when you leave the 'with' block.

To get a little more complicated, it can be used with any class that has an __exit__ and optionally an __enter__ method. __enter__ gets called when you invoke the with statement, and __exit__ gets called when the code leaves the with statement. The open() function returns a file object, and then file.__exit__() gets invoked when you leave the 'with' block.

So you can't do this:

code:
with 5 as i:
  print i
#This will cause an error
because integer instances don't have a __exit__ method.

code:
>>> help(int)
#A whole bunch of stuff gets printed about the int class, 
#but __exit__ is not defined, so the with block complains 
#when you try to give it an int instance
File instances do define __exit__

code:
>>> help(file)
Help on class file in module __builtin__:

class file(object)
#--- A whole bunch of text, and then this:
 |  __exit__(...)
 |      __exit__(*excinfo) -> None.  Closes the file.
#--- A lot more text
As you can see, __exit__ just closes the file.

So to summarize, the open() function returns an instance of the File class, and the File class has a __exit__ method that just closes the file. The 'with' keyword calls the __exit__ method of whatever it is provided with when the 'with' block is closed. So by providing a file instance to the with keyword, we're creating a situation where we open a file and then cleanly close it after doing something with it, but without having to call the file.close() method ourselves.

e: That's a lot of words to say "with lets you close a file when you're done with it without calling the close() method"

vvv Right, it saves you from having to write a try block, too. Very useful

QuarkJets fucked around with this message at 02:04 on Jan 26, 2014

SurgicalOntologist
Jun 17, 2004

Importantly, __exit__ gets called even if an error occurs inside the with block, so using with has a distinct advantage over simply closing the file when you're done.

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug

Dominoes posted:

str(f.read())

What's f? Specifically, is it a file object opened in binary mode or text mode? Calling str on f.read() is at best a no-op if f is opened in text mode, and at worst it'll give you the wrong results if it's is opened in binary mode:

Python code:
>>> # simulate f.read() on a file opened with 'rb' mode
>>> b = b'some bytes \x80\x90\xa0\xb0\xc0\xd0\xe0\xf0'
>>> b
b'some bytes \x80\x90\xa0\xb0\xc0\xd0\xe0\xf0'
>>> str(b)
"b'some bytes \\x80\\x90\\xa0\\xb0\\xc0\\xd0\\xe0\\xf0'"

salisbury shake
Dec 27, 2011

post generator posted:

I 'm having fun taking it slowly and learning Python right away.

quote:

I am so fed up and farted , Bill Murray appeared and gave me something `` I can't edit the request headers they"

Has anyone used NLTK? It's py2k only, but suits my needs for funny text generation. Above was generated from a trigram model of this thread's last 50 pages.

Besides a basic Markov chain, how can I take advantage of the toolkit's tokenization and tagging features? The docs get NLP heavy and I just want generate funny nonsense :(

Also turning this (github: here) into a Plasma widget so I can pin threads on the Desktop. No native widgets yet and it's super nested, but it's got some niace transitions and scrolling thanks to QML. QtQuick/QML is a pain in the rear end due to having to interface between PyQt5, QML and Javascript to get anything done.
And then PyKDE4 and PyQt4 to integrate into that ecosystem.

For posterity: If you decide to use Qt's QML you will end up writing Javascript

edit: lol Text reflow on resize bug in screenshot. Literally all the UI code is in Javascript and it isn't so bad tbh.

salisbury shake fucked around with this message at 11:14 on Jan 26, 2014

Dominoes
Sep 20, 2007

Lysidas posted:

What's f? Specifically, is it a file object opened in binary mode or text mode? Calling str on f.read() is at best a no-op if f is opened in text mode, and at worst it'll give you the wrong results if it's is opened in binary mode:

Python code:
>>> # simulate f.read() on a file opened with 'rb' mode
>>> b = b'some bytes \x80\x90\xa0\xb0\xc0\xd0\xe0\xf0'
>>> b
b'some bytes \x80\x90\xa0\xb0\xc0\xd0\xe0\xf0'
>>> str(b)
"b'some bytes \\x80\\x90\\xa0\\xb0\\xc0\\xd0\\xe0\\xf0'"
A file wrapper. It's bytes. Str() appears to work, as the text prints out ok (and has all the \r\n\x03 stuff in addition to the text). Is there a better way to do it.

I think this has to do with the newline characters. After more testing, I think the string is basically intact, and I can re things that don't have newlines. The regexes I need require newline checking. The regexes check for \r\n. However, the text printout's showing \r\n as expected, so I dunno.

For example, The printed text shows:
code:
-----\r\nRecord Time
I can match 'Record Time' with Regex. '\nRecord Time' won't work. This is the actual regex I've been using: '-{5}\s+Record\sTime.*?-{5}'


Edit - fixed. I printed a raw string using
Python code:
print(repr(text))
This showed that there was an extra slash before each newline character.

Fixed with this:
Python code:
file_text = file_text.replace('\\r', '\r')
file_text = file_text.replace('\\n', '\n')

Dominoes fucked around with this message at 13:16 on Jan 26, 2014

Nippashish
Nov 2, 2005

Let me see you dance!

salisbury shake posted:

Has anyone used NLTK? It's py2k only, but suits my needs for funny text generation. Above was generated from a trigram model of this thread's last 50 pages.

NLTK is my goto for text wrangling in python, although I'm far from an expert in it. (I'm 100% python 2.7 so the version restriction doesn't bother me). I made this thing one bored evening a while back http://uligen.herokuapp.com/. I also used a trigram model iirc.

Lysidas
Jul 26, 2002

John Diefenbaker is a madman who thinks he's John Diefenbaker.
Pillbug

Dominoes posted:

A file wrapper. It's bytes. Str() appears to work

Don't call str directly on a bytes object. If you want to use the file data as text, read it as text (without a 'b' flag to open), or call its .decode() method after reading it from the file.

You're searching the __repr__ of a bytes object, which actually has escape sequences represented as backslash characters. Fixing these escape sequences is the wrong way to deal with this; just decode the bytes.


EDIT: shouldn't post without any coffee. I'd forgotten that this data comes from Django file uploads. My recommendation of 'call .decode' stands, but if you're not sure about the actual encoding and just want to match an ASCII regex against whatever ASCII characters you can pull from those bytes, this would be f.read().decode('ascii', errors='ignore'). You could use the Django UploadedFile.charset field as a hint about what encoding to use other than ASCII, but this isn't guaranteed to be correct since clients can declare whatever encoding they want.

EDIT 2: or you could use a bytes regex with re.compile(br'a pattern (\d+)...')

Lysidas fucked around with this message at 16:32 on Jan 26, 2014

SurgicalOntologist
Jun 17, 2004

Does this have code smell?

Python code:
from contextlib import contextmanager


@contextmanager
def dummy_context():
   yield


user_context = dummy_context

# Allow user to supply different context


with user_context():
    # do stuff
I couldn't think of a way to enter a with statement only if the user wanted to. So instead I made a default with statement.

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I have no idea what the hell that code is doing.

SurgicalOntologist
Jun 17, 2004

It's not doing anything, it's a minimal example. I was trying to use a 'with' conditionally. As in, sometimes use with, sometimes not, depending on if the user has overwritten user_context with a contextmanager.

The alternative I guess would be:

Python code:
user_context = None

if user_context:
    with user_context():
        do_stuff()
else:
    do_stuff()

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
I don't know why you would ever want a with to sometimes do something and sometimes not. I'd never expect that from any code, ever.

SurgicalOntologist
Jun 17, 2004

So what you're saying is yes, it does have code smell. Well, I don't have time right now but later I'll explain my rationale and hopefully someone can tell me where I went wrong.

Dominoes
Sep 20, 2007

SurgicalOntologist posted:

Does this have code smell?

Python code:
from contextlib import contextmanager


@contextmanager
def dummy_context():
   yield


user_context = dummy_context

# Allow user to supply different context


with user_context():
    # do stuff
I couldn't think of a way to enter a with statement only if the user wanted to. So instead I made a default with statement.
Post more of the code. I guess it's code smell if you assume the rest of the code is also full of abstractions for the hell of it.

Dominoes fucked around with this message at 18:44 on Jan 27, 2014

SurgicalOntologist
Jun 17, 2004

Dominoes posted:

Post more of the code. I guess it's code smell if you assume the rest of the code is also full of abstractions for the hell of it.

https://bitbucket.org/hharrison/experimentator/src/0cc62ce0ea4b0cdb4ec824db43a2ee21cde2745f/experimentator/experiment.py?at=default

With statement on line 254, initialized on 151, set by user (possibly) on 286-287.

In brief, my library allows the user to set up an experiment by setting 'start', 'end', and 'inter' callbacks at different levels of the experiment hierarchy (e.g., call a function at the beginning of a session, call another function in-between trials, etc.). Then I have other code that uses a contextmanager to conveniently open and close an external resource. I would like to open the resource in the 'start' callback and close it in the 'end' callback, but I can't split the with statement over multiple functions.

One option would be to implement the opening and closing of the resource by hand in the start and end callbacks, but that doesn't handle the case of when an exception occurs. So I thought... why not provide the option for the user to specify a "with" function to use for any section of the experiment?

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!

Oh poo poo, a fellow puertorican goon?

accipter
Sep 12, 2003
Typically, I create multiple Python files that accomplish a small task. By the end of a project, I might have a dozen or so scripts the rely on the output from a couple different other scripts. I don't want to create one massive script because there are times when just one portion needs to be updated.

Do anyone have a method for keeping track of the dependencies like this? Perhaps a Make file would work, but I thought there might be a more pythonic solution.

Adbot
ADBOT LOVES YOU

OnceIWasAnOstrich
Jul 22, 2006

accipter posted:

Typically, I create multiple Python files that accomplish a small task. By the end of a project, I might have a dozen or so scripts the rely on the output from a couple different other scripts. I don't want to create one massive script because there are times when just one portion needs to be updated.

Do anyone have a method for keeping track of the dependencies like this? Perhaps a Make file would work, but I thought there might be a more pythonic solution.

The way I usually handle this is by having each script call functions defined in that file in a if __name__ == '__main__': block separating out the output from the actual work, and then I can easily combine these into one superscript by importing those functions and making the whole pipeline call the imported functions in the correct order. Then I get one big script that can do everything, as well as a bunch of scripts that can do each step.

I may be missing something in your description, but if you have a pipeline of scripts either combine them or break their functionality into functions so that they can be imported and called directly without the need for intermediate files, but still used with an extra function or bit of code on their own.

  • Locked thread