Open Side Menu Go to the Top
Register
** Python Support Thread ** ** Python Support Thread **

07-17-2012 , 05:52 AM
I'm looking for a good way of sorting an array of dicts by two dict elements, and nothing i've written so far looks maintainable or reusable for similar data.

Code:
leaguegames = LeagueGame.objects.filter(Q(division__exact = division))
    teams = division.get_team_list()
    ladder = []
    for t in teams:
        _dict = t.get_ladder_data()
        _dict['team'] = t.name
        ladder.append(_dict)
Where get_ladder_data() looks like you'd see on any sporting ladder:

{ "played":2, "won": 2, "lost":0, "For": 32, "against": 28, "percent":53.3 , "points":4 }

I'd like to sort by "points" then "percent".

Ideas?
** Python Support Thread ** Quote
07-17-2012 , 07:00 AM
Quote:
Originally Posted by tyler_cracker
rounding error? chop equity being left out?
Thanks tyler. As I understand it, the chop equity must already be included (because the ev entry is different from the scoop entry).

I'm thinking it might be down to one of the following:

1. It's assuming tied pots are tied n ways instead of being tied between 2 and n ways. (This would then give slightly too little equity to each.)

2. It's a rounding error internal to the library.


Either way my currently solution is just to normalise the equity, so if I get told equity is 499 497 then I just convert multiply each equity by 1000/996.

It worries me though that either the library has this bug, or I'm not fully understanding the results it is returning.
** Python Support Thread ** Quote
07-17-2012 , 02:44 PM
Quote:
Originally Posted by sorrow
I'm looking for a good way of sorting an array of dicts by two dict elements, and nothing i've written so far looks maintainable or reusable for similar data.

Code:
leaguegames = LeagueGame.objects.filter(Q(division__exact = division))
    teams = division.get_team_list()
    ladder = []
    for t in teams:
        _dict = t.get_ladder_data()
        _dict['team'] = t.name
        ladder.append(_dict)
Where get_ladder_data() looks like you'd see on any sporting ladder:

{ "played":2, "won": 2, "lost":0, "For": 32, "against": 28, "percent":53.3 , "points":4 }

I'd like to sort by "points" then "percent".

Ideas?
sorted(_dict, lamda x: (x["points"], x["percent"])) should do it.
** Python Support Thread ** Quote
07-17-2012 , 04:54 PM
ups. Obviously _dict should be ladder in my post above.

sorted(ladder, lambda x: (x["points"], x["percent"]))
** Python Support Thread ** Quote
07-17-2012 , 08:10 PM
Hey guys,

I've written the below code that simulates randomly drawing a card from a 52-card deck (with replacement) and tells the user how many cards and face cards he was dealt in order to get a total of four aces.

Here's the thing: I want to modify my code so that it stops only once I've drawn the same card twice in a row. I know I have to use a while loop but it gets messy, b/c I *think* I'll have to introduce other variables like rank2 and suit2.

But I still want it to simulate drawing one card each time. Sorry for the rambly post, hopefully it made sense.

Thanks in advance for the help!



import random

number_card = 1

number_aces = 0

number_face_cards = 0

while number_aces < 4:

rank = random.randint(1,13)

if rank in range(2,10):
print("Card #" + str(number_card) + ": " + str(rank) + " of ", end="")

elif rank == 1:
print("Card #" + str(number_card) + ": Ace of ", end="")
number_aces = number_aces + 1

elif rank == 11:
print("Card #" + str(number_card) + ": Jack of " , end="")

elif rank == 12:
print("Card #" + str(number_card) + ": Queen of " , end="")

else:
print("Card #" + str(number_card) + ": King of " , end="")

if rank in range(11,13):
number_face_cards = number_face_cards + 1

suit = random.randint(1,4)

if suit == 1:
print("Clubs")

elif suit == 2:
print("Diamonds")

elif suit == 3:
print("Hearts")

else:
print("Spades")

number_card = number_card + 1

print("")
print("It took " + str(number_card) + " cards to get 4 Aces!")
print("")
print("In total, you were dealt " + str(number_face_cards) + " face cards!")
** Python Support Thread ** Quote
07-17-2012 , 08:28 PM
Use code tags for large samples
** Python Support Thread ** Quote
07-17-2012 , 09:48 PM
How do I do that?
** Python Support Thread ** Quote
07-17-2012 , 10:39 PM
Code:
def foo(bar):
    print baz
quote this post to see.
** Python Support Thread ** Quote
07-18-2012 , 09:37 AM
Quote:
Originally Posted by Mariogs37
Hey guys,

I've written the below code that simulates randomly drawing a card from a 52-card deck (with replacement) and tells the user how many cards and face cards he was dealt in order to get a total of four aces.

Here's the thing: I want to modify my code so that it stops only once I've drawn the same card twice in a row. I know I have to use a while loop but it gets messy, b/c I *think* I'll have to introduce other variables like rank2 and suit2.

But I still want it to simulate drawing one card each time. Sorry for the rambly post, hopefully it made sense.

Thanks in advance for the help!



import random

number_card = 1

number_aces = 0

number_face_cards = 0

while number_aces < 4:

rank = random.randint(1,13)

if rank in range(2,10):
print("Card #" + str(number_card) + ": " + str(rank) + " of ", end="")

elif rank == 1:
print("Card #" + str(number_card) + ": Ace of ", end="")
number_aces = number_aces + 1

elif rank == 11:
print("Card #" + str(number_card) + ": Jack of " , end="")

elif rank == 12:
print("Card #" + str(number_card) + ": Queen of " , end="")

else:
print("Card #" + str(number_card) + ": King of " , end="")

if rank in range(11,13):
number_face_cards = number_face_cards + 1

suit = random.randint(1,4)

if suit == 1:
print("Clubs")

elif suit == 2:
print("Diamonds")

elif suit == 3:
print("Hearts")

else:
print("Spades")

number_card = number_card + 1

print("")
print("It took " + str(number_card) + " cards to get 4 Aces!")
print("")
print("In total, you were dealt " + str(number_face_cards) + " face cards!")
Code:
# inside while
if suit == last_suit and rank == last_rank:
    break

# bottom of while
last_suit = suit
last_rank = rank
** Python Support Thread ** Quote
07-18-2012 , 10:25 AM
Gotcha, thanks for the help.

Quick question about ranges. When I write:

if x in range(2,10)

This means that the condition is met if x = any integer between 2 and 9 inclusive (so it doesn't include 10), correct?

Whereas:

if x in (2,10) includes 10, similar to random.randint(2,10) includes 10, yeah?
** Python Support Thread ** Quote
07-18-2012 , 11:16 AM
Quote:
Originally Posted by Mariogs37
Gotcha, thanks for the help.

Quick question about ranges. When I write:

if x in range(2,10)

This means that the condition is met if x = any integer between 2 and 9 inclusive (so it doesn't include 10), correct?

Whereas:

if x in (2,10) includes 10, similar to random.randint(2,10) includes 10, yeah?
The way 'x in y' works is that x is an element, and y is a list (or tuple) of elements. If x is equivalent to one of the elements in y, then the statement is true.

I can never remember if range is inclusive or exclusive, type range(2,10) into the python shell and check out the list that it produces.

"if x in (2,10)" will only be true if x is 2 or 10. This is because 2 and 10 are the only elements in this tuple.
** Python Support Thread ** Quote
07-18-2012 , 02:28 PM
range is left-inclusive, right-exclusive

It sounded dumb to me at first until I had it explained to me that this means that you can write something like range(x, x+k) and it will contain k elements. e.g. "range(1, 1+8)" is the integers 1 to 8.
** Python Support Thread ** Quote
07-18-2012 , 02:44 PM
I like that explaination a lot, thx.
** Python Support Thread ** Quote
07-18-2012 , 03:45 PM
Ahh v. helpful. Thanks for the clarification guys.
** Python Support Thread ** Quote
07-18-2012 , 04:34 PM
Thanks again for the help guys. I think I've got this one most of the way there; I'm trying to get it so that, if you roll doubles, your turn's over and if not, the program asks you if you want to roll again.

Issue is that, when someone inputs "1", my program doesn't roll again...I thought it would go to the beginning and check if p == 1 and, given that it does, roll again...

Where am I going wrong?

Code:
import random

score1 = 0

score2 = 0

keep_rolling_flag = 1

while keep_rolling_flag == 1:
    die1 = random.randint(1,6)
    die2 = random.randint(1,6)
    print("You rolled a " + str(die1) + " and a " + str(die2))
    print("You rolled a " + str(die1 + die2))
    if die1 == die2:
        turn_points = 0
        score1 = score1 + turn_points
        print("Your points are now " + str(score1))
        print("Your turn is over.")
    else:
        score1 = score1 + die1 + die2
        print("Your points are now " + str(score1))
        p = input("Keep rolling? (0 = no, 1 = yes): ")
        if p == 1:
            keep_rolling_flag = 1
        else:
            keep_rolling_flag = 0
[/QUOTE]
** Python Support Thread ** Quote
07-18-2012 , 05:42 PM
Firstly, try raw_input(), secondly try forcing conversion to int, so actually use int(raw_input())
** Python Support Thread ** Quote
07-19-2012 , 12:11 PM
Quote:
Originally Posted by clowntable
I like that explaination a lot, thx.


You might also find this interesting: http://www.cs.utexas.edu/users/EWD/t...xx/EWD831.html
** Python Support Thread ** Quote
07-21-2012 , 04:54 AM
Quote:
Originally Posted by Neko
sorted(_dict, lamda x: (x["points"], x["percent"])) should do it.
*mutters about gmail spam filter*

Pretty close to what I ended up with:
Code:
ladder = sorted(ladder, key=lambda d: (-d['points'], -d['percent']))
Gotta love python.
** Python Support Thread ** Quote
07-22-2012 , 12:51 AM
Hey guys. So sometimes I find that I want to use a function in a loop where it'll act on the arg only if it exists. Like for example do a loop on a list and keep going only until it finds out that the next index of that list doesn't exist. Or maybe the function operates on a list of various class objects, of which only some of those objects share a certain method. So if that object has that attribute, I want the function to be carried out, but if not, do nothing and move on to the next item in the list.

And the easiest way I can think of to do this is to use a try except. But I'm not sure if that's considered bad form, or if they're only supposed to be used to catch errors.
** Python Support Thread ** Quote
07-22-2012 , 01:03 AM
A lot of people in the python use try/catch for the type of situation you're describing. Personally I'm not a huge fan of it. I'd rather do something like:

Code:
for obj in objects:
    if hasattr(obj,"method_name"):
       obj.method_name()
That looks much nicer to me than

Code:
for obj in objects:
    try:
        obj.method_name()
    except AttributeError():
        pass
That said, in some cases (i.e. when the attribute almost always exists on the objects) there can be performance benefits to the latter method.
** Python Support Thread ** Quote
07-22-2012 , 01:22 AM
+1 neko's answer

two other techniques that seem applicable:

- design your class structure to get rid of this problem:

Code:
class Parent(object):
    def updateDatabse(self):
        pass

class HasADatabase(Parent):
    def updateDatabase(self):
        # do real database-y things
- for data

Code:
attribute = getattr(klass, 'attribute')
if attribute is not None:
    # do the things
** Python Support Thread ** Quote
07-22-2012 , 07:26 PM
Trying to find the smallest number divisible by each of the numbers between 1 and 20. Here's my attempt:

x = 1

y = 1

while y < 21:

if x % y == 0:
y = y + 1
else:
x = x + 1
y = 1

print(str(x))

Issue is, when I run it, Python doesn't print anything...not sure why. Ideas?
** Python Support Thread ** Quote
07-22-2012 , 08:13 PM
use the [ code ] tags.

try putting a print inside your while loop so you can see what x and y are doing.
** Python Support Thread ** Quote
07-23-2012 , 04:31 PM
Quote:
Originally Posted by Mariogs37
Trying to find the smallest number divisible by each of the numbers between 1 and 20. Here's my attempt:

x = 1

y = 1

while y < 21:

if x % y == 0:
y = y + 1
else:
x = x + 1
y = 1

print(str(x))

Issue is, when I run it, Python doesn't print anything...not sure why. Ideas?
Does the program exit? If it doesn't it means that y never reaches 21 and you have an infinite loop. I'm not a python developer but it looks to me like the print statement is not in the loop, given the indentation, so if you are stuck in the loop the print never executes.
** Python Support Thread ** Quote
07-23-2012 , 04:57 PM
Should have used the code tags but have sorted out the issue, thanks guys.

On a dif not, why do the vowels below need quotes around them. I would have done it without...

Code:
secret = input("Type something amusing: ")

count_vowels = 0
count_vowel_pairs = 0

last_char_was_vowel = False


for each_letter in secret.lower():
    print(each_letter)
    if ( each_letter == "a"
         or each_letter == "e"
         or each_letter == "i"
         or each_letter == "o"
         or each_letter == "u" ) :

        count_vowels = count_vowels + 1
Midterm tomorrow so trying to iron these little things out.

Thanks again, you guys have been rly helpful!

-Mariogs
** Python Support Thread ** Quote

      
m