Friday, August 24, 2018

Foreach for double linked list without macro?

I am using double linked list and want to optimize it usage. I have a lot of places where I iterate throw all list elements. I want to use following defines:

//
// Iterates through all protected files
//
#define FOR_EACH_PROTECTED_FILE_START(protectedFile) \
    for(PLIST_ENTRY protectedFileEntry = filterData.ProtectedFilesHead.Flink; protectedFileEntry != &filterData.ProtectedFilesHead; protectedFileEntry = protectedFileEntry->Flink) { \
    protectedFile = CONTAINING_RECORD(protectedFileEntry, MY_PROTECTED_FILE_TYPE, EntryLink);


#define FOR_EACH_PROTECTED_FILE_END }

Is there way to do this without macro (macro is evil bla..bla.bla) to not put this constructs every place I want to iterate foreach file?

How do you like this style?

Solved

You could move the boilerplate logic into a function, which controls the loop and return a state.

inline int iterate_protected_files(ProtectedFile_t* current, /*other state data*/)
{
  /* Bolierplate stuff to get next file*/
  *current = whatever;
  return current_exists;
}

...

while (iterate_protected_files(&protectedFile))
{
  /* do stuff with a protected file */
}

You can stick to macro, but avoiding the braces in the macro itself:

#define FOR_EACH_PROTECTED_FILE(protectedFile) \
    for( \
        PLIST_ENTRY protectedFileEntry = filterData.ProtectedFilesHead.Flink, \
        protectedFile = CONTAINING_RECORD(protectedFileEntry, MY_PROTECTED_FILE_TYPE, EntryLink); \
        protectedFileEntry != &filterData.ProtectedFilesHead; \
        protectedFileEntry = protectedFileEntry->Flink, \
        protectedFile = CONTAINING_RECORD(protectedFileEntry, MY_PROTECTED_FILE_TYPE, EntryLink) \
    )

Use it like a for (as it actually is):

...
FOR_EACH_PROTECTED_FILE(protectedFile) {
    
}

Monday, August 20, 2018

New to C,Loop Issues [closed]

I want to enter value to my array and between 0 and 101 and trying to put zero or 101 will return an error but putting anything from 1-100 will allow me to enter a second number.

but i am stuck when write code to add a second number the loop keeps going in 1 and i cant figure out my error. any help would be apreciated

#include 
#include 

/* run this program using the console pauser or add your own getch, system("pause") or input loop */
char letter;

int main() 
{
    int i;
    int grades[12] ;

    for ( i = 0; i < 12; i++) 
        do{//loops the following peice of code if values over 100 or less than 0 are entered 

            printf("Please Enter Grade 1:\n");
            scanf("%f", & grades[i]);
            if (grades > 100 || grades < 0)
                printf("Invalid Entry please enter another between 0 and 100:\n");
        }while(grades < 100 || grades > 0);
}

Solved

The mistake here is you're comparing the whole array to a value. What you want is one element, plus you need to test that you're outside of the acceptable bounds:

while(grades[i] > 100 || grades[i] < 0);

As Jonathan points out below, the logic in your code tests that it's within, which means only valid answers will loop forever, the opposite of what you wanted.


Sunday, August 19, 2018

entity not recognizing in Google dialogflow

I have created mobile_storage entity as below. enter image description here

and created intent as below.

enter image description here

But while parsing for the below query, it is not recognizing storage correctly.

enter image description here

What could be the issue? Is there any way to capture the storage data more efficiently? Is there any issue in entity which I created?

Solved

I'm able to successfully extract the values from the created entity.

enter image description here enter image description here


Saturday, August 18, 2018

Merging a large number of files from one directory into a data frame in R

I have a large number of data files (>1000) in a single directory. I would like to merge them all in a single data frame in R. They all have the same number and types of columns. So far what I have is:

setwd("directory")
files <- list.files()
for (i in 1:length(files)) assign(files[i], read.csv(files[i]))

This creates data frames for each of the 1000+ files. Is there any way to merge them, without having to type out a list of all 1000+ file names?

Any help would be appreciated!

Solved

The standard way to do this with data.table (recommended because of its speed) is:

library(data.table)
data <- rbindlist(lapply(list.files(), fread))

From 1.9.5+ rbindlist has additional functionalities, e.g.

rbindlist(lapply(list.files(), fread), fill = TRUE)

Will take care of the possibility that some or many of your files have different column names--any non-overlap will be filled with NA in those files lacking that column.


EDIT: as @nicola mentioned, using assign is to be avoided in general.

See this post for further reference to that end.


One good way to do that is to utilize data.table. This library has two benefits that will work in your case: a) it has a fast way of reading .csv files, and b) a fast way of combining data.tables (which are an extension of data.frame) into one. So in this spirit, let me propose the following alternative:

# if you don't have data.table installed, run install.packages('data.table') first
library(data.table)
files <- list.files('directory', full.names = TRUE)
#create a list to manage the individual files, only used to merge them in the end
FILES_LIST=vector("list",length(files)) 
for (i in 1:length(files)) {
    FILES_LIST[[i]]<-fread(files[i]) #this reads your .csv file
}
FILES_LIST = rbindlist(FILES_LIST) #this merges all of your files in a big data.table

The variable you are interested in, in the end is FILES_LIST.

I hope this helps.