I have this piece of code
func sell() throws{
while(true)
{
var choice : String?
print("Please press a number from 1 to 3\n")
let product = readLine(stripNewline: true)!
switch product
{
case "1":
//
case "2":
//
case "3":
//
default:
choice = "Invalid"
try sell()
}
}
try sell()
And it gives me the error
execution was interrupted reason exc_bad_instruction
I realized that the ! is causing the error. If I remove it I have a problem with the comparisons inside switch.
Anyone knows what is the problem?
func foo()->Int {
print("Please press a number from 1 to 3")
while true {
if let l = readLine(),
let i = Int(l) {
if (1..<4).contains(i) {
return i
} else {
print("Number must be in range from 1 to 3")
}
} else {
print("Please press a number")
}
}
}
let r = foo()
print("You chose", r)
an example of ...
Please press a number from 1 to 3
u
Please press a number
7
Number must be in range from 1 to 3
45
Number must be in range from 1 to 3
h76
Please press a number
1
You chose 1
Program ended with exit code: 0
How about create one if let to check if this contains value or is it nil
let product = readLine(stripNewline: true)
if let productNo = product {
switch productNo {
//your same code in switch
}
Related
everyone! I'm a new member of Stack Overflow, just like I'm beginner on swift programming. I'm making this post to find out a solution for the following case:
I'm creating on Swift an app using the Command Line Tool for inputing data. The app basically works as an authenticator. As an example, if someone types USA for the country name and the age is 17, so the program will return a message like "You can not apply to this position". Otherwise, if the country name is USA and the age is equal or higher than 18, so the message returns is "You can forward to the next step". I've tried many times to set this conditions, but it's not working. I'm already knows that the function readLine() is an Optional String, but how can I make my program work correctly? It follows my code above to you understanding my thoughts.
I really appreciate any help. Again, I'm beginner and I'm already studying Swift languages, but I'm seeking some solution that handles Integers and Strings and comparing both data types. Thank you very much!
My code is:
import Foundation
print("Enter your country: ")
var country = readLine()
print("Enter your age: ")
var age = readLine()
if var country, var age = readLine(){
if country == "USA" && age < "18" {
print("You're not allowed to apply to this position.")
} else {
print("You can forward to the next step.")
}
}
PS: As you see, I'm using wrongly the variable age as an String, but I want to convert it to an Int type and then, check if the country name is the same than the value I assigned to or the age is equal or higher than 18. But not found a solution so far.
I'm trying to find a solution that compares two different types on Swift, using Command Line Tool and the readLine() function to check if a condition is true or not. If it's true, an output message will show that the user can proceed to the next step, otherwise he will not be permitted to follow. I'm keeping for an explanation on internet since few days, but not found anything that might help me. I hope to get some help using the Stack Overflow forum to some useful answer.
First one, readline() means you read the current to the end of current line . As your code when you check condition you call readLine() again. The wrong part is here.
I recommend you to read first then do all your logic. You just need to read only one time at first
print("Enter your country: ")
var country = readLine()
print("Enter your age: ")
var ageString = readLine()
Next, check if it is nil or not ( because option value which is value can be nil)
if country == nil || ageString == nil {
print("Error because one of them is nil")
fatalError()
}
Then check if can convert to Int or not. Reach here you sure that the ageString is not nil because you have checked above. So you just simply convert
guard let ageString = ageString else {
print("Error age nil")
fatalError()
}
guard let age = Int(ageString) else {
print("Error age not a number")
fatalError()
}
Then after all, you just check your condition
Full code will be like this
print("Enter your country: ")
var country = readLine()
print("Enter your age: ")
var ageString = readLine()
// check nil first if nil return or do something first and not get to the rest
if country == nil || ageString == nil {
print("Error because one of them is nil")
fatalError()
}
guard let ageString = ageString else {
print("Error age nil")
fatalError()
}
guard let age = Int(ageString) else {
print("Error age not a number")
fatalError()
}
if country == "USA" && age < 18 {
print("You're not allowed to apply to this position.")
} else {
print("You can forward to the next step.")
}
Other methods is use if let to achieve so no force unwrap
print("Enter your country: ")
var country = readLine()
print("Enter your age: ")
var ageString = readLine()
// check nil first if nil return or do something first and not get to the rest
if country == nil || ageString == nil {
print("Error because one of them is nil")
fatalError()
}
if let ageString = ageString {
if let age = Int(ageString) {
if country == "USA" && age < 18 {
print("You're not allowed to apply to this position.")
} else {
print("You can forward to the next step.")
}
} else {
print("Error age not a number")
fatalError()
}
}
SOLUTION SOLVED!
Hey, guys, first of all I want to thank you all for your helpful answers, which helped me a lot. I've got finally a solution, and am going to share it with you.
What did I done? I just created two variables, one String and another Integer. Then, using the if var to force unwrapping of the Int variable, I've made an if statement to check if the both conditions are true (in the case, if the person is from USA and has an age equals or higher than 18). Now, the program is running on the same way I just wanted. If you are from USA but has no 18 years, output returns a message that you can not apply. Otherwise, you're able to forward.
I'll let the code above. If you want to make some comments or any suggestions, it'll be welcome.
Again, thank you very much for all your answers.
var countryCheck = "USA"
var ageCheck: Int = 18
print("Enter your country: ")
var country = readLine()
print("Enter your age: ")
var age = readLine()
if var countryCheck = country, var ageCheck = Int(age!) {
if countryCheck == "USA" && ageCheck >= 18 {
print("You can apply.")
} else {
print("You can not apply to this position.")
}
}
I hope this help you :)
import Foundation
print("Enter your country: ")
if let country = readLine() {
if let num = Int(country) {
print(num)
}
}
let country = readLine()
let age = readLine()
if let USA = country,
let num1 = Int(USA),
let num2 = Int(USA) {
print("The age of \(num1) and \(num2) is \(num1 + num2)")
}
while true {
print ( """
1. Log in
2. Create new user
3. Quit
""")
if let numberString = readLine(), let number = Int(numberString) {
print("you entered \(number)")
break
} else {
print("Try again")
}
}
It is necessary to use the number variable in the future to compare it.
How can it be taken out of sight?
When I try to make a global var something goes wrong:
var numberString: String?
var number: Int?
while true {
print ( """
1. Log in
2. Create new user
3. Quit
""")
if numberString = readLine(), number = Int(numberString) {
print("you entered \(number)")
break
} else {
print("Try again")
}
}
Considering that you are creating a command prompt and that choice has no meaning outside your loop there is no need to make it global. You only need to switch the user selection and decide what to do from there. Note that if you try to break from inside the switch you won't exit your loop as I showed to you in your last question. To allow the compiler to know that you want to break the while loop instead of the switch you need to label your while loop statement, this way you can specify what you want to break when you have a switch inside a loop. Try like this:
func getValue() -> Int? {
guard let line = readLine(), let value = Int(line) else {
return nil
}
return value
}
question: while true {
print("""
1. Log in
2. Create new user
3. Quit
""")
guard let value = getValue() else {
continue
}
switch value {
case 1:
print("you have selected number one")
case 2:
print("you have selected number two")
case 3:
print("Good bye")
break question
default:
print("Try again")
}
}
There is not much information to go off of here, but I think I can help. In the first script, you are creating a new variable and setting the value for that variable:
if let numberString = readLine(), let number = Int(numberString) { ... }
In your second script, you have to global variables, but at no point have you provided them a value. What you need to do is provide both global variables (numberString and number) a value before comparing them. As such, you need to use the == sign to compare different variables/ types. For instance:
var numberString: String?
var number: Int?
while true {
print("""
1. Log in
2. Create new user
3. Quit
""")
numberString = readLine()
number = Int(numberString!)
}
You can now compare and or print your global variables...
Final Code
var numberString: String?
var number: Int?
while true {
print("""
1. Log in
2. Create new user
3. Quit
""")
numberString = readLine()
number = Int(numberString!)
if number == 1 {
print("you have selected number one")
} else if number == 2 {
print("you have selected number two")
} else if number == 3 {
print("you have selected number three")
} else {
print("Try again")
}
}
Due to the fact that both variables numberString and number are now global variables, you can access them in the future if you need to compare them again.
I'm trying to understand swift and therefore try to come up with simple command line games: in this game a player has to guess a secret word within 6 attempts by typing something in the command line, but every time he gets it wrong, a statement prints the number of his wrong attempts:
let response = readLine()
if response != "secret word" {
for n in 1...6 {
print(n)
}
}
else {
print("you are right!")
}
Now I know that my code will print all lines once the condition is not true, but I'm looking for a way to only print one item out of the four loop for every if statement consecutively.
I think a while loop works pretty well. Maybe something like this:
print("Welcome to the input game!\n\n\n\n")
var remainingTries = 5
let dictionary = ["apple", "grape", "pear", "banana"]
let secretWord = dictionary.randomElement()
print("Please guess a fruit")
while remainingTries > 0 {
remainingTries -= 1
let response = readLine()
if response == secretWord {
print("You got it!")
remainingTries = 0
} else if remainingTries <= 0 {
print("Too bad, you lose!")
remainingTries = 0
} else {
print("Incorrect. Tries remaining: \(remainingTries)")
}
}
Well...here is the code
func howMany() -> Int {
return 10
}
func Call() -> Void {
guard case let output = howMany(), output > 5 else { return }
}
Call()
I do not really understand how the guard case works. This looks pretty much like a pattern matching condition where we compare whether the result of howMany() is equal to output, if it is, assign the value to output and then compare it to the literal value 5. However, when I deleted the line of output > 5, the compiler said, "the guard condition is always true, body is unreachable."
According to the pattern, if we translate it into a switch statement, it looks pretty much like this
switch howMany() {
case let output where output > 5:
break;
}
The question is if it could be directly translated into the switch statement, then there should not be a warning of "the guard condition is always true, body is unreachable" when we delete the where condition.
I hope somebody could shed some light on this.
Consider:
func foo() {
guard case let output = howMany(), output > 5 else {
print("less than or equal to 5")
return
}
print("\(output) is greater than 5")
}
That is roughly equivalent to:
func bar() {
switch howMany() {
case let output where output > 5:
print("\(output) is greater than 5")
default:
print("less than or equal to 5")
return
}
}
If you remove that > 5 criteria:
func foo() {
guard case let output = howMany() else {
print("less than or equal to 5")
return
}
print("\(output) is greater than 5")
}
You get your warning:
'guard' condition is always true, body is unreachable
That warning is correct, because the body is unreachable.
And if you do the equivalent in the switch example:
func bar() {
switch howMany() {
case let output:
print("\(output) is greater than 5")
default:
print("less than or equal to 5")
return
}
}
If you do that, you will receive an analogous warning:
default will never be executed
And, again, it makes sense, because default will not be reached.
Now, consider your example switch with no default clause:
func bar() {
switch howMany() {
case let output:
print("output:", output)
}
}
You don't receive a warning here only because there is no default clause (the analog of the "body" of the guard statement).
How can I fix the code so the loop would ask the question for each of the items in the dictionary?
*Edited the code to make what I am trying to do more clear. I want the code to stop and wait for the input BEFORE moving on to the next item in the dictionary.
import Foundation
import UIKit
var squad = [1:"Arsh", 2:"Arbab", 3:"Ayush", 4:"KC", 5:"Jaski", 6:"Gunny", 7:"Harsh", 8:"Nagib", 9:"Rithin", 10:"Gursh", 11:"Sonny"]
let coming = "Yes"
let notComing = "No"
var attendees = [String]()
for ( key , person) in squad {
// key == 1
// key = counter
// repeat {
print("Are you attending \(person)?")
let response = readLine()
print(response as Any)
if response == coming {
attendees.append(person)
}
else if response == notComing {
print("Sorry to hear that")
}
else {
print("Invalid Input")
}
// } while key <= 11
// key += 1
}
print(attendees)
print(attendees.count)
To experiment keyboard input features like readLine(), create a project by choosing from Xcode menu :
File > New > Project > macOS > Command Line Tool
and run it in Xcode, the Debugging Console pane will work as a terminal. Here the code you're looking for :
import Foundation
var squad = [1:"Arsh", 2:"Arbab", 3:"Ayush", 4:"KC", 5:"Jaski", 6:"Gunny", 7:"Harsh", 8:"Nagib", 9:"Rithin", 10:"Gursh", 11:"Sonny"]
let coming = "yes"
let notComing = "no"
var attendees = [String]()
let array = squad.map {return ($0.key, $0.value)} // Turn the dictionary to an array of tuples
let sortedArray = array.sorted(by: {$0.0 < $1.0 }) // Sort the array by the first element of the tuple
// Ask the squad one by one
for ( _ , person) in sortedArray {
print("Are you attending \(person)?")
if let response = readLine() {
//remove white spaces and all letters lowercased so that "Yes", "yes" and "YES" would all be accepted
if response.lowercased().trimmingCharacters(in: .whitespaces) == coming {
attendees.append(person)
}
else if response.lowercased().trimmingCharacters(in: .whitespaces) == notComing {
print("Sorry to hear that")
}
else {
print("Invalid Input")
}
}
}
print("attendees : \(attendees)")
print("attendees.count = \(attendees.count)")