I am getting None type object error but I do not know how and why it is occuring? - class

so I am writing a code for a binary tree and for some functions regardnig it, I am having some trouble running the code and I cannot figure out why this error is occuring.
def insertelement(self,n):
newnode = Node(n)
itr = self.root
x = False
if itr == None:
self.root = newnode
elif itr != None :
while x is False:
if itr.data > n:
itr = itr.right
elif itr.data < n:
itr = itr.left
elif ((itr.right == None) and itr.data > n):
itr.right = newnode
elif ((itr.left == None) and itr.data < n):
itr.left = newnode
else :
return 0
def binarysearchfordatass(self,n):
pppointer = self.root
i = 0
while pppointer.data != n:
if pppointer.data < n:
pppointer = pppointer.left
i = i+1
else:
pppointer = pppointer.right
i = i+1
return i
when I run the following code I get an error message
if itr.data > n:
AttributeError: 'NoneType' object has no attribute 'data'
so here as u can see in the code I already have an if statement which makes self.root = newnode if self.root is None, however I dont why the elif loop below it will execute on self.root if it is none since if it were none the if statement above it would have been executed.
Can someone please help me understand why this error is occuring ?

You are running into an infinite loop as you have set x to False and you are never updating x within the loop, thus the while condition is always True.
And yes you are checking if itr == None first but then you go into this inifinite loop and you might possibly be setting itr to None again in the first iteration of the loop and in the second iteration it will consequently then fail.
This is theoretically possible but you could easily find out what is actually going on by debugging your code and stepping through it line-by-line.

Related

Scala3 inline if reuse result of function

val num = 3
val x = if (func(num) > 3) func(num) else 4
How can i avoid calling func(num) twice here? My project is fully functional so calling func(num) twice is guaranteed to yield the same result. Does the compiler optimize this automatically? I am aware of this:
val num = 3
val x = List(num).map(f(_)).map(a => if (a > 3) a else 4).head
EDIT: I'm looking for a way to improve this
val temp = tl.indexWhere(<bool>)
val insertIndex = if(temp == -1) tl.size else temp
The Scala compiler will generally not know if a function is pure, so it cannot perform that optimization automatically.
val temp = tl.indexWhere(???)
val insertIndex = if(temp == -1) tl.size else temp
Is very likely the clearest and (by explicitly preventing double evaluation) most performant expression of this logic. Assuming that temp is a local variable, the Scala compiler can see that it's not used later in your function/method and reuse the local variable slot.
Just in case you want to make it abundantly clear that the local variable is only used for this particular block of code, you could utilize … a block of code:
val insertIndex = { val temp = tl.indexWhere(<bool>); if (temp == -1) tl.size else temp }
or
val insertIndex = {
val temp = tl.indexWhere(<bool>)
if (temp == -1) tl.size else temp
}
As mentioned in another answer, Scala cannot, generally, know that tl.indexWhere is pure, since Purity Analysis is equivalent to solving the Halting Problem.
Not sure if this is an improvement but you can use pattern matching with guard:
val num = 3
val x = num match {
case v if v > 3 => v
case _ => 4
}
Or in second case simply:
val insertIndex = tl.indexWhere(...) match {
case -1 => tl.size
case v => v
}

trying to solve palindrome integer in python 3 code is working but giving wrong output

enter code here''' class Solution:
def isPalindrome(self, x: int) -> bool:
x = str(x)
lst = list(x)
str_val = []
count = len(lst)
for i in range(len(lst)):
str_val.append(lst[count-1])
count -= 1
value = [str(i) for i in str_val]
res = int("".join(value))
if int(res) == x:
return True
else:
return False
'''
trying to solve palindrome integer in python 3 code is working but giving wrong output.
If you're just trying to check for integers only, you can try the below code. It's a two pointer approach.
class Solution:
def isPalindrome(self, x: int) -> bool:
x = str(x)
if len(x) < 2: return True
s, e = 0, len(x)-1
while s < e:
if x[s] != x[e]: return False
s += 1
e -= 1
return True
You can also do this in one line in python to check if a number (as a string) and it's reverse is same or not.
str(x) == str(x)[::-1]
The reason your results are not as expected is due to the type change that you make in the first line of your function.
x = str(x)
It is necessary to convert x into a string so that you can iterate over it and put it into a list for your second line of code:
lst = list(x)
but by re-assigning that back to x, you get an x at the end of the function call that is not equal to the int(res) when you make the final comparison to get your boolean:
if int(res) == x:
A simple solution is to just not assign the temporary string that is created from the parameter x back to itself, and rather to just merge the first and second lines of your function into one:
lst = list(str(x))

unable to understand the else if statement in scala code below

I am pretty new to Scala and was going through the docs when I came across this code in the below link
https://www.scala-lang.org/old/node/135.html
def filter(xs: List[Int], p: Int => Boolean): List[Int] =
if (xs.isEmpty) xs
else if (p(xs.head)) xs.head :: filter(xs.tail, p)
else filter(xs.tail, p)
Can anyone please tell me what the else if line does?
The second parameter to the filter function p is a function that takes Int as a parameter and returns Boolean.
So, in the else if, it is calling the function p with xs.head which is first element from xs which is Int. If it returns true, it adds an element at the beginning of a list and returns a list with the added element.
To test this -
You can try two variations of p one which returns true when number is even and one which returns true when the number is odd and see what it prints.
val output = filter(List(1,2,3,4), (p) => p % 2 != 0);
print(output) // prints `List(1, 3)`
val output = filter(List(1,2,3,4), (p) => p % 2 == 0);
print(output) // prints `List(2, 4)`
Hope this helps!

Combine multiple sequential entries in Scala/Spark

I have an array of numbers separated by comma as shown:
a:{108,109,110,112,114,115,116,118}
I need the output something like this:
a:{108-110, 112, 114-116, 118}
I am trying to group the continuous numbers with "-" in between.
For example, 108,109,110 are continuous numbers, so I get 108-110. 112 is separate entry; 114,115,116 again represents a sequence, so I get 114-116. 118 is separate and treated as such.
I am doing this in Spark. I wrote the following code:
import scala.collection.mutable.ArrayBuffer
def Sample(x:String):ArrayBuffer[String]={
val x1 = x.split(",")
var a:Int = 0
var present=""
var next:Int = 0
var yrTemp = ""
var yrAr= ArrayBuffer[String]()
var che:Int = 0
var storeV = ""
var p:Int = 0
var q:Int = 0
var count:Int = 1
while(a < x1.length)
{
yrTemp = x1(a)
if(x1.length == 1)
{
yrAr+=x1(a)
}
else
if(a < x1.length - 1)
{
present = x1(a)
if(che == 0)
{
storeV = present
}
p = x1(a).toInt
q = x1(a+1).toInt
if(p == q)
{
yrTemp = yrTemp
che = 1
}
else
if(p != q)
{
yrTemp = storeV + "-" + present
che = 0
yrAr+=yrTemp
}
}
else
if(a == x1.length-1)
{
present = x1(a)
yrTemp = present
che = 0
yrAr+=yrTemp
}
a = a+1
}
yrAr
}
val SampleUDF = udf(Sample(_:String))
I am getting the output as follows:
a:{108-108, 109-109, 110-110, 112, 114-114, 115-115, 116-116, 118}
I am not able to figure out where I am going wrong. Can you please help me in correcting this. TIA.
Here's another way:
def rangeToString(a: Int, b: Int) = if (a == b) s"$a" else s"$a-$b"
def reduce(xs: Seq[Int], min: Int, max: Int, ranges: Seq[String]): Seq[String] = xs match {
case y +: ys if (y - max <= 1) => reduce(ys, min, y, ranges)
case y +: ys => reduce(ys, y, y, ranges :+ rangeToString(min, max))
case Seq() => ranges :+ rangeToString(min, max)
}
def output(xs: Array[Int]) = reduce(xs, xs.head, xs.head, Vector())//.toArray
Which you can test:
println(output(Array(108,109,110,112,114,115,116,118)))
// Vector(108-110, 112, 114-116, 118)
Basically this is a tail recursive function - i.e. you take your "variables" as the input, then it calls itself with updated "variables" on each loop. So here xs is your array, min and max are integers used to keep track of the lowest and highest numbers so far, and ranges is the output sequence of Strings that gets added to when required.
The first pattern (y being the first element, and ys being the rest of the sequence - because that's how the +: extractor works) is matched if there's at least one element (ys can be an empty list) and it follows on from the previous maximum.
The second is if it doesn't follow on, and needs to reset the minimum and add the completed range to the output.
The third case is where we've got to the end of the input and just output the result, rather than calling the loop again.
Internet karma points to anyone who can work out how to eliminate the duplication of ranges :+ rangeToString(min, max)!
here is a solution :
def combineConsecutive(s: String): Seq[String] = {
val ints: List[Int] = s.split(',').map(_.toInt).toList.reverse
ints
.drop(1)
.foldLeft(List(List(ints.head)))((acc, e) => if ((acc.head.head - e) <= 1)
(e :: acc.head) :: acc.tail
else
List(e) :: acc)
.map(group => if (group.size > 1) group.min + "-" + group.max else group.head.toString)
}
val in = "108,109,110,112,114,115,116,118"
val result = combineConsecutive(in)
println(result) // List(108-110, 112, 114-116, 118)
}
This solution partly uses code from this question: Grouping list items by comparing them with their neighbors

Stream find method - getting an out of memory

Can somebody help me with what I may be missing here:
def isDivisibleByRange(n: Int, r: Range) = {
r.forall(n % _ == 0)
}
def from(n: Int): Stream[Int] = n #:: from(n + 1)
Now, the following gives me an OOM:
val o = from(1).find(isDivisibleByRange(_, Range(2, 21)))
There is nothing wrong with your code, the problem is with Stream.find, or rather the find in LinearSeqOptimized where the method is inherited from:
override /*IterableLike*/
def find(p: A => Boolean): Option[A] = {
var these = this
while (!these.isEmpty) {
if (p(these.head)) return Some(these.head)
these = these.tail
}
None
}
This method has been written to run with a while loop, instead of using recursion. For non-lazy sequences this won't use any extra memory and will run faster than a recursive solution. Unfortunately, Stream is lazy, and when this method is used with large (esp. infinite) sequences it leads to runaway memory consumption. This happens because the method always keeps its this pointer on the stack, and so the garbage collector never collects the beginning, or any of the rest of, the Stream.
The problem can be fixed by writing a find that works recursively:
import annotation.tailrec
#tailrec
def betterFind[A](s: Stream[A], p: A => Boolean): Option[A] = {
if (s.isEmpty)
None
else if (p(s.head))
Some(s.head)
else
betterFind(s.tail, p)
}
In practice, it may be simpler to use Stream.iterator.find rather than writing your own method. Stream.iterator returns an Iterator over the elements of the Stream, and will be safe to use even with infinite streams.
Let's step through your code a bit:
from(1) // 2, 3, 4, 5, 6 ...
isDivisibleByRange(1, Range(2, 21)
Range(2, 21).forall(1 % _ == 0) // false
isDivisibleByRange(2, Range(2, 21)
Range(2, 21).forall(2 % _ == 0) // false
isDivisibleByRange(3, Range(2, 21)
Range(2, 21).forall(3 % _ == 0) // false
... OOME
The first number to satisfy (2 to 21) mod == 0 is 232792560. So you get an OOME before you reach 232792560.
Since stream is just a lazy list, you're basically creating a list of all possible positive integers, which takes all your memory. Maybe increase your heap space? Remember that there's some extra allocation around the stream container, not just 4 bytes for the int, so maybe -Xmx4G.
UPDATE
Using an iterator approach, you can do this in decent time with minimal memory (find on Range is implemented with an Iterator):
Range(1, Int.MaxValue).find(r => Range(2, 21).forall(r1 => r % r1 == 0))
//Some(232792560)