I am learning how to make a multiplication table in swift and used
override func viewDidLoad() {
let n = Int(str)!
while (i<=10) {
let st = "\(n) * \(i) = \(n * i)"
lbl.text = st
i += 1
}
this code. i have a label in which i want to show the table, but the problem is that only the last result which is say 2*10 = 20 is showing and not all the other value. i am confused what to do, please help what to do so that all the values are displayed.
Glad you've decided to learn Swift. You're on the right track, but as others have said, your final iteration of the loop is replacing the contents of lbl.text.
There are many ways to achieve what you want, but for problems like this I'd suggest starting off working in a playground rather than worrying about labels, viewDidLoad and suchlike.
Here's a nice Swift-y way to do what you want
let n = 12
let table = Array(0...10).map({"\(n) * \($0) = \(n * $0)"}).joinWithSeparator("\n")
print("\(table)")
Gives…
12 * 0 = 0
12 * 1 = 12
12 * 2 = 24
12 * 3 = 36
12 * 4 = 48
12 * 5 = 60
12 * 6 = 72
12 * 7 = 84
12 * 8 = 96
12 * 9 = 108
12 * 10 = 120
To break that down…
// Take numbers 0 to 10 and make an array
Array(0...10).
// use the map function to convert each member of the array to a string
// $0 represents each value in turn.
// The result is an array of strings
map({"\(n) * \($0) = \(n * $0)"}).
// Join all the members of your `String` array with a newline character
joinWithSeparator("\n")
Try it for yourself. In Xcode, File -> New -> Playground, and just paste in that code. Good luck!
That's because every time the loop iterates, it overwrites the previous value in label.text. You need to append the new value to existing string value in label, as suggested by RichardG.
let n = Int(str)!
while (i<=10) {
let st = "\(n) * \(i) = \(n * i)"
lbl.text = lbl.text + " " +st //Append new value to already existing value in label.text
i += 1
}
There is also a possibility of UI issue. You have to provide number of lines to the label or it will mess up the display. It also needs to be of size enough to hold your data. A better option would be UITextView which is scrollable, if you are unwilling to handle cases for label height and width. But if you want to stick with UILabel, the following code will resize the label depending on text for you:
lbl.numberOfLines = 0; //You only need to call this once. Maybe in `viewDidLoad` or Storyboard itself.
lbl.text = #"Some long long long text"; //here you set the text to label
[lbl sizeToFit]; //You must call this method after setting text to label
You can also handle that by Autolayout constraints.
Easy way to do it with SWIFT 2.0
var tableOf = 2 //Change the table you want
for index in 1...10 {
print("\(tableOf) X \(index) = \(index * tableOf)")
}
OUTPUT
repeat-while loop, performs a single pass through the loop block first before considering the loop's condition (exactly what do-while loop does).
1) repeat...while Loop
var i = Int()
repeat {
print("\(i) * \(i) = \(i * 11)")
i += 1
} while i <= 11
2) While Loop
var i = Int()
while i <= 11
{
print("\(i) * \(i) = \(i * 11)")
i += 1
}
3) For Loop
for n in 1..<11
{
print("\(n) * \(n) = \(n * 10)")
}
Related
I am writing a wireshark dissector of a custom protocol using LUA.For this custom protocol,there are no underlying TCP port or UDP port hence i have written a postdissector.
I am able to capture the payload from the below layers and convert it into a string.
local io_b = tostring(customprotocol)
After this, io_b has the following data
io_b = 10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00
At first I split this string with : as the seperator and copy the elements into an array/table.
datafields = {}
index = 1
for value in string.gmatch(io_b, "[^:]+") do
datafields[index] = value
index = index + 1
end
Then I read each element of the datafield array as a uint8 value and check if a bit is set in that datafield element.How to make sure that each element of the table is uint8?
function lshift(x, by)
return x * 2 ^ by
end
--checks if a bit is set at a position
function IsBitSet( b, pos)
if b ~= nil then
return tostring(bit32.band(tonumber(b),lshift(1,pos)) ~= 0)
else
return "nil"
end
end
Then I want to display the value of each bit in the wireshark.I dont care about the first four bytes. The script displays each bit of the 5th byte(which is the 1st considered byte) correctly but displays all the bits value of the 6th byte and other remaining bytes as "nil".
local data_in_2 = subtree:add(customprotocol,"secondbyte")
data_in_2:add(firstbit,(IsBitSet((datafields[6]),7)))
data_in_2:add(secondbit,(IsBitSet((datafields[6]),6)))
data_in_2:add(thirdbit,(IsBitSet((datafields[6]),5)))
data_in_2:add(fourbit,(IsBitSet((datafields[6]),4)))
data_in_2:add(fivebit,(IsBitSet((datafields[6]),3)))
data_in_2:add(sixbit,(IsBitSet((datafields[6]),2)))
data_in_2:add(sevenbit,(IsBitSet((datafields[6]),1)))
data_in_2:add(eightbit,(IsBitSet((datafields[6]),0)))
What am i doing wrong?
Maybe i am wrong but it seems you can do it simpler with...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Now replace all : on the fly with nothing and convert it with #Egor' comment tip
-- Simply by using string method gsub() from within io_b
b_num = tonumber(io_b:gsub('%:', ''), 16)
print(b_num)
-- Output: 537526272
#shakingwindow - I cant comment so i ask here...
Do you mean...
io_b = '10:10:10:10:01:0f:00:0d:00:00:00:00:01:00:00:00:00:20:0a:00:00'
-- Converting HEX to string - Replacing : with ,
io_hex = io_b:gsub('[%x]+', '"%1"'):gsub(':', ',')
-- Converting string to table
io_hex_tab = load('return {' .. io_hex .. '}')()
-- Put out key/value pairs by converting HEX value string to a number on the fly
for key, value in pairs(io_hex_tab) do
print(key, '=', tonumber(value, 16))
end
...that puts out...
1 = 16
2 = 16
3 = 16
4 = 16
5 = 1
6 = 15
7 = 0
8 = 13
9 = 0
10 = 0
11 = 0
12 = 0
13 = 1
14 = 0
15 = 0
16 = 0
17 = 0
18 = 32
19 = 10
20 = 0
21 = 0
...?
This might be a lame question and even have already answered in SO.i have even searched about this but could not understand in a proper way. what is happening here..??please help me out to understand this.
let size = Double(arc4random_uniform(5)) + 1
for index in 0..<ITEM_COUNT
{
let y = Double(arc4random_uniform(100)) + 50.0
let size = Double(arc4random_uniform(5)) + 1
entries.append(ChartEntry(x: Double(index) + 0.5, y: y, size: CGFloat(size)))
}
arc4random_uniform(x) returns a random value between 0 and x-1
Examples:
arc4random_uniform(2) -> returns 0 or 1 randomly
arc4random_uniform(2) == 0 returns true or false randomly
arc4random_uniform(6) + 1 returns a number between 1 and 6 (like a dice roll)
There are a multitude of reasons that arc4random_uniform(5) returns a number between 0 and 5, but the main one is that this is a basic functionality in programming, where numbers start at zero. An example of why this would be useful would be returning a random value from an array. Example:
func randomArrayValue(array: [Int]) -> Int {
let index = arc4random_uniform(array.count)
return array[index]
}
let arrayOfInt = [10,20,30]
print("Random Int: \(randomArrayValue(array: arrayOfInt))")
//"Random Int: 10"
//"Random Int: 20"
//"Random Int: 30"
For these three lines of code in your questions:
let y = Double(arc4random_uniform(100)) + 50.0
let size = Double(arc4random_uniform(5)) + 1
entries.append(ChartEntry(x: Double(index) + 0.5, y: y, size: CGFloat(size)))
y is a random variable between 50 and 149
size is a random variable between 1 and 5
you then add an item onto an array that goes onto a chart. The value being added specifies the x location (the index) and the y location (the random y value). Size is some code specific requirement, which we wouldn't be able to help with without seeing the functionality.
I was trying to do something about percentages but i think i did something wrong.
let randomNum = arc4random_uniform(25) + 71
let wrongNumber = 100 - Int(randomNum)
let firstWrong = wrongNumber - 10
var first = arc4random_uniform(UInt32(firstWrong))
var second = arc4random_uniform(UInt32(wrongNumber) - first)
var third = arc4random_uniform(UInt32(wrongNumber) - (first + second))
let plus = (UInt32(wrongNumber) - (first + second + third)) / 3
first = first + plus
second = second + plus
third = third + plus
let total = randomNum + first + second + third
if (total < 100) {
first += (100 - total)
}
It sometimes gives this BAD INSTRUCTION error
And it usually works fine
Your logic is completely flawed, consider the first few lines:
let randomNum = arc4random_uniform(25) + 71 // values 71 ... 95
let wrongNumber = 100 - Int(randomNum) //values 5 ... 29
let firstWrong = wrongNumber - 10 // -5 ... 19
The maximum randomNum is 95. Then wrongNumber is 5 and firstWrong is -5.
Then
var first = arc4random_uniform(UInt32(firstWrong))
has to crash when casting -5 to an unsigned number.
Similar errors can happen on other lines if the values get into negatives.
I am trying to translate some sample code from objective-c into swift!
I got it all working except for the multithreading part which is cruical to this simulation.
For some reason when I start using multiple threads it has access errors. Specefically when getting or setting things from the array.
This class is instanced inside of a static class.
var screenWidthi:Int = 0
var screenHeighti:Int = 0
var poolWidthi:Int = 0
var poolHeighti:Int = 0
var rippleSource:[GLfloat] = []
var rippleDest:[GLfloat] = []
func update()
{
let queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_apply(Int(poolHeighti), queue, {(y: size_t) -> Void in
//for y in 0..<poolHeighti
//{
let pw = self.poolWidthi
for x in 1..<(pw - 1)
{
let ai:Int = (y ) * (pw + 2) + x + 1
let bi:Int = (y + 2) * (pw + 2) + x + 1
let ci:Int = (y + 1) * (pw + 2) + x
let di:Int = (y + 1) * (pw + 2) + x + 2
let me:Int = (y + 1) * (pw + 2) + x + 1
let a = self.rippleSource[ai]
let b = self.rippleSource[bi]
let c = self.rippleSource[ci]
let d = self.rippleSource[di]
var result = (a + b + c + d) / 2.0 - self.rippleDest[me]
result -= result / 32.0
self.rippleDest[me] = result
}
}
)
}
It is important to note that there is also another loop that should run on a different thread right after this one, it acesses the same arrays. That being said it will still bad acess without having the 2nd in another thread so I feel that it is irrelivant to show.
If you could please tell me what is going on that causes this crash to happen at randomish times rather then the first time.
If you want reference here is what it was like in objective c
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_apply(poolHeight, queue, ^(size_t y) {
for (int x=0; x<poolWidth; x++)
{
float a = rippleSource[(y)*(poolWidth+2) + x+1];
float b = rippleSource[(y+2)*(poolWidth+2) + x+1];
float c = rippleSource[(y+1)*(poolWidth+2) + x];
float d = rippleSource[(y+1)*(poolWidth+2) + x+2];
float result = (a + b + c + d)/2.f - rippleDest[(y+1)*(poolWidth+2) + x+1];
result -= result/32.f;
rippleDest[(y+1)*(poolWidth+2) + x+1] = result;
}
});
How do you ensure that variables are able to be accessed from different threads? How about static members?
I only no how to print out the call stack before the app crashes, however after, the only way I know to get to the call stack is to look at the threads. Let me know if there is a different way I should do this.
NOTE: I noticed something wierd. I put a print statement in each loop so I could see what x and y coordinate it was processing to see if the crash was consistant. Obiously that brought the fps down to well under 1 fps, however I did notice it has yet to crash. The program is running perfect so far without any bad acess just at under 1 fps.
The Apple code is using a C-style array, these are "thread safe" when used appropriately - as the Apple code does.
Swift, and Objective-C, arrays are not thread-safe and this is the cause of your issues. You need to implement some form of access control to the array.
A simple method is to associate a GCD sequential queue with each array, then to write to the array dispatch async to this queue, and to read dispatch sync. This is simple but reduces concurrency, to make it better read Mike Ash. For Swift code
Mike Ash is good if you need to understand the issues, and for Swift code you and look at this question - read all the answers and comments.
HTH
I have a dynamic array. I need to display tableview as following scenario...
In the First cell i need to display 1 item.
In the second cell i need to display 2 items.
In the third cell i need to display 3 items.
In the forth cell i need to display 1 item.
In the fifth cell i need to display 2 items.
In the sixth cell i need to display 3 items.
and so on...
Could any one please suggest how to return no of rows in a section.
Try this :
int noOfRow = total/2 + ceil((total % 3)/3.0);
Simple logic for this is:
NoOfRows = TotalCount / 2
For e.g.:
If last value is 6 then, total no of rows are (6 / 2) = 3
If last value is 12 then, total no of rows are (12 / 2) = 6
You have to think logical that's it.
Hope this helps.
A faster method might be:
Notice in the divide by 2 method, most numbers work. The ones don't work are:
2, 4, 8, 10... basically, even numbers that aren't divisible by 6.
So we can come up with something like:
int count = array.count;
if (count % 2 == 0 && count % 6 != 0) {
count + 2;
}
int rows = ceilf(count / 2);
Or we can write a for loop:
int counter = array.size;
int rows = 0;
int dec = 1;
while (counter > 0) {
rows++;
counter - dec;
dec = dec % 3 + 1;
}
The for loop is of course, slower.