how to use array.count in swift for-in loop - arrays

I'm a beginner in swift (probably) and I am learning how to use arrays I was trying to make a for-in loop with a loop amount of 1...array.count, but instead I get an error of:
Fatal error: Index out of range Current stack trace: 0
libswiftCore.so 0x00007f0f71f0aea0
swift_reportError + 50 1 libswiftCore.so
0x00007f0f71f7c0c0 swift_stdlib_reportFatalError + 69 2
libswiftCore.so 0x00007f0f71e775d7 +
3347927 3 libswiftCore.so 0x00007f0f71c94d80
fatalErrorMessage(::file:line:flags:) + 19 4 libswiftSwiftOnoneSupport.so 0x00007f0f755c7ad0 specialized
Array.subscript.getter + 85 6 swift
0x00000000004f23c9 + 992201 7 swift
0x00000000004f6a40 + 1010240 8 swift
0x00000000004e62ef + 942831 9 swift
0x00000000004d5093 + 872595 10 swift
0x00000000004d0e4e + 855630 11 swift
0x0000000000473c16 + 474134 12 libc.so.6
0x00007f0f73771ab0 __libc_start_main + 231 13 swift
0x000000000047387a + 473210 Stack dump:
0. Program arguments: /usr/bin/swift -frontend -interpret Forecast.swift -disable-objc-interop -module-name Forecast
/usr/bin/swift[0x4521834] /usr/bin/swift[0x451f48e]
/usr/bin/swift[0x4521c48]
/lib/x86_64-linux-gnu/libpthread.so.0(+0x128a0)[0x7f0f7532b8a0]
/usr/lib/swift/linux/libswiftCore.so(+0x3315d7)[0x7f0f71e775d7]
/usr/lib/swift/linux/libswiftCore.so($ss18_fatalErrorMessage__4file4line5flagss5NeverOs12StaticStringV_A2HSus6UInt32VtF+0x13)[0x7f0f71c94d93]
/usr/lib/swift/linux/libswiftSwiftOnoneSupport.so($sSayxSicigSi_Tg5+0x55)[0x7f0f755c7b25]
[0x7f0f7575d315] /usr/bin/swift[0x4f23c9] /usr/bin/swift[0x4f6a40]
/usr/bin/swift[0x4e62ef] /usr/bin/swift[0x4d5093]
/usr/bin/swift[0x4d0e4e] /usr/bin/swift[0x473c16]
/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xe7)[0x7f0f73771b97]
/usr/bin/swift[0x47387a]
what do I do? Here is my code, it is for CodeAcademy:
var temperature: [Int] = [66, 68, 72, 76, 80, 82, 85, 85, 84, 82, 81, 78, 74, 73, 72, 71, 70, 69, 68, 65, 63, 62, 61, 63]
// Write your code below 🌴
for i in 1...temperature.count{
print(temperature[i])
}

I presume your goal is to print all the temperature elements. Change
for i in 1...temperature.count {
To
for i in 0..<temperature.count {
Array indexes start at zero and end at one less than the count. The ..< operator handles this nicely. Or, even better, say
for i in temperature.indices {

One more option is to use forEach:
array.forEach { print($0) }

use for i in temperature. this is basic array iteration, keep in mind :D

var temperature: [Int] = [66, 68, 72, 76, 80, 82, 85, 85, 84, 82, 81, 78, 74, 73, 72, 71, 70, 69, 68, 65, 63, 62, 61, 63]
// Write your code below 🌴
for i in 1...temperature.count{
print(temperature[i-1])
}
You are getting this error because temperature[temperature.count] doesn't exist. You need to limit it till temperature[temperature.count-1] and the index should start from 1 instead of 0.
Alternatively
for i in 0...(temperature.count-1){
print(temperature[i])
}

Related

Finding the lowest 8 values in an Array in Swift

I am complete novice who is trying to supplement online course learning, by building some rudimentary programs. I am currently trying to build a program to calculate one's golf index. In order to do this, I must first calculate the average of the lowest 8 rounds, of the golfer's last 20. Calculating the average of the last 20 rounds was easy enough. It is isolating the lowest 8 rounds from the last twenty that I cannot figure out.
Generalized, how does one calculate the sum of the lowest N values in an array?
A note for the golfers out there: for the purposes of this exercise I am imagining that the individual only plays at one course, with a par of 72. I realize that the program will not work as currently constructed if par changes.
var scores: Array = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
var lastTwentyScores = scores.suffix(20)
var total = lastTwentyScores.reduce(0, +)
var avg = Double(total) / Double(lastTwentyScores.count)
var index = avg - 72
Right now, it is giving me the average of the last twenty - 72.
I know I will need to create a new variable, and change the final divisor to 8, instead of 20. I just don't know how to call the 8 lowest values from the array.
You just need to sort the last 20 and take the first 8 of that sorted result. That will give you the lowest 8 of the last 20.
var scores: Array = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
var lastTwentyScores = scores.suffix(20)
var lowestEightScores = lastTwentyScores.sorted().prefix(8)
var total = lowestEightScores.reduce(0, +)
var avg = Double(total) / Double(lowestEightScores.count)
This gives a total of 666 and an average of 63.25.
You can simplify most of the code to just:
var total = scores.suffix(20).sorted().prefix(8).reduce(0, +)
This makes it nice and neat but having the intermediate steps can make it easier to read and certainly easier to debug.
Like #HangarRash said, it's a lot easier to do this if you sort the scores first. Simply sort the array in ascending order, and fetch the first 8 elements.
var scores: Array = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
scores = scores.sorted() //Sorts the scores (from least to greatest)
var eightLowestScores: Array = scores[...8] // Gets the first 8 elements based on their index.
I think you are looking for this:
scores
.suffix(20) // last 20
.sorted() // sort to get the ordered slice
.prefix(8) // 8 lowest
.reduce(0, +) / 8 // average
Swift Algorithms provide an optimised way: min(count:sortedBy:)
import Algorithms
let scores = [98, 99, 87, 86, 88, 92, 88, 87, 84, 98, 85, 84, 80, 99, 100, 101, 94, 96, 79, 99, 92, 94, 87, 99, 80]
let lowestEight = scores.suffix(20).min(count: 8, sortedBy: <)
let average = lowestEight.reduce(0.0) { $0 + Double($1) / Double(lowestEight.count) }
print(average - 72)

When trying to remove just one element in a nested numpy array the whole subarray gets deleted

I have a 3 dimensional numpy array (temp_X) like:
[ [[23,34,45,56],[34,45,67,78],[23,45,67,78]],
[[12,43,65,43],[23,54,67,87],[12,32,34,43]],
[[43,45,86,23],[23,45,56,23],[12,23,65,34]] ]
I want to remove the 1st element of each 3rd sub-array (highlighted values).
shown below is the code that i tried:
for i in range(len(temp_X)):
temp_X = np.delete(temp_X[i][(len(temp_X[i]) - 1)], [0])
Somehow when I run the code the whole array gets deleted except for 3 values. Any help is much appreciated. Thank you in advance.
With a as the 3D input array, here's one way -
m = np.prod(a.shape[1:])
n = m-a.shape[-1]
out = a.reshape(a.shape[0],-1)[:,np.r_[:n,n+1:m]]
Alternative to last step with boolean-indexing -
out = a.reshape(a.shape[0],-1)[:,np.arange(m)!=n]
Sample input, output -
In [285]: a
Out[285]:
array([[[23, 34, 45, 56],
[34, 45, 67, 78],
[23, 45, 67, 78]],
[[12, 43, 65, 43],
[23, 54, 67, 87],
[12, 32, 34, 43]],
[[43, 45, 86, 23],
[23, 45, 56, 23],
[12, 23, 65, 34]]])
In [286]: out
Out[286]:
array([[23, 34, 45, 56, 34, 45, 67, 78, 45, 67, 78],
[12, 43, 65, 43, 23, 54, 67, 87, 32, 34, 43],
[43, 45, 86, 23, 23, 45, 56, 23, 23, 65, 34]])
Here's another with mask creation to mask along the last two axes -
mask = np.ones(a.shape[-2:],dtype=bool)
mask[-1,0] = 0
out = np.moveaxis(a,0,-1)[mask].T

Taking minimum value of each entry +- 10 rows either side in numpy array

I have a 3d numpy array and want to generate a secondary array consisting of the minimum of each value and the values in the 10 rows directly above and 10 rows directly below (i.e each entry is the minimum value from 21 values) for each 2d array.
I've been trying to use 'numpy.clip' to deal with the edges of the array - here the range of values which the minimum is taken from should simply reduce to 10 at the values on the top/bottom of the array. I think something like 'scipy.signal.argrelmin' seems to be what I'm after.
Here's my code so far, definitely not the best way to go about it:
import numpy as np
array_3d = np.random.random_integers(50, 80, (3, 50, 18))
minimums = np.zeros(array_3d.shape)
for array_2d_index in range(len(array_3d)):
for row_index in range(len(array_3d[array_2d_index])):
for col_index in range(len(array_3d[array_2d_index][row_index])):
minimums[array_2d_index][row_index][col_index] = min(array_3d[array_2d_index][np.clip(row_index-10, 0, 49):np.clip(row_index+10, 0, 49)][col_index])
The main issue I think is that this is taking the minimum from the columns either side of each entry instead of the rows, which has been giving index errors.
Would appreciate any advice, thanks.
Approach #1
Here's one approach with np.lib.stride_tricks.as_strided -
def strided_3D_axis1(array_3d, L):
s0,s1,s2 = array_3d.strides
strided = np.lib.stride_tricks.as_strided
m,n,r = array_3d.shape
nL = n-L+1
return strided(array_3d, (m,nL,L,r),(s0,s1,s1,s2))
out = strided_3D_axis1(array_3d, L=21).min(axis=-2)
Sample run -
1) Input :
In [179]: array_3d
Out[179]:
array([[[73, 65, 51, 76, 59],
[74, 57, 75, 53, 70],
[60, 74, 52, 54, 60],
[54, 52, 62, 75, 50],
[68, 56, 68, 63, 77]],
[[62, 70, 60, 79, 74],
[70, 68, 50, 74, 57],
[63, 57, 69, 65, 54],
[63, 63, 68, 58, 60],
[70, 66, 65, 78, 78]]])
2) Strided view :
In [180]: strided_3D_axis1(array_3d, L=3)
Out[180]:
array([[[[73, 65, 51, 76, 59],
[74, 57, 75, 53, 70],
[60, 74, 52, 54, 60]],
[[74, 57, 75, 53, 70],
[60, 74, 52, 54, 60],
[54, 52, 62, 75, 50]],
[[60, 74, 52, 54, 60],
[54, 52, 62, 75, 50],
[68, 56, 68, 63, 77]]],
[[[62, 70, 60, 79, 74],
[70, 68, 50, 74, 57],
[63, 57, 69, 65, 54]],
[[70, 68, 50, 74, 57],
[63, 57, 69, 65, 54],
[63, 63, 68, 58, 60]],
[[63, 57, 69, 65, 54],
[63, 63, 68, 58, 60],
[70, 66, 65, 78, 78]]]])
3) Strided view based min :
In [181]: strided_3D_axis1(array_3d, L=3).min(axis=-2)
Out[181]:
array([[[60, 57, 51, 53, 59],
[54, 52, 52, 53, 50],
[54, 52, 52, 54, 50]],
[[62, 57, 50, 65, 54],
[63, 57, 50, 58, 54],
[63, 57, 65, 58, 54]]])
Approach #2
Here's another with broadcasting upon creating all sliding indices along the second axis -
array_3d[:,np.arange(array_3d.shape[1]-L+1)[:,None] + range(L)].min(-2)
Approach #3
Here's another using Scipy's 1D minimum filter -
from scipy.ndimage.filters import minimum_filter1d as minf
L = 21
hL = (L-1)//2
out = minf(array_3d,L,axis=1)[:,hL:-hL]
Runtime test -
In [231]: array_3d = np.random.randint(50, 80, (3, 50, 18))
In [232]: %timeit strided_3D_axis1(array_3d, L=21).min(axis=-2)
10000 loops, best of 3: 54.2 µs per loop
In [233]: %timeit array_3d[:,np.arange(array_3d.shape[1]-L+1)[:,None] + range(L)].min(-2)
10000 loops, best of 3: 81.3 µs per loop
In [234]: L = 21
...: hL = (L-1)//2
...:
In [235]: %timeit minf(array_3d,L,axis=1)[:,hL:-hL]
10000 loops, best of 3: 32 µs per loop

Defining long arrays in C

I want to define a very long array in C and at the mean time write the elements not side by side but in a vertical manner. The code block I typed will illustrate the situation. Which character should I use at the end of the line in order to continue the definition of the array "/" works but the preceding and following elements are not printed and a zero or a one is printed instead. How can I accomplish this?
int i, grades[40] = {49, 80, 84, 73, 89, 78, 78, 92, 56, 85, 10, 84, 59, 56
62, 53, 83, 81, 65, 81, 69, 69, 53, 55, 77, 82, 81, 76, 79, 83, 74, 86
78, 55, 66, 60, 68, 92, 87, 86};
Thanks for your contribution. I am on Ubuntu 12.04 by the way (thought the end line character may be different for Ubuntu and Windows).
Edit: Comma was the culprit. Sorry to take your time.
Escaping new-lines is only necessary in pre-processor directives and inside strings. Just enter it with all the white-space you like. As long as the compiler doesn't complain you should be good.
As discussed in the other answer the compiler is smart enough to recognize if a statement extends over several lines.
However, there actually is an explicit way to tell the compiler that the statement continues in the next line : \.
In your example you used a slash (/) instead of a backslash and forgot the ,. This lead to an integer division resulting in the 0 and 1 you observed.
If you want to use the '\' you could write the code like this:
int i, grades[40] = {49, 80, 84, 73, 89, 78, 78, 92, 56, 85, 10, 84, 59, 56, \
62, 53, 83, 81, 65, 81, 69, 69, 53, 55, 77, 82, 81, 76, 79, 83, 74, 86, \
78, 55, 66, 60, 68, 92, 87, 86};
In most cases, C compilers don't care about whitespace ( except for strings, etc. ). That means that as long as the syntax is still valid, you can have as much whitespace as you'd like. The only constraint is that each token has to be separated by at least one whitespace.
So, in short, you can write out the array with as many spaces, tabs, and newlines as you'd like, provided there is a comma after every element before the last one.

Rand() seems to not work properly [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why do I always get the same sequence of random numbers with rand()?
I've been experimenting with generating random numbers in C, and I've come across something weird. I don't know if it's only on my compiler but whenever I try to generate a pseudo-random number with the rand() function, it returns a very predictable number — the number generated with the parameter before plus 3.125 to be exact. It's hard to explain but here's an example.
srand(71);
int number = rand();
printf("%d", number);
This returns 270.
srand(72);
int number = rand();
printf("%d", number);
This returns 273.
srand(73);
int number = rand();
printf("%d", number);
This returns 277.
srand(74);
int number = rand();
printf("%d", number);
This returns 280.
Every eighth number is 4 higher. Otherwise it's 3.
This can't possibly be right. Is there something wrong with my compiler?
Edit: I figured it out — I created a function where I seed only once, then I loop the rand() and it generates random numbers. Thank you all!
The confusion here is about how pseudorandom number generators work.
Pseudorandom number generators like C's rand work by having a number representing the current 'state'. Every time the rand function is called, some deterministic computations are done on the 'state' number to produce the next 'state' number. Thus, if the generator is given the same input (the same 'state'), it will produce the same output.
So, when you seed the generator with srand(74), it will always generate the same string of numbers, every time. When you seed the generator with srand(75), it will generate a different string of numbers, etc.
The common way to ensure different output each time is to always provide a different seed, usually done by seeding the generator with the current time in seconds/milliseconds, e.g. srand(time(NULL)).
EDIT: Here is a Python session demonstrating this behavior. It is entirely expected.
>>> import random
If we seed the generator with the same number, it will always output the same sequence:
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
>>> random.seed(500)
>>> [random.randint(0, 100) for _ in xrange(20)]
[80, 95, 58, 25, 76, 37, 80, 34, 57, 79, 1, 33, 40, 29, 92, 6, 45, 31, 13, 11]
If we give it a different seed, even a slightly different one, the numbers will be totally different from the old seed, yet still the same if the same (new) seed is used:
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
>>> random.seed(501)
>>> [random.randint(0, 100) for _ in xrange(20)]
[64, 63, 24, 81, 33, 36, 72, 35, 95, 46, 37, 2, 76, 21, 46, 68, 47, 96, 39, 36]
How do we make our program have different behavior each time? If we supply the same seed, it will always behave the same. We can use the time.time() function, which will yield a different number each time we call it:
>>> import time
>>> time.time()
1347917648.783
>>> time.time()
1347917649.734
>>> time.time()
1347917650.835
So if we keep re-seeding it with a call to time.time(), we will get a different sequence of numbers each time, because the seed is different each time:
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[60, 75, 60, 26, 19, 70, 12, 87, 58, 2, 79, 74, 1, 79, 4, 39, 62, 20, 28, 19]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[98, 45, 85, 1, 67, 25, 30, 88, 17, 93, 44, 17, 94, 23, 98, 32, 35, 90, 56, 35]
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[44, 17, 10, 98, 18, 6, 17, 15, 60, 83, 73, 67, 18, 2, 40, 76, 71, 63, 92, 5]
Of course, even better than constantly re-seeding it is to seed it once and keep going from there:
>>> random.seed(time.time())
>>> [random.randint(0, 100) for _ in xrange(20)]
[94, 80, 63, 66, 31, 94, 74, 15, 20, 29, 76, 90, 50, 84, 43, 79, 50, 18, 58, 15]
>>> [random.randint(0, 100) for _ in xrange(20)]
[30, 53, 75, 19, 35, 11, 73, 88, 3, 67, 55, 43, 37, 91, 66, 0, 9, 4, 41, 49]
>>> [random.randint(0, 100) for _ in xrange(20)]
[69, 7, 25, 68, 39, 57, 72, 51, 33, 93, 81, 89, 44, 61, 78, 77, 43, 10, 33, 8]
Every invocation of rand() returns the next number in a predefined sequence where the starting number is the seed supplied to srand(). That' why it's called a pseudo-random number generator, and not a random number generator.
rand() is implemented by a pseudo random number generator.
The distribution of numbers generated by consecutive calls to rand() have the properties of being random numbers, but the order is pre-determined.
The 'start' number is determined by the seed that you provide.
You should give a PRNG a single seed only. Providing it with multiple seeds can radically alter the randomness of the generator. In addition, providing it the same seed over and over removes all randomness.
Generating a "random" number regardless of the implementation is dependent on a divergent infinite sequence. The infinite sequence is generated using the seed of the random function and it is actually pseudo random because of its nature. This would explain to you why your number is actually very dependent on the seed that you give the function.
In some implementations the sequence is only one and the seed is the starting member of the sequence. In others there are difference sequences depending on the seed. If a seed is not provided then the seed is determined by the internal "clock".
The number is truncated when using an upper and lower bounds for your random number by respectively doing randValue % upperBound and randValue + lowerBound. Random implementation is very similar to Hash Functions. Depending on architecture the upper bound of the random value is set depending on what it the largest integer/double that it can carry out if not set lower by the user.

Resources