Mom file creation (5 product limit) - loops

Ok, I realize this is a very niche issue, but I'm hoping the process is straight forward enough...
I'm tasked with creating a data file out of Customer/Order information. Problem is, the datafile has a 5 product max limit.
Basically, I get my data, group by cust_id, create the file structure, within that loop, group by product_id, rewrite the fields in previous file_struct with new product info. That's worked all well and good until a user exceeded that max.
A brief example.. (keep in mind, the structure of the array is set by another process, this CANNOT change)
orderArray = arranyew(2);
set order = 1;
loop over cust_id;
field[order][1] = "field(1)"; // cust_id
field[order][2] = "field(2)"; // name
field[order][3] = "field(3)"; // phone
field[order][4] = ""; // product_1
field[order][5] = ""; // quantity_1
field[order][6] = ""; // product_2
field[order][7] = ""; // quantity_2
field[order][8] = ""; // product_3
field[order][9] = ""; // quantity_3
field[order][10] = ""; // product_4
field[order][11] = ""; // quantity_4
field[order][12] = ""; // product_5
field[order][13] = ""; // quantity_5
field[order][14] = "field(4)"; // trx_id
field[order][15] = "field(5)"; // total_cost
counter = 0;
loop over product_id
field[order[4+counter] = productCode;
field[order[5+counter] = quantity;
counter = counter + 2;
end inner loop;
order = order + 1;
end outer loop;
Like I said, this worked fine until I had a user who ordered more than 5 products.
What I basically want to do is check the number of products for each user if that number is greater than 5, start a new line in the text field, but I'm stufk on how to get there.
I've tried numerous fixes, but nothing gives the results I need.
I can send the entire file if It can help, but I don't want to post it all here.

You need to move the inserting of the header and footer fields into product loop eg. the custid and trx_id fields.
Here's a rough idea of one why you can go about this based on the pseudo code you provided. I'm sure that there are more elegant ways that you could code this.
set order = 0;
loop over cust_id;
counter = 1;
order = order + 1;
loop over product_id
if (counter == 1 || counter == 6) {
if (counter == 6) {
counter == 1;
order= order+1;
}
field[order][1] = "field(1)"; // cust_id
field[order][2] = "field(2)"; // name
field[order][3] = "field(3)"; // phone
}
field[order][counter+3] = productCode; // product_1
field[order][counter+4] = quantity; // quantity_1
counter = counter + 1;
if (counter == 6) {
field[order][14] = "field(4)"; // trx_id
field[order][15] = "field(5)"; // total_cost
}
end inner loop;
if (counter == 6) {
// loop here to insert blank columns and the totals field to fill out the row.
}
end outer loop;
One thing goes concern me. If you start a new line every five products then your transaction id and total cost is going to be entered into the file more than once. You know the receiving system. It may be a non-issue.
Hope this helps

As you put the data into the row, you need check if there are more than 5 products and then create an additional line.
loop over product_id
if (counter mod 10 == 0 and counter > 0) {
// create the new row, and mark it as a continuation of the previous order
counter = 0;
order = order + 1;
field[order][1] = "";
...
field[order][15] = "";
}
field[order[4+counter] = productCode;
field[order[5+counter] = quantity;
counter = counter + 2;
end inner loop;
I've actually done the export from an ecommerce system to MOM, but that code has since been lost. I have samples of code in classic ASP.

Related

Salesforce Apex -- Better way at achieving a nested table output

public pageReference getData(){
date sd = date.parse(sDate).toStartOfWeek();
date ed = date.parse(eDate);
hList = new list<Hours__c>([SELECT Name,Employee__r.Id,Date_worked__c,Employee__r.Offshore__c,Employee__r.Name,Employee__r.Department__c,Employee_Name__c,hours__c,Minutes__c,Hours_Decimal__c FROM Hours__c WHERE Type_of_Hours__c = 'Work' AND Date_worked__c >= :sd AND Date_worked__c <= :ed AND Employee__r.Department__c IN :selected ORDER BY Employee__r.Department__c,Date_worked__c,Employee__r.Name LIMIT 3000]);
wrap = new list<wrapper>();
string tempDepartment;
string tempEmpName;
date tempWorkDate;
date tempStart = sd;
decimal offshore = 0;
decimal onshore = 0;
decimal totalOffshore = 0;
decimal totalOnShore = 0;
decimal dateCount = 0;
decimal aggreagteTotal = 0;
integer hitLimit = 3000;
integer rpwp = 0;
integer compareRPWP = 0;
boolean fired = false;
boolean dateChanged = false;
boolean dateCountis13 = false;
map<date,integer> mapDateCount = new map<date,integer>();
if(hList.size() > 0 && hList.size() < hitLimit){
noResults = false;
for(Hours__c h: hList){
//initiate a new wrapper for each department as a primary header
if( (h.Employee__r.Department__c != null && ((tempDepartment != null && tempDepartment != h.Employee__r.Department__c) || ( tempDepartment == null)) ) ){
fired = true;
tempDepartment = h.Employee__r.Department__c;
wrap.add(new wrapper(null,null,null,null,null,tempDepartment,'','','',null,'',''));
}else{
fired = false;
}
if(fired || dateCountis13){
dateCountis13 = false;
dateCount = 0;
totalOffshore = 0;
totalOnShore = 0;
}
//initiate a new wrapper for each new week period, total employee hours for each week period for each department
if(fired || (h.Date_worked__c != null && ((tempWorkDate != null && tempWorkDate != h.Date_worked__c) || ( tempWorkDate == null)) ) || (h.Employee__r.Department__c != null && ((tempDepartment != null && tempDepartment != h.Employee__r.Department__c) || ( tempDepartment == null)) ) ){
dateChanged = true;
tempWorkDate = h.Date_worked__c;
offshore = 0;
onshore = 0;
rpwp = 0;
dateCount++;
for(Hours__c h1: hList){
//get count of each record that is inside a given week period
if(h1.Date_worked__c == tempWorkDate && h1.Employee__r.Department__c == tempDepartment){
rpwp++;
}
//logic for totaling offshore hours by date and department
if(h1.Date_worked__c == tempWorkDate && h1.Employee__r.Offshore__c && h1.Employee__r.Department__c == tempDepartment){
offshore += h1.Hours_Decimal__c != null ? h1.Hours_Decimal__c : 0;
}
//logic for totaling onshore hours by date and department
if(h1.Date_worked__c == tempWorkDate && h1.Employee__r.Offshore__c == false && h1.Employee__r.Department__c == tempDepartment){
onshore += h1.Hours_Decimal__c != null ? h1.Hours_Decimal__c : 0;
}
}
system.debug('rpwp: ' + rpwp);
wrap.add(new wrapper(h.Date_worked__c.toStartOfWeek(),h.Date_worked__c,onshore,offshore,null,'total','','','',null,'',''));
totalOffshore += offshore;
totalOnShore += onshore;
system.debug('OffShore: ' + offshore + ' ' + tempWorkDate.format());
system.debug('OnShore: ' + onshore + ' ' + tempWorkDate.format());
}else{
dateChanged = false;
}
//initiate a new wrapper for each record and give the ability to open and collapse all records under a given total week period
// functionality now does an aggregate total of employee's that have multiple hour entrees for each week period.
if( dateChanged || (h.Employee__r.Name != null && ((tempEmpName != null && tempEmpName != h.Employee__r.Name) || ( tempEmpName == null)) ) ){
tempEmpName = h.Employee__r.Name;
aggreagteTotal = 0;
for(Hours__c h2: hList){
if(tempEmpName == h2.Employee__r.Name && tempWorkDate == h2.Date_worked__c){
aggreagteTotal += h2.Hours_Decimal__c;
}
}
if(h.Employee__r.Offshore__c){
wrap.add(new wrapper(h.Date_worked__c.toStartOfWeek(),h.Date_worked__c,0,h.hours__c,aggreagteTotal,'collapse',h.Employee__r.Name,h.Employee__r.Id,h.Name,h.Employee__r.Offshore__c,h.Employee__r.Department__c,h.Date_worked__c.format() ));
}else{
wrap.add(new wrapper(h.Date_worked__c.toStartOfWeek(),h.Date_worked__c,h.hours__c,0,aggreagteTotal,'collapse',h.Employee__r.Name,h.Employee__r.Id,h.Name,h.Employee__r.Offshore__c,h.Employee__r.Department__c,h.Date_worked__c.format() ));
}
}
//compare record count on the outside loop to record count on the inner loop and set compare iterator to 0 if the date changes
if(dateChanged){
compareRPWP = 0;
}
compareRPWP++;
system.debug('compareRPWP: ' + compareRPWP );
//if on the 13th week -- initiate a new wrapper and get quarterly totals -- compare record count so that inner loop matches outer loop
if( (dateCount == 13 && compareRPWP == rpwp) ){
system.debug('totalOffshore: ' + totalOffshore );
system.debug('totalOnShore: ' + totalOnShore );
dateCountis13 = true;
wrap.add(new wrapper(null,null,totalOnShore,totalOffshore,null,'quarter',tempDepartment,'','',null,'',''));
}
}
}else if(hList.size() <= 0){
noResults = true;
bannerMessage = 'Oops! No record found.';
}else if(hList.size() >= hitLimit){
noResults = true;
bannerMessage = 'Oops! 3000 Record limit hit.';
}else{
noResults = true;
bannerMessage = 'Oops! 50000 record limit hit.';
}
system.debug('wrap: ' + wrap);
system.debug('hList: ' + hList);
return null;
}
Here is my working method inside my class. Essentially I am doing a query on a custom object Hours__c. What I want to do is have the output on the table be first nested by each employee department. Then Nested by each work period, with all hours worked by that department for each work period. I essentially achieved this from the start by ordering the query that way. Now it was about how to make the logic grab it at the time I needed. But it also needed to aggregate the total hours if employees had more than one hour record per week period. I also finally after every 13 weeks output a total of hours for that quarter.
Here is a screencast of my custom report if you are interested in seeing what I achieved on the front-end but what I want to achieve on the backend and in a more effecient manner. The problem with my logic, is while it works, if there is a lot of data being queried. This logic is pretty slow. Because first it loops the query results once. but inside the first for loop I loop the same query 2 different times... ::slaps head:: ...I know it is terrible.
So I want to see maybe if there is a more effecient way of achieving this with potentially a map or another wrapper class? Because it is all in one wrapper class too. I use front end logic to sort out the table based on results in the wrapper class. I just hide and show rows. Like i said, it works just not as effecient as I would like my logic to run.
here is the screen cast:
https://screencast-o-matic.com/watch/cF60cwYAiB
My first idea is about preparing new Map<Date, List<Hour__c>> dateWorkedToHoursMap map in controller just after your SOQL. With this map you will be able to get quickly Hour__c records by specic Date (Date_worked__c) and go only through them in your sub for loops.
public class Controller {
// (...)
Map<Date, List<Hour__c>> dateWorkedToHoursMap; // New map in controller
// (...)
// Updated "getData()" method which will prepare "dateWorkedToHoursMap"
// map just after SOQL and then will use in both sub for loops
public pageReference getData() {
// (...)
// Your SOQL for Hour__c records
// dateWorkedToHoursMap = prepareDateWorkedToHoursMap(hList);
// (...)
// main for through hList
// (...)
// 1 sub for through list returned by: dateWorkedToHoursMap.get(h.Date_worked__c)
// (...)
// 2 sub for through list returned by: dateWorkedToHoursMap.get(h.Date_worked__c)
// (...)
// end of main for
}
// New "prepareDateWorkedToHoursMap()" method used to prepare "dateWorkedToHoursMap" map
private void prepareDateWorkedToHoursMap(List<Hour__c> hours) {
dateWorkedToHoursMap = new Map<Date, List<Hour__c>>();
for(Hour__c hour : hours) {
if(hour.Date_worked__c != null) {
if(!dateWorkedToHoursMap.containsKey(hour.Date_worked__c)) {
dateWorkedToHoursMap.put(hour.Date_worked__c, new List<Hour__c>());
}
dateWorkedToHoursMap.get(hour.Date_worked__c).add(h);
}
}
}
}
If you think that it will be better then you can try to prepare map like:
Map<String, Map<Date, List<Hour__c>>> departmentToDateWorkedToHoursMap
And then you should be able to quickly get the list of Hour__c records based on DEPARTMENT and DATE WORKED.

File line affecting the index of a storage array?

I have a simple bit of code written in Octave, all is does is open 3 files (one at a time) and scans each line for one of two strings, if it finds the matching string it extracts the number which follows the string and appends that number to an array.
clear
names = dir('*txt');
rec = [];
emit = [];
for i = 1:length(names)
name = names(i).name;
fid = fopen(name);
while !(feof(fid))
tline = fgets(fid);
if !(isempty(regexp(tline,'reception: ')))
offset = regexp(tline,'reception: ');
val = str2double(strtok(tline(offset+11:end)));
rec(end+1) = val;
elseif !(isempty(regexp(tline,'emission: ')))
offset = regexp(tline,'emission: ');
val = str2double(strtok(tline(offset+10:end)));
emit(end+1) = val;
end
end
length(rec)
end
fn = strcat(name,'REC.mat');
save('-mat',fn,'rec');
fn = strcat(name,'EMIT.mat');
save('-mat',fn,'emit');
I expect the "length(rec) to be a cumulative value, but it's not - it just prints the number of "reception:" lines in each file, each time a new file is loaded its like the arrays "rec" and "emit" are being cleared, why does this happen? Is it to do with the file index? How can this be affecting the arrays?!
I tried this with a simple test program and it works exactly as I expect:
clear
test = [];
fin = 5;
for i = 1:3
j = 0;
while (j<fin)
j = j+1;
test(end+1) = j;
end
fin = fin+5;
length(test)
end
length(test) prints a cumulative value (as it should). What's going on?
NOTE:
I can easily solve the problem by adding at the beginning:
totalRec = [];
and after each iteration of the for loop:
totalRec = [totalRec,rec]
But I'm interested in why it's happening.
EDIT:
An example of the content of the data files is as follows:-
2017.07.13 10:31:04:346301 FESA.USR.ABT_SocketServer.RealTime.CustEvtSrcProducer src/ABT_SocketServer/RealTime/CustEvtSrcProducer.cpp:168 INFO Control_data_reception: 10936 us
2017.07.13 10:31:04:363889 FESA.USR.ABT_SocketServer.RealTime.RT_NewCycleReady src/ABT_SocketServer/RealTime/RT_NewCycleReady.cpp:52 INFO RT_NewCycleReady execute -> Start
2017.07.13 10:31:05:050910 FESA.USR.ABT_SocketServer.RealTime.RT_ELFTReady src/ABT_SocketServer/RealTime/RT_ELFTReady.cpp:49 INFO RT_ELFTReady execute -> Start
2017.07.13 10:31:05:057764 FESA.USR.ABT_SocketServer.RealTime.CustEvtSrcProducer src/ABT_SocketServer/RealTime/CustEvtSrcProducer.cpp:112 INFO acquisition_data_emission: 6469 us
2017.07.13 10:31:05:474323 FESA.USR.ABT_SocketServer.RealTime.RT_endCycle src/ABT_SocketServer/RealTime/RT_endCycle.cpp:49 INFO RT_endCycle execute -> Start
2017.07.13 10:31:05:504081 FESA.USR.ABT_SocketServer.RealTime.RT_NewCycle src/ABT_SocketServer/RealTime/RT_NewCycle.cpp:59 INFO RT_NewCycle execute -> Start
2017.07.13 10:31:05:544370 FESA.USR.ABT_SocketServer.RealTime.CustEvtSrcProducer src/ABT_SocketServer/RealTime/CustEvtSrcProducer.cpp:168 INFO Control_data_reception: 9424 us

Biopython for Loop IndexError

I get "IndexError: list is out of range" when I input this code. Also, the retmax is set at 614 because that's the total number of results when I make the request. Is there a way to make the retmode equal to the number of results using a variable that changes depending on the search results?
#!/usr/bin/env python
from Bio import Entrez
Entrez.email = "something#gmail.com"
handle1 = Entrez.esearch(db = "nucleotide", term = "dengue full genome", retmax = 614)
record = Entrez.read(handle1)
IdNums = [int(i) for i in record['IdList']]
while i >= 0 and i <= len(IdNums):
handle2 = Entrez.esearch(db = "nucleotide", id = IdNums[i], type = "gb", retmode = "text")
record = Entrez.read(handle2)
print(record)
i += 1
Rather than using a while loop, you can use a for loop...
from Bio import Entrez
Entrez.email = 'youremailaddress'
handle1 = Entrez.esearch(db = 'nucleotide', term = 'dengue full genome', retmax = 614)
record = Entrez.read(handle1)
IdNums = [int(i) for i in record['IdList']]
for i in IdNums:
print(i)
handle2 = Entrez.esearch(db = 'nucleotide', term = 'dengue full genome', id = i, rettype = 'gb', retmode = 'text')
record = Entrez.read(handle2)
print(record)
I ran it on my computer and it seems to work. The for loop solved the out of bounds, and adding the term to handle2 solved the calling error.

Creating buttons through iteration?

I've been using the Corona engine and I'm trying to create multiple buttons through a loop rather than explicitly creating each individual button. Problem is the loop only seems to be generating one button which suggests it's only iterating once.
Below is what I've got so far...
UPDATED
--> Create Level Selection:
local levelSelectionGroup = display.newGroup( );
--> Level Selected:
local function levelSelected()
print(id);
end
--> Button Creation:
local function createLevelSelection()
local levelsToBeMade = 30; -- Ignore these random numbers for now.
local positionX = 1; -- Ignore again.
local positionY = 1; -- Ignore again.
for buttonNumber=1, levelsToBeMade do
print(buttonNumber);
positionX = (positionX + 10); -- Ignore again.
positionY = (positionY + 10); -- Ignore again.
levelButton[buttonNumber] = widget.newButton{
id = buttonNumber,
label = buttonNumber,
default = "images/levelButton.png",
over = "images/levelButtonPressed.png",
width = 50,
height = 50,
onRelease = levelSelected
}
levelButton[buttonNumber].x = positionX;
levelButton[buttonNumber].y = positionY;
levelSelectionGroup:insert(levelButton[buttonNumber]);
end
end
The console states...
attempt to index global 'levelButton' (a nil value)
I guess you might have a problem with your variables or your scopes. So make sure that levelsToBeMade variable and positionX and positionY variables are correct. If you are absolutely sure, this should work: ( I don't see anything wrong in your code but, for loops are more trustable I guess. )
for i=1, levelsToBeMade do
print( "levelButton+1).." will be created." )
positionX = positionX + 10; -- Ignore numbers.
positionY = postionY + 10; -- Ignore numbers.
levelButton[#levelButton+1] = widget.newButton{
id = #levelButton,
label = #levelButton,
default = "images/levelButton.png",
over = "images/levelButtonPressed.png",
width = 50,
height = 50,
onRelease = levelSelected
}
levelButton[#levelButton].x = positionX;
levelButton[#levelButton].y = positionY;
end
If it doesn't work, just check console and see if the loop is executed desired times.
Last edit:
Oh, didn't notice that. You never created levelButton table before! Before starting to create level buttons you should create that like this: local levelButton = {}, at outside of for loop
You might want to reconsider your algorithm and change this while loop.
If the number of levels to be generated is going to stay constant you might want to do a for loop until the 31 st loop is reached.
for i=1,levelstToBeMade do
levelstToBeMade = (levelsToBeMade - 1); -- Ignore numbers.
positionX = positionX + 10; -- Ignore numbers.
positionY = postionY + 10; -- Ignore numbers.
levelButton[levelsToBeMade] = widget.newButton{
id = levelsToBeMade,
label = levelsToBeMade,
default = "images/levelButton.png",
over = "images/levelButtonPressed.png",
width = 50,
height = 50,
onRelease = levelSelected
}
levelButton[levelsToBeMade].x = positionX;
levelButton[levelsToBeMade].y = positionY;
end
Hope this helps.
Cheers
(Sorry, I don't know Corona so this might not apply.)
What is levelButton, and are you sure it exists? Maybe it should be levelButtons?
If that's fine as it is, then check to make sure newButton() actually returns a table as expected: print(levelButton[buttonNumber])

Appending Int to an Array Matlab

I am using an API to get real data times of trains and am trying to get the closest train time to a user entered time and then display that train time, and the next 4 granted the trains are running. I am reading in the information and the code goes through what its supposed to do but when I look at the array its a bunch of [] brackets in 7 cells instead of the calculated numbers. Any suggestions? Code is below with the API
TEST VALUES:
requestStationSelected = 'University%20City' and requestEndStation = 'Roslyn'
%this is the API link for the live data from Septa this will get 30
%results and see which time is closer to the user entered time
requestInfoSeptaLive = ['http://www3.septa.org/hackathon/NextToArrive/' requestStationSelected '/' requestEndStation '/30'];
%Again tries to get the information and if there is a failure it will give
%a probable cause and terminate the program
try
getInfoSeptaLive = urlread(requestInfoSeptaLive);
catch
if getInfoSeptaLive ~= '[]'
disp...
('Either the arrival/depart stations dont quite match up or theres a server error. Try again.');
return;
else
disp('Unable to fetch the information from Septa, please try again')
return;
end
end
%parses the information returned from the Live API
dataReturnedFromLiveAPI = parse_json(getInfoSeptaLive);
dataReturnedFromLiveAPI = dataReturnedFromLiveAPI{1};
%gets the size of the API in case there are no trains running
sizeOfDataNoTrains = size(dataReturnedFromLiveAPI, 1);
sizeOfData = size(dataReturnedFromLiveAPI, 2);
counter = 0;
for i = 1:sizeOfData
scanForClosestTime = dataReturnedFromLiveAPI{1,i}.orig_departure_time;
trainTimeGivenH = sscanf(scanForClosestTime, '%i');
findColonTrain = strfind(scanForClosestTime, ':');
trainTimeGivenMStr = scanForClosestTime(findColonTrain+1:4);
trainTimeGivenM = int32(str2num(trainTimeGivenMStr));
trainDepartTimeM = (trainTimeGivenH(1,1) * 60) + (trainTimeGivenM);
differenceBetweenTimes = trainDepartTimeM - userEnteredMins;
if trainDepartTimeM < userEnteredMins
differenceBetweenTimes = userEnteredMins - trainDepartTimeM;
end
stopAtEndOfData = sizeOfData;
goodTimeFrame = 60;
closestTime = cell(1, stopAtEndOfData);
storeTheDifference = cell(1, stopAtEndOfData);
if(differenceBetweenTimes < 60)
if (counter < 5)
closestTime{i} = scanForClosestTime;
storeTheDifference{i} = differenceBetweenTimes;
counter = counter + 1;
end
end
end
You assign your cell arrays inside the for loop:
for i = 1:sizeOfData
...
closestTime = cell(1, stopAtEndOfData);
storeTheDifference = cell(1, stopAtEndOfData);
...
end
This means that you turn both of them into an array of {[],[],[],[],[]...} on every iteration of the loop - so unless the last iteration has a valid "closest Time" in it, your cell array will be all empty arrays - and if it does, all but the last element will still be [].
To fix this, move the two lines to before the start of the for loop.
The second problem seems to be the indexing of the arrays where you store the results. If you only want five results, I am assuming you want to store them in elements 1 - 5 of your array, and not in "just any" locations. I would change the code to
if (counter < 5)
counter = counter + 1;
closestTime{counter} = scanForClosestTime;
storeTheDifference{counter} = differenceBetweenTimes;
end
But maybe I misinterpreted how you want to handle that?
Unrelated to your question, you might want to take a look at the line
trainTimeGivenMStr = scanForClosestTime(findColonTrain+1:4);
It is quite possible that this is not what you intended to do - looking at an example of the response, I found the string "orig_departure_time":"11:57PM". I expect that findColonTrain == 3, so that the above line becomes
trainTimeGivenMStr = scanForClosestTime(4:4);
just a single character. Perhaps you meant
trainTimeGivenMStr = scanForClosestTime(findColonTrain+(1:4));
which would turn into
trainTimeGivenMStr = scanForClosestTime(4:7);
so that
trainTimeGivenMStr = '57PM';
I hope these three things help you get it all working!
EDIT: had a chance to run your code this morning - discovered a number of other problems. I include below an annotated "working" code: the biggest problem was most likely that you were not handling AM/PM in your code. Note that I used a different json parser - this changed a couple of lines very slightly. I'm sure you can put it back together to work the way you want. This returned valid data in all cells.
dataReturnedFromLiveAPI = loadjson(getInfoSeptaLive);
% next line not needed - loadjson returns struct array, not cell array
%dataReturnedFromLiveAPI = dataReturnedFromLiveAPI{1};
%gets the size of the API in case there are no trains running
sizeOfDataNoTrains = size(dataReturnedFromLiveAPI, 1);
sizeOfData = size(dataReturnedFromLiveAPI, 2);
counter = 0;
stopAtEndOfData = sizeOfData;
closestTime = cell(1, stopAtEndOfData);
storeTheDifference = cell(1, stopAtEndOfData);
userEnteredMins = 12*60+30; % looking for a train around 12:30 pm
for ii = 1:sizeOfData
scanForClosestTime = dataReturnedFromLiveAPI(ii).orig_departure_time;
trainTimeGivenH = sscanf(scanForClosestTime, '%i');
% since we'll be considering AM/PM, have to set 12 = 0:
if (trainTimeGivenH == 12), trainTimeGivenH = 0; end
findColonTrain = strfind(scanForClosestTime, ':');
% change next line to get minutes plus AM/PM:
trainTimeGivenMStr = scanForClosestTime(findColonTrain+(1:4));
% look at just minutes:
trainTimeGivenM = int32(str2num(trainTimeGivenMStr(1:2)));
% adjust for AM/PM:
if(trainTimeGivenMStr(3:4)=='PM'), trainTimeGivenH = trainTimeGivenH+12; end;
% compute time in minutes:
trainDepartTimeM = (trainTimeGivenH * 60) + (trainTimeGivenM);
differenceBetweenTimes = trainDepartTimeM - userEnteredMins;
if trainDepartTimeM < userEnteredMins
differenceBetweenTimes = userEnteredMins - trainDepartTimeM;
end
% added a couple of lines to see what is happening:
fprintf(1, 'train %d: depart %s - in minutes this is %d vs user entered %d\n', ...
ii, scanForClosestTime, trainDepartTimeM, userEnteredMins);
goodTimeFrame = 60;
if(differenceBetweenTimes < 600)
if (counter < 10)
counter = counter + 1;
closestTime{counter} = scanForClosestTime;
storeTheDifference{counter} = differenceBetweenTimes;
end
end
end

Resources