I am a beginner in Python and I am trying to understand trees better. Why can't I add nodes inside the function f below? I would expect that the final print returns the value 2 instead of an error that f(test) in None.
class Testcls(object):
def __init__(self,data):
self.data= data
self.children = []
def add_child(self,obj):
self.children.append(obj)
def f(test):
data1 = test.data+1
test.add_child(Testcls(data1))
test = Testcls(1)
print f(test).data
Final print in your case should actually return an error. Function f doesn't return anything (hence the None if you type print f(test). To add children using f you can add a return statement:
def f(test):
data1 = test.data+1
test.add_child(Testcls(data1))
return test
Which now returns the object test which you can further access and process,
f(test)
print test.children[0].data
Since it actually returns the test object you can also call it and use it directly:
print (f(test).children)[0].data
You don't have to have a return statement either - f will still change the object you're sending to it. In case you don't want to return the object, you just need to call the function separately and only then use test like shown in the second code snippet.
Related
I'm practicing leetcode problems to perfect my kotlin syntax and am wondering why this code doesn't work. My question specifically is why doesn't my courses hashmap populate with this code.
Prerequisites is an array in this form [[0,1][0,3][4,5][6,7]] and if I print my variables for pre and post they print what I expect
But I'm trying to turn courses into an adjacency matrix like this {0: [1,3], 4: [5], 6: [7]}
and instead it just prints an empty set every time
class Solution {
fun canFinish(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
val courses = HashMap<Int, MutableList<Int>>().withDefault{ mutableListOf<Int>() }
for ((pre, post) in prerequisites){
courses[pre]?.add(post)
}
print(courses)
return false
}
}
stdout: {}
[] does not give you the default value
From the docs of withDefault:
This implicit default value is used when the original map doesn't contain a value for the key specified and a value is obtained with Map.getValue function
If you want to get the default value, you need to use getValue instead of the index operator.
Using the index operator, you would just get null and because of the the null-safe operator, the add operation would not even be executed.
If you take a look at the relevant source code, you can see that the funxtionality get is not changed when using .withDefault but only getOrImplicitDefault returns the default value.
Getting the default does not set anything
Furthermore, when accessing courses.getValue(pre) in the loop, the Map will be empty. Because of the withDefault, it will return a MutableList where you can add elements but getting such a list and adding elements to it will not add the list to the Map. Reading and accessing an element does not insert it.
Simple solution
If you want to make sure the element is present in the Map, you can use courses[pre]=course.getValue(pre) before reading courses[pre]?:
class Solution {
fun canFinish(numCourses: Int, prerequisites: Array<IntArray>): Boolean {
val courses = HashMap<Int, MutableList<Int>>().withDefault{ mutableListOf<Int>() }
for ((pre, post) in prerequisites){
courses[pre] = courses.getValue(pre)
courses[pre]?.add(post)
}
print(courses)
return false
}
}
If the entry is set already, it will be set to itself (no change) and if it isn't set, it will be set to the default value (empty list).
dan1st's answer covers it - your default list is just returned, not put and returned, so it's not part of the map - but here's a different take to get that functionality:
val courses = HashMap<Int, MutableList<Int>>().run {
withDefault{ key ->
mutableListOf<Int>().also { put(key, it) }
}
}
So basically using the withDefault wrapper, using run so the map is this in the default value function, so you can add your list to the map before returning it. Then when you call courses.getValue(69) you'll get back a list that's already been inserted into the map
If you like, there's also a function that'll do this grouping for you, groupBy
val nums = arrayOf(
intArrayOf(0,1),
intArrayOf(0,3),
intArrayOf(4,5),
intArrayOf(6,7)
)
val groups = nums.groupBy(keySelector = { it[0] }, valueTransform = { it[1] })
println(groups)
>> {0=[1, 3], 4=[5], 6=[7]}
I'm really at a loss here. I need to pass arguments to the wrapper; these arguments change with runtime. Any idea how this could be solved using wrappers for classes?
def wrapper(x=None):
def decorate(cls):
def fct(self):
print('wrapper argument is: %s' % x)
cls.fct = fct
return cls
return decorate
a = 'first'
#wrapper(x=a)
class Test():
pass
test = Test()
test.fct() # Prints: first
a = 'second'
test.fct() # Prints: first (instead of second)
I can't put code in a comment, so here's how you'd do it.
def wrapper(x=None):
def decorate(cls):
def fct(self):
print('wrapper argument is: %s' % x[0])
cls.fct = fct
return cls
return decorate
a = ['first']
#wrapper(x=a)
class Test():
pass
test = Test()
test.fct() # Prints: first
a[0] = 'second'
test.fct() # Prints: second
The key is that strings are immutable, whereas lists are mutable. When you pass in a string, it's basically copied. When you pass in a list, you're sort of passing a reference to the original list, which is itself mutable.
I would like to apply a function to all objects in a list, where all objects in the list inherit from a common class. In this function, I would like to use an implicit class to ensure that the correct operation is applied based on the object's type.
For example, I want to ensure that all Employee objects in a list are converted using the employeeConverter below. Calling convert with the Employee directly works just fine, but applying convert to a list of Employee objects is a compiler error.
import scala.reflect.ClassTag
object Example {
abstract class Person { def age: Int }
case class Employee(age: Int) extends Person
class Converter[T] { def convert(t: T) = (t,t) }
def convert[T <: Person:ClassTag](p: T)(implicit converter: Converter[T]) =
converter.convert(p)
def main(args: Array[String]): Unit = {
implicit val employeeConverter = new Converter[Employee]()
println(convert(Employee(1)))
//println(List(Employee(2)) map convert) // COMPILER ERROR
}
}
The above code correctly prints the following:
$ scalac Example.scala && scala Example
(Employee(1),Employee(1))
However, if I uncomment the line indicated with COMPILER ERROR, I get this compiler error:
Example.scala:20: error: could not find implicit value for parameter converter: Example.Converter[T]
println(l map convert)
^
Is this a problem that can be resolved using ClassTag? How can I modify this example to apply convert to a list?
The compiler needs a little bit of hand-holding in this case. This works:
println(List(Employee(2)) map { e => convert(e) })
I have a custom class called Values that is a wrapper of arrays. For a given object vFoo of class Values, which contains an array of objects of class Foo, the var format -T vFoocommand returns the following structure:
(MyNameSpace::Values) vFoo = {
(void *) p = 0x0000000100204378
(size_t) n = 2
(MyNameSpace::ValueType) type = FOO
}
where vFoo.p is a pointer to the array<Foo> that contains 2 elements. I can access the array elements with the following command in the lldb prompt:
expression ((MyNameSpace::Foo*)vFoo.p)[0]
which returns
(MyNameSpace::Foo) $0 = "foo"
according to my summary provider.
I would like to write a synthetic child provider that returns something like:
(MyNameSpace::Values) vFoo = {
(MyNameSpace::Foo) vFoo.p[0] = "foo"
(MyNameSpace::Foo) vFoo.p[1] = "bar"
}
Unfortunately, I have no idea how to do that. I read the lldb data formatters page and try to follow the structure given at the end of the page. I have also had a look at the bitfield and libcxx examples, but I can't find my way to the solution. Any help would be deeply appreciated!
Many thanks in advance
You need to get the internal representation of the type Foo. You can get this from the SBModule using self.valobj.GetFrame().GetModule().FindFirstType("Foo"). Something like this will work with some poking around.
class Values_SynthProvider:
def __init__(self, valobj, dict):
self.valobj = valobj
self.num_elements = None
def update(self):
self.num_elements = self.valobj.GetChildMemberWithName('n').GetValueAsUnsigned(0)
def num_children(self):
return self.num_elements
def get_child_at_index(self,index):
# Here you could switch on the value of Values::type to get the right type name to search for
foo_type = self.valobj.GetFrame().GetModule().FindFirstType("Foo")
return self.valobj.GetChildMemberWithName('p').Cast(foo_type.GetPointerType()).GetChildAtIndex(index,0,True)
def get_child_index(self,name):
return int(name.lstrip('[').rstrip(']'))
I'm having a problem in calling a function that returns a result, from another function
To make it clear, my functions are:
def calculate_questions_vote(request):
useranswer = Answer.objects.filter (answer_by = request.user)
positive_votes = VoteUpAnswer.objects.filter(answer = useranswer)
negative_votes = VoteDownAnswer.objects.filter(answer = useranswer)
question_vote_rank = sum(positive_votes) - sum(negative_votes.count)
return question_vote_rank
def calculate_replies(request):
the_new = News.objects.filter(created_by = request.user)
reply = Reply.objects.filter(reply_to = the_new)
reply_rank = sum(reply)
return reply_rank
and I want to call them in another function, so that it could return a value.
I'm calling the function form another function like this:
rank = calculate_questions_vote
Let's say I just want for now to display the value returned by the function calculate_questions_vote.
Of course, I'm putting the rank variable in the context of the function.
My problem is that my output is:
<function calculate_questions_vote at 0x9420144>
How can I actually make it display the value returned by the function, instead of that string?
This is basic Python. What you are doing is simply referring to the function - assigning the function itself to another variable. To actually call a function, you need to use parenthesis after its name:
calculate_questions_vote()
In your case, you've defined that function as needing the request object, so you need to use that in the call as well:
calculate_questions_vote(request)
you need to pass a request object to calculate_questions_vote like:
rank = calculate_questions_vote(request)