poker five card draw with Django Rest Framework - django

I Have this code Written with Python. The logic of the Code is to shuffle a deck of Cards, deal one single hand to the player and after Evaluate the Highest rank of the Player's hand and return an appropriate message to the player like. (Ex: Your Hand : 5K 8H 2S 3D 9S
Your Rank : Flush)
I want to use Django framework to create an API that will return an HttpResponse to mimic this (Ex: Your Hand : 5K 8H 2S 3D 9S
Your Rank : Flush) as a Json Object.
I would like to know how would about writing API and which design consideration i should have in mind.
Which part of the code should go into the view to return the appropriate endpoint exemple : the hand of the player the shuffling of the deck, and the rank of the user.
from constants import Constant
class Card(Constant):
def __init__(self, suit, val):
# initialize the card object
self.suit = suit
self.value = val
# get the rank of the card by indexing the RANKS dictionary
self.rank = self.RANKS[val]
def get_rank(self):
# return the rank of the card
if self.rank:
return self.rank
else:
raise Exception('No rank')
def get_suit(self):
# return the suit of the card
if self.suit:
return self.suit
else:
raise Exception('No suit')
def __str__(self):
# return the string representation of the card
return f'{self.get_rank()}{self.get_suit()}'
import random
from card import Card
# class to represent a deck of cards
class Deck(Card):
def __init__(self):
# initialize the deck object
self.cards = []
self.build_deck()
# Create Our Deck of 52 cards
def build_deck(self):
# loop through each suit
for suit in self.SUITS:
for rank in self.RANKS:
self.get_deck().append(Card(suit, rank))
random.shuffle(self.get_deck())
# return the deck of cards
def get_deck(self):
return self.cards
# print the deck object as a string
def __str__(self):
return " ".join([str(card) for card in self.get_deck()])
# Shuffle the deck of cards
def shuffle(self):
for i in range(len(self.get_deck()) - 1, 0, -1):
# pick a random index between 0 and i (inclusive)
if i > 0:
j = random.randint(0, i)
# swap the cards at position i and j
self.get_deck()[i], self.get_deck()[
j] = self.get_deck()[j], self.get_deck()[i]
else:
# return an empty string if the deck is empty
raise Exception('No cards to shuffle')
return True
# draw a single card from the deck (the bottom card)
def deal(self):
if self.get_deck():
# return the last card in the deck
return self.get_deck().pop()
else:
# return an empty string if the deck is empty
raise Exception('No cards to deal')
from deck import Deck
# class to represent a hand of cards
class Hand(Deck):
def __init__(self):
# initialize the hand object
self.hand = []
def get_hand(self):
# return the hand
return self.hand
def __str__(self):
if self.get_hand():
# return the string representation of the hand
return ' '.join([str(card) for card in self.get_hand()])
else:
# raise an exception if the hand is empty
raise Exception('No cards in hand')
# Make the Hand Iterable
def __iter__(self):
if not self.get_hand():
# raise an exception if the hand is empty
raise StopIteration
else:
# return an iterator for the hand
return iter(self.get_hand())
def draw_cards(self, deck, num):
# draw cards from the deck and add them to the hand
for _ in range(num):
# draw a card from the deck
cards_in_deck = deck.deal()
if cards_in_deck:
# add the card to the hand
self.get_hand().append(cards_in_deck)
else:
# raise an exception if the
raise Exception('No cards to draw')
# return the string representation of the hand
return True
class HandRank:
#staticmethod
def is_cards_in_sequence(ranks):
sorted_ranks = sorted(ranks)
for i in range(len(sorted_ranks) - 1):
# check if the next card is one rank higher than the current card
if i == 0:
# check if the first card is an ace
if sorted_ranks[i] == 'A' and sorted_ranks[i + 1] == '10':
continue
if sorted_ranks[i] != (sorted_ranks[i + 1] - 1):
return False
return True
# function to return a count of each rank in the hand
#staticmethod
def get_counts(ranks):
ranks = []
for c in ranks:
if c in ranks:
# increment the count of the rank
ranks[c] += 1
else:
# add the rank to the dictionary
ranks[c] = 1
return ranks
# get the rank of the hand
def get_hand_rank(self, hand):
suits = [card.suit for card in hand] # get the suits of the cards
ranks = [card.rank for card in hand] # get the ranks of the cards
# check for Straight flush
if self.is_cards_in_sequence(ranks) and len(set(suits)) == 1:
return Constant.STRAIGHT_FLUSH
# check for four of a kind
elif self.get_counts(ranks) == 4:
return Constant.FOUR_OF_A_KIND
# check for full house
elif self.get_counts(ranks) == 3 and self.get_counts(ranks) == 2:
return Constant.FULL_HOUSE
# check for flush
elif len(set(suits)) == 1:
return Constant.FLUSH
# check for straight
elif self.is_cards_in_sequence(ranks):
return Constant.STRAIGHT
# check for three of a kind
elif self.get_counts(ranks) == 3:
return Constant.THREE_OF_A_KIND
# check for two pair
elif len(set(self.get_counts(ranks))) == 3:
return Constant.TWO_PAIR
# check for one pair
elif len(set(self.get_counts(ranks))) == 4:
return Constant.ONE_PAIR
#
else:
return Constant.HIGH_CARD
Exemple of the output:
Your Hand : 5K 8H 2S 3D 9S
Your Rank : Flush

Related

(In Python 3.8) filling in lists to mantain them similar in length and average?

I need to allocate some values in 3 individual lists.
The values are generated on the fly but all included in the 0-6 range.
The point is that these values should be put in the three lists so that the average of each list does not differ so much from the others. The lists also need to be similar in length.
So the goal would be to progressively fill these lists to maintain, as much as possible, a uniform average value and size for all of them.
As I didn't found any built-in function to do this, I have implemented a code which keeps track of lists length and tries to keep them as close as possible in their average value. You can play with it and improve it to better fit your case.
class Data:
def __init__(self):
"""Init the three lists."""
self.a = []
self.b = []
self.c = []
#staticmethod
def get_average(data: list):
"""Get average value of a list."""
try:
return sum(data) / len(data)
except ZeroDivisionError:
return 0
def get_shortest(self):
"""Return list with the shortest length."""
shortest_length = min(len(self.a), len(self.b), len(self.c))
if len(self.a) == shortest_length:
return self.a
elif len(self.b) == shortest_length:
return self.b
else:
return self.c
def get_smallest(self):
"""Return list with the smallest average value."""
smallest_average = min(self.get_average(self.a), self.get_average(self.b), self.get_average(self.c))
if self.get_average(self.a) == smallest_average:
return self.a
elif self.get_average(self.b) == smallest_average:
return self.b
else:
return self.c
def get_highest(self):
"""Return list with the highest average value."""
highest_average = max(self.get_average(self.a), self.get_average(self.b), self.get_average(self.c))
if self.get_average(self.a) == highest_average:
return self.a
elif self.get_average(self.b) == highest_average:
return self.b
else:
return self.c
def add_number(self, num):
"""Add number to one of the lists."""
shortest = self.get_shortest()
smallest = self.get_smallest()
highest = self.get_highest()
# Lists must not differ by more than two elements
if len(smallest) - len(shortest) >= 2 or len(highest) - len(shortest) >= 2:
shortest.append(num)
else:
# Test if the number uppers the smallest average
initial_avg = self.get_average(smallest)
smallest.append(number)
final_avg = self.get_average(smallest)
if final_avg > initial_avg:
return
else:
smallest.pop()
# Test if the number lowers the highest average
initial_avg = self.get_average(highest)
highest.append(number)
final_avg = self.get_average(highest)
if final_avg < initial_avg:
return
else:
highest.pop()
# Last resort
shortest.append(num)
d = Data()
value = input("Add number: ")
while value != 'e':
try:
number = int(value)
except ValueError:
break
d.add_number(number)
print(f"List a: {d.a}, avg. {d.get_average(d.a)}")
print(f"List b: {d.b}, avg. {d.get_average(d.b)}")
print(f"List c: {d.c}, avg. {d.get_average(d.c)}")
value = input("Add number:")

sorting a list of objects_python_3

How can i sort "cardsListObj" with suit and then rank?
I've done something like "print (cardsListObj.sort (key = card.getRank))" and it didn't work, i have "None".
Actually i did this on another code that is quite the same as this (in my opinion as a newbie) and that worked. (that code is about 300 lines that's why i didn't post it, here)
class card :
def __init__ (self, rank, suit) :
self.rank = rank # cards numbers
self.suit = suit # cards characters Diamonds, Clubs, Hearts, Spades
def getRank (self):
return self.rank
def getSuit (self):
return self.suit
def main():
cards = open (input ("file? "))
cardsListObj = []
for i in cards:
cardObj = card (i.split () [0], i.split () [1])
cardsListObj.append (cardObj)
Input file is a txt file with a number and a name of cards in each line separated by space.
Thanks in advance
if you want to sort your cards, you can create a function like this:
from operator import attrgetter
def sort_cards(cards): #cards is an list containing 'Cards' objects
"""Function sorting cards"""
return sorted(cards, key=attrgetter('suit', 'rank'))
deck = [
Cards(3, 'Diamonds'),
Cards(7, 'Clubs'),
Cards(5, 'Hearts'),
Cards(8, 'Diamonds'),
Cards(4, 'Spades'),
Cards(10, 'Clubs')
]
print(sort_cards(deck))
Output (you should define the method __repr__)
['7 of Clubs', '10 of Clubs', '3 of Diamonds', '8 of Diamonds', '5 of Hearts', '4 of Spades']
NB:
In my example, __repr__ is something like that:
class Card:
[...]
def __repr__(self):
return '%d of %s' % (self.rank, self.suit)

Object not iterable when assigning to a list

I am coding a 2048 game via pygame. below is the relevant section of my code:
class Data():
def __init__(self):
self.data = getnull()
self.score = 0
def updatesprites(self): # EXP
spritelist = [[],[],[],[]]
for count in range(4): # for row loop
for i in range(4): # per column loop
if self.data[count][i] != 0:
spritelist[count]+= newSprite(str(self.data[count] [i])+".png") # error occurs here
spritelist[count][i].move(15 + i*115, 15 + count*115)
showSprite(spritelist[count][i])
class newSprite(pygame.sprite.Sprite):
def __init__(self,filename):
pygame.sprite.Sprite.__init__(self)
self.images=[]
self.images.append(loadImage(filename))
self.image = pygame.Surface.copy(self.images[0])
self.currentImage = 0
self.rect=self.image.get_rect()
self.rect.topleft=(0,0)
self.mask = pygame.mask.from_surface(self.image)
self.angle = 0
def addImage(self, filename):
self.images.append(loadImage(filename))
def move(self,xpos,ypos,centre=False):
if centre:
self.rect.center = [xpos,ypos]
else:
self.rect.topleft = [xpos,ypos]
----------------Main-------------------
from functions import *
from config import *
from pygame_functions import *
import pygame
screenSize(475,475) # call screen init
gameboard = newSprite("game board.png") # createboard
showSprite(gameboard)
game = Data()
game.updatesprites()
while True:
pass
when game.updatesprites() is called, "newSprite object is not iterable" error is raised in function Data.updatesprites
+ concatenates lists and strings, and adds numbers.
What you are trying to do, is to add an element to a list.
This is done as follows:
li.append(element) # adds the element to the end of the list
Or in your case:
spritelist[count].append(newSprite(str(self.data[count][i]) + ".png"))
Another solution: You could create a new type, that lets you add elements the way you were trying to:
class UglyList(list):
def __iadd__(self, other):
self.append(other)
You'd need to change another line here:
spritelist = [UglyList() for i in range(4)]

Why doesn't my find function compare the nodes correctly?

I'm working on a concordance dictionary that reads a data file and records every unique word and the word's line number in a AVL tree. The problem is that my find method is not finding the Entry's within the tree so it adds every word instead of every unique word.
I'm also having trouble making my program keep a list of the line numbers within each entry. I'm using an entry class to keep the key(word) and the list of line numbers. Thank you for any help.
I'm writing in Python 2.7 and have included all my program so far.
My Main Program:
import string #NEW
from time import clock
import sys #for BST recursion limit
from dictionary import Entry
sys.setrecursionlimit(3000)#for BST
from avl import AVL
def main():
"""Calls on necessary functions to fill the dictionary, and process the keys"""
start = clock() #times runtime
stopWordDict = AVL()#Empty Dictionary
stopWordDict = fillStopWordDict(stopWordDict)
keyList = []
wordConcordanceDict = AVL()#Empty Dictionary
wordConcordanceDict = fillWordDict(stopWordDict,wordConcordanceDict, keyList)
print str(wordConcordanceDict) #wordconcorddict made here.
keyList.sort()
print keyList
writeWordConDict(wordConcordanceDict, keyList)
end = clock() #gets runtime
runTime = end - start
print("Done. Runtime was:",runTime,"seconds.")
def fillStopWordDict(stopWordDict):
"""fills chain dict with all of the stop words"""
fileNew=open('stop_words.txt', "r")
for word in fileNew:
word=word.lower().strip() #strip will strip \n from word
if stopWordDict.find(word) == None:
stopWordDict.add(word)
fileNew.close()
return stopWordDict
def fillWordDict(stopWordDict,wordConcordanceDict, keyList):
"""opens hw5data.txt and calls on processLine function"""
lineCounter = 1
fileNew=open('hw5data.txt', "r")
for line in fileNew:
processLine(lineCounter, line, stopWordDict,wordConcordanceDict, keyList)
lineCounter+=1 #changes to next line of file
fileNew.close()
return wordConcordanceDict
def processLine(lineCounter, line, stopWordDict,wordConcordanceDict, keyList):
"""process each line into the wordConcordanceDict"""
line=line.split() #splits line into list of words
for word in line:
word=word.lower().strip(string.punctuation)#strips punctuation
if stopWordDict.find(word) == None:
wordEntry = Entry(word, None)
if wordConcordanceDict.find(wordEntry) == None:
lineList = wordEntry.value
lineList.append(lineCounter)
wordEntry.value = lineList
wordConcordanceDict.add(wordEntry)
keyList.append(word)
else:
wordEntry = wordConcordance.find(wordEntry)
lineList = wordEntry.value
lineList.append(lineCounter)
wordEntry.value = lineList
wordConcordanceDict.add(wordEntry)
return wordConcordanceDict
def writeWordConDict(wordConcordanceDict, keyList):
"""takes in wordConcordanceDict and list of its keys. Then prints the key value pairs to the screen"""
fileNew=open("ProgProj5Concordance.txt", 'w')
# listOfWords = wordConcordanceDict.inorder()
for key in keyList:
wordEntry = wordConcordanceDict.find(key) #makes the values into a string
lineList = wordEntry.value
line=str(key + ":" + lineList + "\n")
fileNew.write(line)
fileNew.close()
main()
MY ENTRY CLASS:
"""
File: bst.py
BST class for binary search trees.
"""
from queue import LinkedQueue
from binarytree import BinaryTree
class BST(object):
def __init__(self):
self._tree = BinaryTree.THE_EMPTY_TREE
self._size = 0
def isEmpty(self):
return len(self) == 0
def __len__(self):
return self._size
def __str__(self):
return str(self._tree)
def __iter__(self):
return iter(self.inorder())
def find(self, target):
"""Returns data if target is found or None otherwise."""
def findHelper(tree):
if tree.isEmpty():
return None
elif target == tree.getRoot():
return tree.getRoot()
elif target < tree.getRoot():
return findHelper(tree.getLeft())
else:
return findHelper(tree.getRight())
return findHelper(self._tree)
def add(self, newItem):
"""Adds newItem to the tree."""
# Helper function to search for item's position
def addHelper(tree):
currentItem = tree.getRoot()
left = tree.getLeft()
right = tree.getRight()
# New item is less, go left until spot is found
if newItem < currentItem:
if left.isEmpty():
tree.setLeft(BinaryTree(newItem))
else:
addHelper(left)
# New item is greater or equal,
# go right until spot is found
elif right.isEmpty():
tree.setRight(BinaryTree(newItem))
else:
addHelper(right)
# End of addHelper
# Tree is empty, so new item goes at the root
if self.isEmpty():
self._tree = BinaryTree(newItem)
# Otherwise, search for the item's spot
else:
addHelper(self._tree)
self._size += 1
def inorder(self):
"""Returns a list containing the results of
an inorder traversal."""
lyst = []
self._tree.inorder(lyst)
return lyst
def preorder(self):
"""Returns a list containing the results of
a preorder traversal."""
# Exercise
pass
def postorder(self):
"""Returns a list containing the results of
a postorder traversal."""
# Exercise
pass
def levelorder(self):
"""Returns a list containing the results of
a levelorder traversal."""
# Exercise
pass
def remove(self, item):
# Exercise
pass
def main():
tree = BST()
print "Adding D B A C F E G"
tree.add("D")
tree.add("B")
tree.add("A")
tree.add("C")
tree.add("F")
tree.add("E")
tree.add("G")
print tree.find("A")
print tree.find("Z")
print "\nString:\n" + str(tree)
print "Iterator (inorder traversal): "
iterator = iter(tree)
while True:
try:
print iterator.next(),
except Exception, e:
print e
break
# Use a for loop instead
print "\nfor loop (inorder traversal): "
for item in tree:
print item,
if __name__ == "__main__":
main()
AND FINALLY THE BINARY TREE AVL CLASS:
from binarytree import *
class BinaryTreeAVL(BinaryTree):
def __init__(self, item, balance = 'EQ'):
BinaryTree.__init__(self, item)
self._balance = balance
def getBalance(self):
return self._balance
def setBalance(self, newBalance):
self._balance = newBalance
def __str__(self):
"""Returns a string representation of the tree
rotated 90 degrees to the left."""
def strHelper(tree, level):
result = ""
if not tree.isEmpty():
result += strHelper(tree.getRight(), level + 1)
result += "| " * level
result += str(tree.getRoot())+ " : " + tree.getBalance() + "\n"
result += strHelper(tree.getLeft(), level + 1)
return result
return strHelper(self, 0)

Questions about python inheritance and argument lists

First off I am getting this error
File "E:\New folder (7)\maingame.py", line 64, in play print self.introduction AttributeError: 'game' object has no attribute 'introduction'
I am not to sure as to what it means because I am pulling the self.introduction from the previous class..
I am also getting an
File "E:\New folder (7)\maingame.py", line 96, in <module>
game.play()
TypeError: play() takes exactly 2 arguments (1 given)
error, but can't for the life of me find what argument it is looking for, I simply want it to work.
from random import random
class place(object):
def __init__(self, title, description, events):
self.title = title
self.description = description
self.events = events
class event(object):
def __init__(self, probability, message, healthChange):
self.probability = probability
self.message = message
self.healthChange = healthChange
def process(self):
if random() < self.probability:
print self.message
return self.healthChange
return 0
class textadventure():
def __init__(self):
super(textadventure, self).__init__()
self.introduction = """
Welcome player, you are a lone traveler in space whom has set out to find glories beyond measure.
Unfortunately for you the dread pirate Roberts has attacked. You must defeat him.
"""
commandDeck = place('Command Deck', "You are now in the command center, here you can drive the ship and fire its weapons.",(
event(0.7, "The pirate ship fires at you! You take damage to your engines!", -10),
event(0.2, "One of the pirates manages to beam onto your ship! He shoots you before beaming away!",0),
))
engineRoom = place('Engine Room', "You are now in the main engine room here you can repair damage to the ship",(
event(0.7, "The pirate ship fires at you! You take damage to your engines!", -10),
))
restQuarters = place('Resting Quarters', "Here you can take a rest and heal your self",(
event(1.0, 'You are able to patch up your wounds and get back to the battle',0),
event(0.5, "The pirate ship fires at you! You take damage to your engines!", -10),
))
commandDeck.transitions = (engineRoom, restQuarters),
engineRoom.transitions = (commandDeck, restQuarters),
restQuarters.transitions = (commandDeck, engineRoom),
self.location = commandDeck
pirateHp = 50
class game(object, textadventure):
def __init__(self):
super(game, self).__init__()
self.health = 100
def location(self):
if self.location == commandDeck:
choice = raw_input('would you like to fire on the enemy ship?')
if choice == 'yes':
print 'You have hit the pirates!'
pirateHp -= 10
else: choice == 'no'
elif self.location == engineRoom:
choice = raw_input('Would you like to repair the engines?')
if choice == "yes":
event(1, "You repair what you can of the engines.", 10)
def __init__(self):
self.health = 100
def play(self, textadventure):
print textadventure.introduction
while True:
print (self.location.description)
for event in self.location.events:
self.health += event.process()
if self.health <= 0:
print ("Your ship has been destroyed!")
pause
exit(1)
print ('Your ships health is at %d percent' % self.health)
self._transition()
def _transition(self):
transitions = self.location.transitions
print ('you can go to: ')
for (index, transition) in enumerate(transitions):
print (index + 1, transition.title)
choice = int(raw_input('Choose one '))
if choice == 0:
exit(0)
else:
self.location = transitions[choice - 1]
def pirateShip(Object):
if pirateHp == 0:
print "You have defeated the pirates! Congradualations!"
pause
exit(1)
game = game()
game.play(game)
'game' object has no attribute 'introduction'
You should call the init of your super class when initializing game. In your current code, textadventure.init is never called which is why introduction is never added to textadventure.
Game should also not inherit from object (it does that through textadventure).
class game(textadventure):
def __init__(self):
super(game, self).__init__()
self.health = 100
def play(self):
print self.introduction
Should do the trick.
TypeError: play() takes exactly 2 arguments (1 given)
You never use your textadventure argument in play. Removing this should get things working.