Slice indexing weird edge case - go

In Go slice indices use half-open range. For a[low:high] the slice includes a[low] but exclude a[high]. Ref: https://tour.golang.org/moretypes/7. Another way to think of it is it goes from a[low] to a[high-1] inclusive.
But take a look at this code. You can run it at: https://play.golang.com/p/DSLs7V8gom0
func main() {
t := []int{5}
fmt.Println(t)
fmt.Println(t[0:0])
fmt.Println(t[1:1])
}
If you ran the code you can see that both t[0:0] and t[1:1] are valid and allowed.
t[0:0] means includes t[0] (which exists) but stop before t[0] (which is t[-1] which does not exist).
t[1:1] means includes t[1] (which does not exist) but stop before t[1] (which is t[0] which exists).
In both cases one of the indices refer to something that doesn't exist, i.e. index out of range ==> yet syntactically perfect and allowed in Golang!!
Yet if you try any other index, such as t[2], the compiler will expectedly complain loudly.

You need to think of a range as starting at the lower value and stopping when you reach the upper value. The upper can never be less than the lower but they can be any valid index or the one past the end - ie 0 or 1 in your example.
So t[0:0] means start then stop immediately giving a zero-length range. Eg:
t[0:0] and t[1:1] are valid zero length slices
t[0:1] is a slice of length 1
t[2:2] and t[1:0] are invalid
I explain in detail about the advantages of half-open ranges and not making zero a special case in my blog - eg see http://devmethodologies.blogspot.com/2012/12/asymmetric-bounds-and-zero-based.html

Related

What happens when I range over an uninitialized pointer to array in golang

I have this code
var j *[33]byte
for i := range j {
fmt.Println(j[i])
}
Now when I run this code I get nil pointer dereference error when I try access values in j. I'm not sure why I was even able to enter the loop in the first place considering my pointer is uninitialized.
I know an uninitialized array has all its values set to their zero value. That is
var a [5]int
Will have a default value of [0, 0, 0, 0, 0].
But I don't understand what golang does when you don't initialize a pointer to an array. Why is range able to range over it even though its nil?
From the Go spec Range Clause:
... For an array, pointer to array, or slice value a, the index
iteration values are produced in increasing order...
so as a convenience the Go language is dereferencing the pointer with the intent to iterating over its elements. The fact that the pointer is nil is a simple programming error. If this can occur, one should have a runtime check in place to guard against it.
Static analysis may be able to detect this type of bug ahead of time - but what if the variable j is accessible from another goroutine - how would the compiler know for sure that another goroutine may update it to a non-nil value right before the range loop is reached?
Go has a zero value defined for each type when you initialize a variable with var keyword (this may change when using :=, ideally used when need copies of values or specific values). In the case of the pointer the zero value is nil (also maps, interfaces, channels, slices, and functions) in case of array of type int the zero value is 0.
So, to answer your question, Go is able to iterate because you have 33 valid spaces idependently of what value is inside of that position. You can check the diference between slices and arrays on the Golang documentation to have more insights on why is that.

find endpoints for range given a value within the range

I am trying to solve a simple problem, but at the moment I cannot think of a better solution. I am testing an API that is not documented.
There is an ID used to fetch objects and it has a min and max value with random values missing in-between. I'm trying to test the responses I receive for random objects, but to find objects, I need to have valid IDs.
It would be very inefficient to test random numbers and hope that I get an object back. The best I can do is find a range, get a random number between that range and check if it exists before conducting tests.
A sample list of all of the IDs in the database might look like this:
[1005, 25984, 25986, 29587, 30000, ...]
Assuming the deviation from one value to another will never exceed C, e.g. from the first value to the next value, the difference will never be greater than a pre-defined constant, how would you calculate the min/max of the range given only one value in the range?
Starting from a given value and looping until the last value is found is horrible but that is how it was implemented by previous devs. Below is pseudocode that more or less covers what they do.
// this can be any valid object ID from the database
// assuming the ID's in the database are [1005, 25984, 25986, 29587, 30000]
// "i" could be any one of these values
var i = givenPredefinedObjectId;
var deviation = 100;
// objectWithIdExists() is going to lookup an object with the ID "i" in the database
// if there is no object with the ID "i" , it will return false
// otherwise the object will get tested and return true
while(objectWithIdExists(i)){
i++;
}
for(i; i < i+deviation; i++){
if(objectWithIdExists(i)){
goto while loop;
}
}
endPoint = i - deviation;
Assuming there is no knowledge about the possible values except you can check if they exist and you are given one valid value (there is no array with all possible IDs, that was just an example), how would you find the min/max values?
Unbounded binary search is feasible, with a factor of C slowdown. Given an algorithm for unbounded binary search that, given access to the oracle less_equal(n) for some natural number n, returns n in time O(log n), implement the oracle on input k by querying all of the IDs C*k, C*k+1, ..., C*k+C-1 and reporting that k is less than or equal to n if and only if one ID is found. The running time is O(C*log((max-min)/C)).

What is the benefit of NSScanner's charactersToBeSkipped?

I have the string #" ILL WILL KILLS ", and I'm using NSScanner's scanUpToString:intoString: to find every occurrence of "ILL". If it's accurate, it will NSLog 4, 9, and 14.
My string begins with 4 spaces, which I realize are members of the NSScanner's default charactersToBeSkipped NSCharacterSet. If I set charactersToBeSkipped to nil, as in the example below, then this code accurately finds the 3 occurrences of "ILL".
NSScanner* scanner = [NSScanner scannerWithString:#" ILL WILL KILLS "] ;
scanner.charactersToBeSkipped = nil ;
NSString* scannedCharacters ;
while ( TRUE ) {
BOOL didScanUnignoredCharacters = [scanner scanUpToString:#"ILL" intoString:&scannedCharacters] ;
if ( scanner.isAtEnd ) {
break ;
}
NSLog(#"Found match at index: %tu", scanner.scanLocation) ;
// Since stopString "ILL" is 3 characters long, advance scanLocation by 3 to find the next "ILL".
scanner.scanLocation += 3 ;
}
However, if I don't nullify the default charactersToBeSkipped, here's what happens:
scanner is initialized with scanLocation == 0.
scanUpToString executes for the 1st time, it "looks past" 4 empty spaces and "sees" ILL at index 4, so it immediately stops. scanLocation is still 0.
I believe that I found a match, and I increment scanLocation by 3.
scanUpToString executes for the 2nd time, it "looks past" 1 empty space and "sees" ILL at index 4, so it immediately stops. scanLocation is still 3.
To me, it's a design flaw that scanner stopped at scanLocation == 0 the first time, since I expected it to stop at scanLocation == 4. If you believe that the above code can be rewritten to accurately NSLog 4, 9, and 14 without settings charactersToBeSkipped to nil, then please, show me how. For now, my opinion is that charactersToBeSkipped exists solely to make NSScanners more difficult to use.
For now, my opinion is that charactersToBeSkipped exists solely to make NSScanners more difficult to use.
Then you aren't very imaginative. The "benefit" of charactersToBeSkipped is to… wait for it… skip characters. For example, if you have a string like #" 8 9 10 ", you can scan those three integers using -scanInt: three times. You don't have to care about the precise amount of whitespace that separates them.
Given the task you describe, where you're just looking for instances of a string within a string, NSScanner is probably not the right tool. You probably want to use -[NSString rangeOfString:options:range:].
The docs for -scanUpToString:intoString: are fairly clear. If stopString is the first string in the receiver (taking into account that charactersToBeSkipped will be skipped), then the method returns NO, meaning it didn't scan anything. Consequently, the scan location won't be changed.
The return value indicates success or failure. If the stop string is next (ignoring characters to be skipped), then there's nothing to scan "up to" the stop string; the scanner is already at the stop string, so the method fails.

how can I get the location for the maximum value in fortran?

I have a 250*2001 matrix. I want to find the location for the maximum value for a(:,i) where i takes 5 different values: i = i + 256
a(:,256)
a(:,512)
a(:,768)
a(:,1024)
a(:,1280)
I tried using MAXLOC, but since I'm new to fortran, I couldn't get it right.
Try this
maxloc(a(:,256:1280:256))
but be warned, this call will return a value in the range 1..5 for the second dimension. The call will return the index of the maxloc in the 2001*5 array section that you pass to it. So to get the column index of the location in the original array you'll have to do some multiplication. And note that since the argument in the call to maxloc is a rank-2 array section the call will return a 2-element vector.
Your question is a little unclear: it could be either of two things you want.
One value for the maximum over the entire 250-by-5 subarray;
One value for the maximum in each of the 5 250-by-1 subarrays.
Your comments suggest you want the latter, and there is already an answer for the former.
So, in case it is the latter:
b(1:5) = MAXLOC(a(:,256:1280:256), DIM=1)

When are numbers NOT Magic?

I have a function like this:
float_as_thousands_str_with_precision(value, precision)
If I use it like this:
float_as_thousands_str_with_precision(volts, 1)
float_as_thousands_str_with_precision(amps, 2)
float_as_thousands_str_with_precision(watts, 2)
Are those 1/2s magic numbers?
Yes, they are magic numbers. It's obvious that the numbers 1 and 2 specify precision in the code sample but not why. Why do you need amps and watts to be more precise than volts at that point?
Also, avoiding magic numbers allows you to centralize code changes rather than having to scour the code when for the literal number 2 when your precision needs to change.
I would propose something like:
HIGH_PRECISION = 3;
MED_PRECISION = 2;
LOW_PRECISION = 1;
And your client code would look like:
float_as_thousands_str_with_precision(volts, LOW_PRECISION )
float_as_thousands_str_with_precision(amps, MED_PRECISION )
float_as_thousands_str_with_precision(watts, MED_PRECISION )
Then, if in the future you do something like this:
HIGH_PRECISION = 6;
MED_PRECISION = 4;
LOW_PRECISION = 2;
All you do is change the constants...
But to try and answer the question in the OP title:
IMO the only numbers that can truly be used and not be considered "magic" are -1, 0 and 1 when used in iteration, testing lengths and sizes and many mathematical operations. Some examples where using constants would actually obfuscate code:
for (int i=0; i<someCollection.Length; i++) {...}
if (someCollection.Length == 0) {...}
if (someCollection.Length < 1) {...}
int MyRidiculousSignReversalFunction(int i) {return i * -1;}
Those are all pretty obvious examples. E.g. start and the first element and increment by one, testing to see whether a collection is empty and sign reversal... ridiculous but works as an example. Now replace all of the -1, 0 and 1 values with 2:
for (int i=2; i<50; i+=2) {...}
if (someCollection.Length == 2) {...}
if (someCollection.Length < 2) {...}
int MyRidiculousDoublinglFunction(int i) {return i * 2;}
Now you have start asking yourself: Why am I starting iteration on the 3rd element and checking every other? And what's so special about the number 50? What's so special about a collection with two elements? the doubler example actually makes sense here but you can see that the non -1, 0, 1 values of 2 and 50 immediately become magic because there's obviously something special in what they're doing and we have no idea why.
No, they aren't.
A magic number in that context would be a number that has an unexplained meaning. In your case, it specifies the precision, which clearly visible.
A magic number would be something like:
int calculateFoo(int input)
{
return 0x3557 * input;
}
You should be aware that the phrase "magic number" has multiple meanings. In this case, it specifies a number in source code, that is unexplainable by the surroundings. There are other cases where the phrase is used, for example in a file header, identifying it as a file of a certain type.
A literal numeral IS NOT a magic number when:
it is used one time, in one place, with very clear purpose based on its context
it is used with such common frequency and within such a limited context as to be widely accepted as not magic (e.g. the +1 or -1 in loops that people so frequently accept as being not magic).
some people accept the +1 of a zero offset as not magic. I do not. When I see variable + 1 I still want to know why, and ZERO_OFFSET cannot be mistaken.
As for the example scenario of:
float_as_thousands_str_with_precision(volts, 1)
And the proposed
float_as_thousands_str_with_precision(volts, HIGH_PRECISION)
The 1 is magic if that function for volts with 1 is going to be used repeatedly for the same purpose. Then sure, it's "magic" but not because the meaning is unclear, but because you simply have multiple occurences.
Paul's answer focused on the "unexplained meaning" part thinking HIGH_PRECISION = 3 explained the purpose. IMO, HIGH_PRECISION offers no more explanation or value than something like PRECISION_THREE or THREE or 3. Of course 3 is higher than 1, but it still doesn't explain WHY higher precision was needed, or why there's a difference in precision. The numerals offer every bit as much intent and clarity as the proposed labels.
Why is there a need for varying precision in the first place? As an engineering guy, I can assume there's three possible reasons: (a) a true engineering justification that the measurement itself is only valid to X precision, so therefore the display shoulld reflect that, or (b) there's only enough display space for X precision, or (c) the viewer won't care about anything higher that X precision even if its available.
Those are complex reasons difficult to capture in a constant label, and are probbaly better served by a comment (to explain why something is beng done).
IF the use of those functions were in one place, and one place only, I would not consider the numerals magic. The intent is clear.
For reference:
A literal numeral IS magic when
"Unique values with unexplained meaning or multiple occurrences which
could (preferably) be replaced with named constants." http://en.wikipedia.org/wiki/Magic_number_%28programming%29 (3rd bullet)

Resources