I am slightly confused by the output of this program:
class Test(object):
a = None
b = None
def __init__(self, a):
print self.a
self.a = a
self._x = 123;
self.__y = 123;
b = 'meow'
The Outputs for the following lines are what confuse me:
instance = Test(3) #Output is None
print Test.a #Output is None
print instance.a #Output is 3. Why does this print 3?
I am struggling with why print Instance.a prints 3 and the other two lines don't.
Thanks
instance = Test(3) #Output is None
This is None, because you print self.a before it has been assigned.
print Test.a #Output is None
This is None b because you are printing A in the Class, which hasn't been initialized yet so only the a = None of the class definition has been processed.
print instance.a #Output is 3. Why does this print 3?
this prints 3, because you are calling it on the instance of the Test class that you created with the first call. __init__ has been run, and modified self.a to be the 3 that you provided (it is different from above since calling Test.a, the __init__ method isn't called, so you get your assignment from the class definition
Usually one write instances lowercase (i fixed it).
In order reading your program.
entering init.
I should printing self.a:
Does the current instance have an a attribute ? no.
Ok, look at the types, then.
Does the Test usually have a a attribute? Yes, it's None.
Ok, print None
set self.a to 3.
Does this instance have a attribute? no.
ok create it and give it the value 3.
What the default a values for Test object ? it's None. Print it.
What the value of a for this instance? it's 3.
Take a more human example.
Usually unamed people are named John Doe.
Someone unconscious enter an hospital at 8am. What's his name? (don't know, let's write "John Doe")
What's the name of the person that enter at 8 ? "John Doe"
He woke up, hey what's your name ? I'm Bob.
What's the name of the person that enter at 8 ? "Bob"
When someone unconscious enter the hospital, what's his name ? "John Doe" (didn't changed to "Bob")
If another patient enter and her Id is "Alice", what's her name ? Probably "Alice"
Related
There are both placeholder variables and topic variables in Perl 6. For example, the following two statements are the same
say ( $_ * 2 for 3, 9 ); # use topic variables
say ( { $^i * 2 } for 3, 9 ); # use placeholder variables
It seems to me, the only benefit one gets from topic variables is saving some keyboard strokes.
My question is: Is there a use case, where a topic variable can be much more convenient than placeholder variables?
The topic can have method calls on it:
say ( .rand for 3,9);
Compared to a placeholder:
say ( {$^i.rand} for 3,9);
Saves on typing a variable name and the curly braces for the block.
Also the topic variable is the whole point of the given block to my understanding:
my #anArrayWithALongName=[1,2,3];
#anArrayWithALongName[1].say;
#anArrayWithALongName[1].sqrt;
#OR
given #anArrayWithALongName[1] {
.say;
.sqrt;
}
That's a lot less typing when there are a lot of operations on the same variable.
There are several topic variables, one for each sigil: $, #, %_ and even &_ (yep, routines are first-class citizens in Perl6). To a certain point, you can also use Whatever (*) and create a WhateverCode in a expression, saving even more typing (look, ma! No curly braces!).
You can use the array form for several variables:
my &block = { sum #_ }; say block( 2,3 )
But the main problem they have is that they are single variables, unable to reflect the complexity of block calls. The code above can be rewritten using placeholder variables like this:
my &block = { $^a + $^b }; say block( 2,3 )
But imagine you've got some non-commutative thing in your hands. Like here:
my &block = { #_[1] %% #_[0] }; say block( 3, 9 )
That becomes clumsy and less expressive than
my &block = { $^divi %% $^divd }; say block( 3, 9 ); # OUTPUT: «True»
The trick being here that the placeholder variables get assigned in alphabetical order, with divd being before divi, and divi being short for divisible and divd for divided (which you chould have used if you wanted).
At the end of the day, there are many ways to do it. You can use whichever you want.
So, I'm trying to set a variable in my main program to an integer input from a function in a module. I can't work out how to do this.
This is my main program. Menu is the name of my module, as I'm using it to display a menu. 'menulist' is where you say what you want the menu to display. That part works OK.
import time, sys
from menu import *
menulist = ['Say hi', 'Say bye', 'Say yes', 'Say no', 'Exit']
choice = int(0)
menu(menulist)
choosing(menulist, choice)
print(choice) ##This is so I can see what it is
if choice == 1:
print('Say hi')
elif choice == 2:
print('Say bye')
elif choice == 3:
print('Say yes')
elif choice == 4:
print('Say no')
elif choice == 5:
sys.exit()
else: ##This will print if choice doesn't equal what I want
print('Error')
This is my module.
import time
def menu(menulist):
print('Menu:')
time.sleep(1)
x = 0
while x < len(menulist):
y = x + 1
printout = ' ' + str(y) + '. ' + menulist[x]
print(printout)
x = x + 1
time.sleep(0.3)
time.sleep(0.7)
print('')
def choosing(menulist, choice):
flag = True
while flag:
try:
choice = int(input('Enter the number of your choice: '))
time.sleep(0.8)
if choice < 1 or choice > len(menulist):
print('That wasn\'t an option sorry')
time.sleep(1)
else:
flag = False
except ValueError:
print('That wasn\'t an option sorry')
time.sleep(1)
The menu function works fine, and the choosing function almost does what I want it to, but it won't set 'choice' in my main program to the input when I call it from my module. Sorry if it's something blatantly obvious, I'm pretty new to programming. Thanks
Your module doesn't recognise choice as a global variable. Inside def choosing(...), choice is simply a local variable that gets assigned the value of your input (converted to an int).
You do pass choice to choosing, but since you've set choice to 0 before that, it is an immutable variable, and Python has (behind the scenes) created a local copy. So for all matters, choice is a local variable inside choosing.
Once your program leaves the function choosing, the variable and its value simply disappear (for all practical purposes).
To solve this, you shouldn't attempt to make choice global: generally, that is bad design (plenty of exceptions, but still, don't).
Instead, you can simply return choice from the function, and assign it in your main program. Relevant part of your module:
def choosing(menulist):
while True:
try:
choice = int(input('Enter the number of your choice: '))
time.sleep(0.8)
if choice < 1 or choice > len(menulist):
print('That wasn\'t an option sorry')
time.sleep(1)
else:
break
except ValueError:
print('That wasn\'t an option sorry')
time.sleep(1)
return choice
(I made a slight alteration here: you can simply use the break statement to break out of the continous while loop, instead of the extra flag variable.)
Note: there is no need to assign an initial value to choice: the function is structured to it always has to pass through the line choice = int(.... That, or it exist with an exception other than ValueError.
The relevant part of your main program:
import time, sys
from menu import *
menulist = ['Say hi', 'Say bye', 'Say yes', 'Say no', 'Exit']
menu(menulist)
choice = choosing(menulist)
Together with my above note: no need for an initial value of choice.
Finally: see how choice has disappeared from the parameters in the function, both in the call to and the definition of choosing.
That last point suggest to me that you might be coming from a different programming language. In Python, it is rare to pass a parameter to a function to have it altered. You simply return it, because that is easy and clearer. In you have multiple variables to alter, you can for example return a tuple: return a, b, c. Or a dict, or whatever you fancy (but the tuple is the starting point for multiple return values).
I have the following problem:
prolog prog:
man(thomas, 2010).
man(leon, 2011).
man(thomas, 2012).
man(Man) :- once(man(Man, _).
problem:
?- man(thomas).
true ; %i want only on true even if there are more "thomas" *working because of once()*
?- man(X).
X = thomas ; %i want all man to be listed *isn't working*
goal:
?- man(thomas).
true ;
?- man(X).
X = thomas ;
X = leon ;
X = thomas ;
I do unterstand why this happens, but still want to get the names of all man.
So my solution woud be to look if "Man" is initialized, if yes than "once.." else then... something like that:
man(Man) :- (->check<-,once(man(Man, _)); man(Man, _).
On "check" shoud be the code sniped that checks if the variable "Man" is filled.
Is this possible?
One way to achieve this is as follows:
man(X) :-
(nonvar(X), man(X, _)), !
;
man(X, _).
Or, more preferred, would be:
man(X) :-
( var(X)
-> man(X, _)
; once(man(X, _))
).
The cut will ensure only one solution (at most) to an instantiated X, whereas the non-instantiated case will run its course. Note that, with the cut, you don't need once/1. The reason once/1 doesn't work as expected without the cut is that backtracking will still come back and take the "or" condition and succeed there as well.
man(X) :-
setof(t,Y^man(X,Y),_).
Additionally to what you are asking this removes redundant answers/solutions.
The built-in setof/3 describes in its last argument the sorted list of solutions found in the first argument. And that for each different instantiation of the free variables of the goal.
Free variables are those which neither occur in the first argument nor as an existential variable – the term on the left of (^)/2.
In our case this means that the last argument will always be [t] which is uninteresting. Therefore the _.
Two variables occurring in the goal are X and Y. Or, to be more precise the variables contained in X and Y. Y is an existential variable.
The only free variable is X. So all solutions for X are enumerated without redundancies. Note that you cannot depend on the precise order which happens to be sorted in this concrete case in many implementations.
Okay, so I'm trying to have the program do three steps...
1: choose a number between (m,n) which are parameters being passed in (Set to variable "repeat")
2: choose a random number between 0 and the variable "repeat" from step one. (Set to variable "o")
3: subract "o" from "repeat" and set that result to variable "p"
thus I get a number (lets say 100)
then a random number from 0-100 (lets say 40)
and then I get the difference of 100-40 (60...)
I then want the program to run a for loop "o" (40) times and another for loop "p" (60) times...
the code for the for loops section looks like this (keep in mind there is more code before this... It just doesn't really pertain to this question:
def randomStars(pic,m,n):
repeat=random.randint(200,300)
o=random.randint(0,repeat)
p=repeat-o
for i in o:
star(pic,x,y)
for j in p:
largeStar(pic,x,y)
show(pic)
What's happening is I'm getting an error message on the line:
for i in o:
that says "iteration over non-sequence
inappropriate argument type
I've also added print statements after the 3 variables are set and they are working...
ex.1 repeat=230; o=103; p=127
ex.2 repeat=221; o=72; p=149
and then I immediately try to get the for loop to run "o"number of times and I get the above error message... I don't see how it is a non-sequence. But perhaps I'm simply not understanding the definition of a sequence
o and p are integers. For for loops you need something that is iterable. I thing you can change it to:
for i in range(o):
This is range() documentation for Python 2.x
Not sure that the example (nor the actual usecase) qualifies as NP-Complete, but I'm wondering about the most Pythonic way to do the below assuming that this was the algorithm available.
Say you have :
class Person:
def __init__(self):
self.status='unknown'
def set(self,value):
if value:
self.status='happy'
else :
self.status='sad'
... blah . Maybe it's got their names or where they live or whatev.
and some operation that requires a group of Persons. (The key value is here whether the Person is happy or sad.)
Hence, given PersonA, PersonB, PersonC, PersonD - I'd like to end up a list of the possible 2**4 combinations of sad and happy Persons. i.e.
[
[ PersonA.set(true), PersonB.set(true), PersonC.set(true), PersonD.set(true)],
[ PersonA.set(true), PersonB.set(true), PersonC.set(true), PersonD.set(false)],
[ PersonA.set(true), PersonB.set(true), PersonC.set(false), PersonD.set(true)],
[ PersonA.set(true), PersonB.set(true), PersonC.set(false), PersonD.set(false)],
etc..
Is there a good Pythonic way of doing this? I was thinking about list comprehensions (and modifying the object so that you could call it and get returned two objects, true and false), but the comprehension formats I've seen would require me to know the number of Persons in advance. I'd like to do this independent of the number of persons.
EDIT : Assume that whatever that operation that I was going to run on this is part of a larger problem set - we need to test out all values of Person for a given set in order to solve our problem. (i.e. I know this doesn't look NP-complete right now =) )
any ideas?
Thanks!
I think this could do it:
l = list()
for i in xrange(2 ** n):
# create the list of n people
sublist = [None] * n
for j in xrange(n):
sublist[j] = Person()
sublist[j].set(i & (1 << j))
l.append(sublist)
Note that if you wrote Person so that its constructor accepted the value, or such that the set method returned the person itself (but that's a little weird in Python), you could use a list comprehension. With the constructor way:
l = [ [Person(i & (1 << j)) for j in xrange(n)] for i in xrange(2 ** n)]
The runtime of the solution is O(n 2**n) as you can tell by looking at the loops, but it's not really a "problem" (i.e. a question with a yes/no answer) so you can't really call it NP-complete. See What is an NP-complete in computer science? for more information on that front.
According to what you've stated in your problem, you're right -- you do need itertools.product, but not exactly the way you've stated.
import itertools
truth_values = itertools.product((True, False), repeat = 4)
people = (person_a, person_b, person_c, person_d)
all_people_and_states = [[person(truth) for person, truth in zip(people, combination)] for combination in truth_values]
That should be more along the lines of what you mentioned in your question.
You can use a cartesian product to get all possible combinations of people and states. Requires Python 2.6+
import itertools
people = [person_a,person_b,person_c]
states = [True,False]
all_people_and_states = itertools.product(people,states)
The variable all_people_and_states contains a list of tuples (x,y) where x is a person and y is either True or False. It will contain all possible pairings of people and states.