How do I print the boolean value? - swift

Okay, so I'm currently trying to write the code for a very inaccurate stoplight--one that is only meant to help me understand what I've learned, but I can't seem to figure it out! In my code, at the very end, I say print("Green Light!") after setting up a few variables, but I would like to indicate what the computer should do instead of flat out saying "print this phrase," if that makes sense... not sure it does.
How would I write this if I wanted to simply print the Boolean value of greenLight without saying print("Green Light!")?
I'm very much a beginner and I might be asking the wrong question--I know that, but I'm hoping someone can help!
Something tells me I haven't learned enough to do this, yet, but I really wanna know how this works.
This is what I've written so far. It runs, but I would like to change it so all I have to say is print(greenLight) or print(Bool).
When I try putting in print(greenLight), it returns an error:
Output:
Review.swift:14:7: error: variable 'greenLight' used before being initialized
print(greenLight)
^
Review.swift:4:5: note: variable defined here
var greenLight: Bool
^
var carAtRightIntersection = false
var carAtLeftIntersection = false
var carStraightAhead = true
var greenLight: Bool
if !(carAtRightIntersection && carAtLeftIntersection) && carStraightAhead {
greenLight = true
}
if carAtRightIntersection && carAtLeftIntersection && !(carStraightAhead) {
greenLight = false
}
print("Green light!")
Edit: I consulted a few coding friends, and they provided a very good solution! Provided here:
var carAtRightIntersection = false
var carAtLeftIntersection = false
var carStraightAhead = true
var colorOfLight: String = "Red"
if !(carAtRightIntersection && carAtLeftIntersection) && carStraightAhead {
colorOfLight = "Green"
}
/*
if carAtRightIntersection && carAtLeftIntersection && !(carStraightAhead) {
greenLight = false
}
*/
print(colorOfLight + " light :)")

If you don't want to print the actual phrases, You could use a switch case statement
switch greenLight{
case true:
print("Green Light!")
case false:
print("Red Light!")
default:
print("Yellow Light!")
}
After the first block executes

Related

how to avoid while loop and return in scala

I see in scala it is a bad practice to use both while and return. I have to click on the next page link if it exists. How can I do it without while and return?
def check = {
do {
if (findElements(locator).exists(_.getText.contains(input)))
return true
} while (nextPageLocatorInPageExists(nextPageLocator))
false
}
Here's a straightforward recursive solution:
def check = {
if (findElements(locator).exists(_.getText.contains(input)))
true
else if (! nextPageLocatorInPageExists(nextPageLocator))
false
else
check
}
It can be written in a terser way by using || and &&, but then it wouldn't be tail recursive, and that's pretty much mandatory in a case like this.
From your code, I'm guessing nextPageLocatorInPageExists(nextPageLocator) mutatates locator, and that's what drives your while loop.
If that's the case, here are two options:
a do-while loop without return: the closest to what you wrote:
def check = {
var found = false
do {
found = findElements(locator).exists(_.getText.contains(input))
} while (!found && nextPageLocatorInPageExists(nextPageLocator))
found
}
a recursive solution
def check: Boolean = findElements(locator).exists(_.getText.contains(input)) ||
(nextPageLocatorInPageExists(nextPageLocator) && check)

Swift 4.2 computed variable [String:Bool] does not assign value correctly

[MacOS 10.14.1, Xcode 10.1, Swift 4.2]
I'm working on creating a getopt style CLI argument processor whilst practising Swift. In my design, I decided to create a computed variable, represented as a [String:Bool] dictionary, that can be checked to see if an option (key) is just a switch (value = true) or whether it may include parameters (value = false). So I've written the code below, all of which is, at the moment, in my small (300 lines) main.swift file.
The code works correctly in a playground, but in my Swift Xcode project, whilst the dictionary's keys are correct, values are always false and inconsistent with the printed messages.
let options = "cwt:i:o:"
//lazy var optionIsSwitch : [String:Bool] = { (This will be moved to a class)
var optionIsSwitch : [String:Bool] = {
var tmpOptionIsSwitch : [String:Bool] = [:]
let optionsStrAsArray = Array(options)
let flags = Array(options.filter { !":".contains($0) } )
tmpOptionIsSwitch.reserveCapacity(flags.count)
for thisOption in 0...flags.count-1 {
var posInOptionsStr = 0
while posInOptionsStr < optionsStrAsArray.count-1 && flags[thisOption] != optionsStrAsArray[posInOptionsStr] {
posInOptionsStr += 1
}
if posInOptionsStr < optionsStrAsArray.count-1 && optionsStrAsArray[posInOptionsStr+1] == ":" {
tmpOptionIsSwitch[String(flags[thisOption])] = false
print("\(flags[thisOption]) is FALSE")
} else {
tmpOptionIsSwitch[String(flags[thisOption])] = true
print("\(flags[thisOption]) is TRUE")
}
}
return tmpOptionIsSwitch
}()
I've stepped through the code in my project to observe the execution sequence, and found it to be correct. As per the first image, tmpOptionIsSwitch returns a dictionary containing the right keys but all the values are set to false, which is inconsistent with the print statements.
As part of my debugging activities, I copied the above code into a Swift Playground where I found it gave the correct results, as per the image below.
Has anyone has such an issue? Is there something I've done wrong?

Form validation issue in macOS app

I am trying to run through a settings form and make sure that the user hasn't left any of the required fields empty.
Some of the forms fields are secure ( eg password).
Whats the easiest way to loop through all these fields and check they are not empty?
I have tried below - but I get a weird error:
if textfield1.stringValue == "",
textfield2.stringValue == "",
passwordfield.stringValue == "" {
//Shows error: Braced block of statements is an unused closure
}
Additionally I am unable to group all these NSTextfields into an array as the password textfields are NSSecureTextField which despite being inherited from NSTextfield, the are not groupable with NSTextfield.
You can have NSTextField and NSSecureTextField in the same array. This is indeed an easy way to find the empty ones.
let tf = NSTextField()
let stf = NSSecureTextField()
let tf2 = NSTextField()
tf2.stringValue = "some text"
let all = [tf, stf, tf2]
let emptyTextFields = all.filter { $0.stringValue.isEmpty }
Also in your example you can't use commas to group conditions in if, you have to use &&:
if tf.stringValue.isEmpty && stf.stringValue.isEmpty && tf2.stringValue.isEmpty {
// do something
}
but this is not a good solution, better use the array and filter.
Under Swift 2, here's what Eric Aya correctly identified:
if textfield1.stringValue == "" && textfield2.stringValue == "" && == "" {
}
It also compiles under Swift 3.
On the other hand, the code you put in your question actually works in Swift 3.
Other way to check empty string with isEmpty variable of String object.
let userName = ""
let email = ""
if(userName.isEmpty && email.isEmpty) {
print("empty strings")
}
else {
print("good strings")
}

expectationForPredicate Fails test case

Recently started working on XCode UI test with SWIFT.
My problem is I need to wait until a element appears on iPhone screen.
I found a solution with '''expectationForPredicate''' and '''waitForExpectationsWithTimeout''' but the problem this is this methods are designed to fail test case if expected predicate not matched within timeout.
I need a code which can wait for element to appear on screen if the element did not appear and timeout exceeded then I don't want test case to fail. rather I would like to return true (element exists) / false (not exists)
I found a solution by avoiding the above mentioned functions as those are failing my tests instead of returning true or false
Below is the method i created
func waitForElementToAppear(element: XCUIElement, file: String = #file, line: UInt = #line) -> Bool {
let TIMEOUT: Double = 120 ;
var isFound = false;
let start = NSDate();
var diff : Double = 0;
repeat{
print("Is element \(element) found : \(element.exists)")
print("Printing debugDescription -> ")
print(XCUIApplication().debugDescription)
if(element.exists){
isFound = true;
break;
}
print("Waiting for element to exists... Time counter :\(diff)")
sleep(1)
let end = NSDate();
diff = end.timeIntervalSinceDate(start);
}while(diff <= TIMEOUT);
return isFound;
}
I hope this will help others, But if you still have any other better solution please answer here.

How would I create a constant that could be one of several strings depending on conditions?

I want to have a constant using let that may be one of several values.
For instance:
if condition1 {
constant = "hi"
}
else if condition2 {
constant = "hello"
}
else if condition3 {
constant = "hey"
}
else if condition4 {
constant = "greetings"
}
I'm not sure how to do this with Swift and the let feature. But I'm inclined to believe it's possible, as this is in the Swift book:
Use let to make a constant and var to make a variable. The value of a constant doesn’t need to be known at compile time, but you must assign it a value exactly once.
How would I accomplish this?
As pointed out in the other answers you can't directly do this. But if you're looking to just variably set the initial value of a constant, then yes, that is possible. Here's an example with a computed property.
class MyClass {
let aConstant: String = {
if something == true {
return "something"
} else {
return "something else"
}
}()
}
I think you are looking for variable which will be assigned later inside switch-case:
let constant :String
switch conditions {
case condition1:
constant = "hi"
case condition2:
constant = "hello"
case condition3:
constant = "hey"
case condition4:
constant = "greetings"
default:
constant = "salute"
}
One option would be something like this, using a closure:
let constant: String = ({ value in
if conditionOne {
return "Hi"
} else if conditionTwo {
return "Bye"
}
return "Oops!"
})(myData /*needed for condition*/)
Or, for another twist, using generics:
func fancySwitch<S, T>(val: S, fn: S -> T) -> T {
return fn(val)
}
let x: String = fancySwitch(3) { val in
if val == 2 {
return "Hi"
} else if val < 5 {
return "Bye"
}
return "Oops"
}
let y: String = fancySwitch((3, 4)) { (a, b) in
if a == 2 {
return "Hi"
} else if b < 5 {
return "Bye"
}
return "Oops"
}
I understand what you're looking for. In Scala and some other functional languages this can be done using the match statement (kind of like switch) because the entire statement resolves to a value like this:
val b = true
val num = b match {
case true => 1
case false => 0
}
This is unfortunately not directly possible in Swift because there is no way to get a value from a branch statement. As stated in the Swift book, "Swift has two branch statements: an if statement and a switch statement." Neither of these statements resolve to a value.
The closest code structure I can think of is to first use a variable to retrieve the correct value and then assign it to a constant to be used in any later code:
let b = true
var num_mutable: Int
switch b {
case true:
num_mutable = 1
default:
num_mutable = 0
}
let num = num_mutable
Just add the line let constant: String before your if/else statement.
Below, an excerpt from Swift 1.2 and Xcode 6.3 beta - Swift Blog - Apple Developer elaborates.
let constants are now more powerful and consistent — The new rule is
that a let constant must be initialized before use (like a var), and
that it may only be initialized, not reassigned or mutated after
initialization. This enables patterns like:
let x : SomeThing
if condition {
x = foo()
} else {
x = bar()
}
use(x)
This formerly required the use of a var even though there is no
mutation taking place. Properties have been folded into this model to
simplify their semantics in initializers as well.
I found the Swift blog post above from the article "Let It Go: Late Initialization of Let in Swift", which I found by googling: swift let constant conditional initialize.