Why it tells me "NameError: name 'self' is not defined" when I run this code?
I don't know why it's all fine except the last block (update method) gives me that error anyone can help?
This code is a game that takes in the lenth of the hand and gives you a random letters to create a word from the hand ,when you enter an currect word, the letters used in the word get removed automaticlly till the words
import random
class Hand(object):
self.hand = {}
def __init__(self, n):
'''
Initialize a Hand.
n: integer, the size of the hand.
'''
assert type(n) == int
self.HAND_SIZE = n
self.VOWELS = 'aeiou'
self.CONSONANTS = 'bcdfghjklmnpqrstvwxyz'
# Deal a new hand
self.dealNewHand()
def dealNewHand(self):
'''
Deals a new hand, and sets the hand attribute to the new hand.
'''
# Set self.hand to a new, empty dictionary
self.hand = {}
# Build the hand
numVowels = self.HAND_SIZE // 3
for i in range(numVowels):
x = self.VOWELS[random.randrange(0,len(self.VOWELS))]
self.hand[x] = self.hand.get(x, 0) + 1
for i in range(numVowels, self.HAND_SIZE):
x = self.CONSONANTS[random.randrange(0,len(self.CONSONANTS))]
self.hand[x] = self.hand.get(x, 0) + 1
def setDummyHand(self, handString):
'''
Allows you to set a dummy hand. Useful for testing your implementation.
handString: A string of letters you wish to be in the hand. Length of this
string must be equal to self.HAND_SIZE.
This method converts sets the hand attribute to a dictionary
containing the letters of handString.
'''
assert len(handString) == self.HAND_SIZE, "Length of handString ({0}) must equal length of HAND_SIZE ({1})".format(len(handString), self.HAND_SIZE)
self.hand = {}
for char in handString:
self.hand[char] = self.hand.get(char, 0) + 1
def calculateLen(self):
'''
Calculate the length of the hand.
'''
ans = 0
for k in self.hand:
ans += self.hand[k]
return ans
def __str__(self):
'''
Display a string representation of the hand.
'''
output = ''
hand_keys = sorted(self.hand.keys())
for letter in hand_keys:
for j in range(self.hand[letter]):
output += letter
return output
def update(self, word):
"""
Does not assume that self.hand has all the letters in word.
Updates the hand: if self.hand does have all the letters to make
the word, modifies self.hand by using up the letters in the given word.
Returns True if the word was able to be made with the letter in
the hand; False otherwise.
word: string
returns: Boolean (if the word was or was not made)
"""
for i in word :
if self.hand.get(i , 0) == 0 :
return False
else :
self.hand[i] -=1
return True
I think it's this line:
self.hand = {}
at the top of your class that is the problem. There is no self at the point when the class is being defined. This line should be inside your __init__ method.
def __init__(self, n):
'''
Initialize a Hand.
n: integer, the size of the hand.
'''
self.hand = {}
# ... and the rest
Related
I got this code from a book name 'Data Structures and Algorithms in Python from Michael T. Goodrich ' chapter 5.5.1 Storing High Scores for a Game.
Can some one can explain to me what this self._board[-1].get_score( ) means ??
I try to print it to see what happens but I got:
print(self._board[-1].get_score( ))
AttributeError: 'NoneType' object has no attribute 'get_score'
class GameEntry:
def __init__(self, name, score):
self._name = name
self._score = score
def get_name(self):
return self._name
def get_score(self):
return self._score
def __str__(self):
return ('({0}, {1})'.format(self._name, self._score)) # e.g., (Bob, 98)
class Scoreboard():
def __init__(self, capacity=10):
self._board = [None]*capacity # reserve space for future scores
self._n=0 # number of actual entries
def __getitem__(self, k):
return self._board[k]
def add(self, entry):
score = entry.get_score()
print(score)
if self._n < len(self._board) or score > self._board[-1].get_score(): # what is it " self._board[-1].get_score()"
if self._n < len(self._board): # no score drops from list
self._n += 1 # so overall number increases
j = self._n - 1
while j > 0 and self._board[j-1].get_score( ) < score:
self._board[j] = self._board[j-1] # shift entry from j-1 to j
j -= 1 # and decrement j
self._board[j] = entry
def __str__(self):
return '\n' .join(str(self._board[j]) for j in range(self._n))
a_ = Scoreboard()
a = ('a','b','c','d')
b = (5,4,8,4)
c = dict(zip(a,b))
print(c)
for i,j in c.items():
x = GameEntry(i,j)
print(x)
y=a_.add(x)
print(y)
Inside your class Scoreboard you keep a list of game entries:
self._board = [None]*capacity # reserve space for future scores
This list is used to keep GameEntry entries:
self._board[j] = entry
The logic in your application uses ._n to track the number of entries added, but only up to total number of score slots available (self._n < len(self._board)).
If this is False (i.e. the number of entries added is the same as the capacity of the entry list when it was initialized), the other part of the or statement gets executed:
score > self._board[-1].get_score()
This looks at the last element in self._board - i.e. what is supposed to be the slot entry with the lowest score to see if this score deserves to be entered into the list instead of the previous one. Any negative list index starts from the end of the list instead of the wrong, so -1 points to the last entry, -2 the second to last entry, and so on.
If you get a None entry while running your code (and not just printing it out before you've added ten entries) is another question, and is probably what you need to debug further (but it doesn't seem to be the case from your code). If you attempt to print that entry before inserting all ten entries (i.e. filling up the entry list), there won't be an entry in last place, and the None placeholder will still be there.
can u help me to solve the following
am trying to get a string input from user, then push the string into the StackMachine so as to check the validity of the string. if the String passes the rules defined, the output string from the StackMachine is to be checked if its a palindrome or not ..this is what i have tried so far
note you can only use the function in the StackMachine class and not another method to determine the validity of the string. The condition to accept a string is that you have read all the input string and the stack is empty
```
class StackMachine(object):
SMRules = {} # dictionary of SM rules
def __init__(self):
self.Stack = ['S'] # populate stack with initial 'S'
self.size = 1 # set size of stack to 1
self.SMRules = {} # Place rules here
def pop(self):
if len(self.Stack) <1:
pass
else:
self.Stack.pop(0)
self.size-= 1 # reduce stack size by 1
return
def peek(self):
ss = ""
if len(self.Stack) < 1:
return ""
else:
ss = self.Stack
return ss[0]
def stackIsEmpty(self):
if len(self.Stack) == 0:
return True
else:
return False
def push(self,str):
sStr = str[::-1] # slicing
for chr in sStr:
self.Stack.insert(0,chr) # push string onto top of stack
self.size = len(self.Stack)
return
def printStack(self):
print("Stack: [",end='')
for item in self.Stack:
print(item,end='')
print("]")
return
def printRules(self):
print("SM Rules:")
rn = 1
for key, value in self.SMRules.items():
print("Rule",rn,"%4s" % key,"|", value)
rn += 1
return
def main():
Stk = StackMachine()
text =str(input('Please enter the string: '))
for character in text:
Stk.push(character)
reversed_text = ''
while not Stk.stackIsEmpty():
reversed_text = reversed_text + Stk.pop()
if text == reversed_text:
print('The string is a palindrome.')
else:
print('The string is not a palindrome.')
if __name__ == '__main__':
main()
Am getting the following Error and i dont know how to solve it
```
File "C:\Users\user\Stack-Machine\StackMachine.py", line 91, in main
reversed_text = reversed_text + Stk.pop()
TypeError: can only concatenate str (not "NoneType") to str`enter code here`
my question is
1.how do I solve the error?
2.how to print string chracter by character from the stackMachine
3.successfully check if the processed string from the Stack Machine is a palindrome or not
As defined, StackMachine.pop() returns None.
When you do reversed_text + Stk.pop(), even though reversed_text is a string, Stk.pop() is None, which causes the TypeError you are seeing.
Why do you need to use the so called StackMachine class to check if a string is a palindrome? There are simpler ways to check if a string is a palindrome.
If all you want to do is get a string input and determine whether it's a palindrome, you can do so like this:
text = input()
isPalindrome = text == text[::-1]
I want to search for specific characters in a string list. For example, string_list = ['sasasd']; I want to search for 'sa'. The linear function will return True, but I tried many times, It can not return True.
class String:
def __init__(self, str_value = []):
self.value = str_value
def search_data(self,target_value):
m = len(self.value)
for i in range(m):
if self.value[i] == target_value:
return True
return False
value_data = ['dasdasd']
my_str = String(value_data)
result = my_str.search_data('da')
print(result)
You have a few problems in your code.
str_value is a list and you initialize the value of the class attribute like this: self.value = str_value. So, when you give it the value ['dasdasd'], you end up having a list with one string element.
When declaring the m variable, m = len(self.value), you compute the number of elements from that list NOT the number of characters from the string value inside the list (m = len(['dasdasd']) = 1).
Also, the for that searches for the target_value string inside the self.value string is incorrect.
Quick fix to correct the current code:
class String:
def __init__(self, str_value = []):
self.value = str_value
def search_data(self, target_value):
# assumption here that self.value has the format: ['string'] (list with 1 string element)
if self.value[0].find(target_value) == 0:
return True
return False
value_data = ['dasdasd']
my_str = String(value_data)
result = my_str.search_data('da')
print(result)
Tested and it outputs True.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Context:
I have a class, in which I have to make a password protected something or other.
(My instructor is not very specific.) The reason for me asking for a method in which I could use a standard import statement was so I could just upload a single folder that only contained a text file and the program itself. I want to do something as follows:
#Import Statements Here
outFile = open('myFile.txt',"wt");
#Here is the tricky part.
#In place of all of these comments,
#I want to encrypt the file with a key given by a user(in this case,givenKey):
givenKey = input("Please input your key:>>>");
outFile.close();
Resolution:
The answer by Sasszem was the one that worked for me. Look into the comments
for a simplified explanation of the main answer. The person who gave me his/her custom made code (I cant remember who gave it to me, sorry.) had a good idea. But I don't like using code I don't understand. And finally, the person who gave me the Cryptography module as an idea wasn't wrong, but I use python on Windows.
A simple way to encrypt data is to add a constant to every byte.
You can generate some random byte from the pwd and then add it to every byte in the input. It won't be strong, but it's simple.
If you make something like your program generates random numbers to add to the bytes after seeding your pwd to the random generator, your instructor will be impressed.
To decode, simply subtract the same numbers from the bytes.
Package cryptography provides support for encryption/decryption: https://pypi.python.org/pypi/cryptography. I understand that it is included in Anaconda.
Here is a module I wrote a while back. It uses only built-in python modules. I give you permission to use it!
import string, random
class Round(object):
def __init__(self, *seqs):
self.position = 0
self.data = [i for x in seqs for i in x]
self.len = len(self.data)
def __repr__(self):
return str(self.data)
def __iter__(self):
self.position = 0
return self
def is_item(self, item):
if str(self.data[self.position]) == str(item):
return True
return False
def __getitem__(self, index):
if index < self.len-1 and index >= 0:
return self.data[index]
else:
while index < 0:
index += self.len-1
while index > self.len-1:
index -= self.len-1
return self.data[index]
def next(self):
if self.position >= self.len-1:
self.position = 0
raise StopIteration
else:
self.position += 1
return self.data[self.position-1]
class JCripter(object):
def __init__(self, string):
self.string = string
self.generate_key_set()
self.encrypted = False
def generate_key_set(self):
self.alphabet = list(string.ascii_lowercase)
self.numbers = [str(x) for x in range(10)]
self.special_characters = ['"',"'",',','?','.',
' ','(',')',':',';',
'!','#','#','$','%',
'^','&','*','_','-',
'+','=','<','>','~',
'`','{','[','}',']',
'\\','|']
self.key_base = Round(self.alphabet, self.numbers, self.special_characters)
def get_key_index(self, key):
for i in self.key_base:
if isinstance(key, int):
if i == self.key_base[key]:
return self.key_base.position-1
elif i == key.lower():
return self.key_base.position-1
else:
print 'not found'
def __repr__(self):
return self.string
def _encrypt(self, string, func, *args):
if string == None:
string = self.string
if string == None:
return
string = string.lower()
n_string = func(string, *args)
self.encrypted = not self.encrypted
self.string = n_string
return n_string
class CeaserCypher(JCripter):
def __init__(self, string, shift=None):
JCripter.__init__(self, string)
if shift == None:
self.shift = random.randint(0, self.key_base.len)
else:
self.shift = shift
def encrypt(self, string=None):
def inner(string):
n_string=''
for i in string:
if self.encrypted == True:
n_string += self.key_base[self.get_key_index(i)-self.shift]
else:
n_string += self.key_base[self.get_key_index(i)+self.shift]
return n_string
return self._encrypt(string, inner)
class PseudoRandomCypher(JCripter):
def __init__(self, string, shifts=None):
if shifts == None:
self.shift = [random.randint(0, 500) for x in string]
else:
self.shift = shifts
JCripter.__init__(self, string)
def encrypt(self, string=None):
def inner(string):
ind = 0
n_string = ''
for i in string:
if ind >= len(self.shift)-1:
ind = 0
if self.encrypted == True:
n_string += self.key_base[self.get_key_index(i)-self.shift[ind]]
else:
n_string += self.key_base[self.get_key_index(i)+self.shift[ind]]
ind += 1
return n_string
return self._encrypt(string, inner)
class PolyAlphabeticCypher(JCripter):
def __init__(self, string, key, enc=False):
JCripter.__init__(self, string)
self.key=list(key)
self.encrypted = enc
def encrypt(self, string=None):
def inner(string):
index = 0
n_string = ''
for i in string:
if index >= len(self.key)-1:
index = 0
if self.encrypted == True:
n_string += self.key_base[self.get_key_index(i)-self.get_key_index(self.key[index])]
else:
n_string += self.key_base[self.get_key_index(i)+self.get_key_index(self.key[index])]
index += 1
return n_string
return self._encrypt(string, inner)
n = 'Hello world my name is anonymous!'
p = PolyAlphabeticCypher(n, 'super_secret_password')
print p.encrypt() #--> returns encrypted data
print p.encrypt() #--> decrypts data
#if you are decrypting a previously encrypted text
n = 'Some sensitive data'
first = PolyAlphabeticCypher(n, 'some pass')
my_data = first.encrypt()
second = PolyAlphabeticCypher(my_data, 'some pass', True)
print second.encrypt()
I have a few problems I can't get over even after a few days of working on it.
A Toy has no instance variables and one method, play, which returns the string "Squeak!\n" (with the exclamation mark and the capital 'S', without spaces, and with a newline at the end). The constructor for Toy (its __init__ method) takes no parameter (except the usual self) and does nothing (so it can probably be omitted).
A Dog has one instance variable, its name, which must be provided as a parameter to the constructor. It has two methods:
call(self, shout) returns True if shout is exactly "Here, n!" (with the comma, the space and the exclamation mark, and no leading or trailing spaces), where n is the Dog's name. Otherwise, it returns False.
play(self, toy, n) produces the string "Yip! " (with the trailing space) concatenated with the the string returned by toy.play(). It returns this combination repeated n times, except if n is negative, it is the same as if it were 0. Clarification: "s" repeated 2 times is "ss". "s" repeated 0 times is "".
This is what i have:
class Toy:
def __init__(self):
pass
def play(self):
return "Squeak!\n"
class Dog:
def __init__(self, name):
self.name = name
def call(self, shout):
self.shout = shout
if self.shout == 'Here, ' + self.name + '!':
return True
return False
def play(self, toy, n):
self.toy = toy
self.n = n
if n <= 0:
print('')
else:
for i in range(n):
print('Yip ' + self.toy.play())
However, I get few errors such as this:
TestDog2.test_dog_fancy_toy
FAILURE: AssertionError
None != 'Yip! Ding, Dong!\n'
-
TestDog2.test_dog_play_once
FAILURE: AssertionError
None != 'Yip! Squeak!\n'
-
TestDog2.test_dog_play_zero_twice
ERROR: TypeError
Can't convert 'NoneType' object to str implicitly
In the Toy class, the play method return a string while the play method of Dog returns nothing (It just print stuff).
When you're calling dog.call() you don't get the 'Yip ' + self.toy.play() value in return. So the function returns None as expected and your assertion is wrong.
To fix that, you should return the value instead of print it.
For example, in your Dog.call() method:
if n <= 0:
return ''
else:
phrases = ['Yip ' + self.toy.play() for i in range(n)]
return '\n'.join (phrases)
phrases is a list constructed using list comprehension. It'll contains n elements, formed with the expression 'Yip ' + self.toy.play(). You just have to join every elements with \n to create a new line after each phrase and you're done.
#!/usr/bin/env python
class Toy:
def play(self):
return "Squeak!\n"
class Dog:
def __init__(self, name):
self.name = name
def call(self, shout):
if shout == 'Here, ' + self.name + '!':
return True
return False
def play(self, toy, n):
if n <= 0:
print('')
else:
for i in range(n):
print('Yip ' + toy.play())
dog = Dog("Spot") # Spot the dog
toy = Toy()
assert(toy.play() == "Squeak!\n")
assert(dog.call("Here, {0}!".format('Spot'), 'Here, Spot!')
Not sure exactly what your question is but that may help slightly?
Really we need more information to be able to help you here.