I have an array, tiles, which contains tiles in a tileset. I also have a 15x10 2 dimensional array, room, which has numbers corresponding to the tiles in tiles. What I'm having trouble with is this:
room = { ... } -- 15x10 2d array
csv = require("csv") -- load a csv file, not relevant to the problem
file = csv.open("room/room-0.0.csv")
row = 1
for fields in file:lines() do
for col, val in ipairs(fields) do
room[row][col] = val
end
row = row + 1
end
-- room looks something like this:
-- { {1, 4, 2, 3, 2, ...},
-- ...
-- {3, 3, 2, 4, 2, ...} }
All is well at this point. Here is where things go wrong though:
tiles = {"banana", "apple", "orange", "pitaya"}
for i, j in ipairs(room) do -- looping through room
print("-------")
for k, tilenum in ipairs(j) do -- tilenum = room[i][k]
print(tiles[tilenum]) -- tiles[room[k][i]]
end -- tiles[tilenum] == nil
end
The output:
-------
nil
nil
nil
nil
nil
...
What should happen:
-------
banana
pitaya
apple
orange
apple
...
Note: Though the objects actually in tiles are not printable, I have tried this example with numbers, strings, etc. They don't work.
You are not showing the value of tilenum, but I suspect that even if it's a number, it's in a string form, and when indexing Lua tables, "1" index is not the same as 1 index (and that's probably why your tiles[tilenum] returns nil).
You need to check the val values you assign (that later become tilenum) and if they are indeed numbers, then change = val to = tonumber(val).
Related
I am new to Scala and this is the first time I'm using it. I want to read in a textfile with with two columns of numbers and store each column items in a separate list or array that will have to be cast as integer. For example the textfile looks like this:
1 2
2 3
3 4
4 5
1 6
6 7
7 8
8 9
6 10
I want to separate the two columns so that each column is stored in its on list or array.
Lets say you named the file as "columns", this would be a solution:
val lines = Source.fromFile("columns").getLines()
/* gets an Iterator[String] which interfaces a collection of all the lines in the file*/
val linesAsArraysOfInts = lines.map(line => line.split(" ").map(_.toInt))
/* Here you transform (map) any line to arrays of Int, so you will get as a result an Interator[Array[Int]] */
val pair: (List[Int], List[Int]) = linesAsArraysOfInts.foldLeft((List[Int](), List[Int]()))((acc, cur) => (cur(0) :: acc._1, cur(1) :: acc._2))
/* The foldLeft method on iterators, allows you to propagate an operation from left to right on the Iterator starting from an initial value and changing this value over the propagation process. In this case you start with two empty Lists stored as Tuple an on each step you prepend the first element of the array to the first List, and the second element to the second List. At the end you will have to Lists with the columns in reverse order*/
val leftList: List[Int] = pair._1.reverse
val rightList: List[Int] = pair._2.reverse
//finally you apply reverse to the lists and it's done :)
Here is one possible way of doing this:
val file: String = ??? // path to .txt in String format
val source = Source.fromFile(file)
scala> val columnsTogether = source.getLines.map { line =>
val nums = line.split(" ") // creating an array of just the 'numbers'
(nums.head, nums.last) // assumes every line has TWO numbers only
}.toList
columnsTogether: List[(String, String)] = List((1,2), (2,3), (3,4), (4,5), (1,6), (6,7), (7,8), (8,9), (6,10))
scala> columnsTogether.map(_._1.toInt)
res0: List[Int] = List(1, 2, 3, 4, 1, 6, 7, 8, 6)
scala> columnsTogether.map(_._2.toInt)
res1: List[Int] = List(2, 3, 4, 5, 6, 7, 8, 9, 10)
I have a list of cell array with many repeated values, which includes strings, sample time, saturation upper limit and lower limit.
For example:
MyValues={ 'Lookc_at_the_stars'
'Lookc_how_they_shine'
'forc_you'
'andm_everything_they_do'
'Theym_were_all_yellow'
'COLDPLAY_STOP'
'COLDPLAY_PLAY'
'COLDPLAY_PLAY'
'COLDPLAY_PLAY'
'COLDPLAY_BREAK'
'COLDPLAY_BREAK'
'Lookc_How_they_shinefor_you'
'its_true'
'COLDPLAY_STOP'
'COLDPLAY_STOP' }
And the output what I require is:
NewMyValues = { 'Lookc_at_the_stars'
'Lookc_how_they_shine'
'forc_you'
'andm_everything_they_do'
'Theym_were_all_yellow'
'COLDPLAY_STOP'
'COLDPLAY_PLAY'
'COLDPLAY_BREAK'
'Lookc_How_they_shinefor_you'
'its_true' }
Since I have tried using the function unique, I am not able to get the output as it's giving me an error, saying
"Error using cell/unique
Input A must be a cell array of strings."
MyValues consists of different types of data type values.
Can someone provide me a solution or function code, that I could remove the repeated values?
Here is a loop based solution to extract unique values of a cell array will different types:
MyValues={ 'Lookc_at_the_stars',
'Lookc_how_they_shine',
1,
'forc_you',
'andm_everything_they_do',
'Theym_were_all_yellow',
2,
'COLDPLAY_STOP',
'COLDPLAY_PLAY',
1,
'COLDPLAY_PLAY',
'COLDPLAY_PLAY',
{1 2 3},
'COLDPLAY_BREAK',
{4 3 5},
'COLDPLAY_BREAK',
{1 2 3},
'Lookc_How_they_shinefor_you',
'its_true',
'COLDPLAY_STOP',
'COLDPLAY_STOP' };
N = numel(MyValues);
idx = true(N,1);
for m = 1: N
if idx(m)
for n = (m+1):N
if idx(n) && isequal(MyValues{m}, MyValues{n})
idx(n) = false;
end
end
end
end
result = MyValues(idx);
the result:
result =
{
[1,1] = Lookc_at_the_stars
[1,2] = Lookc_how_they_shine
[1,3] = 1
[1,4] = forc_you
[1,5] = andm_everything_they_do
[1,6] = Theym_were_all_yellow
[1,7] = 2
[1,8] = COLDPLAY_STOP
[1,9] = COLDPLAY_PLAY
[1,10] =
{
[1,1] = 1
[1,2] = 2
[1,3] = 3
}
[1,11] = COLDPLAY_BREAK
[1,12] =
{
[1,1] = 4
[1,2] = 3
[1,3] = 5
}
[1,13] = Lookc_How_they_shinefor_you
[1,14] = its_true
}
The function isequal can compare anything using it all values compared and duplicates removed. so result is a cell array that contains unique values.
Based on the example in the question if you want to have unique cell array of characters you can use cellfun with ischar to check if the cell value is a character array. Then use the logical index to extract them and apply unique.
unique(MyValues(cellfun(#ischar,MyValues)),'stable')
without using stable option the result will be sorted
The cell you supplied in your question only contained strings, so unique can handle it. However, if you add ints, floats or complex numbers to it, the way to go is to convert all the cell elements to strings before calling unique. For example, I'll show you a small strcaster function
function y = strcaster(x)
if ischar(x)
y = x;
elseif isreal(x)
y = num2str(x);
else
if imag(x)>=0
s = '+j';
else
s = '-j';
end
y = [num2str(real(x)),s,num2str(imag(x))];
end
end
and then you can get the unique elements, preserving the order in which they appear in the cell doing the following:
MyValues={'Lookc_at_the_stars',...
'Lookc_how_they_shine',...
'forc_you',...
'andm_everything_they_do',...
'Theym_were_all_yellow',...
'COLDPLAY_STOP',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_BREAK',...
'COLDPLAY_BREAK',...
'Lookc_How_they_shinefor_you',...
'its_true',...
'COLDPLAY_STOP',...
'COLDPLAY_STOP',...
1,...
1.32423,...
complex(-3.,13)};
[u,i] = unique(cellfun(#(x)strcaster(x),MyValues,'uniformoutput',false),'stable');
disp(MyValues(i))
Edit
Based on your comment, it is clear that the MyValues cell contains other cells, which was not clear from your question's example. The best way to get the unique values in MyValues is still casting the contents to strings. The JSON protocol will allow you to convert almost any data type to a string, so I recommend using matlab's jsonencode function in the following way:
MyValues={'Lookc_at_the_stars',...
'Lookc_how_they_shine',...
'forc_you',...
'andm_everything_they_do',...
'Theym_were_all_yellow',...
'COLDPLAY_STOP',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_PLAY',...
'COLDPLAY_BREAK',...
'COLDPLAY_BREAK',...
'Lookc_How_they_shinefor_you',...
'its_true',...
'COLDPLAY_STOP',...
'COLDPLAY_STOP',...
1,...
1.32423,...
[1,23,4,4;5,3,2,1],...
{'bla',1324,{'12',123}},...
struct('NextTime','Provide a complete working example in the question')};
[u,i] = unique(cellfun(#(x)jsonencode(x),MyValues,'uniformoutput',false),'stable');
disp(MyValues(i))
If I have the following array:
x = double([1, 1, 1, 10, 1, 1, 50, 1, 1, 1 ])
I want to do the following:
Group the array into groups of 5 which will each be evaluated separately.
Identify the MAX value each of the groups of the array
Remove that MAX value and put it into another array.
Finally, I want to print the updated array x without the MAX values, and the new array containing the MAX values.
How can I do this? I am new to IDL and have had no formal training in coding.
I understand that I can write the code to group and find the max values this way:
FOR i = 1, (n_elements(x)-4) do begin
print, "MAX of array", MAX( MAX(x[i-1:1+3])
ENDFOR
However, how do I implement all of what I specified above? I know I have to create an empty array that will append the values found by the for loop, but I don't know how to do that.
Thanks
I changed your x to have unique elements to make sure I wasn't fooling myself. It this, the number of elements of x must be divisible by group_size:
x = double([1, 2, 3, 10, 4, 5, 50, 6, 7, 8])
group_size = 5
maxes = max(reform(x, group_size, n_elements(x) / group_size), ind, dimension=1)
all = bytarr(n_elements(x))
all[ind] = 1
x_without_maxes = x[where(all eq 0)]
print, maxes
print, x_without_maxes
Lists are good for this, because they allow you to pop out values at specific indices, rather than rewriting the whole array again. You might try something like the following. I've used a while loop here, rather than a for loop, because it makes it a little easier in this case.
x = List(1, 1, 1, 10, 1, 1, 50, 1, 1, 1)
maxValues = List()
pos = 4
while (pos le x.length) do begin
maxValues.add, max(x[pos-4:pos].toArray(), iMax)
x.Remove, iMax+pos-4
pos += 5-1
endwhile
print, "Max Values : ", maxValues.toArray()
print, "Remaining Values : ", x.toArray()
This allows you to do what you want I think. At the end, you have a List object (which can easily be converted to an array) with the max values for each group of 5, and another containing the remaining values.
Also, please tag this as idl-programming-language rather than idl. They are two different tags.
I have an array of objects (or just numbers), and I have another array which contains all the objects that should not be removed from the first array in any circumstances. It looks something like this:
-- Array of objects (just numbers for now)
Objects = {}
-- Array of objects that should always stay in the 'Objects' array
DontDestroyThese = {}
-- Populate the arrays
Objects[#Objects+1] = 1
Objects[#Objects+1] = 2
Objects[#Objects+1] = 3
Objects[#Objects+1] = 4
Objects[#Objects+1] = 5
DontDestroyThese[#DontDestroyThese+1] = 2
DontDestroyThese[#DontDestroyThese+1] = 5
Now, I have a method called destroy() that should remove all objects from the Objects array except those included in the DontDestroyThese array. The method looks something like this:
function destroy()
for I = 1, #Objects do
if(DontDestroyThese[Objects[I]] ~= nil) then
print("Skipping " .. Objects[I])
else
Objects[I] = nil
end
end
end
However, as the result, the Objects array now contains nil values here and there. I'd like to remove these nils so that the Objects array would consist only of the numbers that were left there after calling destroy(). How do I do that?
The most efficient way is probably to create a new table to hold the result. Trying to move values around in the array is likely to have a higher overhead than simply appending to a new table:
function destroy()
local tbl = {}
for I = 1, #Objects do
if(DontDestroyThese[Objects[I]] ~= nil) then
table.insert(tbl, Objects[I])
end
end
Objects = tbl
end
This method also means you don't have to deal with altering the contents of the table/array you're iterating over.
I think the solution is much simpler. To remove any nils ('holes' in your array), all you need to do is iterate your table using pairs(). This will skip over any nils returning only the non-nil values that you add to a new local table that is returned in the end of the 'cleanup' function. Arrays (tables with indices from 1..n) will remain with the same order. For example:
function CleanNils(t)
local ans = {}
for _,v in pairs(t) do
ans[ #ans+1 ] = v
end
return ans
end
Then you simply need to do this:
Objects = CleanNils(Objects)
To test it:
function show(t)
for _,v in ipairs(t) do
print(v)
end
print(('='):rep(20))
end
t = {'a','b','c','d','e','f'}
t[4] = nil --create a 'hole' at 'd'
show(t) --> a b c
t = CleanNils(t) --remove the 'hole'
show(t) --> a b c e f
local function remove(t, pred)
for i = #t, 1, -1 do
if pred(t[i], i) then
table.remove(t, i)
end
end
return t
end
local function even(v)
return math.mod(v, 2) == 0
end
-- remove only even numbers
local t = remove({1, 2, 3, 4}, even)
-- remove values you want
local function keep(t)
return function(v)
return not t[v]
end
end
remove(Objects, keep(DontDestroyThese))
I have the following array, with (I think) sub lists within it:
items = [('this', 5, 'cm'), ('that', 3, 'mm'), ('other', 15, 'mm')]
I need to read it into new values for future calculations.
For example:
item1 = this
size1 = 5
unit1 = cm
item2 = that
size2 = 3
unit2 = mm
...
There may be more than 3 items in future arrays, so ideally some form of loop is needed?
Arrays in Python can be of 2 types - Lists & Tuples.
list is mutable (i.e. you can change the elements as & when you wish)
tuple is immutable (read only array)
list is represented by [1, 2, 3, 4]
tuple is represented by (1, 2, 3, 4)
Thus, the given array is a list of tuples!
You can nest tuples in lists but not lists in tuples.
This is more pythonic -
items = [('this', 5, 'cm'), ('that', 3, 'mm'), ('other', 15, 'mm')]
found_items = [list(item) for item in items]
for i in range(len(found_items)):
print (found_items[i])
new_value = int(input ("Enter new value: "))
for i in range(len(found_items)):
recalculated_item = new_value * found_items[i][1]
print (recalculated_item)
Output from above code (taking input as 3)
['this', 5, 'cm']
['that', 3, 'mm']
['other', 15, 'mm']
15
9
45
Update : Following up on this comment & this answer I've updated the above code.
Following on Ashish Nitin Patil's answer...
If there are are going to be more than three items in the future you can use the asterisk to unpack the items in the tuples.
items = [('this', 5, 'cm'), ('that', 3, 'mm'), ('other', 15, 'mm')]
for x in items:
print(*x)
#this 5 cm
#that 3 mm
#other 15 mm
Note: Python 2.7 doesn't seem to like the asterisk in the print method.
Update:
It looks like you need to use a second list of tuples that defines the property names of each value tuple:
props = [('item1', 'size2', 'unit1'), ('item2', 'size2', 'unit2'), ('item3', 'size3', 'unit3')]
values = [('this', 5, 'cm'), ('that', 3, 'mm'), ('other', 15, 'mm')]
for i in range(len(values)):
value = values[i]
prop = props[i]
for j in range(len(item)):
print(prop[j], '=', value[j])
# output
item1 = this
size2 = 5
unit1 = cm
item2 = that
size2 = 3
unit2 = mm
item3 = other
size3 = 15
unit3 = mm
The caveat here is that you need to make sure that the elements in the props list are matched sequentially with the elements in the values list.