Please assist in discovering error in MATLAB function - database

I am taking a MATLAB programming class and we are currently working on a project which uses a database called Project2 of several structs of airline flight data (all 1 x N). One exercise requires us to create a function that identifies the number of flights segments (housed in the flights struct) that used the Boeing 737-800 aircraft. Below I have included the code for the function I created (NOTE: The format of the first line is such that was dictated in the instructions and must remain that way). Although this function seems to work and be free of bugs, it consistently returns a result of 0 and I cannot figure out why. Can anyone help? Suggestions for fixing the problem and/or cleaning up the code would be greatly appreciated!
function total = Problem2 (flights, aircraft, airlines, airports)
load Project2
id=findAircraftID (aircraft, Boeing 737-800)
seg=0;
for jj = 1:length(flights)
if (strcmp (flights(1,jj).aircraft_id, id))
seg=seg+1
end
end
fprintf ('A total of %d flight segments used the Boeing 737-800 aircraft.\n', seg)
end
function id=findAircraftID (aircraft, AircraftName)
id=0;
for ii=1:length(aircraft)
if (strcmp (aircraft(1,ii).name, AircraftName))
id=ii;
return;
end
end
end

Why are you using strcmp to compare integers? Is aircraft_id a string? Perhaps you can cast id from an int to a string if so. Or better yet you can just use isequal(a,b):
if isequal(flights(1,jj).aircraft_id, id)
seg=seg+1;
end
Also see other methods at Octave/MATLAB: How to compare structs for equality?
Also (or alternatively if that's not the issue) you're iterating through your second function and setting id several times, but only the last value goes into the first function. Take a closer look at your for loops to see whether you need to wrap them, store id as an array rather than a single integer, etc.
Never mind I see that your code could work if aircraft names are unique. strcmp should work in that case - but perhaps step through and check that you aren't having issues because of capitalization, spaces, etc.

Usually when you want to find an element in an array that matches a condition, you use something like
bWhenAis3 = B(A == 3);
To find the value of B when A is 3. This can return a vector of multiple values, and is usually much faster than an explicit loop.
In your code, aircraftID is an integer because it's returned by findAircraftID which returns ii. You cannot compare this with a string! You need to compare like types.

Related

How can I read a parameter array from excel so that its values are available when stocks are initialized?

The problem:
I need to read a row of values from an excel spreadsheet into a parameter array and use these values to set the initial values of stocks.
The specifics:
a. I can successfully set the scalar parameters default values from excel using ExcelControlName.getCellNumericValue("ExcelSheetName", RowNumber, ColumnNumber).
b. Trying to set default values for array parameters with ExcelControlName.readHyperArray(DestinationArrayName,"ExcelSheetName",RowNumber, ColumnNumber, false) returns a "Cannot return a void result" error on build.
c. I can read the parameter arrays from a function called from the Agent actions "On startup:" section using ExcelControlName.readHyperArray(DestinationArrayName,"ExcelSheetName",RowNumber, ColumnNumber, false).
d. Stocks with their initial values set to the parameter array that was successfully loaded by the function are all zero even though the parameter array shows values (when run). Initial value: ParameterArrayName.
e. When I set the parameter array values through the value editor the stocks initialize correctly.
My suspicion:
I'm thinking that the issue has something to do with the internal timing within the entrails of the model generated by Anylogic such that the function to load the parameters is executed after the stocks get initial values - but that could just be the delirium caused by repeatedly smashing my forehead into the wall. But, if this is indeed the case, how can I sneak the function in earlier or, better yet, how would someone who actually knows what they're doing accomplish this?
What I'm trying to accomplish:
As a septuagenarian with lots of time on my hands and a vague recollection of dynamic modeling using Dynamo from a Systems Science program in the early seventies (and not used since), I thought I'd take a whack at age-based modeling of the COVID-19 pandemic. I wanted to see, among other things, whether establishing elder-prisons (in now vacant Club-Meds, Sandals... I'm sure) would be an economically advantageous strategy. Getting there requires dis-aggregating classic SIR approaches into age-specific chains of causality. So far, I'm at 27 age-specific parameters for eight age-groups and 24 scalar parameters. As much as I'd like to type and retype... all this data I'm really hoping there is a better way.
I must say that I am amazed at how far modeling has come in only 50 or so years and I am enthralled with Anylogic's application - even though it's a bit java-ish for me.
Thank you ever so much,
Carl Cottrell
Equivalent parameter arrays - one with values entered in edit the other read from excel file through a function
Not sure if I understand but here it goes:
I understand that you have the following structure:
and you want to initialize the stock as follows.
To do that, on the initial value of your parameter use a function that returns an HyperParameter:
the function getInitialValue should return an HyperParameter and I think this code should work for you (you have to choose RowNumber according to whatever is on your excelfile, MyDimension is the name of your dimension, and ExcelControlName is the excel in which you hold the values of the initial values of the stock)
HyperArray x=new HyperArray(MyDimension);
for(int i=0;i<=numColumns;i++){
x.set(ExcelControlName.getCellNumericValue("ExcelSheetName", RowNumber, i), i);
}
return x;

Minimal element of an array

An abstract question, not related to any particular language:
If I have a function as follows
min(int, int) :: int
which returns the smallest value in an array, and
concat([int], [int]) :: [int]
which combines two arrays, how should I write a function like
minInArray([int]) :: Int
which returns the smallest element in an array, but where the ouput could be chained like so, even with an empty input array:
min(minInArray(array1), minInArray(array2)) == minInArray(concat(array1, array2))
In other words, is there any commonly-used neutral element which minInArray could return on empty input, which wouldn't mess up min()?
One option would be to return some neutral value like null or NaN if the array has no elements, and then if the min() function is run and one of the arguments is the neutral value, then you just return the min of the other array. Another option would be to return the closest value the language has to +Infinity if the array is empty; this works and does not require modifying min(), but does have the side effect of returning an infinite value sometimes when the minInArray() function is called. This infinite value could work as a truly neutral value that works with the default min() function, but it may cause some confusion if the minimum value in an array really is infinite.
minInArray(arr1) to return null if arr1 is empty.
min() should return only non-null values over null. Meaning min() will only return null if both parameters are null. Otherwise, it will return the minimum non-null value.
While thinking about the issue we've come to seemingly the only solution possible:
if an array is empty - we should return the maximum possible value for int to satisfy the condition.
Not that nice actually...
Just to add some perspectives (not that this is a duplicate of the listed questions) -
All of these throw errors of some kind when asked to calculate min of an empty list or array: Java, Scala, Python, numpy, Javascript, C#. Probably more, but that's as far as I looked. I'm sure there are some that don't, but I'd expect most of those to be languages which have traded understandability and clarity for speed.
This question is about a specific language, but has answers relevant to all languages.
Note here how one can get around the issue in something like Python.
For Haskell in particular, note the advice in this question.
And lastly here's a response for a more general case of your question.
In general, it is always most important for code to work, but a close second to that is it must be understandable to humans. Perhaps it doesn't matter for your current project, if you'll be the only one dealing with that function, but the last thing I'd expect when calling a 'get_minimum' function, is Int.MAX.
I understand it makes the coding simple, but I'd urge you to beware of code that is easy to write and tricky to understand. A little more time spent making the code easy to read, with as much as possible having an immediately obvious meaning, will always save much more time later on.

In Lua, how should I handle a zero-based array index which comes from C?

Within C code, I have an array and a zero-based index used to lookup within it, for example:
char * names[] = {"Apple", "Banana", "Carrot"};
char * name = names[index];
From an embedded Lua script, I have access to index via a getIndex() function and would like to replicate the array lookup. Is there an agreed on "best" method for doing this, given Lua's one-based arrays?
For example, I could create a Lua array with the same contents as my C array, but this would require adding 1 when indexing:
names = {"Apple", "Banana", "Carrot"}
name = names[getIndex() + 1]
Or, I could avoid the need to add 1 by using a more complex table, but this would break things like #names:
names = {[0] = "Apple", "Banana", "Carrot"}
name = names[getIndex()]
What approach is recommended?
Edit: Thank you for the answers so far. Unfortunately the solution of adding 1 to the index within the getIndex function is not always applicable. This is because in some cases indices are "well-known" - that is, it may be documented that an index of 0 means "Apple" and so on. In that situation, should one or the other of the above solutions be preferred, or is there a better alternative?
Edit 2: Thanks again for the answers and comments, they have really helped me think about this issue. I have realized that there may be two different scenarios in which the problem occurs, and the ideal solution may be different for each.
In the first case consider, for example, an array which may differ from time to time and an index which is simply relative to the current array. Indices have no meaning outside the code. Doug Currie and RBerteig are absolutely correct: the array should be 1-based and getIndex should contain a +1. As was mentioned, this allows the code on both the C and Lua sides to be idiomatic.
The second case involves indices which have meaning, and probably an array which is always the same. An extreme example would be where names contains "Zero", "One", "Two". In this case, the expected value for each index is well-known, and I feel that making the index on the Lua side one-based is unintuitive. I believe one of the other approaches should be preferred.
Use 1-based Lua tables, and bury the + 1 inside the getIndex function.
I prefer
names = {[0] = "Apple", "Banana", "Carrot"}
name = names[getIndex()]
Some of table-manipulation features - #, insert, remove, sort - are broken.
Others - concat(t, sep, 0), unpack(t, 0) - require explicit starting index to run correctly:
print(table.concat(names, ',', 0)) --> Apple,Banana,Carrot
print(unpack(names, 0)) --> Apple Banana Carrot
I hate constantly remembering of that +1 to cater Lua's default 1-based indices style.
You code should reflect your domain specific indices to be more readable.
If 0-based indices are fit well for your task, you should use 0-based indices in Lua.
I like how array indices are implemented in Pascal: you are absolutely free to choose any range you want, e.g., array[-10..-5]of byte is absolutely OK for an array of 6 elements.
This is where Lua metemethods and metatables come in handy. Using a table proxy and a couple metamethods, you can modify access to the table in a way that would fit your need.
local names = {"Apple", "Banana", "Carrot"} -- Original Table
local _names = names -- Keep private access to the table
local names = {} -- Proxy table, used to capture all accesses to the original table
local mt = {
__index = function (t,k)
return _names[k+1] -- Access the original table
end,
__newindex = function (t,k,v)
_names[k+1] = v -- Update original table
end
}
setmetatable(names, mt)
So what's going on here, is that the original table has a proxy for itself, then the proxy catches every access attempt at the table. When the table is accessed, it increment the value it was accessed by, simulating a 0-based array. Here are the print result:
print(names[0]) --> Apple
print(names[1]) --> Banana
print(names[2]) --> Carrot
print(names[3]) --> nil
names[3] = "Orange" --Add a new field to the table
print(names[3]) --> Orange
All table operations act just as they would normally. With this method you don't have to worry about messing with any unordinary access to the table.
EDIT: I'd like to point out that the new "names" table is merely a proxy to access the original names table. So if you queried for #names the result would be nil because that table itself has no values. You'd need to query for #_names to access the size of the original table.
EDIT 2: As Charles Stewart pointed out in the comment below, you can add a __len metamethod to the mt table to ensure the #names call gives you the correct results.
First of all, this situation is not unique to applications that mix Lua and C; you can face the same question even when using Lua only apps. To provide an example, I'm using an editor component that indexes lines starting from 0 (yes, it's C-based, but I only use its Lua interface), but the lines in the script that I edit in the editor are 1-based. So, if the user sets a breakpoint on line 3 (starting from 0 in the editor), I need to send a command to the debugger to set it on line 4 in the script (and convert back when the breakpoint is hit).
Now the suggestions.
(1) I personally dislike using [0] hack for arrays as it breaks too many things. You and Egor already listed many of them; most importantly for me it breaks # and ipairs.
(2) When using 1-based arrays I try to avoid indexing them and to use iterators as much as possible: for i, v in ipairs(...) do instead of for i = 1, #array do).
(3) I also try to isolate my code that deals with these conversions; for example, if you are converting between lines in the editor to manage markers and lines in the script, then have marker2script and script2marker functions that do the conversion (even if it's simple +1 and -1 operations). You'd have something like this anyway even without +1/-1 adjustments, it would just be implicit.
(4) If you can't hide the conversion (and I agree, +1 may look ugly), then make it even more noticeable: use c2l and l2c calls that do the conversion. In my opinion it's not as ugly as +1/-1, but has the advantage of communicating the intent and also gives you an easy way to search for all the places where the conversion happens. It's very useful when you are looking for off-one bugs or when API changes cause updates to this logic.
Overall, I wouldn't worry about these aspects too much. I'm working on a fairly complex Lua app that wraps several 0-based C components and don't remember any issues caused by different indexing...
Why not just turn the C-array into a 1-based array as well?
char * names[] = {NULL, "Apple", "Banana", "Carrot"};
char * name = names[index];
Frankly, this will lead to some unintuitive code on the C-side, but if you insist that there must be 'well-known' indices that work in both sides, this seems to be the best option.
A cleaner solution is of course not to make those 'well-known' indices part of the interface. For example, you could use named identifiers instead of plain numbers. Enums are a nice match for this on the C side, while in Lua you could even use strings as table keys.
Another possibility is to encapsulate the table behind an interface so that the user never accesses the array directly but only via a C-function call, which can then perform arbitrarily complex index transformations. Then you only need to expose that C function in Lua and you have a clean and maintainable solution.
Why not present your C array to Lua as userdata? The technique is described with code in PiL, section 'Userdata'; you can set the __index, __newindex, and __len metatable methods, and you can inherit from a class to provide other sequence manipulation functions as regular methods (e.g., define an array with array.remove, array.sort, array.pairs functions, which can be defined as object methods by a further tweak to __index). Doing things this way means you have no "synchronisation" issues between Lua and C, and it avoids risks that "array" tables get treated as ordinary tables resulting in off-by-one errors.
You can fix this lua-flaw by using an iterator that is aware of different index bases:
function iarray(a)
local n = 0
local s = #a
if a[0] ~= nil then
n = -1
end
return function()
n = n + 1
if n <= s then return n,a[n] end
end
end
However, you still have to add the zeroth element manually:
Usage example:
myArray = {1,2,3,4,5}
myArray[0] = 0
for _,e in iarray(myArray) do
-- do something with element e
end

Prolog - The same functioning but with no findall

Does anyone know how I could implement I predicate doing what this one does but without "findall"?
Thank you a lot.
domains
oferta = rebaixat ; normal
element = string
list = element*
database
producte (string, integer, oferta)
predicates
nondeterm reduced2(list)
clauses
producte("Enciam",2,rebaixat).
producte("Peix",5,normal).
producte("Llet",1,rebaixat).
producte("Formatge",5,normal).
reduced2(Vals):-
findall(Val, producte(Val,_,rebaixat),Vals).
Goal
write("Amb findall"),nl,
reduced2(List).
I don't know much about Visual Prolog, but I will try to give a general answer. It depends on whether you want to find a findall/3 replacement for a specific case or in general, though.
In the specific case, you can use an accumulator. In your case, this would be a list into which the values are added as you find them. Something like:
acc(In, List) :-
... % do something to generate possible next value
... % test if value is already in list In
!,
Out = [Val|In], % adds to the head, but is faster than using append
acc(Out, List).
acc(List, List).
I.e., when you can't find another possible value, you return the list of values that you found. Note that this may be slow if you have to accumulate a lot of values and generating the next possible value is done via backtracking. Also, this will not let you generate duplicates, so it's not an exact replacement for findall/3.
If you want a general replacement for findall/3, where you can specify a goal and a variable or term that will contain the instance to be accumulated, then you won't get around using some sort of non-logical global variable. After finding the next value, you add it to what's been stored in the global variable, and cause backtracking. If generating the next value fails, you retrieve the content of the global variable and return it.

What is the best way to count the number of times a value occurs in an array?

I have been given an assignment to write a program that reads in a number of assignment marks from a text file into an array, and then counts how many marks there are within particular brackets, i.e. 40-49, 50-59 etc. A value of -1 in the text file means that the assignment was not handed in, and a value of 0 means that the assignment was so bad that it was ungraded.
I could do this easily using a couple of for loops, and then using if statements to check the values whilst incrementing appropriate integers to count the number of occurences, but in order to get higher marks I need to implement the program in a "better" way. What would be a better, more efficient way to do this? I'm not looking for code right now, just simply "This is what you should do". I've tried to think of different ways to do it, but none of them seem to be better, and I feel as if I'm just trying to make it complicated for the sake of it.
I tried using the 2D array that the values are stored in as a parameter of a function, and then using the function to print out the number of occurences of the particular values, but I couldn't get this to compile as my syntax was wrong for using a 2D array as a parameter, and I'm not too sure about how to do this.
Any help would be appreciated, thanks.
Why do you need a couple for loops? one is enough.
Create an array of size 10 where array[0] is marks between 0-9, array[1] is marks between 10-19, etc. When you see a number, put it in the appropriate array bucket using integer division, e.g. array[(int)mark/10]++. when you finish the array will contain the count of the number of marks in each bucket.
As food for thought, if this is a school assignment, you might want to apply other things you have learned in the course.
Did you learn sorting yet? Maybe you could sort the list first so that you are not iterating over the array several times. You can just go over it once, grab all the -1's, and spit out how many you have, then grab all the ones in the next bracket and so on.
edit: that is of course, assuming that you are using a 1d array.

Resources