Delete all files except in array in NodeMCU Lua - arrays

Delete all files except the files in array
files = {"init.lua", "client.lua", "config.htm", "server.lua", "update.lua"}

As mentioned in the documentation, you can get a list of all the files on the filesystem using file.list().
This returns a map file name => file size; so the filename is the table key, which you can make use of.
Keep in mind that:
Table indexing in Lua is acceptably fast
Key-Value pairs can be removed by setting the value to nil
So we can do something like this:
local whitelist = {"init.lua", "client.lua", "config.htm", "server.lua", "update.lua"}
local files = file.list()
-- Remove files found in the whitelist
for _, filename in ipairs(whitelist) do
files[filename] = nil
end
-- Delete the remaining files
for filename in pairs(files) do
file.remove(filename)
end

Firstly, we can create 3 array-like tables: one for the protected files (the one you provided), another to list all files in the directory and the last to select the files we will delete.
local protected = {"init.lua", "client.lua", "config.htm", "server.lua", "update.lua"}
local found = {}
local delete = {}
Next, we will gather the directory contents:
for name in io.popen([[dir "" /b]]):lines() do
table.insert(found, name)
end
It is worth noticing that it will get folders too, but it doesn't matter here, since we won't be able to delete these anyway.
Now, with a simple function and a for-loop we will get the values from found to delete except for the ones in protected:
local function contains(t, v)
for index, value in ipairs(t) do
if value == v then
return true
end
end
return false
end
for _, value in ipairs(found) do
if not contains(protected, value) then
table.insert(delete, value)
end
end
Now we delete the files in delete
for _, filename in ipairs(delete) do
print("Deleting "..filename.." (unless it is a folder)")
os.remove(filename) -- this function is simply unable to delete folders
end
And this is it. I must admit, I'm running it on Windows, so I used the dir command. Where you want to run it may need it to be changed to ls (from io.popen([[dir "" /b]]):lines() to io.popen([[ls "" /b]]):lines()).

Related

How to check if file exists in Eiffel

feature
open_file_sample
local
l_file: UNIX_FILE_INFO
l_path: STRING
do
make
l_path := "/var/log/syslog"
l_file.update (l_path)
if l_file.parent_directory.exists and then l_file.parent_directory.is_writtable then
create l_file.make
end
-- AS the above statement doesn't exist!
check
syslog_file_exists_and_is_readable: l_file.exists and then l_file.is_readable
end
end
Is this the proper way to check for file existence in Eiffel?
I was wondering if there is a way not to create 2 objects. I'll complete my check with following statement:
define path `l_file_path := "/some/path/with_file.log"
check if parent directory exists and has rights to write into
create log file
The problem when accessing the file system is that the property of a file or directory may have changed between the time you query it and the time you want to use it (even if it's only a small fraction of a second). Because of that, assertions in Eiffel of the form:
f (a_file: RAW_FILE)
require
a_file.is_writable
do
a_file.open_write
may be violated. In the Gobo Eiffel libraries, instead of checking whether a file can be opened in write mode before actually opening it, the revert approach was chosen: try to open the file, and check whether it was opened successfully.
f (a_pathname: STRING)
local
l_file: KL_TEXT_OUTPUT_FILE
do
create l_file.make (a_pathname)
l_file.recursive_open_write
if l_file.is_open_write then
-- Write to the file.
l_file.close
else
-- Report the problem.
end
Note that it uses recursive_open_writeand not just open_write so that missing directories in the path get created as well.
You can use
{FILE_UTILITIES}.file_exists (the_file_name)
or
(create {RAW_FILE}.make_with_name (the_file_name)).exists
do
if not l_file.exists then
print ("error: '" + l_path + "' does not exist%N")
else
...
You can something similar to this
My final solution is following, and is subject to critics, I personnaly find it very complicated in comparison to more low level languages and libs (as bash for ex)
log_file_path: detachable PATH
-- Attached if can be created
local
l_file: UNIX_FILE_INFO
l_path, l_parent_dir: PATH
l_fu: FILE_UTILITIES
do
create l_fu
-- Parent directory check
create l_path.make_from_string ({APP_CONFIGURATION}.application_log_file_path)
l_parent_dir := l_path.parent
if not l_fu.directory_exists (l_parent_dir.out) then
l_fu.create_directory_path (l_parent_dir)
end
create l_file.make
l_file.update (l_parent_dir.out)
if not l_file.exists or
l_file.is_access_writable
then
io.putstring ("Error: " + log_file_path_string + " parent directory is not writtable and cannot be created")
check
parent_dir_exists_and_is_writtable: False
end
else
Result := l_path
end
ensure
file_name_could_be_created: Result /= Void
end

SQL - trying to find a set of data which only has a certain set of values but not anything else in a few columns

Hopefully an easy problem for an experienced SQL person. I have an application which uses SQL Server, and I cannot perform this query in the application, so I'm hoping to back-door it, but I need help.
I have a table with a large list of emails and all its metadata. I'm trying to find email that is only between parties of this one company and flag them.
What I did was search where companyName.com is in To and From and marked a TagField as 1 (I did this through my application's front end).
Now what I need to do is search where any other possible values, ignoring companyName.com exist in To and From where I've already flagged them as 1 in TagField. From will usually just have one value, but To could have multiple, all formatted differently, but all separated by a semi-colon (I will probably have to apply this same search to CC and BCC columns, too).
Any thoughts?
Replace the ; with the empty string. Then check to see if the length changed. If there's one email address, there shouldn't be a ';'. You could also use the same technique to replace the company name with the empty string. Anything left would be the other companies.
select email_id, to_email
from yourtable
where TagField = 1 and len(to_email) <> len(replace(to_email,';',''))
This solution is based on the following thread
Number of times a particular character appears in a string
So I went an entirely different route and exported my data to a CSV and used Python to get to where I needed. Here's the code I used in case anybody needs it. What this returned for me was a list of DocIDs (unique identifiers that were in the CSV) where ever there was an email address in the To field that wasn't from one specific domain. I went into the original CSV and made sure all instances of this domain name were in all lowercase, too.
import csv
import tkinter as tk
from tkinter import filedialog
root = tk.Tk()
root.withdraw()
file_path = filedialog.askopenfilename()
sub = "domainname"
def findMultipleTo(dict):
for row in reader:
if row['To'].find(";") != -1:
toArray = row['To'].split(';')
newTo = [s for s in toArray if sub not in s]
row['To'] = newTo
else:
row['To'] = 'empty'
with open('location\\newCSV-BCCFieldSearch.csv', 'a') as f:
if row['To'] != "empty" and row['To'] != []:
print(row['DocID'], row['To'], file = f)
else:
pass
with open(file_path) as csvfile:
reader = csv.DictReader(csvfile)
findMultipleTo(reader)

Insert contents of a text file recursively into mysql database Erlang

I'm having problem inserting a .txt file contents into my MySQL DB recursively.
Right now i have a function that reads a .txt file and gets a specific line from the file. It succeeds on inserting a specific line to an List where i then insert it into the MySQL DB but when i try to go from line 1 to n and do each line sepperatly I am truly lost.
I've tried to use the erlang:length() to gather the max lenght of the list and make it reduce by one for each line i insert but it wont work. I've tried something like this.
start() ->
Lines = into_list("Filepath"),
LineNR = erlang:length(Lines),
getLine(LineNR, Lines).
getLine(NewLineNR, List) when NewLineNR >= 0 ->
NewNewLineNR = NewLineNR - 1,
task(NewNewLineNR, List).
task(NewLineNR, List) ->
Line = line_nr( NewLineNR , List),
[List] = string:tokens(Line, ","),
Insert = [List],
%%The insertion in the DB happens here
insert_to_db(Insert),
getLine(NewLineNR, List).
But it crashed and i dont know why. Tips are appreciated! Thanks!
So what happens when NewLineNR = -1? Erlang will freak out because it can't match any of the getLine clauses.
You can do this a little simpler though (assuming line_nr just gets line x out of the list). In Erlang you can use pattern matching to control the program flow, instead of relying on keeping track of which item in the list you are working with:
start() ->
Lines = into_list("Filepath"),
task(Lines).
task([Head | Tail]) ->
TokensList = string:tokens(Head, ","),
%%The insertion in the DB happens here
insert_to_db(TokensList),
task(Tail);
task([]) -> done.
This version uses list head/tail pattern matching to help recurse through the list. Assuming into_list just reads the file into a list of strings, the code does the following:
Read file into list
Tokenize first entry in list
Insert into DB
Repeat 2-3 on remainder of list until list is empty.
Return done atom when list is empty.

MatLab - Execute functions base on their name

I have a couple of MatLab function, and almost all of them have a test function. There is not really a naming convention right now for test functions, so I end up with functions like test_functionName, tests_functionName, FunctionName_Test, etc.
Howerver, I see two things these functions have in common :
The name contains "test" (with different casing).
They have no input or output parameters.
I would like to write a function that would find, under a given folder (or in the PATH), all the functions that respect these two conditions and execute them. This way I could execute all my tests functions in one single call.
Is there any way I can do that?
You can do as follow:
fun=dir('*test*.m'); %% look for matlab scripts which name contains 'test'
fun={fun.name}; %% extract their names
fun=fun(cellfun(#(x) (nargin(x)==0),fun)); %% select the ones with no input arguments
fun = regexprep(fun, '.m', ''); % remove '.m' from the filenames
cellfun(#eval,fun); %% execute them
First, get all files under your folder:
d = dir(myFolder);
Remove those whose extension is not .m :
indexes = strcmp('.m',{d.ext});
d(indexes) = [];
Then, collect all of their names:
fileNames = {d.Name};
Check which one start or end with test:
testPrefix = strncmp('test',fileNames)
testPostfix = %# Left as an exercise to the reader
sutiableFileNames = fileNames( testPrefix | testPostfix);
Now you can check the amount of parameters using `nargin':
numOfInParams = cellfun(#nargin,sutiableFileNames);
numOfOutParams = cellfun(#nargout,sutiableFileNames);
And then filter again (I think you already got the idea)

MEL: Traverse through hierarchy

I'm writing a MEL script that will rename all of the joints in a joint hierarchy to a known format. The idea is that you would select the Hip joint and the script would rename the Hips, and go through every other joint and rename it based on its position in the hierarchy.
How can you traverse through a joint hierarchy in MEL?
If you assign to $stat_element the name of your top joint in the hierarchy and run the following code, it will add a prefix "myPrefix_" to all children elements of that joint.
string $stat_element = "joint1";
select -r $stat_element;
string $nodes[] = `ls -sl -dag`;
for($node in $nodes){
rename -ignoreShape $node ("myPrefix_" + $node);
}
Hope this helps
If you need to make detailed decisions as you go along, instead of bulk-renaming, traversing the hierarchy is pretty simple. The command is 'listRelatives'; With the 'c' flag it returns children of a node and with the 'p' flag it returns the parent. (Note that -p returns a single objects, -c returns an array)
Joint1
Joint2
Joint3
Joint4
listRelatives -p Joint2
// Result: Joint1 //
listRelatives -c Joint2
// Result: Joint3, Joint4
The tricky bit is the renaming, since maya will not always give you the name you expect (it won't allow duplicate names at the same level of the hierarchy). You'll need to keep track of the renamed objects or you won't be able to find them after they are renamed in case the new names don't match your expectations.
If you need to keep track of them, you can create a set with the set command before renaming; no matter what becomes of the names, all of the objects will still be in the set. Alternatively, you can traverse the hierarchy by selecting objects and renaming the current selection -- this won't record the changes but you won't have problems with objects changing names in the middle of your operation and messing up your commands.
It can be messy to do this in MEL if you have non-unique names because the handle you have for the object is the name itself. Once you rename a parent of a node with a non-unique name, the child's name is different. If you stored the list of all names before starting to rename, you will get errors as the rename command will attempt to rename nodes that don't exist. There are 2 solutions I know of using MEL. But first, here's the pyMel solution which is much easier and I recommend you use it.
PyMel Solution:
import pymel.core as pm
objects = pm.ls(selection=True, dag=True, type="joint")
pfx = 'my_prefix_'
for o in objects:
o.rename(pfx + o.name().split('|')[-1])
As pm.ls returns a list of real objects, and not just the names, you can safely rename a parent node and still have a valid handle to its children.
If you really want to do it in MEL, you need to either rename from the bottom up, or recurse so that you don't ask for the names of children before dealing with the parent.
The first MEL solution is to get a list of long object names and sort them based on their depth, deepest first. In this way you are guaranteed to never rename a parent before its children. The sorting bit is too convoluted to be bothered with here, and the recursive solution is better anyway.
Recursive MEL solution:
global proc renameHi(string $o, string $prefix) {
string $children[] = `listRelatives -f -c -type "joint $o`;
for ($c in $children) {
renameHi( $c ,$prefix ) ;
}
string $buff[];
int $numToks = tokenize($o, "|", $buff);
string $newName = $buff[( $numToks - 1)];
$newName = ($prefix + $newName);
rename($o,$newName);
}
string $prefix = "my_prefix_";
string $sel[] = `ls -sl -type "joint"`;
for ($o in $sel) {
renameHi($o, $prefix);
}
This recursive solution drills down to the leaf nodes and renames them before renaming their parents.

Resources