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
hey mom its 420
May 12, 2007

Ah yeah, glad we got this cleared up. I knew about accessing variables from parent namespaces.

They're planning to implement a keyword called nonlocal, which would allow you to alter parent namespaces, which I think is pretty cool but isn't as cool as real closures.

Adbot
ADBOT LOVES YOU

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

ATLbeer posted:

This might warrant it's own thread but, I'm having problems with both Python24 and 25 installed on my Mac.

I don't particularly remember installing 25 but, I guess it might have come from my Leopard upgrade. I don't honestly care much which version I am using but, my problem comes from the fact that any type of library or module install I am doing is defaulting into the 2.5 installation directory but, all my scripts are executed by 2.4.4.

Can anyone help me sort out this all?

Should I remove one installation (24 or 25) or how can I at least just get easy_install etc, to use one installation (preferably 24, since I already have a bunch of packages installed there) or migrate my packages over?

No need to remove one or the other - they can co-exist nicely. And some software *cough*Zope*cough* can't use 2.5.

It's odd about the install and execution going to different pythons. Type in "which python" at the terminal to see what your default Python is. (I'm guessing 2.5.) Do you have any execution line at the top of your scripts like "#/usr/bin/python24"? Finally, is there an alias or symbolic link to python anywhere that you might have made?

nonathlon fucked around with this message at 12:59 on Feb 12, 2008

ATLbeer
Sep 26, 2004
Über nerd

outlier posted:

No need to remove one or the other - they can co-exist nicely. And some software *cough*Zope*cough* can't use 2.5.

It's odd about the install and execution going to different pythons. Type in "which python" at the terminal to see what your default Python is. (I'm guessing 2.5.) Do you have any execution line at the top of your scripts like "#/usr/bin/python24"? Finally, is there an alias or symbolic link to python anywhere that you might have made?

Thanks for the reply. I figured out the problem. I had installed MacPorts and it had put an ugly 2.4.4 version on top of 2.4 and 2.5 and injected itself into my profile. Took MacPorts out and it went back to normal again

Thanks though

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

ATLbeer posted:

Thanks for the reply. I figured out the problem. I had installed MacPorts and it had put an ugly 2.4.4 version on top of 2.4 and 2.5 and injected itself into my profile. Took MacPorts out and it went back to normal again

Same thing happened to me, except with fink. One of the reasons I stopped using fink.

porkface
Dec 29, 2000

outlier posted:

Same thing happened to me, except with fink. One of the reasons I stopped using fink.

You guys know you can safely run multiple versions of Python on the same machine? You just have to set them up right, and choose which version you want to be your generic system-wide install.

m0nk3yz
Mar 13, 2002

Behold the power of cheese!

porkface posted:

You guys know you can safely run multiple versions of Python on the same machine? You just have to set them up right, and choose which version you want to be your generic system-wide install.

This man speaks truth: I have several versions installed on my mac. I just twiddle my bash_profile to point to the one I want.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

porkface posted:

You guys know you can safely run multiple versions of Python on the same machine? You just have to set them up right, and choose which version you want to be your generic system-wide install.

I'm aware, thanks. It wasn't the Python alone (once I knew about that I could work it out) but dealing with similar problems with other apps and libraries, and making sure that things that relied upon the fink versions could find the fink versions and those that wanted non-fink ...

One reason to be grateful for the framework builds under OSX - it keeps everything nice and separated and easy to find. I've got 3 versions of Python installed currently with no problems.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...
On to other topics: web development in Python. I've got a couple of web-applications (or rather, applications and databases that need a web front-end). It makes sense for all the logic to be in Python, rather than mix-and-matching languages and models. So what are people's experiences with Python webwork?

My own (limited) experience:

* Zope / Plone: I've done a lot of work with these and would advise anyone think strongly before before getting into them. You get a lot with Zope / Plone (default content presentation, ubiquitous and finely grained security, administrative tools, combining multiple applications / tools / products in the one web front). But they're tools that are a way of life - you have to dedicate a lot of time to get the framework to do anything, and I commonly spend more time wondering how to get Zope to do what I want, rather than solving the domain problems. And arguably Zope-Plone gets in the way of the development process, making it difficult be Pythonic and bang out some quick code to see how things work.

* Pylons: The Pylons philosophy looks good (use anything you want with our framework), but I've seen argued that this actually means that Pylons provides you with drat-all. Nonetheless, it seemed to work okay and I've been thinking about this for a dedicated web-service (as opposed to a general CMS).

* Django is the officially blessed framework. My one (and major) quibble is that it's using it's own database layer and ORM, which defeats the point if you have your own database layer already laid out (as I do). And Django's efforts at integrating SQLALchemy appear to have gone nowhere in 2 years.

* Webware has finally tottered out from it's coma and looks cool.

* I worked through the Turbogears book and it all seemed simple but (1) can it go beyond simple things, (2) with Turbogears 2 being mooted, this may not be a good time to commit.

Opinions?

SmirkingJack
Nov 27, 2002

outlier posted:

* Django is the officially blessed framework. My one (and major) quibble is that it's using it's own database layer and ORM, which defeats the point if you have your own database layer already laid out (as I do). And Django's efforts at integrating SQLALchemy appear to have gone nowhere in 2 years.


I thought part of Django's charm was that it didn't force you to use anything you didn't want to. So if you wanted to use a different db layer/ORM then you could.

bitprophet
Jul 22, 2004
Taco Defender

SmirkingJack posted:

I thought part of Django's charm was that it didn't force you to use anything you didn't want to. So if you wanted to use a different db layer/ORM then you could.

Yup. This is a major misunderstanding about Django; it is loosely coupled by design. Yes, you lose the contrib apps (admin, auth, etc) and generic views, but it still works perfectly fine in terms of URL dispatch, view functions and template rendering.

Now, given that the contrib stuff is a large part of what people like about Django, it's fair to say that you prefer how TG or Pylons does things at that level (when Django is "only" the URL dispatch + views + templates) but it's entirely possible to use Django sans its ORM, and it's designed that way on purpose.

Allie
Jan 17, 2004

outlier posted:

* Pylons: The Pylons philosophy looks good (use anything you want with our framework), but I've seen argued that this actually means that Pylons provides you with drat-all. Nonetheless, it seemed to work okay and I've been thinking about this for a dedicated web-service (as opposed to a general CMS).

Pylons being a "collection" of separate components is a load of poo poo. It's all tightly coupled together and about the only place you really get any freedom is in OR mapping. It touts being WSGI-based but it abstracts away WSGI to the point of it being irrelevant. You see other projects writing "adapters" just for Pylons compatibility.

And not to mention it's poorly documented, and just poorly designed all around. It's like they went out of their way to make their framework as complicated as possible.

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!
Hey I was wondering, what way do you guys use of getting a class from a string? I've been doing it in a fairly convoluted way and really think there's an easier way.

No Safe Word
Feb 26, 2005

deimos posted:

Hey I was wondering, what way do you guys use of getting a class from a string? I've been doing it in a fairly convoluted way and really think there's an easier way.

You mean serialization? There are a couple of ways: the shelve and pickle modules that are built in will do it for you fairly easy and there are a number of other ways as well.

deimos
Nov 30, 2006

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

No Safe Word posted:

You mean serialization? There are a couple of ways: the shelve and pickle modules that are built in will do it for you fairly easy and there are a number of other ways as well.

Nah, I am more thinking for settings and class loading. Like storing the name of the class you're supposed to use for a certain task on a settings file as a string then loading the correct class. Right now I use an eval and I really don't like it.

lilbean
Oct 2, 2003

deimos posted:

Nah, I am more thinking for settings and class loading. Like storing the name of the class you're supposed to use for a certain task on a settings file as a string then loading the correct class. Right now I use an eval and I really don't like it.
I've been trying to find this too (basically the equivalent of a lot of the Java reflection API).

bitprophet
Jul 22, 2004
Taco Defender

lilbean posted:

I've been trying to find this too (basically the equivalent of a lot of the Java reflection API).

Can you guys elaborate more on the background of wanting to do things this way / what problem needs solving? On the face of it it sounds sort of icky / un-Pythonic, to me, but I don't want to be judgemental until I know more.

I can say that generally when I hear someone wanting to make code-loading decisions based on a string, the answer is either getattr()/dict key access, or __import__().

Edit: vvv That works too - globals() and locals() exist for a reason. Just try not to alter them, I think that's generally a big no-no :)

bitprophet fucked around with this message at 00:00 on Feb 16, 2008

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.
I would use a metaclass (or a decorator, although I don't think class decorators are done yet) to add all class names to a dictionary as they're created, then just look up the class in the dictionary.

code:
class_dict = {}

# define the metaclass
class Registered(type):
  def __new__(cls, name, bases, dct):
    newCls = type.__new__(cls, name, bases, dct)
    class_dict[newCls.__name__] = newCls
    return newCls
Now you can create objects using that metaclass:

code:
>>> class C(object):
...   __metaclass__ = Registered
...   def hello(self):
...     print "Hi"
...
>>> class_dict["C"]
<class '__main__.C'>
>>> c = class_dict["C"]()
>>> c.hello()
Hi
EDIT: come to think of it, that's not even necessary:

code:
>>> class C:
...   def hello(self): print "Hi"
...
>>> locals()["C"]
<class __main__.C at 0x2a955c1ef0>
>>> c = locals()["C"]()
>>> c.hello()
Hi

JoeNotCharles fucked around with this message at 23:51 on Feb 15, 2008

gabensraum
Sep 16, 2003


LOAD "NICE!",8,1
Does anyone know of any 64-bit python database back-ends for windows? I've just installed Vista x64 and this has put a stop to my django tomfoolery. I prefer postgres but any database will do at this stage. Looks like I'll have to run it in vmware again :(

edit: even if someone can explain what I'll need to do to compile a 64-bit version of win-psycopg I'd be grateful. http://www.stickpeople.com/projects/python/win-psycopg/index.html

duck monster
Dec 15, 2004

I really loving wish the Python people would use an open source compiler (ie gcc) for its windows distros. It pisses me off into near nerd-rage when I need to compile poo poo for windows but woops don't own Visual studio, and I can't get it to work with the express one worth poo poo. This has been a show stopper for me numerous times now, and makes me want to summon robot-stallman to shoot motherfuckers dead.

dwayne_dibbley
Nov 26, 2005
Any idea how I can get python to read and show umlaut characters from a file properly?

My file is called data and contains only:
ö

My python program:

import string, msvcrt, sys
myfile=open("data")
print myfile.readlines()

When I run it, I get (in the XP command prompt)

C:\Python\test>test.py
['\xf6']

Replacing the umlaut with a plain x in the "data" file works OK:

C:\Python\test>test.py
['x']

I suspect it's not really python but XP because of this:

C:\Python\test>type data
÷

But I can type in umlauts on the prompt:
C:\Python\test>ööööääääää
'ööööääääää' is not recognized as an internal or external command,
operable program or batch file.

Any ideas? Thanks.

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

dwayne_dibbley posted:

Any idea how I can get python to read and show umlaut characters from a file properly?

Not Vista's fault, not Python's fault. You're got a non-ascii file.

Open the file with `codecs.open()`, while specifying the encoding you want and then treat it like a normal file. You'll get unicode strings back. Arguably, the issue is that unicode and normal string interoperate in Python so much that the fact you have to use a different call here is anomalous. See http://www.jorendorff.com/articles/unicode/python.html

JoeNotCharles
Mar 3, 2005

Yet beyond each tree there are only more trees.

duck monster posted:

I really loving wish the Python people would use an open source compiler (ie gcc) for its windows distros. It pisses me off into near nerd-rage when I need to compile poo poo for windows but woops don't own Visual studio, and I can't get it to work with the express one worth poo poo. This has been a show stopper for me numerous times now, and makes me want to summon robot-stallman to shoot motherfuckers dead.

If you're gonna be compiling your own extensions anyway, why not compile Python yourself? (EDIT: how can this be a show stopper when you know what the solution is?)

EDIT: oh, so the problem is that you have third-party, closed source Python extensions that you want to use at the same time as your own extensions? Asking people writing closed-source stuff on Windows to switch to mingw just to get Python compatibility seems like too much to ask - isn't paying for VC++ the standard for Windows development?

JoeNotCharles fucked around with this message at 19:31 on Feb 17, 2008

duck monster
Dec 15, 2004

Because it then breaks compatibility with all the other stuff people have compiled in MS C++

And if you don't have the sources, your boned.

dwayne_dibbley
Nov 26, 2005

outlier posted:

Not Vista's fault, not Python's fault. You're got a non-ascii file.

Open the file with `codecs.open()`, while specifying the encoding you want and then treat it like a normal file.

Aha! Thanks very much. After living in Switzerland all this time I've become so used to umlauts that I forgot they are non-ASCII.

Ishmael
May 31, 2006
Why is that once I run a script in IDLE the text highlighting disappears? Is there any way I can turn it on again?

duck monster
Dec 15, 2004

Zcientista posted:

Why is that once I run a script in IDLE the text highlighting disappears? Is there any way I can turn it on again?

Really? I havent seen that before. I wonder what causes it. :(

Hey, if you get a chance, play with iPython. Its loving wonderful. If you run it on windows, be sure to set up Readline libs, but if you do its amazing, and if there was a way of making it work inside of idle, it'd make idle into gods own python environ. (Well, if I could get idle running as the shell in eclipse python, I'd probably consider that it).

Ishmael
May 31, 2006

duck monster posted:


Hey, if you get a chance, play with iPython. Its loving wonderful. If you run it on windows, be sure to set up Readline libs, but if you do its amazing, and if there was a way of making it work inside of idle, it'd make idle into gods own python environ. (Well, if I could get idle running as the shell in eclipse python, I'd probably consider that it).

Wow, I'm just starting out here and iPython is so over my head. It sure looks pretty though.

Yeah, I've realized that I don't even need to run the script in IDLE, it goes black and white even if I save.

I have no idea what is going but I'm sure I'll figure it out at some point.

Edit: figured it out... I assumed that IDLE was saving every file as *.py without me having to type in the file extension. I most definitely do have to add the file extension, at least in windows.

Ishmael fucked around with this message at 19:03 on Feb 19, 2008

FrontLine
Sep 17, 2003
I gave Mr. Adequate hot, steamy man love and all he bought me was a custom title!
I wrote this short program as a cheap excuse to mess around with Python a bit more (only started learning about a week ago) and to screw around with VIM. Just wondering if there's any stupid newbie mistakes I've made or things I should watch out for. Considering it's pretty short I think I'm safe but just to be sure...

code:
#!/usr/bin/python
# Basic python program that will download a user specified number of images from WaffleImages.
# Please be warned that some of the images you may get back from WaffleImages could be NWS. This is unavoidable.

# Imports blah blah
import urllib
import urllib2
import os

# These headers may be redundant but it's what your browser sends when it makes a request so I've included it here just in case.
headers = {'Referer' : 'http://waffleimages.com/random', 'Cookie' : 'tg-visit=7e8303b895110be9868e2af52424643bcaa92c87;' + 
		'__utma=104184454.1558119543.1203770220.1203770220.1203770220.1; __utmb=104184454; __utmc=104184454; __' + 
		'utmz=104184454.1203770220.1.1.utmccn=(organic)|utmcsr=google|utmctr=waffle+images|utmcmd=organic'}

# This block specifys what data will be used when we send our GET to WaffleImages asking for a random image.
randomURL = 'http://waffleimages.com/random'
randomOpener = urllib2.build_opener()
randomRequest = urllib2.Request(randomURL, "", headers)

# Ask the user how many images they want.
iteration = raw_input('How many images do you want to download? ')

# Self explanatory.
print "Downloading... Please wait..."

# This is the work horse for the program and where I'm sure improvements can be made. 
# The loop runs the amount of times the user specified. It sends a GET to WaffleImages asking for a random image to be sent back.
# WaffleImages returns a web page with the location of the random image within. The program hunts down the link, currently located between
# characters 516 - 556 and requests that. The file is then saved as a .jpg. 
for i in xrange(int(iteration)):
	randomWriter = randomOpener.open(randomRequest).read()
	imageURL = 'http://img.waffleimages.com/' + str(randomWriter)[516:556]
	urllib.urlretrieve(imageURL, str(randomWriter)[516:556] + ".jpg")

print "Finished!"

# Things to be improved:
#	- A way of telling the user which file is being downloaded and how many there are left to download.
#	- A better way of finding the image URL. The current method will be prone to breaking if the html is changed by even a single character.
# Any suggestions are very much welcomed.
edit: Apologies for the heavy commenting. I just wanted to make sure what I was trying to do was obvious.

Wedge of Lime
Sep 4, 2003

I lack indie hair superpowers.

FrontLine posted:

I wrote this short program as a cheap excuse to mess around with Python a bit more (only started learning about a week ago) and to screw around with VIM. Just wondering if there's any stupid newbie mistakes I've made or things I should watch out for. Considering it's pretty short I think I'm safe but just to be sure...

After a quick once over (I've not tested the program) the first thing I noticed was the lack of input validation.

For example, when asked how many images I want to download I type 'five.' what happens?

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

Milde posted:

Pylons being a "collection" of separate components is a load of poo poo. It's all tightly coupled together and about the only place you really get any freedom is in OR mapping. It touts being WSGI-based but it abstracts away WSGI to the point of it being irrelevant. You see other projects writing "adapters" just for Pylons compatibility.

And not to mention it's poorly documented, and just poorly designed all around. It's like they went out of their way to make their framework as complicated as possible.

Okaayyyy ...

Actually that's just the sort of information I was looking for. A lot of things look good from the outside, or have a good image due to the relentless promotion by the inner circle, but when you get to actually do something non-trivial, you run into problems.

(Cue, my grousing about Plone's form handling which was abysmal until recently. For every form you had to write the HTML by hand, supply two scripts for handling the form that had a very restricted range of python you could use in them, and another two files of metadata. As a consequence, changing a form was like turning an oil-tanker ... yet no one in the Plone community complained about this.)

bitprophet posted:

Yup. This is a major misunderstanding about Django; it is loosely coupled by design. Yes, you lose the contrib apps (admin, auth, etc) and generic views, but it still works perfectly fine in terms of URL dispatch, view functions and template rendering.

Also good to hear. I'd avoided Django because I didn't want to deal with its ORM (SQLAlchemy for ever!)- but the contrib stuff looks nice, as does encapsulating a site as a Python package.

On other matters, has anyone coded a plugin / extension using setuptools entry point schema? It seems to be simple (especially compared to zope.interface) but like a lot fo thinsg with setuptools, it's under explained and I can't find many examples.

FrontLine
Sep 17, 2003
I gave Mr. Adequate hot, steamy man love and all he bought me was a custom title!

Wedge of Lime posted:

After a quick once over (I've not tested the program) the first thing I noticed was the lack of input validation.

For example, when asked how many images I want to download I type 'five.' what happens?

I've thrown this bit in. Effective?

code:
while True:
	iteration = raw_input('How many images do you want to download? ')
	try:
		checkInt = str(int(iteration))
		break
	except:
		print "Invalid input"

Allie
Jan 17, 2004

FrontLine posted:

I've thrown this bit in. Effective?

code:
while True:
	iteration = raw_input('How many images do you want to download? ')
	try:
		checkInt = str(int(iteration))
		break
	except:
		print "Invalid input"

Don't do "except:", that swallows all exceptions. And I'm not sure why you need to turn it back into a string. And the convention for naming non-class variables in Python is lowercase_with_underscores:
code:
while True:
    image_count = raw_input('Blah blah blah ')
    try:
        image_count = int(image_count)
        break
    except ValueError:
        print 'Whoa man, not cool.'

FrontLine
Sep 17, 2003
I gave Mr. Adequate hot, steamy man love and all he bought me was a custom title!

Milde posted:

Don't do "except:", that swallows all exceptions. And I'm not sure why you need to turn it back into a string. And the convention for naming non-class variables in Python is lowercase_with_underscores:
code:
while True:
    image_count = raw_input('Blah blah blah ')
    try:
        image_count = int(image_count)
        break
    except ValueError:
        print 'Whoa man, not cool.'

Thanks for the info :)

The example I found for checking for the int turned it into a string so I didn't think much of it. I also didn't know about python naming conventions, much appreciated :)

nonathlon
Jul 9, 2004
And yet, somehow, now it's my fault ...

Milde posted:

And the convention for naming non-class variables in Python is lowercase_with_underscores

Kind of. It's more of a convention than camelCaps but the whole style issue isn't as fixed as it is in (say) Java. l lowercase_with_underscores is what they use in the Python style sheet, but several communities have quite different styles (e.g. Zope). The major styles points would be to be consistent, use lowercase (no underscores) for module Names, CapsStyle for classes and *never* mix spaces and tabs for indentation.

Allie
Jan 17, 2004

outlier posted:

Kind of. It's more of a convention than camelCaps but the whole style issue isn't as fixed as it is in (say) Java. l lowercase_with_underscores is what they use in the Python style sheet, but several communities have quite different styles (e.g. Zope). The major styles points would be to be consistent, use lowercase (no underscores) for module Names, CapsStyle for classes and *never* mix spaces and tabs for indentation.

It's as fixed as in you always follow PEP 8, so everyone else follows it, so style conventions can be consistent and meaningful. Things like Zope are essentially legacy applications (though in this case it's the APIs that are legacy) and obviously have their own rules. That doesn't mean you should make up your own rules too for no good reason.

king_kilr
May 25, 2007
I have a python application that is just about finished up, you can check out the code here: http://github.com/alex/pyelection/tree/master any thoughts on it would be great, there are some areas where the code is a little messy and any thoughts would be great.

FinkieMcGee
May 23, 2001

Look, I have to go identify our dead father's body. I'm sorry you're having a bad drug experience, but deal with it.
I've started messing with django recently, and I won't deny it is pretty sweet...

Now, I want to try to create an import script. My model is really simple, but all I really want to do is take some stuff from a text file, parse it, then send the data to the database. Anyone ever put something like this together in django? What's the best way to go about this?

deimos
Nov 30, 2006

Forget it man this bat is whack, it's got poobrain!
This is something I threw together last time I needed importing from CSV:

code:
from django.conf import settings
from django.db import transaction

from clients.models import Informacion_Dentista

import csv, codecs, unicodedata, sys
from datetime import datetime

@transaction.commit_manually
def main():
    rc=0
    try:
        print sys.argv[1]
    except:
        transaction.rollback()
        raise
    csvreader = unicode_csv_reader(codecs.open(sys.argv[1], "r", "utf-8"))
    transaction.commit()
    try:
        r = csvreader.next()
        row_names = {}
        x = 0
        for f in r:
            row_names[x] = f
            x = x+1
        row_dict = {}
        for row in csvreader:
            for i in range(x):
                row_dict[row_names[i]] = row[i]
            row_dict['apellido_dentista'] = ''

            e = Informacion_Dentista()
            for k,v in row_dict.iteritems():
                e.__setattr__( k, v )
            e.save()

    except:
        print "Exception caught"
        transaction.rollback()
        print r
        raise
    else:
        transaction.commit()

def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs):
    # csv.py doesn't do Unicode; encode temporarily as UTF-8:
    csv_reader = csv.reader(utf_8_encoder(unicode_csv_data),
                            dialect=dialect, **kwargs)
    for row in csv_reader:
        # decode UTF-8 back to Unicode, cell by cell:
        yield [unicode(cell, 'utf-8') for cell in row]

def utf_8_encoder(unicode_csv_data):
    for line in unicode_csv_data:
        yield line.encode('utf-8')

if __name__ == "__main__":
    main() 
I run it like this:
code:
PYTHONPATH='.' DJANGO_SETTINGS_MODULE=settings python csvimport.py buttes.csv

deimos fucked around with this message at 14:52 on Feb 25, 2008

Kresher
Sep 11, 2001
Permanent Patient
Another python newbie assignment question time! (Yay, me)

I'm programming a hangman game, and I've got a working version that has 1 flaw I cannot fix.

code:
import random
def read_list_from_file():
    fileRef = open("ty_words.txt","r") # opening file to be read
    localList=[]
    for line in fileRef:
        word = line[0:len(line)-1]  # eliminates trailing '\n'
                                    # of each line (or last character
                                    # if it is the last line of the file)
                                    
        localList.append(word.lower())  # adds word to list in lower case
        
    fileRef.close()
    return localList

def greetings():
    str_response = raw_input("\nDo you want to play? Y- yes, N - no: ")
    if str_response == "y" or str_response == "Y":
        bool_response = True
    else:
        bool_response = False
    return bool_response   

def ask_user_guess():
    print "".join([((ch in letters) and ch or "-") for ch in word])
    guess = raw_input("Please guess a letter/word (%d/%d): " % (guesses, max_try))
    return guess
def good_bye():
    print " Good bye! "

wants_to_play = greetings()

while wants_to_play:

    guesses = 0
    max_try = 6
    word = random.choice(read_list_from_file()) #a word from ty_words.txt is
    letters = []                                #picked
    
    while (guesses<max_try):     #playing until won == True or
        guess = ask_user_guess() #the players makes 6 wrong guesses
        if guess not in word:
            print "You've made a wrong guess."
            guesses+=1 
            continue #only occur syntactically nested in a for or while loop
                     #couldn't use this in a function and make the program work
        if len(guess)>1:
            print "\nYou've guessed the whole word: %s" % (guess)
            if guess.strip() == word: #compares the word guess against the word
                print "\nYour lucky guess is correct!"
            else:
                print "\n Too bad, you were wrong."
        for ch in guess:
            letters.append(ch)
        if set(letters) == set(word):
            print "\nCongratulations, you win!"
            break
        else:
            print "You've guessed wrong too many times"

    wants_to_play = greetings()

good_bye()
note: I'm importing a list of words from a text file.

My prof's objective was to familiarize us with the top level programming using functions.

However, I cannot use the functions to syntactically add 1 to the variable 'guesses', using the continue statement.

Also, when the user makes 6 wrong guesses, I want the program to print "You've guessed wrong too many times.", but it just skips that part and heads back to greetings(). (Not to mention the fact that the wrong guess indicator only goes to (5/6))

I've made a nightmarish hack job that has very little top level programming, and it's going to be a bitch to draw the flow chart for, but I'm drat proud of it.

If you guys could give me some advice as to accomplish the task I wish to do, I'd be really grateful.

Adbot
ADBOT LOVES YOU

trashmatic
Jan 27, 2006

Kresher posted:

Another python newbie assignment question time! (Yay, me)

I'm programming a hangman game, and I've got a working version that has 1 flaw I cannot fix.
Your effort here is in some ways similar to others I've seen from intro-level CS courses. As you mention, the programming style could use a lot of work, but that's not a big deal. You've done a pretty good job of making the computer do things. The problem is that you haven't thoroughly decided what it should be doing.

Start analyzing the program from the beginning of the inner while loop. Write out a few possible inputs you could give the program at ask_user_guess(). For each one of those, go very carefully line by line and see what the program will do.

You have five possibilities, in general: nothing, a single letter not in the word, a single letter that is in the word, multiple letters that do not equal the word, multiple letters that equal the word.

For example, if you give it multiple letters that do not equal the word, 'guess not in word' will evaluate true, so you will enter that if-block. It will print "You've made a wrong guess", and hit the continue statement and reset the while loop. Not what you were intending.

If you patch that up, you may find that the program is appending all the letters in the guess to 'letters' even if the guess is wrong, with entertaining results.

Also, due to the way the last if-else block is written, it will print "You've guessed wrong too many times" every time the set of letters is not equal to the set of words, even if your guess was correct! What's with that?

Basically, the core logic is all wrong. Rethink it, flowchart it, then rewrite it, and you'll be off and running.

quote:

However, I cannot use the functions to syntactically add 1 to the variable 'guesses', using the continue statement.
What are you talking about here? Less jargon, please. If you mean that you can't call 'continue' inside a function and expect it to abort the loop it was called from... well, yes. You can't do that.

  • Locked thread