So I'm trying to make yahtzee-board, but I've come to an obstacle which shouldn't be that hard to solve, but I simply cant fix it. This is how my remove function is looking currently:
class Player:
def __init__(self,name):
self.name=name
self.lista={"aces":0,"twos":0,"threes":0,"fours":0,"fives":0,"sixs":0,"upperscore":0,"bonus":0,"pair":0,"twopair":0,"3ofakind":0,"4ofakind":0,"smallstraight":0,"largestraight":0,"fullhouse":0,"chance":0,"yahtzee":0,"lowerscore":0,"totalscore":0}
self.upperbracket={"aces":0,"twos":0,"threes":0,"fours":0,"fives":0,"sixs":0}
self.lowerbracket={"pair":0,"twopair":0,"3ofakind":0,"4ofakind":0,"smallstraight":0,"largestraight":0,"fullhouse":0,"chance":0,"yahtzee":0}
def remove(self,i):
b=input("Do you want to remove a moment?:")
if b=="yes":
c=input("Which moment do you want to remove?")
spelarlista[i].lista[c]=str("&")
self.printtable()
return True
if b=="no":
return False
def add(self):
rundor=0
while rundor!=15:
for i in range(len(spelarlista)):
count=0
print("Rolling dice for: ", str(spelarlista[i]))
self.rolldice()
if self.remove(i)==True:
i=i+1
count+=1
while count<=0:
moment=input("Where do you want to put your points,"+" "+ str(spelarlista[i])+"?:""\n" )
while moment not in self.lista:
print("oops! Try again!")
if spelarlista[i].lista[moment]!=0 or spelarlista[i].lista[moment]==str("&"):
print("Moment has either been removed or you already got points there")
else:
points=input("How many points did you get?: ")
What I want to do is that if I decide to remove an already removed "moment" it's supposed to print "no can do" or something like that, the same thing is if there is already points there.
currently the line of code is looking like this:
if spelarlista[i].lista[moment]!=0 or spelarlista[i].lista[moment]==str("&"):
Notice that this line is working prefectly if I've already added points, but if I try to remove an already removed "moment" it does not work as intended, I simply cant see where everything has gone wrong...
thanks in advance
Related
So, I am working on a Django-based website (Django 3) and I am trying to use a file to add certain elements into the database. While reading the file and its data works smoothly, the script seems to stop abruptly on this line:
studentClass.student_set.add(student)
Right before that, I have lines like these being executed with no problem:
school = get_object_or_404(School, pk=form.cleaned_data['school'].pk)
studentClass, created = StudentClass.objects.get_or_create(
school=school,
name=form.cleaned_data['name'],
grade=form.cleaned_data['grade']
)
.
.
.
print("\nSUCCESS!\n")
print("\nAttempting to add {} to {}".format(
student,
studentClass))
studentClass.student_set.add(student) <---- SUSPECTED CULPRIT!
print("SUCCESS!")
The output from the print statement to the console:
Attempting to add (<Student: 1 - Jessica>, False) to 1 - HenMei
EDIT: I did not see this the first time, but if it relates to the question and someone smart enough to know what that "False" in the string output above is, an explanation would be much appreciated.
The second print statement:
print("SUCCESS!")
is not executed, thus I am quite sure that
studentClass.student_set.add(student)
is the line that's causing some trouble. Since I am a beginner, I may very well be wrong.
EDIT: Just to make sure that the way I was doing things wasn't part of the problem, I also tried to rewrite the line above to:
student.studentClass.add(studentClass)
But the same thing happened; no output after that line either.
Models are defined as follows:
class StudentClass(models.Model):
school = models.ForeignKey(School, on_delete=models.SET_NULL, null=True)
name = models.CharField(max_length=25)
grade = models.PositiveSmallIntegerField(default=1)
class Meta:
ordering = ['grade', 'name']
def __str__(self):
return "{} - {}".format(self.grade, self.name)
class Student(models.Model):
studentClass = models.ManyToManyField(StudentClass)
student_number = models.PositiveSmallIntegerField()
first_name = models.CharField(max_length=50)
gender = models.CharField(max_length=6, default='Female')
class Meta:
ordering = [F('student_number').asc(nulls_last=True)]
def __str__(self):
return "{} - {}".format(self.student_number, self.first_name)
Last but not least, here's the last line that gets printed to console:
[16/Jun/2020 18:14:06] "POST /teachadmin/addStudentClass/ HTTP/1.1" 302 0
Which doesn't tell me a whole lot, but I thought maybe you professionals out there might need it :P
Any ideas what I am doing wrong?
Thanks in advance!
After a couple of hours searching through the (wrong part of the) documentations for Django, I finally realized that I had not been doing any tuple unpacking on the following line:
student = Student.objects.get_or_create(
student_number=row.Index,
first_name=row.Name,
gender=row.Gender
)
You might be confused and say "Umm.. I didn't see this?". That is perfectly normal - I was an idiot and thought "There can't possibly be a mistake in there."
This proved to be wrong as the statement:
studentClass.student_set.add(student)
tries to add the tuple instead of a Student-object.
Instead, I changed the line to simply do tuple unpacking on spot:
student, created = Student.objects.get_or_create(
student_number=row.Index,
first_name=row.Name,
gender=row.Gender
)
And then finally go ahead and add the StudentClass to the Student object:
studentClass.student_set.add(student)
Sometimes it's funny how you assume someTHING is wrong with your code and you realize it was your own silly mistake all along... :P
Thanks to everyone who bothered checking in and thought about an answer :)
In the following Program, the calculator gui is closing itself when i press "=" for getting the result. I think there is some problem with the eval function. if i remove the eval then i didn't encounter any problem with the program. Need help in figuring this out. Is there any other approach i can try besides this? Thanks in advance.
class Calci(QWidget):
def __init__(self, Parent=None):
super(Calci,self).__init__()
self.initgui()
def initgui(self):
self.list1=
["%","rt","pow","1/x","CE","C","BCK","/","7","8","9","*","4","5","6","-
","1","2","3","+","+-","0",".","="]
self.list2=[(i,j) for i in range(2,8) for j in range(0,4)]
self.button={}
self.data1=""
self.data2=0
self.lineedit=QLineEdit()
self.lineedit.setFocus()
grid=QGridLayout()
self.setLayout(grid)
self.font=QFont("Bookman Old Style",15,25)
self.lineedit.setFont(self.font)
for x,y in zip(self.list1,self.list2):
self.button[y]=QPushButton(x)
grid.addWidget(self.lineedit,0,0,2,4)
self.lineedit.setSizePolicy(QSizePolicy.Preferred,QSizePolicy.Expanding)
self.lineedit.setMinimumHeight(70)
grid.addWidget(self.button[y],*y)
self.button[y].setSizePolicy(QSizePolicy.Preferred,QSizePolicy.Expanding)
self.button[y].setMinimumHeight(70)
self.lineedit.setAlignment(Qt.AlignRight)
self.button[y].clicked.connect(lambda state,x=x: self.click(x))
def click(self,n):
if (n=="="):
data1=self.lineedit.text()
self.lineedit.clear()
self.lineedit.insert(eval(data1))
else:
self.lineedit.insert(n)
app=QApplication(sys.argv)
calci=Calci()
calci.show()
app.exec_()
It's most likely failing because of a TypeError when you try to set the line edit text to an integer value. I also don't think self.lineedit.insert() is the method that you want to use. This will add the calculation after the line after the text already entered.
try:
self.lineedit.setText(str(eval(data1)))
This will clear the line edit and set the text to the calculated value.
But:
Please don't use eval like this. This is a very dangerous practice as any python code entered in the text edit will be run.
What I want is this - I have a list of names created from user input. now i have to come up with a way for the user to edit a name by entering the name that they what to edit and then obviously edit it into what they want and store it in the list.
if it helps heres everything I have so far. def edit() is where im struggling.
def mainMenu():
print("\nMAIN MENU")
print("1. Display Members:")
print("2. Add A Member(s):")
print("3. Remove A Member:")
print("4. Edit Member:")
print("5. Exit:")
selection = int(input("\nEnter Choice: "))
if selection == 1:
display()
elif selection == 2:
add()
elif selection == 3:
remove()
elif selection == 4:
edit()
elif selection == 5:
exit()
else:
print("Invalid choice, enter 1-5.")
mainMenu()
def display():
#displaying roster...
print(roster)
mainMenu()
def add():
#adding team members...
size = int(input("How many players are you adding?"))
global roster
roster = [0] * size
for i in range(size):
roster[i] = input("Enter members name: ")
roster.append(roster)
mainMenu()
def remove():
#removing a team member...
roster.remove(input("Enter member to be removed: "))
mainMenu()
def edit():
#edit a team member...
roster.insert(input("Enter Name to be edited: "))
mainMenu()
mainMenu()
Removing and adding elements are pretty easy in python because they are directly supported by the language. Each of them can be translated into only one instruction.
When something doesn't seem very obvious, such as the editing functionality you are trying to implement, try breaking it down to things that can be expressed as a simple operation that holds one one line (even if not in order).
To find the answer I thought this: somewhere in my code, I want to type roster[ind_name_to_edit] = new_name.
I knew then that before typing this, I would want to find the value of ind_name_to_edit. This can be done by roster.index(name_to_edit). And you already know how to get the name to be edited and the name to edit ;)
If you're still unsure how to do what you want to do, re-read this answer and see the documentation of the index method of list in python3 and maybe some examples here.
N.B: If your list is supposed to be sorted in some way, you should implement your own search algorithm instead of using index, and you should consider re-sorting the list after the edit. I know it's a long shot but just in case.
Okay, trying to make a simple game of Guessing Numbers but I can't find the mistake in this code. Still pretty new to python so probably the reason why but I can't figure out what is wrong with it.
import random
from time import sleep
def start():
print("Welcome To The Guessing Game \n Try to guess the number I'm thinking of \n Good luck!")
selectRandomNumber()
guessCheck(number, numberInput=1)
def restart():
print("Creating new number ...")
sleep(1)
print("OK")
selectRandomNumber()
guessCheck(number,numberInput=1)
def selectRandomNumber():
number = random.randint(0,1000)
tries = 0
return
def tryAgain():
while True:
try:
again = int(input("Do you want to play again? y/n:"))
except ValueError:
print("Couldn't understand what you tried to say")
continue
if again == "y" or "yes":
print("Awesome! Lets go")
restart()
elif again == 'n' or "no":
print("Goodbye!")
break
else:
print("Not a valid option")
continue
def guessCheck(number,numberInput=1):
while True:
try:
numberInput = int(input("What number do you think it is?: "))
except ValueError:
print("Couldn't understand that. Try again")
continue
if numberInput > number:
print("Too high")
tries += 1
continue
elif numberInput < number:
print("Too low")
tries += 1
continue
elif numberInput == number:
print("Congrats! You got my number")
tryAgain()
number = selectRandomNumber()
print(number)
start()
Every time I try to run the program I keep getting the same mistake.
It tells me:
Traceback (most recent call last):
File "python", line 60, in <module>
start()
File "python", line 8, in start
guessCheck(number, numberInput)
NameError: name 'number' is not defined
Don't quite understand what that means.
Some help would be appreciated. Thanks!
* UPDATE *
Was able to fix the part about defining the variable but now new problem happened where when I try to run
Same code as before but added
guessCheck(number,numberInput=1)
and also added the variable number at the end
number = selectRandomNumber()
print(number)
start()
when I run it I get this
None # this is from `print(number)` so instead of getting a number here I'm getting `None`
Welcome To The Guessing Game
Try to guess the number I'm thinking of
Good luck!
What number do you think it is?:
The Traceback is telling you this:
We got to start().
start() called guessCheck().
We tried to pass two pieces of information to guessCheck(): the variable names number and numberInput.
We don't have those variables defined yet! numberInput doesn't get defined until once we've already started guessCheck(), and number isn't actually defined anywhere.
As Manoj pointed out in the comments, you probably want number to hold the output of selectRandomNumber(). So, instead of just calling selectRandomNumber() in start(), try number = selectRandomNumber() instead.
You can add a print(number) on the line right after that to make sure number has a value assigned to it.
Now number has a value, going into your call to guessCheck(). That still leaves numberInput undefined though. You can set a default value for function arguments like this:
guessCheck(number, numberInput=1)
That way, when guessCheck is called but numberInput hasn't been defined yet, it will automatically give it the value 1 until you set it explicitly.
You may encounter other issues with your code the way it is. My advice would be to start really simply - build up your game from each individual piece, and only put the pieces together when you're sure you have each one working. That may seem slower, but trying to go too fast will cause misunderstandings like this one.
I wasn't entirely sure how to word this question, so I'll stick with explaining my specific goal.
I'm trying to implement an 'eat' option to a user_input function for a text adventure. I want it to check if the verb is 'eat', check if the item is in the player's inventory, check if the item is consumable or not, and then - my goal - show that the player eats it (and only show it once, see below). The 'eat' option has no functionality as of yet, I'm only testing print statements.
I'm totally aware that the code below is not the most efficient way to handle user input (I'm still tweaking ways to handle input that is unexpected), so I'm 100% open to criticism. This was just my initial way of handling it and I'd like to try to make it work. I have a few other verbs ('go', 'look', 'take', etc.) that work, I'm just having a lot of trouble with 'eat'.
def user_input(self):
player = Player()
while True:
user_input = input("> ").lower()
words = user_input.split(" ")
wordlist = list(words)
verb = wordlist[0]
if len(wordlist) == 2:
noun = wordlist[1]
if noun not in items:
print("Somehow '{}' isn't the right word.".format(noun))
continue
else:
pass
# The above works fine because I don't have
# an issue with any of the other verbs regarding
# that bit of code.
# There's more code between these blocks to:
# handle if the user enters a noun that is > 1 word,
# define a few more verbs,
# then,
if verb == "eat":
for item in player.inventory:
if item.name == noun:
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
break
else:
print("You can't eat that!")
break
else:
print("You don't have '{}'.".format(noun))
I had to use the for loop (at least, I think I had to) because I'm iterating over a list that has objects in them, not strings, so I couldn't just use
if noun in player.inventory:
(I still tried it a million times though, it took forever to come up with a solution for that problem). Here's my specific example for the code above:
class Fists(Weapons):
def __init__(self):
self.name = "fists"
# more instance variables for Fists()
class LeatherWallet(Classy):
def __init__(self):
self.name = "leather wallet"
# more ...
class Pizza(Consumable):
def __init__(self):
self.name = "pizza"
# more ...
class Player():
def __init__(self):
self.inventory = [Fists(), LeatherWallet(), Pizza()]
# other stuff
*eat fists
You can't eat that!
*eat leather wallet
You don't have 'leather wallet'.
You can't eat that!
*eat pizza
You don't have 'pizza'.
You don't have 'pizza'.
You eat the pizza.
From the looks of it, it has got to be a simple fix, because it's clear what's happening as it iterates over the list. I just don't know how to (or if you can) wrangle a for loop to make it check conditions first then print later. At the risk of sounding dumb, I turn to you all for help!
Thank you, and please let me know if I can make this question/my goal any clearer.
Edit:
Tried to make the goal a little clearer in opening paragraphs.
You're not saying what you want the output to be, but my best guess is you don't want to say "you don't have X" more than once.
One way to do this is to use a flag, initialized to false, set to true when you find the item. When you get out of the loop the flag will tell you if you found it.
Something like this:
if verb == "eat":
found = false
for item in player.inventory:
if item.name == noun:
found = true
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
break
else:
print("You can't eat that!")
break
if !found:
print("You don't have '{}'.".format(noun))
for loops have else clauses that are run if the loop doesn't exit with a break. The idea is that the loop is looking for an item, will break when it finds it, and the else clause handles the default case where you don't find what you're looking for. The variables used inside the loop are still valid after the loop ends so the found (or defaulted) variable can be used in the next bit of code.
In your case, if you move that final else clause out one level, it will only run if the item is not found. In your example output, the two "you don't have 'pizza1" lines will no longer be printed.
for item in player.inventory:
if item.name == noun:
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
break
else:
print("You can't eat that!")
break
else:
print("You don't have '{}'.".format(noun))
item = None # <-- you can give a default value if you want to
# use the variable later
Looping through the list is okay until the list gets large. Then you are better off indexing the list with a dict for faster lookup.
self.inventory = dict((item.name, item)
for item in (Fists(), LeatherWallet(), Pizza()))
Then the for loop is replaced with
try:
item = player.inventory[noun]
if isinstance(item, Consumable):
print("You eat the {}.".format(noun))
else:
print("You can't eat that!")
except KeyError:
print("You don't have '{}'.".format(noun))
So, another approach is to just make this work, right?
if noun in player.inventory:
...
You have (at least) two ways to do it.
List comprehension
The first and easy one is using a list comprehension:
inventory_items = [item.name for name in player.inventory]
if noun in inventory_items:
...
That's it.
Custom class
The second one is creating an Inventory class inheriting from list and overriding the __contains__ method so you can compare them however you want.
Something like:
class Inventory(list):
def __contains__(self, item):
"""
Override `list.__contains__`.
"""
# First, check whether `item` is in the inventory.
#
# This is what a normal `list` would do.
if list.__contains__(self, item):
return True
# If we couldn't find the item in the list searching
# the "normal" way, then try comparing comparing it
# against the `name` attribute of the items in our
# inventory.
for inventory_item in self:
# Ensure we can do `inventory_item.name` so we don't get
# an AttributeError.
if 'name' not in dir(inventory_item):
continue
if inventory_item.name == item:
return True
return False
Then you instantiate your inventory like:
self.inventory = Inventory([Fists(), LeatherWallet(), Pizza()])
Remember that Inventory inherits from list, so if you can do list(x) then you should also be able to do Inventory(x) and get a very similar result (depending on how much you override in your class).
You could also get creative and make all items inherit from an Item class where you define the __eq__ method and make Pizza() == 'pizza' to simplify the Inventory comparisons.