lrh9 95 Posting Whiz in Training

The Caesar cipher is also good, but I'd like to mention a couple of things.

The string module has constants for ascii_letters, ascii_uppercase, and ascii_lowercase.

A constant can be safely created outside of a function and still be used within it.
This is preferred when calculation is involved in creating the constant because it will only occur once instead of each time the function is called.

We should generally use str.join for string concatenation. In certain situations adding strings is faster than str.join, but in other situations adding strings occurs in quadratic time. O(n**2)

It's also possible to use a bytes translation to perform a Caesar shift, but you have to create the translation table for each shift. I think it would be less efficient than Lardmeister's implementation. However, if your program only ever needs shifts by one value, say 5, it might be better.

lrh9 95 Posting Whiz in Training

Lardmeister, that is a good use of itertools.permutations to find string permutations.

I just want to explicitly caution others that when working with permutations you should use generators like Lardmeister is. The number of permutations of a string is the factorial of its length. Don't attempt to store all of the permutations in a collection. You can quickly run out of memory.

Lardmeister commented: good point here +6
lrh9 95 Posting Whiz in Training

Python comes with a csv module you should use to extract the data.

Search your documentation for how to write to files. The way you are doing it is totally wrong.

lrh9 95 Posting Whiz in Training

I'm interested in a generic event system for Python. I've searched the forum for similar topics, and I've searched the web for existing implementations. I haven't found exactly what I'm looking for.

I'm familiar with the Observer pattern. However, my implementation and other implementations lack strong support for concurrency and scheduling.

Do you know of anything that fits the bill or can you help me create an implementation?

I want to use this for simulations and games.

lrh9 95 Posting Whiz in Training

An object is just an abstraction of data and functions.

An object has attributes (data) and methods (functions that interact with its attributes).

A class is a blueprint describing the objects created from it.

When you write a class you are 'declaring' a class.

An object created from a class is an 'instance' of that class.

Objects are most useful when the systems you are modeling in your program can be abstracted as objects.

Anything you can refer to with a noun is a potential candidate.

I recommend that people learning object-oriented programming model concrete objects.

http://www.chompchomp.com/terms/concretenoun.htm

lrh9 95 Posting Whiz in Training

I don't think there is a module or package providing key press event functionality for the console.

If you want user input, you should use the function raw_input in 2.x and input in 3.x.

lrh9 95 Posting Whiz in Training

Do you want to do a graphical application or a console application?

lrh9 95 Posting Whiz in Training

That will break if the user entered nothing.

lrh9 95 Posting Whiz in Training

I make my user input loops follow this pattern:

#Start a loop that will run indefinitely.
while True:
    i = input("Prompt: ")
    #Here I do my input checking. In this example it checks that i isn't an empty string.
    if i:
        #Break out of the indefinite loop.
        break
lrh9 95 Posting Whiz in Training

I learned it from someone at #python on irc.freenode.net

lrh9 95 Posting Whiz in Training

I like using dictionaries for my multidimensional containers using coordinate tuples as keys. It's not a conventional approach, but despite any disadvantages it has some advantages. For very small or very large coordinates, it has a memory advantage because "coordinates" don't need to exist until they are assigned to. The fact that coordinates can be any hashable objects also presents some interesting options.

griswolf commented: A nice bright light went off over my head. Thanks. +1
lrh9 95 Posting Whiz in Training

I was looking for a high level language to program a.i. in and after trying AutoHotkey I decided to try Python since it provides standard library support for more processing primitives. (Threading and multiprocessing.)

lrh9 95 Posting Whiz in Training

redyugi showed you. Phill should be an instance of a Hero class.

lrh9 95 Posting Whiz in Training

Here's Python 3.x code I wrote for cards and decks. Maybe it will give you some inspiration.

http://pastebin.com/wujeXQjV

In most implementations, suits and ranks are simply represented by numbers. I make my implementation only slightly more complex for extra expressiveness. (My suits have symbols and words, and my ranks have words.)

I do a lot of early computation in some __init__ methods, this is usually a bad idea if you create a lot of objects and don't need the data immediately. However, my card and deck objects get created only once. Each new deck is a copy.

On my machine I can create a deck, shuffle it, and draw 7 cards 500,000 times in under a minute. (I have a top-tier CPU though.)

lrh9 95 Posting Whiz in Training

In Python, It Just Works! (TM)

Don't worry about it.

If you must know how wait works you can read the source in threading.py or the multiprocessing source files.

lrh9 95 Posting Whiz in Training

Yes. I'm coding in Python 3.

If you want to propose changes, feel free. You won't be stepping on any toes. I've been collaborating with people on #python on irc.freenode.net. They've given advice and recommendations. Some I've adopted and some I've rejected.

Posting the source in this thread was a mistake. I won't make it again. I've had to split the source and make it a package. I'm going to get project hosting and then post the link.

Right now I'm working on adding code for hole cards in hold'em. My first goal is to create a collection of possible hole cards. Then I want to go through each and simulate a certain number of hands against a range of opponents for each. I will log the result, and this will create a table of percent probabilities for the hand to win/tie/lose.

lrh9 95 Posting Whiz in Training

You are right that checking is terribly inefficient. Use messaging instead of checking. (When an event happens, make that system send a notification to the systems waiting on it.)

There are packages for event systems out there. I can't recommend one, but search and check out the source. You might find one you like or you might get ideas for writing one of your own.

lrh9 95 Posting Whiz in Training

There is a small bug in my code. The __eq__ method for the card should be:

def __eq__(self, other):
    return hash(self) == hash(other)

I know suits aren't an issue when you compare two cards in a standard game of poker, but if you want to use deck.remove to remove a card you need this new method. Don't worry. It doesn't change hand evaluation. Other comparison methods will remain the same unless I find a reason to alter them.

lrh9 95 Posting Whiz in Training
# -*- coding: utf-8 -*-

##Copyright © 2010 Larry Haskins
##This program is free software: you can redistribute it and/or modify
##it under the terms of the GNU General Public License as published by
##the Free Software Foundation, either version 3 of the License, or
##(at your option) any later version.

##This program is distributed in the hope that it will be useful,
##but WITHOUT ANY WARRANTY; without even the implied warranty of
##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##GNU General Public License for more details.

##You should have received a copy of the GNU General Public License
##along with this program.  If not, see <http://www.gnu.org/licenses/>.

import collections
import copy
import itertools
from random import shuffle

#Lookup tables are faster than functions for string operations.
PLURALS = {'ace': 'aces',
           'king': 'kings',
           'queen': 'queens',
           'jack': 'jacks',
           'ten': 'tens',
           'nine': 'nines',
           'eight': 'eights',
           'seven': 'sevens',
           'six': 'sixes',
           'five': 'fives',
           'four': 'fours',
           'three': 'threes',
           'two': 'twos',
           'spade': 'spades',
           'heart': 'hearts',
           'diamond': 'diamonds',
           'club': 'clubs'}

"""Next three functions use certain attributes as keys to group items
according to the value of that key."""
def pigeonholed_by_suit(cards):
    suits_ = {}
    for suit in suits:
        suits_[suit] = []
    for card in cards:
        suits_[card.suit].append(card)
    return suits_

def pigeonholed_by_rank(cards):
    ranks_ = collections.OrderedDict()
    for rank in ranks:
        ranks_[rank] = []
    for card in cards:
        ranks_[card.rank].append(card)
    return ranks_

def pigeonholed_by_len(values):
    lens = collections.OrderedDict()
    for i in (0, 1, 2, 3, 4):
        lens[i] = []
    for value in values:
        lens[len(value)].append(value)
    return lens    

"""Helper function for checking …
lrh9 95 Posting Whiz in Training

I refactored the code and added an example.

The only problem remaining as far as I know is that if two hands are of equal rank but one has higher kickers, my test code will display text suggesting that they are equal. (Differences in kickers are significant in this program though. If one hand has higher kickers than another it will be greater than the other.)

##Copyright © 2010 Larry Haskins
##This program is free software: you can redistribute it and/or modify
##it under the terms of the GNU General Public License as published by
##the Free Software Foundation, either version 3 of the License, or
##(at your option) any later version.

##This program is distributed in the hope that it will be useful,
##but WITHOUT ANY WARRANTY; without even the implied warranty of
##MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
##GNU General Public License for more details.

##You should have received a copy of the GNU General Public License
##along with this program.  If not, see <http://www.gnu.org/licenses/>.

import collections
import math
import random

_vowels = 'aeiou'

def _pluralize(word):   #The bird is indeed equal to or greater than the word!
    if word[-1] in 'xX':
        ending = 'es'
    else:
        ending = 's'
    return ''.join((word, ending))

class Suit:

    names = ('spade',
             'heart',
             'diamond',
             'club')
    symbols = ('♠',
               '♥',
               '♦',
               '♣')

    def __init__(self, symbol, name, short=None):
        self.symbol = symbol
        self.name = name
        self.short = short
        if self.short is None:
            self.short = self.name[0]

    def __repr__(self):
        return "Suit({symbol}, {name}, …
lrh9 95 Posting Whiz in Training

The structure is admittedly confusing. I need to work on that. I had a Dealer class I forgot to include. Some code for shuffling and dealing from the deck because a deck doesn't really shuffle or deal itself. Was a poor decision that sacrificed practicality for purity. Would be easier if they were methods on the deck.

How are the docstrings broken?

I'll probably remove the class namespaces because they aren't necessary.

I'll post some usage examples later.

lrh9 95 Posting Whiz in Training

Hand evaluator for Texas Hold'em. If a "hand" has five or more cards, hand.rank will find the best five card hand the hand can form. Two hands can be compared using the comparison operators. The final hand can be gotten from the "hand" with hand.rank.hand. The value used for comparisons can be retrieved with hand.rank.value. Hand value is determined by the hand's Hold'em rank and the card values.

I welcome questions, comments, and bugfixes and other improvements to the code.

lrh9 95 Posting Whiz in Training

The @ symbol is syntax indicating a decorator. In this instance, the decorator takes the function it decorates (a.k.a. wraps) and makes a new function that starts the old function in a new thread. A normal decorator will not preserve the name and docstring of the old function, but @wraps will preserve that information in the new function.

Once the async decorator has been defined, you can decorate any function with it to have that function start in a new thread when called.

lrh9 95 Posting Whiz in Training

Smart thinking. I might drop back by and add some stuff.

I would make a minor gripe. Attributes and methods with two leading underscores and no trailing underscores are mangled by Python. I know your intention is to indicate that these attributes and methods should not be accessed externally, but typically a single leading underscore indicates internal use. A double leading underscore is primarily intended to prevent name clashes with derived classes.

I take my information from PEP 8, Python community guidelines on style.

Use one leading underscore only for non-public methods and instance variables.

To avoid name clashes with subclasses, use two leading underscores to invoke Python's name mangling rules.

http://www.python.org/dev/peps/pep-0008/

Cheers!

lrh9 95 Posting Whiz in Training

Seems to me like it would be good to use both concurrently. I've all ready written a few scripts that can run with both 2.x and 3.x.

Python packages and modules are open source. If you ever want them for a new version you can always refactor the old version. In fact, I think their creators and the community at large would be appreciative of such an effort.

Doing so would be a great opportunity to prove that you are not only a programmer capable of implementing useful Python packages and modules but that you are also well versed in the relevant Python versions.

lrh9 95 Posting Whiz in Training

God I want to smack the creators of some of those courses upside the head with a thick book.

lrh9 95 Posting Whiz in Training

Couple of problems. The first is poor class implementation.

It's OK to make your class without attribute getters and setters. You can access instance attributes by referring to the attributes themselves.

class Car:

    def __init__(self, year):
        self.year = year

mycar = Car(1999)
mycar.year

The second problem with implementation is that you require a speed argument to accelerate and decelerate the car, but inside of those methods you accelerate or decelerate by a constant of 5. Is that desired behavior, or would you rather to accelerate or decelerate by the amount passed as the argument?

The third problem is with your script's structure. You try to create the car before you've gotten the user's input. You must assign identifiers before you can use them elsewhere.

year = raw_input('What year is your car? ')
mycar = car.Car(year)
print mycar.year

You did a decent job with the class for a beginner. Don't get discouraged. Good luck.

lrh9 95 Posting Whiz in Training

It depends on whether or not rexona wants the elements of the list to be unique or if each number should be chosen randomly over the whole range.

Sample takes unique elements from the given population. Example: For range 10 and the number of elements taken being 4 the list could be this '[1, 5, 0, 8]' but it could never be this '[2, 2, 6, 3]'.

lrh9 95 Posting Whiz in Training

I'd typecast during the comparison. Good luck.

lrh9 95 Posting Whiz in Training

Typecasting the numbers to a string doesn't make much sense to me, but whatever.

You are mistakenly using the sample function.

Here's what you want to do.

import random

def make_secret(numdigits):
    a = []
    for i in range(numdigits):
        a.append(str(random.randrange(0, 10)))
    return a
lrh9 95 Posting Whiz in Training

http://github.com/pepijndevos/PyMouse

Automated mouse control is a somewhat esoteric programming feature. You may have to experiment, research, and refactor other code to get a solution.

lrh9 95 Posting Whiz in Training

It's bad because it isn't friendly to other objects that act like your class.

You should use hasattr instead to check that the object you are working with is appropriate. That way as long as the object has the required attribute or method it will work with your code as well as your own objects. (If it is a method it still must accept the appropriate arguments.)

class YourClass:

    def required_method(self):
        pass

class MyClass:

    def required_method(self):
        pass

yourobj = YourClass()
myobj = MyClass()

isinstance(yourobj, YourClass)    #True
isinstance(myobj, YourClass)    #False
hasattr(yourobj, 'required_method')    #True
hasattr(myobj, 'required_method')    #True
lrh9 95 Posting Whiz in Training

A technical term for creating a class is 'declare'.

When you create a class you are declaring a class, and when you see a class in code it is a class declaration. Just thought you might want to know the lingo.

b

lrh9 95 Posting Whiz in Training

A quick hack would be something like this:

def run_async(fnc):
    def newfnc(*args, **kwargs):
        thread = threading.Thread(target=fnc, args = args, kwargs = kwargs)
        thread.start()
    return newfnc

@run_async
def on_mode(self, connection, event):
    if event.arguments() [ 0 ] == "-v":
    vname = event.arguments() [ 1 ]
    self.connection.mode(channel + " +v", vname)
lrh9 95 Posting Whiz in Training

Python isn't a bad language, even when it comes to threading.

The 'vibe' I'm getting from the modules you are using is that the objects and process of creating and operating a bot are overly complex.

There isn't much that can be done about that except a rewrite with different design principles, philosophies, and use specifications in mind. (I'm working on an irc bot library at the moment. When I publish the source hopefully it will be more suited for your use and for other people.)

But in the meantime we must make do with what we have here.

Seems like to me you need to add your global handler to an event and that should do the trick.

Doesn't the on_mode method you defined in the bot do what you want?

If so when you initiate your bot you should do something like this I think.

self.add_global_handler("mode", self.on_mode)

P.S. I posted after you said you needed to add threads.

lrh9 95 Posting Whiz in Training

If you don't mind me asking, what are the "ircbot" and "irclib" modules or packages you imported, and where could we acquire them or view the source?

lrh9 95 Posting Whiz in Training

Are you sure you want to use bubble sort?

http://en.wikipedia.org/wiki/Bubble_sort#Performance

According to the Wikipedia article it is one of the worst sorting algorithms.

lrh9 95 Posting Whiz in Training

That's cool, Tony. I'll have to look over that thread some more.

lrh9 95 Posting Whiz in Training

Cool, Buster. I might implement some of your ideas in my own class.

I wish the original poster would have told us which card game he is programming.

My best guess at the moment is seven card stud.

If we knew then we could get to work on making a good hand class.

I'm having trouble thinking of a way to rank a hand as a whole.

http://www.thepokerforum.com/pokerhands.htm

(I'm programming for the hold'em variant, btw.)

lrh9 95 Posting Whiz in Training

Seems to me like this would be a great opportunity to apply and use object oriented programming.

A card is a type of object. What I would try is to make a card class with rank and suit attributes. Then I'd add comparison methods to compare card rank. (I'm assuming a lone card's suit is unimportant. However, in some games or rules suit does determine rank.) If my idea is correct any sort function should return the correct order. I think we could even add a method to return a nice string representation of the card.

Something like this.

#Python 3.1

class Card:

    suits = {'spades': '♠',
             'hearts': '♥',
             'diamonds': '♦',
             'clubs': '♣',}

    ranks = {1: 'A',
             10: 'T',
             11: 'J',
             12: 'Q',
             13: 'K',
             14: 'A',}

    for i in range(2, 10):
        ranks[i] = str(i)

    def __init__(self, rank, suit):
        self.rank = rank
        self.suit = suit

    #==
    def __eq__(self, other):
        if self.rank == other.rank:
            return True
        else:
            return False

    #>=
    def __ge__(self, other):
        if self.rank >= other.rank:
            return True
        else:
            return False

    #>
    def __gt__(self, other):
        if self.rank > other.rank:
            return True
        else:
            return False

    #<=
    def __le__(self, other):
        if self.rank <= other.rank:
            return True
        else:
            return False

    #<
    def __lt__(self, other):
        if self.rank < other.rank:
            return True
        else:
            return False

    #!=
    def __ne__(self, other):
        if self.rank != other.rank:
            return True
        else:
            return False

    def __str__(self):
        #Return a string representation of the card. Example: A♠
        return Card.ranks[self.rank] + Card.suits[self.suit]

    def __repr__(self):
        #Needed to make printing a list of …
lrh9 95 Posting Whiz in Training
lrh9 95 Posting Whiz in Training

I'm talking about dotted relative imports.

lrh9 95 Posting Whiz in Training

Try relative imports.

http://www.python.org/dev/peps/pep-0328/#guido-s-decision

Seem like just the thing. I've used them. They permit you to import modules from a relative parent package.

They're hard to figure out though. The documentation is somewhat lacking so you might have to tinker until you get it right.

lrh9 95 Posting Whiz in Training

"...head over to the sales websites..."

Marketers.

Their goal is to sell at any cost, and not to give you the best product for your needs.

lrh9 95 Posting Whiz in Training

Make an irc bot to connect to an irc server and channel and respond to users in various ways.

Download irclib to get some code to start from.

http://irclib.bitlbee.org/

If you can, get a copy of IRC Hacks published by O'Reilly.

http://www.jibble.org/irchacks/

lrh9 95 Posting Whiz in Training

Don't separate the user id from the entry.

import csv, contextlib

usernfo = {}

with contextlib.closing(open(data.csv)) as ifile:
    for entry in csv.DictReader(ifile):
        usernfo[entry['id']] = entry

print(usernfo)

Fixed.

lrh9 95 Posting Whiz in Training

Of course users must have their own folder for their own settings. I didn't know that the home folder was that folder on Unix based systems. On Windows we have "\Documents and Settings\User\Application Data", "\Documents and Settings\User\Local Settings" and "\Documents and Settings\User\Local Settings\Application Data". However, we shouldn't just dump settings files into either. They should be separated by sub-directories named after their application.

Did you try my second code using your links?

lrh9 95 Posting Whiz in Training

Don't separate the user id from the entry.

import csv, contextlib

usernfo = {}

with contextlib.closing(open()) as ifile:
    for entry in csv.DictReader(ifile):
        usernfo[entry['id']] = entry

print(usernfo)
lrh9 95 Posting Whiz in Training

Using files can be a better option than using the registry for storing settings in certain situations, especially when users may wish to alter application settings externally and save them for later use.

Storing settings in files can also provide greater cross platform support, especially when the user may wish to transfer settings to a new platform.

The registry has its place, but it isn't a settings panacea.

Also, cluttering a home folder with various settings files doesn't seem like a good idea. It violates the principles of organization and privacy.

How to handle symbolic links:

import os, sys, configparser

config = configparser.ConfigParser()

#Ran as a script?
if __name__ == '__main__':
    #Here by symbolic link?
    if os.path.islink(sys.argv[0]):
        try:
            #Read the path to which the link points.
            link = os.readlink(sys.argv[0])
        except:
            """Insert code to handle if it is a link but reading the link fails."""
            pass
        else:
            if not os.path.isabs(link):
                #If the link was to a relative path need to do some extra work.
                path = os.path.dirname(os.path.join(os.path.dirname(sys.argv[0]), link))
            else:
                #Else assume path OK.
                path = os.path.dirname(link)
    #Else assume path OK.
    else:
        path = os.path.dirname(sys.argv[0])
#Else imported.
else:
    path = os.path.dirname(__file__)

config.read(os.path.join(path, 'HnUsageMeter.cfg'))

allowancelimit = int(config.get('DEFAULT', 'allowancelimit', 0))

You seem to know about symbolic links. If the path read from a link is an absolute path will it be a complete path or will it lack a root?

lrh9 95 Posting Whiz in Training
import configparser
import os
import sys

config = configparser.ConfigParser()

#If the script is executed __name__ will be '__main__' and sys.argv[0] will be the full path of the script.
if __name__ == '__main__':
    path = os.path.dirname(sys.argv[0])
#Else the script was imported as a module and it has a __file__ attribute that will be the full path of the script.
else:
    path = os.path.dirname(__file__)

#The configuration parser reads the file at the full path made from joining the base path and the file name.
config.read(os.path.join(path, 'HnUsageMeter.cfg'))

allowancelimit = int(config.get('DEFAULT', 'allowancelimit', 0))
""";HnUsageMeter.cfg
;In cfg files use ; to comment out a line.
;The DEFAULT section supplies default values for options in all sections.
;If an option of the same name is not overridden in other sections then all options of the same name will have the same value.
[DEFAULT]
allowancelimit=1"""