Is this possible to limited the variable scope in swift? - swift

For example, I need a valuable which is an Int, but I limited it can only set from 1-10. Is this features build in in swift? Except from override the setter. Is this possible to do so?
btw, what is this feature named? I remember I come across some languages got this features, but I don't recall the name of that languages.

You might be looking for an enumeration. It allows you to set a range of values (not strictly numbers though), which are allowed as input. Do something like this:
enum NumsTill10 {
case 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
}
And to set it as a variable:
let number:NumsTill10 = NumsTill10.1
Or even
let number:NumsTill10 = .1
And then you can do:
if number == .7 {
//It's 7!
}

Related

iOS-Charts Library: x-axis labels without backing data not showing

I am using version 3.1.1 of the popular charts library for iOS. I have run into an issue with x-axis labeling that I can't seem to find the answer for online:
Let's say I want to have a chart with one x-axis label for every day of the week (namely: S, M, T, W, T, F, S). Lots of forums I've read suggest taking the approach of setting a custom value formatter on the x-axis as suggested here: https://github.com/danielgindi/Charts/issues/1340
This works for calculating labels on days for which I have data. The issue I'm running into with this approach is that if I don't have data for a specific day, then the label for that day won't get generated.
For example, if I were to use a custom value formatter that looked like this:
public class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: = ["S", "M", "T", "W", "T", "F", "S"]
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return days[Int(value)]
}
}
and my backing data looked like this: [(0, 15.5), (1, 20.1), (6, 11.1)] where 0, 1, and 6 are representations of days, and 15.5, 20.1, and 11.1 are the data points on those days, then when stringForValue is called, some of the days will never get labels generated for them.
Since value is always based on that backing data, it will never be equal to 2, 3, 4, or 5 in this scenario. As such, labels for "T", "W", "T", and "F" are never generated.
Does anyone know how to force the library to generate 7 labels, one for each day of the week, regardless of what my backing data is? Thank you kindly.
Ok so thanks to #wingzero 's comment, I have been able to get this working. There are a few things required to do so. For simplicity's sake, I am going to explain how to get the "days of the week" labels working as I originally asked. If you follow these steps, however, you should be able to tweak them to format your chart however you like (for example, with months of the year).
1) Make sure that your chart's x-axis minimum and maximum values are set. In this case, you'd want to say: chartView.xAxis.axisMinimum = 0.0 and chartView.axisMaximum = 6.0. This is important for step 2.
2) As Wingzero alluded to, create a subclass of XAxisRenderer that allows us to grab the minimum and maximum values set in step one and determine what values should be passed to our IAxisValueFormatter subclass in step three. In this case:
class XAxisWeekRenderer: XAxisRenderer {
override func computeAxis(min: Double, max: Double, inverted: Bool) {
axis?.entries = [0, 1, 2, 3, 4, 5, 6]
}
}
Make sure to pass this renderer to your chart like this: chartView.xAxisRenderer = XAxisWeekRenderer()
3) Create a subclass of IAxisValueFormatter that takes the values we passed to the chart in step two ([0, 1, 2, 3, 4, 5, 6]) and gets corresponding label names. This is what I did in my original question here. To recap:
public class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: = ["S", "M", "T", "W", "T", "F", "S"]
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return days[Int(value)]
}
}
4) Set the labelCount on your graph to be equal to the number of labels you want. In this case, it would be 7. I show how to do this, along with the rest of the steps, below the last step here.
5) Force the labels to be enabled
6) Force granularity on the chart to be enabled and set granularity to 1. From what I understand, setting the granularity to 1 means that if the data your chart passes to stringForValue is not in round numbers, the chart will essentially round said data or treat it like it is rounded. This is important since if you passed in 0.5, it's possible that your stringForValue might not produce the right strings for your labels.
7) Set the value formatter on the xAxis to be the custom formatter you created in step 3.
Steps 4-7 (plus setting the formatter created in step 3) are shown below:
chartView.xAxis.labelCount = 7
chartView.xAxis.forceLabelsEnabled = true
chartView.xAxis.granularityEnabled = true
chartView.xAxis.granularity = 1
chartView.xAxis.valueFormatter = CustomChartFormatter()
First, have you debugged return days[Int(value)] on your side? From your screenshot, it seems obvious that your value after int cast looses the precision. e.g. 2.1 and 2.7 will be 2, which always shows you T. You have to look at your value first.
If you are sure you only get 7 xaxis labels all the time, a tricky way is to force computeAxisValues to have [0,1,2,3,4,5,6] all the time.
Meaning, you make sure your data x range is [1,7] (or [0,6]), and in #objc open func computeAxisValues(min: Double, max: Double), you should be able to see min is 1 and max is 7.
Then you override this method to set axis.entries = [Double]() to be [0,1,2,3,4,5,6], without any calculation. This should gives you the correct mapping.
However, before doing this, I suggest you take some time to debug this method first, to understand why you didn't get the expected values.

Dynamic Json Keys in Scala

I'm new to scala (from python) and I'm trying to create a Json object that has dynamic keys. I would like to use some starting number as the top-level key and then combinations involving that number as second-level keys.
From reading the play-json docs/examples, I've seen how to build these nested structures. While that will work for the top-level keys (there are only 17 of them), this is a combinatorial problem and the power set contains ~130k combinations that would be the second-level keys so it isn't feasible to list that structure out. I also saw the use of a case class for structures, however the parameter name becomes the key in those instances which is not what I'm looking for.
Currently, I'm considering using HashMaps with the MultiMap trait so that I can map multiple combinations to the same original starting number and then second-level keys would be the combinations themselves.
I have python code that does this, but it takes 3-4 days to work through up-to-9-number combinations for all 17 starting numbers. The ideal final format would look something like below.
Perhaps it isn't possible to do in scala given the goal of using immutable structures. I suppose using regex on a string of the output might be an option as well. I'm open to any solutions regarding data structures to hold the info and how to approach the problem. Thanks!
{
"2": {
"(2, 3, 4, 5, 6)": {
"best_permutation": "(2, 4, 3, 5, 6)",
"amount": 26.0
},
"(2, 4, 5, 6)": {
"best_permutation": "(2, 5, 4, 6)",
"amount": 21.0
}
},
"3": {
"(3, 2, 4, 5, 6)": {
"best_permutation": "(3, 4, 2, 5, 6)",
"amount": 26.0
},
"(3, 4, 5, 6)": {
"best_permutation": "(3, 5, 4, 6)",
"amount": 21.0
}
}
}
EDIT:
There is no real data source other than the matrix I'm using as my lookup table. I've posted the links to the lookup table I'm using and the program if it might help, but essentially, I'm generating the content myself within the code.
For a given combination, I have a function that basically takes the first value of the combination (which is to be the starting point) and then uses the tail of that combination to generate a permutation.
After that I prepend the starting location to the front of each permutation and then use sliding(2) to work my way through the permutation looking up the amount which is in a breeze.linalg.DenseMatrix by using the two values to index the matrix I've provided below and summing the amounts gathered by indexing the matrix with the two sliding values (subtracting 1 from each value to account for the 0-based indexing).
At this point, it is just a matter of gathering the information (starting_location, combination, best_permutation and the amount) and constructing the nested HashMap. I'm using scala 2.11.8 if it makes any difference.
MATRIX: see here.
PROGRAM:see here.

Swift: Set<Object> fundamental operations result in copies or pointers?

I'm currently looking for some reference, outside apple's swift programming reference for the memory space of Set types and resulting fundamental operations (union, intersection, exclusion, subtraction etc)
Given the below pseudo code:
var entities = Set<GKEntity>()
var subSetA = Set<GKEntity>()
var subSetB = Set<GKEntity>()
Each subset will have a subclass of GKEntity which will be called on some routines I will use elswhere in my application.
When I use the union of these subsets, IE: I will have set as the superset of all subsets, or the union of all subsets.
Does this mean that the superset will be a copy of the elements in the subset or will they be pointers only?
I ask this for memory space usage as if the operation requires copying or allocating new memory adresses, I will need to use a different strategy of storing my elements.
From a purely structural standpoint, I assume these will be "shallow" copies meaning they will be pointers to memory adresses, but once I have created the superset as the union of all subsets, I want any removal or addition to be reflected on the superset, or down on the particular subset if the operation is made on the superset.
Hope this question is valid
Note, I'm assuming you mean this GKEntity.
Since GKEntity is a class, the sets you created will store references (pointers) to those actual GKEntity objects. So any changes to the objects in a subset will be reflected in the superset.
Here is a short piece of code that demonstrates this:
class A: IntegerLiteralConvertible, Hashable, CustomStringConvertible {
var x: Int
required init(integerLiteral value: Int) {
self.x = value
}
var hashValue: Int {
return x
}
var description: String {
return String(x)
}
}
func ==(lhs: A, rhs: A) -> Bool {
return lhs.hashValue == rhs.hashValue
}
let setA: Set<A> = [1, 2, 3, 4]
let setB: Set<A> = [5, 6, 7, 8]
print(setA) // [2, 3, 1, 4]
print(setB) // [5, 6, 7, 8]
let union = setA.union(setB)
print(union) // [2, 4, 5, 6, 7, 3, 1, 8]
setA.first!.x = 30
print(union) // [30, 4, 5, 6, 7, 3, 1, 8]
As you can see, I made a change (changed x from 2 to 30) to the first item in setA. Then I printed out union, which did contain a 30 in it.

Conditional "in" for arrays in Swift

I have tried all imagined ways and searched for it in Google, StackOverflow and official reference book, but still couldn't find out how to do such operation in Swift:
let basicPrimes = (1,2,3,5,7,11,13,17,19)
if number in basicPrimes {
println("Is prime!")
}
Error message says "Braced block of statements is an unused closure" but I couldn't find any plausible explanation on it that I could make use of.
Any idea what am I doing wrong?
I'd suggest using an Array instead of a Tuple for your basic primes. Then you could use contains() to check if a number is in your array of basic primes. Something like this would work:
let basicPrimes = [2, 3, 5, 7, 11, 13, 17, 19]
let number = 5
if contains(basicPrimes, number)
{
println("Is prime!")
}
There are 2 errors in your code:
an array is initialized with square brackets - what you have created instead is a tuple, which is not a sequence type
to check if an element is contained in a sequence, you have to use the contains global function - in is a keywords used in closures instead, that's the reason for that strange error message
So your code should look like:
let basicPrimes = [1,2,3,5,7,11,13,17,19]
if contains(basicPrimes, number) {
println("Is prime!")
}

How exactly does the "let" keyword work in Swift?

I've read this simple explanation in the guide:
The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once.
But I want a little more detail than this. If the constant references an object, can I still modify its properties? If it references a collection, can I add or remove elements from it? I come from a C# background; is it similar to how readonly works (apart from being able to use it in method bodies), and if it's not, how is it different?
let is a little bit like a const pointer in C. If you reference an object with a let, you can change the object's properties or call methods on it, but you cannot assign a different object to that identifier.
let also has implications for collections and non-object types. If you reference a struct with a let, you cannot change its properties or call any of its mutating func methods.
Using let/var with collections works much like mutable/immutable Foundation collections: If you assign an array to a let, you can't change its contents. If you reference a dictionary with let, you can't add/remove key/value pairs or assign a new value for a key — it's truly immutable. If you want to assign to subscripts in, append to, or otherwise mutate an array or dictionary, you must declare it with var.
(Prior to Xcode 6 beta 3, Swift arrays had a weird mix of value and reference semantics, and were partially mutable when assigned to a let -- that's gone now.)
It's best to think of let in terms of Static Single Assignment (SSA) -- every SSA variable is assigned to exactly once. In functional languages like lisp you don't (normally) use an assignment operator -- names are bound to a value exactly once. For example, the names y and z below are bound to a value exactly once (per invocation):
func pow(x: Float, n : Int) -> Float {
if n == 0 {return 1}
if n == 1 {return x}
let y = pow(x, n/2)
let z = y*y
if n & 1 == 0 {
return z
}
return z*x
}
This lends itself to more correct code since it enforces invariance and is side-effect free.
Here is how an imperative-style programmer might compute the first 6 powers of 5:
var powersOfFive = Int[]()
for n in [1, 2, 3, 4, 5, 6] {
var n2 = n*n
powersOfFive += n2*n2*n
}
Obviously n2 is is a loop invariant so we could use let instead:
var powersOfFive = Int[]()
for n in [1, 2, 3, 4, 5, 6] {
let n2 = n*n
powersOfFive += n2*n2*n
}
But a truly functional programmer would avoid all the side-effects and mutations:
let powersOfFive = [1, 2, 3, 4, 5, 6].map(
{(num: Int) -> Int in
let num2 = num*num
return num2*num2*num})
Let
Swift uses two basic techniques to store values for a programmer to access by using a name: let and var. Use let if you're never going to change the value associated with that name. Use var if you expect for that name to refer to a changing set of values.
let a = 5 // This is now a constant. "a" can never be changed.
var b = 2 // This is now a variable. Change "b" when you like.
The value that a constant refers to can never be changed, however the thing that a constant refers to can change if it is an instance of a class.
let a = 5
let b = someClass()
a = 6 // Nope.
b = someOtherClass() // Nope.
b.setCookies( newNumberOfCookies: 5 ) // Ok, sure.
Let and Collections
When you assign an array to a constant, elements can no longer be added or removed from that array. However, the value of any of that array's elements may still be changed.
let a = [1, 2, 3]
a.append(4) // This is NOT OK. You may not add a new value.
a[0] = 0 // This is OK. You can change an existing value.
A dictionary assigned to a constant can not be changed in any way.
let a = [1: "Awesome", 2: "Not Awesome"]
a[3] = "Bogus" // This is NOT OK. You may not add new key:value pairs.
a[1] = "Totally Awesome" // This is NOT OK. You may not change a value.
That is my understanding of this topic. Please correct me where needed. Excuse me if the question is already answered, I am doing this in part to help myself learn.
First of all, "The let keyword defines a constant" is confusing for beginners who are coming from C# background (like me). After reading many Stack Overflow answers, I came to the conclusion that
Actually, in swift there is no concept of constant
A constant is an expression that is resolved at compilation time. For both C# and Java, constants must be assigned during declaration:
public const double pi = 3.1416; // C#
public static final double pi = 3.1416 // Java
Apple doc ( defining constant using "let" ):
The value of a constant doesn’t need to be known at compile time, but you must assign the value exactly once.
In C# terms, you can think of "let" as "readonly" variable
Swift "let" == C# "readonly"
F# users will feel right at home with Swift's let keyword. :)
In C# terms, you can think of "let" as "readonly var", if that construct was allowed, i.e.: an identifier that can only be bound at the point of declaration.
Swift properties:
Swift Properties official documentation
In its simplest form, a stored property is a constant or variable that is stored as part of an instance of a particular class or structure. Stored properties can be either variable stored properties (introduced by the varkeyword) or constant stored properties (introduced by the let keyword).
Example:
The example below defines a structure called FixedLengthRange, which describes a range of integers whose range length cannot be changed once it is created:
struct FixedLengthRange {
var firstValue: Int
let length: Int
}
Instances of FixedLengthRange have a variable stored property called firstValue and a constant stored property called length. In the example above, length is initialized when the new range is created and cannot be changed thereafter, because it is a constant property.