var currentnum: Int = 1
for currentnum in 1...100{
if (currentnum % 2) != 0 {
print("Odd number")
}
else{
print("Even number")
}
currentnum += 1
}
Hello. I'm trying to "create a loop that iterates from 1 to 100 that prints out whether the current number in the iteration is even or odd." When I run the above code, I receive "error: expected expression after operator." What is wrong with my code (I'm new to programming). Thanks!
You don't need to declare var currentnum: Int = 1 in your code and increment through currentnum += 1. for-in loop does it for you. In Swift for-in syntax can be used to loop over both ranges of numbers, collections and even strings. All with the same syntax!
It should be as follows,
for currentnum in 1...100{
if (currentnum % 2) != 0 {
print("Odd number")
}
else{
print("Even number")
}
}
Good luck!
You should get rid of this expression currentnum += 1.
Because you are using the In .. Range operator there is no need to increment the counter. The In .. Range Operator will take care of this. This is different to the basic for loop from Java or C++ where you need to increment your counter variable.
Additionally the first declared variable currentnum is never used. This variable could be removed too.
The rest of your algorithm looks good and should work!
Hope this helps!
Unlike some languages you do not need to define the index variable before entering the for-in loop, nor do you need to manually increment the index.
You can also use the new swift function isMultiple(of:) rather than modulus
If you want to loop through a set range you can do:
for num in 1...100 {
if num.isMultiple(of: 2) {
print("\(num) is an even number")
} else {
print("\(num) is an odd number")
}
}
If you have a set of values in an array you can do this:
let numbers = [1,5,12,23,25,27,30,32,35]
for num in numbers {
if num.isMultiple(of: 2) {
print("\(num) is an even number")
} else {
print("\(num) is an odd number")
}
}
One liner without a for loop per the request in the comments
Array(1...100).map{$0 % 2 == 0 ? print("\($0) is even") : print("\($0) is odd") }
#BeginnerCoderGirl i have changed your code please check just remove currentnum += 1 from code and run
Related
I'm learning an swift and I've written two functions and have tried them on their own they both work well. However when I try to call one function within another one I can't seem to get the desired out-put that I seek.
The task at hand is that one function should print Prime numbers whilst the other is to calculate and check if the number is prime. I am supposed to call the check if number is prime from the print Prime numbers function.
below is my code:
This function calculates whether or not the X:Int is a prime number. It's set to a boolean because I'm supposed to print "true" or "false" in the function below it.
func isPrime(_ x: Int) -> Bool {
if(x%2 == 0 || x%3 == 0){
if(x == 2 || x == 3){
return(true)
}
return(false)
}
else{
//if the number is less than or equal to 1, we'll say it's not prime
if(x <= 1){
return(false)
}
}
return true
}
This piece calculates the printing of the prime number from 1 to n.
func PrintPrimes(upTo n: Int) {
for x in 1...n {
var count = 0
for num in 1..<x {
isPrime(x)
count += 1
}
if count <= 1 {
print(isPrime(x))
}
}
}
This piece only runs twice and i'm not exactly sure why. I don't know if its because i'm not calling it correctly or I'd have to change up some calculations.
All help is appreciated
EDIT:
Here is the original printPrimes() before I decided to call isPrime within the function. This function calculates the prime numbers only and prints them up to n.
func printPrimes(upTo n: Int) {
for x in 1...n {
var count = 0
for num in 1..<x {
if x % num == 0 {
count += 1
}
}
if count <= 1 {
print(x)
}
}
}
Your second routine is printing only two values because it is calling isPrime, but never doing anything conditional on the value returned, but rather incrementing count regardless. And since you’re printing only if count is <= 1, that will happen only for the first two values of n.
But let’s say you were trying to print the prime numbers up to a certain number, you could do:
func printPrimes(upTo n: Int) {
for x in 1...n {
if isPrime(x) {
print(x)
}
}
}
(As a matter of convention, in Swift, when we say “through n”, we’d iterate 1...n, and if someone said “up to n”, we’d iterate 1..<n. But because your original code snippet uses upTo in conjunction with 1...n, I’ll use that here, but just note that this isn’t very consistent with standard Swift API patterns.)
Unfortunately, isPrime is not correct, either. So you’ll have to fix that first. For example, consider 25. That is not divisible by 2 or 3, but isn’t prime, either.
If you look at the original printPrimes that was provided, what it effectively does is say “by how many whole integers less than x is x divisible ... if only divisible by one other number (namely 1), then it’s a prime.” That logic, although not efficient, is correct. You should go ahead and use that inside your isPrime routine. But that “is divisible by 2 or 3” logic is not correct.
You can do it this way, in your printPrimes you can loop up to the number you want and just check if the number is prime by calling the function with the number. But you have to check your isPrime function. Your printPrimes should only do what its name says (print the prime numbers up to n) and all the logic to check if the number is prime should be on your isPrime function.
Also its a good practice to use camelCase on functions, you should rename your function to printPrimes instead of PrintPrimes.
func printPrimes(upTo n: Int) {
for x in 1...n {
if isPrime(x) {
print(x)
}
}
}
var array: [Int] = []
//Here I make an array to try to dictate when to perform an IBaction.
func random() -> Int {
let rand = arc4random_uniform(52)*10+10
return Int(rand)
}
//this function makes a random integer for me
func finalRand() -> Int {
var num = random()
while (array.contains(num) == true){
if (num == 520){
num = 10
}else {
num += 10
}
}
array.append(num)
return num
}
The logic in the while statement is somewhat confusing, but you could try this:
var array:Array<Int> = []
func finalRand() -> Int {
var num = Int(arc4random_uniform(52)*10+10)
while array.contains(num) {
num = Int(arc4random_uniform(52)*10+10)
}
array.append(num)
return num
}
This way there will never be a repeat, and you have less boiler code.
There is probably a better method involving Sets, but I'm sorry I do not know much about that.
A few things:
Once your array has all 52 values, an attempt to add the 53rd number will end up in an infinite loop because all 52 values are already in your array.
In contemporary Swift versions, you can simplify your random routine to
func random() -> Int {
return Int.random(in: 1...52) * 10
}
It seems like you might want a shuffled array of your 52 different values, which you can reduce to:
let array = Array(1...52).map { $0 * 10 }
.shuffled()
Just iterate through that shuffled array of values.
If you really need to continue generating numbers when you’re done going through all of the values, you could, for example, reshuffle the array and start from the beginning of the newly shuffled array.
As an aside, your routine will not generate truly random sequence. For example, let’s imagine that your code just happened to populate the values 10 through 500, with only 510 and 520 being the final possible remaining values: Your routine is 51 times as likely to generate 510 over 520 for the next value. You want to do a Fisher-Yates shuffle, like the built-in shuffled routine does, to generate a truly evenly distributed series of values. Just generate array of possible values and shuffle it.
How to increment for-loop variable dynamically as per some condition.
For example.
var col = 10
for (i <- col until 10) {
if (Some condition)
i = i+2; // Reassignment to val, compile error
println(i)
}
How it is possible in scala.
Lots of low level languages allow you to do that via the C like for loop but that's not what a for loop is really meant for. In most languages, a for loop is used when you know in advance (when the loop starts) how many iterations you will need. Otherwise, a while loop is used.
You should use a while loop for that in scala.
var i = 0
while(i<10) {
if (Some condition)
i = i+2
println(i)
i+=1
}
If you dont want to use mutable variables you can try functional way for this
def loop(start: Int) {
if (some condition) {
loop(start + 2)
} else {
loop(start - 1) // whatever you want to do.
}
}
And as normal recursion function you'll need some condition to break the flow, I just wanted to give an idea of what can be done.
Hope this helps!!!
Ideally, you wouldn't use var for this. fold works pretty well with immutable values, whether it is an int, list, map...
It lets you set a default value (e.g. 0) to the variable you want to return and also iterate through the values(e.g i) changing that value (e.g accumulator) on every iteration.
val value = (1 to 10).fold(0)((loopVariable,i) => {
if(i == condition)
loopVariable+1
else
loopVariable
})
println(value)
Example
I want to increment index at some point for this loop it prints 1,3,5 which is i want to. I get the warning
C-Style for statement is deprecated and ...
i know what it means.
for var index=0; index<5; index++ {
//If condition A == true
index++
//else without index++
print(index) // print 1, 3, 5
}
So i changed it to:
for var index in 0..<5 {
//If condition A == true
index += 1
//else without index++
print(index) // print 1,2,3,4,5 Should 1,3,5 from my side
}
I just wondering why index not mutable? Even though i have set it to var or any solutions for my issue.
The index is not mutable because
for var x in y {
...
}
is equivalent to
for temp in y {
var x = temp
...
}
where the var just makes x a copy of temp. When you modify x, it won't modify the real index temp (This is also a reason why SE-0003 is introduced)
The C-style for loop can just be reduced to a while loop:
var index = 0
while index < 5 {
if conditionA {
index += 1
}
print(index)
index += 1
}
If you just need to enumerate odd numbers, the simplest way will be to use stride:
for i in 1.stride(through: 5, by: 2) {
print(i) // prints 1, 3, 5
}
Here is one way to get the results you want:
for var index in 0..<3 {
print(2 * index + 1)
}
I believe swift loop variables are immutable when using the for in loop. Mutating a loop variable inside the loop is usually (one could argue always) a bad idea so it makes sense the swift designers didn't allow it. The desired result can be accomplished in cleaner ways, for instance using continue.
for i in 1...5
{
if i%2==0
{
continue
}
print(i)
}
In Swift 2.2, C-style for statement is deprecated, so I modify following for-loop:
for var idx=data.count-1; idx>=0; --idx
into
for idx in (0...data.count-1).reverse() // <--- new statement
However, I found, when data.count is 0 during execution, the new statement will crash with error fatal error: Can't form range with end < start.
Is there a best/standard way to code for this case?
P.S. I think I have to use different kinds of loops/syntax to replace my unified C-style loops. Any further comment or suggestion on this is welcome.
Creating a range as
0 ... data.count-1
terminates with a runtime exception if data.count is zero. It is
often better to use the ..< operator to make a range that
omits its upper value, in your case:
0 ..< data.count
This works for data.count == 0 as well and creates an empty
range in that case. This applies to
both forward and backward iteration:
for idx in 0 ..< data.count { ... }
for idx in (0 ..< data.count).reverse() { ... }
(Of course stride() is a sensible alternative for the second case.)
You should use Strideable.stride(through:by:) to generate your for-loop range, like this:
for idx in (data.count-1).stride(through: 0, by: -1) {
print(idx)
}
It works even if data.count == 0.
In such a simple loop, there is no need for arithmetic operations.
If data is an array, use indices:
for index in data.indices {
}
for index in data.indices.reverse() {
}
or access the data directly
for item in data {
}
for item in data.reverse() {
}
or a combination of the previous using enumerate
for (index, item) in data.enumerate() {
}
Note that all for-in loops above can be also written as forEach:
data.indices.forEach {
}
Instead, use for idx in (0..<data.count).reverse(). This will form the empty range that you want when data.count == 0.