What does += do for list in Scala? - list

What does the += do here ? Does it mean append to the list?
If maxNodes = 16, Do the below lines mean that values 0 to 15 are stored in NodeList? Or is it 0 to 16?
var Nodelist = new ArrayBuffer[Int]()
for (i <- 0 until maxNodes) {     
Nodelist += i  
 }

You're just appending the Integer value in variable i to the list. Why not try this in the REPL?

According to the Javadoc, += in ArrayBuffer is an "alias" for addOne(). So at the beginning NodeList is empty (I'd rather call it nodeList). On the first go at the For loop, the integer 0 is added to NodeList. On the next go around, the integer 1 will be added to NodeList, and so and so forth. Since you used until rather than to, the iteration will stop one short of maxNodes.

Related

Write a function that calculates the sum of all values in a list of integers that are both positive and even

The function should accept a single list as a parameter. The function should return an integer value as the result of calculation. If there are no positive and even integer values in the list, your function should return 0.
My current code:
def main():
print (sum_positive_even([1,2,3,4,5]))
print (sum_positive_even([-1,-2,-3,-4,-5]))
print (sum_positive_even([1,3,5,7,9]))
def sum_positive_even(list):
for num in list:
if num < 0:
list.remove(num)
for num in list:
if num % 2 == 1:
list.remove(num)
result = sum(list)
return result
main()
The output should be like:
6
0
0
I'm confused where I should put the 'return 0'.
Thanks TA!
Deleting from a list while you iterate over it is a Bad Idea - it's very easy to get hard-to-track-down bugs that way. Much better would be to build a new list of the items you want to keep. You don't need a special case of returning 0; the general approach should be able to handle that.
Also, it's better not to use list as a variable name in Python, because that's the name of a built-in.
A modification of your approach:
def sum_positive_even(lst):
to_keep = []
for num in lst:
if num > 0 and num % 2 == 0:
to_keep.append(num)
return sum(to_keep)
Since the sum of an empty list is 0, this covers the case where there are no positive even numbers.

Scala: decrement for-loop

I noticed that the following two for-loop cases behave differently sometimes while most of the time they are the same. I couldn't figure out the pattern, does anyone have any idea? Thanks!
case 1:
for (i <- myList.length - 1 to 0 by -1) { ... }
case 2:
for (i <- myList.length - 1 to 0) { ...}
Well, they definitely don't do the same things. n to 0 by -1 means "start at n and go to 0, counting backwards by 1. So:
5 to 0 by -1
// res0: scala.collection.immutable.Range = Range(5, 4, 3, 2, 1, 0)
Whereas n to 0 means "start at n and got to 0 counting forward by 1". But you'll notice that if n > 0, then there will be nothing in that list, since there is no way to count forward to 0 from anything greater than zero.
5 to 0
// res1: scala.collection.immutable.Range.Inclusive = Range()
The only way that they would produce the same result is if n=0 since counting from 0 to 0 is the same forwards and backwards:
0 to 0 by -1 // Range(0)
0 to 0 // Range(0)
In your case, since you're starting at myList.length - 1, they will produce the same result when the length of myList is 1.
In summary, the first version makes sense, because you want to count down to 0 by counting backward (by -1). And the second version doesn't make sense because you're not going to want to count forward to 0 from a length (which is necessarily non-negative).
First, we need to learn more about how value members to and by works.
to - Click Here for API documentation
to is a value member that appears in classes like int, double etc.
scala> 1 to 3
res35: scala.collection.immutable.Range.Inclusive = Range(1, 2, 3)
Honestly, you don't have to use start to end by step and start.to(end, step) will also work if you are more comfortable working with in this world. Basically, to will return you a Range.Inclusive object if we are talking about integer inputs.
by - Click Here for API documentation
Create a new range with the start and end values of this range and a new step
scala> Range(1,8) by 3
res54: scala.collection.immutable.Range = Range(1, 4, 7)
scala> Range(1,8).by(3)
res55: scala.collection.immutable.Range = Range(1, 4, 7)
In the end, lets spend some time looking at what happens when the step is on a different direction from start to end. Like 1 to 3 by -1
Here is the source code of the Range class and it is actually pretty straightforward to read:
def by(step: Int): Range = copy(start, end, step)
So by is actually calling a function copy, so what is copy?
protected def copy(start: Int, end: Int, step: Int): Range = new Range(start, end, step)
So copy is literally recreate a new range with different step, then lets look at the constructor or Range itself.
Reading this paragraph of code
override final val isEmpty = (
(start > end && step > 0)
|| (start < end && step < 0)
|| (start == end && !isInclusive)
)
These cases will trigger the exception and your result will be a empty Range in cases like 1 to 3 by -1..etc.
Sorry the length of my post is getting out of control since I am also learning Scala now.
Why don't you just read the source code of Range, it is written by Martin Odersky and it is only 500 lines including comments :)

Sql, Compged, Min and blanks

I'm comparing 4 strings using compged in sql here is an extract:
MIN(compged(a.string1,b.string1),
compged(a.string1,b.string2),
compged(a.string2,b.string1),
compged(a.string2,b.string2)) < 200
Unfortunately there are times that a string from set a and a string from set b is blank/empty, this means compged resolves to 0 and the min found is 0. Is there a way to modify so that comparing two blank strings gives a value greater than 200 or something?
Thanks in advance
You can calculate new variables to handle that situation (both compared variables are blank) and use them inside the MIN() function:
case
when (missing(a.string1) and missing(b.string1)) then 300
else compged(a.string1,b.string1)
end as compged_11,
/* do the same for combinations 12, 21 and 22 */
MIN(calculated compged_11,
calculated compged_12,
calculated compged_21,
calculated compged_22) < 200
The quick and dirty option is to wrap each string with a different 200char string in case the string is null or the length is 0 (as empty strings aren't always referenced as NULL)
So a.string1 = 200*'Z', b.string1 = 200*'X'.....
Or better even, to wrap each call with checks so if a.string1 is null or is empty, then return the length of the other string. And if both are empty, then return 1000 so the record is removed by the where clause.
You can also add a prefix - 'A' to all strings. This will ensure tht there are no empty strings, and will not change the distance. But you still need to weed out cases where both strings are empty.

For loop for in python not working

Im trying to implement this function.
def eq_chars(s,i):
"""Returns: length of sequence of equal characters starting at s[i].
Examples: eq_chars('aaaxxyx',0) is 3 and eq chars('aaaxxyx',5) is 1
Precondition: s is a string, 0 <= i < len(s).""
"
My code thus far has been this:
for i in range(len(s)):
accumulator = 0
if s[i] == s[i+1]:
accumulator = accumulator + 1
return accumulator
else:
pass
I know there is a problem in the beginning of the for loop. I stands for the index which will be given to us. Can you possibly change variables? What am I doing wrong? Any help is appreciated
The problem is that you are returning when the if statement is satisfied and at the beginning of the loop you are losing the value of i. The correct code should be:
def eq_chars(s, i):
accumulator = 1
for j in range(i, len(s) - 1):
if s[j] == s[j+1]:
accumulator += 1
else:
break
return accumulator
This function start from the given index, and checks if the next character is the same with the current one. If it finds a match it increases the count. When a non-matching character is seen, it stops the loop and returns the count.

Limit size of a list in python

I want to limit the size of a list in python 2.7 I have been trying to do it with a while loop but it doesn't work
l=[]
i=raw_input()//this is the size of the list
count=0
while count<i:
l.append(raw_input())
count=count+1
The thing is that it does not finish the loop. I think this problem has an easy answer but I can't find it.
Thanks in advance
I think the problem is here:
i=raw_input()//this is the size of the list
raw_input() returns a string, not an integer, so comparisons between i and count don't make sense. [In Python 3, you'd get the error message TypeError: unorderable types: int() < str(), which would have made things clear.] If you convert i to an int, though:
i = int(raw_input())
it should do what you expect. (We'll ignore error handling etc. and possibly converting what you're adding to l if you need to.)
Note though that it would be more Pythonic to write something like
for term_i in range(num_terms):
s = raw_input()
l.append(s)
Most of the time you shouldn't need to manually keep track of indices by "+1", so if you find yourself doing it there's probably a better way.
That is because i has a string value type, and int < "string" always returns true.
What you want is:
l=[]
i=raw_input() #this is the size of the list
count=0
while count<int(i): #Cast to int
l.append(raw_input())
count=count+1
You should try changing your code to this:
l = []
i = input() //this is the size of the list
count = 0
while count < i:
l.append(raw_input())
count+=1
raw_input() returns a string while input() returns an integer. Also count+=1 is better programming practice than count = count + 1. Good luck