|
TheGreatAndPowerfulOz wrote: Since a range is a set, and you're asking to iterate the set, then it's working exactly as I would have expected.
When I posted, I guessed that I'd get an answer like this. And, I'm not upset with your post, nor do I think it is incorrect.
I figured it was something I just didn't think entirely correctly about.
To me though, it seems like my original code was saying, iterate over this empty set and so I expected it to not run the code inside the for loop.
Another way to say this is, "I accept that I am incorrect about this, but the functionality of the structure as it is defined by Kotlin seems like it leads to grey understanding where the dev could be initially confused until dev obtains some experience with Kotlin Ranges."
But, again, I blame myself for not fully understanding the construct before using it.
I like to shoot first and ask questions later...after all the code is dead (not working).
Thanks for your input on this.
|
|
|
|
|
But the set from 0 to 0 is not empty, there is one item in it: 0.
If you'd said 0 to -1 (or 0 to count()-1 and assuming positive increment), then that would've been empty.
#SupportHeForShe
Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson
You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun
|
|
|
|
|
TheGreatAndPowerfulOz wrote: But the set from 0 to 0 is not empty, there is one item in it: 0.
I agree with you on that. Just a very odd construct when thinking about iterating over a set of items. This gets weird when you are attempting to get an element out of the set that is based upon an index value.
for (i in 0..allItems.count){
allItems.getItem(i);
}
I had fixed it using the notion that you mentioned (before I knew about Until), but it seemed odd
for (i in 0..allItems.count - 1){
allItems.getItem(i);
}
|
|
|
|
|
raddevus wrote: thinking about iterating over a set of item
You are thinking about the wrong set. While you can iterate over the items with a forEach, your code is not doing this. Your code loops over a range from 0 to the length of your (empty) set (0).
My first thought when I encounter a range based set generating construct in a language is always "which if either (or both!) of the bounds is inclusive". You can test this with a quick implementation of the languages version of the following:
for value in 1 to 3
print value
done
|
|
|
|
|
TheGreatAndPowerfulOz wrote: But the set from 0 to 0 is not empty, there is one item in it: 0. Usually, but not always.
The set of years from year 0 to year 0 is empty. Year -1 was immediately followed by year 1. There was no year 0.
Some people claim that this makes sense: There was no "year of Christ", the year before is birth was "year one before Christ" and the year after the birth was "year one". I have never met anyone who agrees that he was born in "year one before Christ", on Christmas day, neither will Christians agree that year one started 358 days before his birth. But the official view of the Christian church is that there was no year 0. This is so strong that even when non-Christians prefer to use the "Common Era" and "Before Common Era" rather than AD and BC, year 0 is skipped. Even in version 1.0 of the XML Schema language defined that for types date and dateTime, there is no year 0. (This definition was modified in later versions.)
The elevator in our office building is not very biblical of nature, yet there is no floor 0. It goes directly from floor 1 to floor -1. Since most of us are closer to mathematicians than to theologicans, to ease our minds we have declared that there is a floor 0, but it is virtual, and that is why the elevator doesn't stop there. Conceptually, it is there.
|
|
|
|
|
Since there is no year 0, then it's even worse than being the empty set, it's NULL.
As for your building, conceptually it is not there, so it is not an empty set, it is NULL.
#SupportHeForShe
Government can give you nothing but what it takes from somebody else. A government big enough to give you everything you want is big enough to take everything you've got, including your freedom.-Ezra Taft Benson
You must accept 1 of 2 basic premises: Either we are alone in the universe or we are not alone. Either way, the implications are staggering!-Wernher von Braun
|
|
|
|
|
The difference between inclusive & exclusive ranges... You (and most of us, thanks to zero based arrays in C, C#, Javascript and the like) are used to exclusive ranges (not including the endpoint), but Kotlin's range notation produces inclusive ranges.
Rust has similar notation, but it produces exclusive ranges (as you were expecting Kotlin to do), and uses ..= for inclusive ranges, so:
fn main() {
for i in 0..=0 {
print!("0..=0: {}\n", i);
}
for i in 0..0 {
print!("0..0: {}\n", i);
}
}
produces
0..=0: 0
Java, Basic, who cares - it's all a bunch of tree-hugging hippy cr*p
|
|
|
|
|
Thanks for sharing that about Rust. I think that makes much more sense and is quite a bit more intuitively obvious.
I recently noticed that C# Enumerable.Range also works the way I would (intuitively) expect it to.
foreach (var index in Enumerable.Range( 0, 0 ))
{
Console.WriteLine(index);
}
|
|
|
|
|
I guess that when we get to know a new language we expect it to be consistent with the languages that we already know. At least this works for me that way. That is the reason one might not expect how range operator in Go works (note the index) or JS sorting numbers lexicographically. And this is also a reason why this topic started in the first place.
|
|
|
|
|
I came across this nugget today. Some values were being stored that were "out" by a factor of 100. Someone claimed it was because the field definition was "7,4 instead of 7,2". I queried this and received this response ...
Quote: It’s because the system is assuming that the value is to 4 decimal places so 50 become 0.0050 whereas if you assume to decimal places it becomes 0.50 which is correct. Which was further explained as Quote: We have told [redacted] that a field which is a number with no decimal places has an implied DP Yes really.
So the company concerned has taken the "implied DP" and decided that the number should be divided by 10 to the power of the number of decimal places defined.
Who does that? Why would you?
Oh - and this is a Financial Services application
|
|
|
|
|
CHill60 wrote: Why would you?
Obfuscated API, maybe?
"Five fruits and vegetables a day? What a joke!
Personally, after the third watermelon, I'm full."
|
|
|
|
|
If only!
But the data is supplied on file supplied via SFTP - and nothing else is obfuscated - including other percentage figures
|
|
|
|
|
CHill60 wrote: and decided that the number should be divided by 10 to the power of the number of decimal places defined.
That actually makes sense. With some of the credit card processors I deal with, all amounts are integers with an implied number of decimal places, usually 2, so 1234 is 12.34. So yeah, if I had a spec that said the number of implied decimal places was 4, then 1234 would be .1234
And yes, only in Financial Services.
What I would be more concerned with is, when they divide by 10^n, what's the data type that's holding the result? Hopefully not a float or a double!
|
|
|
|
|
Marc Clifton wrote: And yes, only in Financial Services. I disagree...
In the Automation world, this is used pretty often.
I.E.
you get analog inputs i.e. [0, 10](V) transformed into decimal (depending on manufacturer or configurations 0 to 27658 or 0 to 32768)
to save data transferred into de bus (i.E. for the SCADA Visualization) is usual to send the int16 or Word and say in the panel, this variable contains 2 decimals (1234 = 12.34) or 4 decimals (1234 = 0.1234)
This is because the float / double would be 32 bits long, which means you save 2 bytes per variable using this method.
And this is still actual because (one of the reasons) the standard "Profi-Bus" speed is 1.5 mbit/s, saving that much bytes still helps.
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
modified 13-Dec-19 9:14am.
|
|
|
|
|
Nelek wrote: In the Automation world, this is used pretty often.
Ah, very true -- I remember doing exactly that sort of thing in the good 'ol days of assembly language programming and interfacing to a variety of hardware.
|
|
|
|
|
PLC LAD is kind of similar to assembler
And still in use almost overall.
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
I'm learning stuff today!
|
|
|
|
|
About this concrete case, I can't say much.
But I have used it a lot in automation. For more details see my answer to Marc.
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
This is a really old programming problem. How would you store a running total of a bank account? Since it has dollars and cents, how about a float?
Ok, so then you run into the "floating-point rounding error" problem.
>>> 0.1+0.1+0.1
0.30000000000000004
Well... that's pretty bad to be adding/dropping pennies every trillion transactions or so because of cumulative binary representation of decimal digit errors. What else can we do?
One of the commonly chosen ways is to used fixed decimal. i.e. Assume a fixed number of decimals and represent everything as integers. One no longer has to worry about fractions of a penny creeping up on you over time if you work in discrete units of pennies. i.e. 100-97 = 3, never 0.30000000000000004
Well... then your manager comes in and says, we need to be able to track hundredths of a penny because the state tax paid even including fractions of a penny. So it is deemed that 4-digits is enough precision to satisfy the need. Now 10000 - 9700 = 300 is still okay, is never gonna be 300.00000000000004 and the same situation applies as before.
But your front-end buddies didn't update the website to account for the fact that the database now assumes 4 digits of precision. And thus the problem is born.
Fun trivia: "Office Space" movie characters took advantage of this to siphon off millions of dollars back when this was a thing in the 80s-90s-00s.
|
|
|
|
|
Yeah - I get that it makes sense. It also saves space in automation etc. TBH we used to do it back in the day (but that was sooo long ago I'd forgotten).
My main gripe with this was that this is the only feed (of many) that was defined like this, and it's not the case for all the fields It looks like the whole shebang was designed by committee!
To make things worse the BA involved shares specifications a page at a time, only the bits that she thinks are necessary to do a job (that she is not qualified to do nor has any experience of). This was not on the pages she chose to share with me
|
|
|
|
|
I have an app that runs on multiple (Windows, iOS, Android - as both a native app or as a web app).
JSON is a nice lingua franca -- I thought.
You see my app has simple string-based keys the user adds to keep track of her sites.
Since I'm not sure what the user might type, I go ahead and encode the keys to Base64.
Normally you see some Base64 encoded keys which look like:
c3VwZXJzaXRl
c2Vjb25kU2l0ZQ==
dGhyZWU=
Serialize Object As JSON
In my web apps and on Windows I serialize all the user's sites as objects via JSON and it works great and looks like:
[{"HasSpecialChars":false,"HasUpperCase":false,"Key":"c3VwZXJzaXRl","MaxLength":0},{"HasSpecialChars":false,"HasUpperCase":false,"Key":"dGhyZWU=","MaxLength":0},{"HasSpecialChars":false,"HasUpperCase":false,"Key":"c2Vjb25kU2l0ZQ==","MaxLength":0},{"HasSpecialChars":false,"HasUpperCase":false,"Key":"eWV0QW5vdGhlcg==","MaxLength":0}]
Of course on web sites (JavaScript), its the old JSON.stringify(allSiteKeys) that handles that so nicely.
And on Windows I've always used NewtonSoft libraries and it all works great. All interchangeable.
Android Gson - Google's JSON
Enter the problem.
However, while developing on Android I wanted to serialize the data the same way so I turned to Gson which is Google's official Android way of doing this.
However, I noticed that values which were Base64 encoded properly were output to JSON in an interesting way. Every equal sign was altered to \u003d which is the unicode equals sign[^].
That means my JSON would be altered to look like:
[{"HasSpecialChars":false,"HasUpperCase":false,"Key":"c3VwZXJzaXRl","MaxLength":0},{"HasSpecialChars":false,"HasUpperCase":false,"Key":"dGhyZWU\u003d","MaxLength":0},{"HasSpecialChars":false,"HasUpperCase":false,"Key":"c2Vjb25kU2l0ZQ\u003d\u003d","MaxLength":0},{"HasSpecialChars":false,"HasUpperCase":false,"Key":"eWV0QW5vdGhlcg\u003d\u003d","MaxLength":0}]
NOTE: This is not a case of oddly encoded Base64 -- if I look directly at the Base64 encoded data it still has the equals signs. This only occurred when the data was serialized to JSON.
Searching For An Answer
It wasn't easy to find the answer, because a Google developer explains it this way[^]:
Google dev = is a special javascript character that must be escaped to unicode in
JSON so that a string literal can be embedded in XHTML without further
escaping.
XHTML? Oh, are we back in the year 2000?
It made no sense to me and others who were like, "Uh, JSON is a format for transmission. Why would I care if there is an equals sign in the data? It's just bytes."
It is quite difficult to find docs on the Gson library. Not great stuff.
But, finally, I found a stackoverflow answer[^] that mentions that you have to use the Gson builder to create the initial Gson object, and when you do you have to turn off html escaping...
Gson gson = new GsonBuilder().disableHtmlEscaping().create();
Normally, that would just looke like:
Gson gson = new Gson();
Everything else is the same so when you serialize it you still call the same code:
String jsonSiteKeys = gson.toJson(allSiteKeys);
The GsonBuilder() is almost like magic, because how would you ever know it is there?
Different Dialect Which Includes HTML Escaping
The final point is "Why would the dev think that the normal case is to include HTML escaping when this is a transmit format?" Why not think that is the special case? Especially since other libraries handle it without the escaping.
All That For Compatible JSON?
That is a sick amount of time just to get JSON in a compatible format.
In the future when AI takes over all development work, how will it handle this? It will not allow anyone else to write JSON libraries.
modified 9-Dec-19 17:03pm.
|
|
|
|
|
|
Thanks for the link, I will check it out.
|
|
|
|
|
|
|