I have a small problem with string formatting. I want to substitute {} for answers. When I change answers, Thing will correctly store the new_answer but incorrectly print it. It will somehow only print the first character!
What's going on here? I'm really confused..
class Thing(object):
def __init__(self,sentence,answer=None):
self.sentence = sentence
self.blanks = sentence.count("{}")
self.answer = (answer if answer else "___" for i in range(0,self.blanks))
def __str__(self):
return self.sentence.format(*self.answer)
def changeAnswer(self,new_answer):
self.answer = new_answer
def returnAnswer(self):
return self.answer
def test():
thang = Thing("Please put it in the {}.")
print thang # Please put it in the ___.
thang.changeAnswer("BLANK")
print thang # Please put it in the B.
print thang.returnAnswer() # BLANK
test()
You used a generator when you first initialized self.answer, but you used a string in changeAnswer. By using argument unpacking, you unpack the generator of strings into individual strings, but you end up unpacking a string into the individual characters.
Something like this should fix it (namely the changes to changeAnswer):
class Thing(object):
def __init__(self, sentence, answer=None):
self.sentence = sentence
self.num_blanks = sentence.count("{}")
self.answer = [answer or "___"] * self.num_blanks
def __str__(self):
return self.sentence.format(*self.answer)
def changeAnswer(self, new_answer):
self.answer = [new_answer] * self.num_blanks
def returnAnswer(self):
return self.answer
def test():
thang = Thing("Please put it in the {}.")
print thang # Please put it in the ___.
thang.changeAnswer("BLANK")
print thang # Please put it in the B.
print thang.returnAnswer() # BLANK
if __name__ == '__main__':
test()
Also, I would avoid methods like returnAnswer.
Related
I have a text file a.txt. I want to perform some preprocess on it like remove punct. and split it into words.
I have written the following code to perform few operations.
class pre:
def __init__(self,textfilepath):
self.textfilepath = textfilepath
def __str__(self,textfilepath):
return str(textfilepath)
def process(textpathfile):
with open(textpathfile, r) as abc:
a = abc.translate(string.maketrans("",""), string.punctuation)
a = a.split(' ')
return a
pre("a.txt")
I tried executing it.But it gave an error pre doesn't take arguments. Can any one help me with how to do this? Thanks all.
You shouldn't pass arguments to __str__. Instead you can access them through the properties of self:
class pre:
def __init__(self,textfilepath):
self.textfilepath = textfilepath
def __str__(self):
return self.textfilepath
def process(self):
with open(self.textfilepath, r) as abc:
a = abc.translate(string.maketrans("",""), string.punctuation)
a = a.split(' ')
return a
p = pre("a.txt")
print(p)
filedata = p.process()
print(filedata)
i have made a program but the output that i'm getting is
(<q3v3.Student instance at 0x023BB620>, 'is doing the following modules:', ' <q3v3.Module instance at 0x023BB670> <q3v3.Module instance at 0x023BB698>')
For example , the above output should give me Alice is doing following module : biology, chemistry
Help
this is my full code:
class Student :
def __init__(self,students):
self.students= students
print self.students
#def __str__(self): # when i used this i've got error type TypeError: __str__ returned non-string (type NoneType)
#print str(self.students)
class Module:
def __init__(self,modules):
self.modules = modules
print self.modules
#def __str__(self):
#print str(self.modules)
class Registrations (Student,Module):
def __init__(self):
self.list= []
self.stulist = []
self.modulist= []
def __iter__(self):
return iter(self.list)
def __str__(self):
return str(self.list)
def add(self,students,modules):
self.list.append((students,modules))
#print (self.list)
def students(self,modules):
for i in self.list:
if i[1] == modules:
self.modulist.append((i[0]))
return iter(self.modulist)
def __str__(self):
return str(self.students)
def modules(self,students):
for i in self.list:
if i[0] == students:
self.stulist.append((i[1]))
return iter(self.stulist)
def __str__(self):
return str(self.modules)
i need to import my program to be able to run it to this :
from q3v4 import *
james = Student('james')
alice = Student('alice')
mary = Student('mary')
agm = Module('agm')
ipp = Module('ipp')
r = Registrations()
r.add(james,agm)
r.add(alice,agm)
r.add(alice,ipp)
mstr = ''
for m in map(str,r.modules(alice)):
mstr = mstr+' '+m
print(alice, 'is doing the following modules:', mstr)
sstr = ''
for s in map(str,r.students(agm)):
sstr = sstr+' '+s
print(agm, 'has the following students:', sstr)
print(r)
You could define a __str__ method in your Student class, and do something like this:
def __str__(self):
return self.name # Here the string you want to print
Are you using Python 2? If so, print is a keyword, not a function. There are two ways to solve your problem:
Write print foo, bar instead of print(foo, bar).
The difference is that print(foo, bar) is actually printing out the tuple (foo, bar), which uses the repr() representation of each element, rather than its str().
At the very top of your file, write from __future__ import print_function. This will magically convert print from a keyword into a function, causing your code to work as expected.
If you are using Python 3, my answer is irrelevant.
I want to change the function name according to result obtained from another function but the function definition remains same How can i do this i tried the following example but it didn't work
def f(text):
def x(text):
return text+"example"
name=x(text)
def name(y):
return y
return name
p=f("hi ")
print p("hello")
print p.__name__
OUTPUT
hello
name
But i want the function name p.__name__ as "hi example" not name
You can simply assign to __name__:
def f(text):
def r(y):
return y
r.__name__ = text + "example"
return r
p = f("hi ")
print (p("hello")) # Outputs "hello"
print (p.__name__) # Outputs "hi example"
Note that a function name does not have any influence on the function's behavior though, and does not have any meaning except as a part of the string representation or a debugging aid.
I'm trying to learn programming through Python and I like to know if it's possible to get just the return value of a function and not its other parts. Here's the code:
Let's say, this is the main function:
variable_a = 5
while variable_a > 0 :
input_user = raw_input(": ")
if input_user == "A":
deduct(variable_a)
variable_a = deduct(variable_a)
else:
exit(0)
Then this is the deduct function:
def deduct(x):
print "Hello world!"
x = x - 1
return x
What happens is that, it does the calculation and deduct until variable_a reaches 0. However, "Hello world!" gets printed twice, I think because of variable_a = deduct(variable_a) (correct me if I'm wrong). So I was thinking, can I just capture the return value of deduct() and not capture the rest? So that in this instance, after going through deduct(), variable_a would just have a plain value of 2 (without the "Hello world!").
Am I missing things? :?
Editor's note: I remove the blank lines, so it can be pasted to REPL.
The printing of "Hello world" is what's known as a side effect - something produced by the function which is not reflected in the return value. What you're asking for is how to call the function twice, once to produce the side effect and once to capture the function return value.
In fact you don't have to call it twice at all - once is enough to produce both results. Simply capture the return value on the one and only call:
if input_user == "A":
variable_a = deduct(variable_a)
else:
If you don't want your function to print output, the correct solution is to not use print in it. :P
The first time you call deduct, it doesn't do anything except print that message, so you could probably just remove that line and be fine.
However, there is a slightly messy way to suppress print statements. You can temporarily replace your program's output file with a placeholder that does nothing.
import sys
class FakeOutput(object):
def write(self, data):
pass
old_out = sys.stdout
sys.stdout = FakeFile()
print "Hello World!" # does nothing
sys.stdout = old_out
print "Hello Again!" # works normally
You could even make a context manager to make this more convenient.
import sys
class FakeOutput(object):
def __enter__(self):
self.out_stdout = sys.stdout
sys.stdout = self
return self
def __exit__(self, *a):
sys.stdout = self.out_stdout
def write(self, data):
pass
print "Hello World!" # works
with FakeOutput():
print "Hello Again!" # doesn't do anything
print "Hello Finally!" # works
So I'm fairly new to Python but I have absolutely no idea why this strong oldUser is changing to current user after I make the parse call. Any help would be greatly appreciated.
while a < 20:
f = urllib.urlopen("SITE")
a = a+1
for i, line in enumerate(f):
if i == 187:
print line
myparser.parse(line)
if fCheck == 1:
result = oldUser[0] is oldUser[1]
print oldUser[0]
print oldUser[1]
else:
result = user is oldUser
fCheck = 1
print result
user = myparser.get_descriptions(firstCheck)
firstCheck = 1
print user
if result:
print "SAME"
array[index+1] = array[index+1] +0
else:
oldUser = user
elif i > 200:
break
myparser.reset()
I don't understand why result doesn't work either... I print out both values and when they're the same it's telling me they're not equal... Also, why does myparser.parse(line) turn oldUser into a size 2 array? Thanks!
** Here's the definition for myparse...
class MyParser(sgmllib.SGMLParser):
"A simple parser class."
def parse(self, s):
"Parse the given string 's'."
self.feed(s)
self.close()
def __init__(self, verbose=0):
"Initialise an object, passing 'verbose' to the superclass."
sgmllib.SGMLParser.__init__(self, verbose)
self.divs = []
self.descriptions = []
self.inside_div_element = 0
def start_div(self, attributes):
"Process a hyperlink and its 'attributes'."
for name, value in attributes:
if name == "id":
self.divs.append(value)
self.inside_div_element = 1
def end_div(self):
"Record the end of a hyperlink."
self.inside_div_element = 0
def handle_data(self, data):
"Handle the textual 'data'."
if self.inside_div_element:
self.descriptions.append(data)
def get_div(self):
"Return the list of hyperlinks."
return self.divs
def get_descriptions(self, check):
"Return a list of descriptions."
if check == 1:
self.descriptions.pop(0)
return self.descriptions
Don’t compare strings with is. That checks if they’re the same object, not two copies of the same string. See:
>>> string = raw_input()
hello
>>> string is 'hello'
False
>>> string == 'hello'
True
Also, the definition of myparser would be useful.
I'm not quite sure what your code is doing, but I suspect you want to use == instead of is. Using is compares object identity, which is not the same as string equality. Two different string objects may contain the same sequence of characters.
result = oldUser[0] == oldUser[1]
If you're curious, for more information on the behaviour of the is operator see Python “is” operator behaves unexpectedly with integers.