Cards: You are right on the merits for combinatory math, but you will run into strong cultural aversions.
Reverse string in place with new iterator: There is a great deal more of this. In the 1980s Hewlett-Packard built an APL system around such transformations in place and lazy evaluation rules, including matrix/table transpose, take, drop, catenate, laminate, and a number of other transformations and combinations. I can probably dig out Harry Saal's paper on the subject. Indeed, that and several others. http://portal.acm.org/citation.cfm?id=801218&dl=GUIDE&coll=GUIDE&CFID=59626041&CFTOKEN=28525913 An APL compiler for the UNIX timesharing system http://portal.acm.org/citation.cfm?id=586034&dl=GUIDE&coll=GUIDE&CFID=59626133&CFTOKEN=77609109 Considerations in the design of a compiler for APL http://portal.acm.org/citation.cfm?id=804441 A software high performance APL interpreter On Sun, Nov 1, 2009 at 19:55, kirby urner <kirby.ur...@gmail.com> wrote: > I'm becoming more enamored of the idea of using playing cards as a > standard feature in my Python pedagogy and andragogy (means teaching > adults). Not only do we have the standard deck, but also Tarot which > could get us more into text files, string substitution > (string.Template) and so forth. > > Cards have all the elements > > Mathematically, a Deck suggests the difference between Cardinality > (yes, a silly pun) and Ordinality. You might imagine a deck in which > you can't decipher the cards, don't know their "face value", and so > have no clear idea of their ranking (ordinality). > > On the other hand, you know which cards are the same and which are > different across multiple decks (le'ts just say), which is the meaning > of "cardinality" (difference without any implied ordering). > > Midhat Gazele dwells on this difference some in his book 'Number'. > You might have a set of objects, say stones or wasp specimens, and a > way of cataloging them that doesn't implement > or < or even ==. > There is only the Python "is" and "is not" for determining of two > objects have the same identity or not. License plates on cars, proper > names, have this purpose of distinguishing. > > However, very quickly just about any set beyond a certain size needs > an ordering, perhaps simply alphabetical, so that one might flip > through a lookup table in a hurry and get to the desired object. > People used to use ledgers, thick books, for such cataloging. > > This is the beginning of data structuring or data structures. The > idea of "ordering" (ordinality) is very closely associated with that > of cardinality. > > Anyway, over on Pyfora I was noticing a member suggesting reversing a > string might be best accomplished by thestring[::-1], i.e. extended > slicing with from the end to the beginning step with a step of -1. > However PEP 322 suggests this will be inefficient compared a a built > in function introduced in 2.4: reversed. > > According to the PEP, all reversed needs is for the consumed object to > support __getitem__ and __len__. If those two are present, the > function will do the rest, and return an iterator object in which the > contents of a sequence are iterated over in reverse order. > >>>> a = 'the rain in spain stays mainly in the plain' >>>> ''.join(reversed(a)) > 'nialp eht ni ylniam syats niaps ni niar eht' > > So for our Deck to be reversible by means of this built in function, > the only methods we need to implement are these two, __getitem__ and > __len__. I do this below, plus make shuffling the deck upon > instantiation an option, not de rigueur (not mandatory). This makes > it easier to see what reverse order is like. > > Note that the returned iterable is not itself a Deck, nor is it > subscriptable, as the whole point of an iterable is it returns its > contents "just in time" as you iterate over it. The cards are not > "already present" in reversed order, are simply returned in reverse > order. > > Of course you can force the iterable to dump all its contents by > coercing it into a list. I do this as a part of the clone_deck > method. Playing Game of War with clone decks, one the reverse of the > other, results in a draw if always dealing from the top (now the > default, yet still optional). > > The code below is just my Game of War again, with a few wrinkles. > I've upgraded all string printing to use the > print(thestring.format(args)) approach, versus the old percent sign > string substitution codes. Other small improvements. > >>>> from sillygame import Deck >>>> d = Deck(10) >>>> newd = d.clone_deck() >>>> newd[0] is d[0] > True >>>> id(newd[0]) > 22884944 >>>> id(d[0]) > 22884944 >>>> d.shuffle() >>>> str(d) > "['7 of Diamonds', 'Jack of Spades', 'Queen of Clubs', 'King of > Spades', '5 of Clubs', '3 of Spades', '6 of Hearts', 'Ace of Clubs', > '2 of Hearts', '9 of Spades']" >>>> str(newd) > "['2 of Hearts', 'Queen of Clubs', '6 of Hearts', '9 of Spades', '5 of > Clubs', '7 of Diamonds', 'Ace of Clubs', '3 of Spades', 'Jack of > Spades', 'King of Spades']" >>>> d[0] > Card(Diamonds, ('7', 7)) >>>> newd[5] > Card(Diamonds, ('7', 7)) >>>> d[0] == newd[5] > True >>>> d[0] is newd[5] > True > > Kirby > > For further reading: > http://www.python.org/dev/peps/pep-0322/ > > > from random import shuffle, randint > > thesuits = ['Hearts','Diamonds','Clubs','Spades'] > theranks = ['Ace'] + [str(v) for v in range(2,11)] + ['Jack','Queen','King'] > rank_values = list(zip(theranks, range(1,14))) > > class Card: > > def __init__(self, suit, rank_value ): > self.suit = suit > self.rank = rank_value[0] > self.value = rank_value[1] > > def __lt__(self, other): > if self.value < other.value: > return True > else: > return False > > def __gt__(self, other): > if self.value > other.value: > return True > else: > return False > > def __eq__(self, other): > if self.value == other.value: > return True > else: > return False > > def __repr__(self): > return "Card({0}, {1})".format(self.suit, (self.rank, self.value)) > > def __str__(self): > return "{0} of {1}".format(self.rank, self.suit) > > class Deck: > > def __init__(self, numcards = 52, shuffle = True): > # build a complete deck then slice > try: > assert 0 < numcards <= 52 > except AssertionError: > print("Defaulting to 52 cards") > numcards = 52 > > self.numcards = numcards > self.cards = [Card(suit, rank_value) > for suit in thesuits > for rank_value in rank_values > ] > if shuffle: self.shuffle() > self.cards = self.cards[ : self.numcards] > > def __getitem__(self, index): > return self.cards[index] > > def shuffle(self): > shuffle(self.cards) > > def spit_card(self, top=True): > try: > assert self.numcards > 0 > except AssertionError: > raise Exception("Out of cards!") > > if top: > some_card = self.cards.pop(0) > else: > some_card = self.cards.pop( randint( 0, self.numcards - 1 )) > > self.numcards = len(self.cards) > return some_card > > def clone_deck(self, reverse=False): > newdeck = Deck(numcards=1) > newdeck.numcards = self.numcards > if reverse: > newdeck.cards = list(reversed(self.cards)) > else: > newdeck.cards = self.cards[:] > return newdeck > > def __repr__(self): > return "Deck({0})".format(self.numcards) > > def __str__(self): > return str([str(card) for card in self.cards]) > > def __len__(self): > return len(self.cards) > > def test(): > thedeck = Deck() > print (str(thedeck)) > > def game_of_war(): > deckA = Deck(10) > # deckB = Deck(10) > deckB = deckA.clone_deck(reverse=True) # play a reversed clone > PlayerA_score = 0 > PlayerB_score = 0 > > try: > assert deckA.numcards == deckB.numcards > except AssertionError: > raise Exception("Decks don't have same number of cards") > > for i in range(deckA.numcards): > playerA_card = deckA.spit_card(top=False) # deal from anywhere > playerB_card = deckB.spit_card(top=False) > > if playerA_card > playerB_card: > PlayerA_score += 1 > print("A's {0} beats B's {1}".format(playerA_card, playerB_card)) > if playerA_card < playerB_card: > PlayerB_score += 1 > print("B's {0} beats A's {1}".format(playerB_card, playerA_card)) > if playerA_card == playerB_card: > print("B's {0} matches A's {1}".format(playerB_card, playerA_card)) > > if PlayerA_score > PlayerB_score: > print("Game Over: A wins") > if PlayerA_score < PlayerB_score: > print("Game Over: B wins") > if PlayerA_score == PlayerB_score: > print("Game Over: it's a draw!") > > if __name__ == '__main__': > # test() > game_of_war() > _______________________________________________ > Edu-sig mailing list > Edu-sig@python.org > http://mail.python.org/mailman/listinfo/edu-sig > -- Edward Mokurai (默雷/धर्ममेघशब्दगर्ज/دھرممیگھشبدگر ج) Cherlin Silent Thunder is my name, and Children are my nation. The Cosmos is my dwelling place, the Truth my destination. http://www.earthtreasury.org/ _______________________________________________ Edu-sig mailing list Edu-sig@python.org http://mail.python.org/mailman/listinfo/edu-sig