这是我第一次使用 stack overflow,所以如果格式与网站不太相符,我深表歉意。 我最近才开始学习编程,已经快两周了。我正在从 http://openbookproject.net/thinkcs/python/english3e/index.html 学习 python直到现在一切都很好,我只是被困了几个小时。 我在谷歌上搜索了很多,但找不到合适的解决方案,所以我来了。
我正在尝试让 OldMaidGame() 正常运行,如 CH17 中所述。 http://openbookproject.net/thinkcs/python/english3e/ch17.html - 大部分代码也来自上一章。
我发现我无法使 Deck.remove、Hand.remove_matches 或任何其他类型的移除功能起作用。经过一些调试我发现 当程序检查给定的卡片是否存在于甲板/手/等中时,就会出现问题。它永远无法匹配。然后经过一些回顾 本章(在 ch16 中),我发现“如果卡片在甲板/手/等中:移除(卡片)”等查找对象的 .cmp() 以确定卡片是否实际上存在于甲板/手/等。这是我的 cmp 在对电子书中的给定代码添加“ace”之后的版本。
def __cmp__(self, other):
""" Compares cards, returns 1 if greater, -1 if lesser, 0 if equal """
# check the suits
if self.suit > other.suit: return 1
if self.suit < other.suit: return -1
# suits are the same... check ranks
# check for aces first.
if self.rank == 1 and other.rank == 1: return 0
if self.rank == 1 and other.rank != 1: return 1
if self.rank != 1 and other.rank == 1: return -1
# check for non-aces.
if self.rank > other.rank: return 1
if self.rank < other.rank: return -1
# ranks are the same... it's a tie
return 0
cmp 本身看起来不错,我当然可以使用一些技巧来让它变得更好(比如 ace 检查)。 所以我不知道为什么牌组/手牌检查中的牌总是返回 false。 这是给定的删除函数:
class Deck:
...
def remove(self, card):
if card in self.cards:
self.cards.remove(card)
return True
else:
return False
拼命想让它工作,我想到了这个:
class Deck:
...
def remove(self, card):
""" Removes the card from the deck, returns true if successful """
for lol in self.cards:
if lol.__cmp__(card) == 0:
self.cards.remove(lol)
return True
return False
似乎工作正常,直到我转向其他不工作的删除功能:
class OldMaidHand(Hand):
def remove_matches(self):
count = 0
original_cards = self.cards[:]
for card in original_cards:
match = Card(3 - card.suit, card.rank)
if match in self.cards:
self.cards.remove(card)
self.cards.remove(match)
print("Hand {0}: {1} matches {2}".format(self.name, card, match))
count = count + 1
return count
我又做了一些调整:
class OldMaidHand(Hand):
def remove_matches(self):
count = 0
original_cards = self.cards[:]
for card in original_cards:
match = Card(3 - card.suit, card.rank)
for lol in self.cards:
if lol.__cmp__(match) == 0:
self.cards.remove(card)
self.cards.remove(match)
print("Hand {0}: {1} matches {2}".format(self.name, card, match))
count = count + 1
return count
移除对卡片来说效果很好,但是当我尝试移除匹配项时它会给出错误(x 不在列表中)。另一个我们左右,我可能也能做到这一点,但因为我已经感觉我走错了路,因为我无法修复原始的“牌组/手牌/等”等,我来这里寻找一些答案/提示。
感谢阅读,非常感谢您提供的任何帮助:)
-------------------- 编辑 1 *
这是我当前的代码: http://pastebin.com/g77Y4Tjr
-------------------- 编辑 2 *
我已经尝试了这里建议的每一个 cmp,但我仍然无法找到带有“in”的卡片。
>>> a = Card(0, 5)
>>> b = Card(0, 1)
>>> c = Card(3, 1)
>>> hand = Hand('Baris')
>>> hand.add(a)
>>> hand.add(b)
>>> hand.add(c)
>>> d = Card(3, 1)
>>> print(hand)
Hand Baris contains
5 of Clubs
Ace of Clubs
Ace of Spades
>>> d in hand.cards
False
>>>
我也尝试过 card.py @DSM 已成功使用,但我也在那里遇到错误,比如在排序函数中它说它无法比较两个卡片对象。
所以我想知道,也许这是 Python 3.2 的问题,或者语法在某处发生了变化?
最佳答案
“所以我想知道,也许这是 Python 3.2 的问题,或者语法在某处发生了变化?”
哦,你运行的是 Python 3.2? 这在 Python 3 中永远行不通:python 3 不使用 __cmp__!
参见 data model (look for __eq__) .另请阅读 what's new in Python 3对于其他一些事情,方式太容易错过了。
抱歉,这是我们 Python 程序员的责任;我们应该早点发现这一点。大多数人可能查看了所有代码,甚至没有考虑就意识到源代码显然是 python 2 代码,并假设这就是我们正在使用的代码。 cmp 函数在 Python 3.2 中甚至不存在,但它没有因 NameError 爆炸的原因是因为从未调用过 __cmp__。
如果我在 Python 3.2 中运行代码,我会完全重现您的问题:
>>> c = Card(0,2)
>>> str(c)
'2 of Clubs'
>>> c in [c]
True
>>> c in Deck().cards
False
在 Python 3 中,您可以实现所有丰富的 cmps 或 __eq__ 和其中之一,并使用 total_ordering 装饰器。
from functools import total_ordering
@total_ordering
class Card(object):
"""Represents a standard playing card."""
suit_names = ["Clubs", "Diamonds", "Hearts", "Spades"]
rank_names = [None, "Ace", "2", "3", "4", "5", "6", "7",
"8", "9", "10", "Jack", "Queen", "King"]
def __init__(self, suit=0, rank=2):
self.suit = suit
self.rank = rank
def __str__(self):
return '%s of %s' % (Card.rank_names[self.rank],
Card.suit_names[self.suit])
def __repr__(self): return str(self)
def __lt__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 < t2
def __eq__(self, other):
t1 = self.suit, self.rank
t2 = other.suit, other.rank
return t1 == t2
>>> c = Card(2,3)
>>> c
3 of Hearts
>>> c in Deck().cards
True
关于Python: 'object in list' 检查和 '__cmp__' 溢出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6215549/
关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。
我正在尝试测试是否存在表单。我是Rails新手。我的new.html.erb_spec.rb文件的内容是:require'spec_helper'describe"messages/new.html.erb"doit"shouldrendertheform"dorender'/messages/new.html.erb'reponse.shouldhave_form_putting_to(@message)with_submit_buttonendendView本身,new.html.erb,有代码:当我运行rspec时,它失败了:1)messages/new.html.erbshou
我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer
在MRIRuby中我可以这样做:deftransferinternal_server=self.init_serverpid=forkdointernal_server.runend#Maketheserverprocessrunindependently.Process.detach(pid)internal_client=self.init_client#Dootherstuffwithconnectingtointernal_server...internal_client.post('somedata')ensure#KillserverProcess.kill('KILL',
我已经从我的命令行中获得了一切,所以我可以运行rubymyfile并且它可以正常工作。但是当我尝试从sublime中运行它时,我得到了undefinedmethod`require_relative'formain:Object有人知道我的sublime设置中缺少什么吗?我正在使用OSX并安装了rvm。 最佳答案 或者,您可以只使用“require”,它应该可以正常工作。我认为“require_relative”仅适用于ruby1.9+ 关于ruby-主要:Objectwhenrun
这个问题在这里已经有了答案:Checktoseeifanarrayisalreadysorted?(8个答案)关闭9年前。我只是想知道是否有办法检查数组是否在增加?这是我的解决方案,但我正在寻找更漂亮的方法:n=-1@arr.flatten.each{|e|returnfalseife
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)