I have one folder with 3 subfolder and in each subfolder there are 10 files without the break in the first loop it will print this
[['folderA', 'folderB', 'folderC'], [], [], []]
How can I break from the 2nd loop and continue with the first and 3rd loop ?
folderName = []
fileName = []
for add, directory, allfiles in os.walk("path"): #loop one
folderName.append([re.sub(r'([^a-zA-Z ]+?)', '', i) for i in directory]) #loop 2
break
for name in allfiles: #loop 3
fileName.append(os.path.join(add, name))
Try this:
for i in directory: #loop 2
name = re.sub(r'([^a-zA-Z ]+?)', '', i)
if name:
folderName.append()
Related
the problem is it cannot print all the text of the from a .txt file. I am able to print the first 3 lines of the txt file but not the rest. So far, I am getting an error which is in print_album': undefined local variable or methodtracks' for main:Object (NameError).
Here's the code:
*I know using global variable is no good in Ruby but this exercise ask me to do it.
module Genre
POP, CLASSIC, JAZZ, ROCK = *1..4
end
$genre_names = ['Null', 'Pop', 'Classic', 'Jazz', 'Rock']
class Album
# NB: you will need to add tracks to the following and the initialize()
attr_accessor :title, :artist, :genre, :tracks
# complete the missing code:
def initialize (atitle, aartist, agenre, arrtrk)
# insert lines here
#genre = agenre
#tracks = arrtrk
#title = atitle
#artist = aartist
end
end
class Track
attr_accessor :ttitle, :tlocation
def initialize (tname, tloc)
#ttitle = tname
#tlocation = tloc
end
end
# Reads in and returns a single track from the given file
def read_track music_file
mytrk_name = music_file.gets
mytrk_location = music_file.gets
mytrk = Track.new(mytrk_name, mytrk_location)
mytrk
end
# Returns an array of tracks read from the given file
def read_tracks music_file
count = music_file.gets().to_i
tracks = Array.new
$i = 0
# Put a loop here which increments an index to read the tracks
while $i < count do
track = read_track(music_file)
tracks << track
$i += 1
end
tracks
end
# Takes an array of tracks and prints them to the terminal
def print_tracks tracks
# print all the tracks use: tracks[x] to access each track.
$i = 0
while $i < tracks.length do
print_track(tracks[$i])
$i +=1
end
tracks
end
# Reads in and returns a single album from the given file, with all its tracks
def read_album music_file
# read in all the Album's fields/attributes including all the tracks
# complete the missing code
album_title = music_file.gets
album_artist = music_file.gets
album_genre = music_file.gets.to_i
tracks = read_tracks(music_file)
album = Album.new(album_title, album_artist, album_genre, tracks)
album
end
# Takes a single album and prints it to the terminal along with all its tracks
def print_album album
# print out all the albums fields/attributes
# Complete the missing code.
puts 'Album title is '+ album.title
puts 'Artist is ' + album.artist
puts 'Genre is ' + album.genre.to_s
puts $genre_names[album.genre]
# print out the tracks
print_tracks(tracks)
end
# Takes a single track and prints it to the terminal
def print_track track
puts('Track title is: ' + track.ttitle)
puts('Track file location is: ' + track.tlocation)
end
# Reads in an album from a file and then print the album to the terminal
def main
music_file = File.new("album.txt", "r")
album = read_album(music_file)
music_file.close()
print_album(album)
end
main
Here's is the album.txt
Greatest Hits
Neil Diamond
1
3
Crackling Rose
sounds/01-Cracklin-rose.wav
Soolaimon
sounds/06-Soolaimon.wav
Sweet Caroline
sounds/20-Sweet_Caroline.wav
Currently my output is :
Album title is Greatest Hits
Artist is Neil Diamond
Genre is 1
Pop
Expected output is :
Album title is Greatest Hits
Artist is Neil Diamond
Genre is 1
Pop
Track title is: Crackling Rose
Track file location is: sounds/01-Cracklin-rose.wav
Track title is: Soolaimon
Track file location is: sounds/06-Soolaimon.wav
Track title is: Sweet Caroline
Track file location is: sounds/20-Sweet_Caroline.wav
The problem is inside your def print_album album method. On the last line of the method it uses print_tracks(tracks), but tracks variable is undefined (that's exactly what error tells you).
You need to call print_tracks(album.tracks)
How would I go about compiling values from a table using a string?
i.e.
NumberDef = {
[1] = 1,
[2] = 2,
[3] = 3
}
TextDef = {
["a"] = 1,
["b"] = 2,
["c"] = 3
}
If I was for example to request "1ABC3", how would I get it to output 1 1 2 3 3?
Greatly appreciate any response.
Try this:
s="1ABC3z9"
t=s:gsub(".",function (x)
local y=tonumber(x)
if y~=nil then
y=NumberDef[y]
else
y=TextDef[x:lower()]
end
return (y or x).." "
end)
print(t)
This may be simplified if you combine the two tables into one.
You can access values in a lua array like so:
TableName["IndexNameOrNumber"]
Using your example:
NumberDef = {
[1] = 1,
[2] = 2,
[3] = 3
}
TextDef = {
["a"] = 1,
["b"] = 2,
["c"] = 3
}
print(NumberDef[2])--Will print 2
print(TextDef["c"])--will print 3
If you wish to access all values of a Lua array you can loop through all values like so (similarly to a foreach in c#):
for i,v in next, TextDef do
print(i, v)
end
--Output:
--c 3
--a 1
--b 2
So to answer your request, you would request those values like so:
print(NumberDef[1], TextDef["a"], TextDef["b"], TextDef["c"], NumberDef[3])--Will print 1 1 2 3 3
One more point, if you're interested in concatenating lua string this can be accomplished like so:
string1 = string2 .. string3
Example:
local StringValue1 = "I"
local StringValue2 = "Love"
local StringValue3 = StringValue1 .. " " .. StringValue2 .. " Memes!"
print(StringValue3) -- Will print "I Love Memes!"
UPDATE
I whipped up a quick example code you could use to handle what you're looking for. This will go through the inputted string and check each of the two tables if the value you requested exists. If it does it will add it onto a string value and print at the end the final product.
local StringInput = "1abc3" -- Your request to find
local CombineString = "" --To combine the request
NumberDef = {
[1] = 1,
[2] = 2,
[3] = 3
}
TextDef = {
["a"] = 1,
["b"] = 2,
["c"] = 3
}
for i=1, #StringInput do --Foreach character in the string inputted do this
local CurrentCharacter = StringInput:sub(i,i); --get the current character from the loop position
local Num = tonumber(CurrentCharacter)--If possible convert to number
if TextDef[CurrentCharacter] then--if it exists in text def array then combine it
CombineString = CombineString .. TextDef[CurrentCharacter]
end
if NumberDef[Num] then --if it exists in number def array then combine it
CombineString = CombineString .. NumberDef[Num]
end
end
print("Combined: ", CombineString) --print the final product.
My script returns an empty array in another empty array (or I guess it's not empty because there is another empty array within the other array).
I have an if condition that checks if the outer array is empty. It says it's not empty because it contains an empty array. I need help to get it return false. I believe the best method would be to check if the inner array is empty, but I'm not sure where the inner array is created.
Here's the code for the method that checks if the array is empty:
def directory_check(directory_list, save_to_file, today_date, output_file, output_extension, results_file_output)
if directory_list.empty? == false
# changes the working directory to the file output directory for the file
Dir.chdir(save_to_file)
# writes the array contents into a new file
file_name = output_file + "_" + today_date + output_extension
puts Time.now.to_s + " > " + "Saving contents to: " + results_file_output + file_name
puts ""
File.open(file_name, "a+") do |f|
directory_list.each { |element| f.puts(element) }
end
else
puts Time.now.to_s + " > " + "This directory does not contain any subdirectories that are older than 24 hours"
exit
end
end
The directory_list returns [[]], and empty? returns false.
I have another method that stores items into an array, but I cannot figure out why there is an array within an array:
def store_directories(directories, folder_to_exclude)
# updates search directory for each value for the directories hash
subdir_list = Array.new
directories.each do |element|
directory = "#{element}"
puts Time.now.to_s + " > " + "Updating search directory: " + directory
Dir.chdir(directory)
# outputs only subdirectories with a creation date of older than 24 hours, except for folders names 'Archive'
Dir.glob("*.*").map(&File.method(:realpath))
puts Time.now.to_s + " > " + "Gathering subdirectories..."
puts ""
# Stores the contents of the query into an array and appends to the list for each iteration of the array
subdir_list << Dir.glob("*").map(&File.method(:realpath)).reject {|files|
(not File.directory?(files) &&
(File.mtime(files) < (Time.now - (60*1440))) &&
(not files == directory + folder_to_exclude))
}
puts ""
puts "Adding new folders to the list..."
puts ""
puts "Excluding: " + directory + folder_to_exclude
puts ""
puts subdir_list
puts " "
end
return subdir_list
end
I'm passing an array of directories into the store_directories method.
The directory_list returns [[]], and empty? returns false.
it's working properly and it returns correct value, as your directory_list is not empty array, it contain empty array. You need to use Array#flatten
> [[]].flatten.empty?
#=> true
I am trying to load multiple files via ruby/tk lib and put them into array:
def openFiles
return Tk.getOpenFile( 'title' => 'Select Files',
'multiple' => true,
'defaultextension' => 'csv',
'filetypes' => "{{Comma Seperated Values} {.csv}} {TXT {.txt}} {All files {.*}}")
end
and then in code
filess = TkVariable.new()
button1 = TkButton.new(root){
text 'Open Files'
command (proc {filess.value = openFiles; puts filess; puts filess.class; puts filess.inspect})
}.grid(:column => 1, :row => 1, :sticky => 'we')
The problem is that I can not manage to get the output as array and I do not know if it is possible or I will have to somehow parse the output. Hm? Please help. Thank you.
this is the output, when I click on the button:
C:\file1
C:\file2
TkVariable
#<TkVariable: v00000>
I think it should be: (for the array part)
['C:\file1','C:\file2']
TkVariable implements #to_a, which you can use to convert its value into the Array you want.
button1 = TkButton.new(root) {
text 'Open Files'
command (proc do
filess.value = openFiles
puts filess.to_a.class
puts filess.to_a.inspect
end)
}.grid(:column => 1, :row => 1, :sticky => 'we')
Array
["C:\file1", "C:\file2"]
This worked for me using Ruby 2.2.5 (with Tk 8.5.12) on Windows 7:
require 'tk'
def extract_filenames_as_ruby_array(file_list_string)
::TkVariable.new(file_list_string).list
end
def files_open
descriptions = %w[
Comma\ Separated\ Values
Text\ Files
All\ Files
]
extensions = %w[ {.csv} {.txt} * ]
types = descriptions.zip(extensions).map {|d,e| "{#{d}} #{e}" }
file_list_string = ::Tk.getOpenFile \
filetypes: types,
multiple: true,
title: 'Select Files'
extract_filenames_as_ruby_array file_list_string
end
def lambda_files_open
#lambda_files_open ||= ::Kernel.lambda do
files = files_open
puts files
end
end
def main
b_button_1
::Tk.mainloop
end
# Tk objects:
def b_button_1
#b_button_1 ||= begin
b = ::Tk::Tile::Button.new root
b.command lambda_files_open
b.text 'Open Files'
b.grid column: 1, row: 1, sticky: :we
end
end
def root
#root ||= ::TkRoot.new
end
main
For reference, Tk.getOpenFile is explained in the Tk Commands and Ruby documentation.
How do I get the last element of an array and show the rest of the elements?
Like this :
#myArray = (1,1,1,1,1,2);
Expected output :
SomeVariable1 = 11111
SomeVariable2 = 2
# print last element
print $myArray[-1];
# joined rest of the elements
print join "", #myArray[0 .. $#myArray-1] if #myArray >1;
If you don't mind modifying the array,
# print last element
print pop #myArray;
# joined rest of the elements
print join "", #myArray;
Сухой27 has given you the answer. I wanted to add that if you are creating a structured output, it might be nice to use a hash:
my #myArray = (1,1,1,1,1,2);
my %variables = (
SomeVariable1 => [ #myArray[0 .. $#myArray -1] ],
SomeVariable2 => [ $myArray[-1] ]
);
for my $key (keys %variables) {
print "$key => ",#{ $variables{$key} },"\n";
}
Output:
SomeVariable1 => 11111
SomeVariable2 => 2