Load data by one button, plot data by a second button - excel

I have a GUI in Matlab, and several buttons, by one button I need to load a file (I don't want the directory to be shown) and by second button plot determined data.
Code for the first button:
[filename, pathname] = uigetfile({'*.xlsx;*.xls'});
Code for the second button:
fileID = fopen(strcat(pathname, filename), 'r');
handles.fileData = xlsread(strcat(pathname, filename));
axes(handles.axes1);
plot(handles.fileData(:,1),'-k')
hold on;
axes(handles.axes1)
plot(handles.fileData(:,2),'k')
I get an error message all the time:
Undefined function or variable 'pathname'.
HOw can I pass the function to the second button?
Thanks for your help in advance!

Ad hoc solution is using: setappdata and getappdata.
Example:
function pushbutton1_Callback(hObject, eventdata, handles)
setappdata(0, 'pathname', 'abc');
function pushbutton2_Callback(hObject, eventdata, handles)
pathname = getappdata(0, 'pathname'); % Return 'abc'.
Another simple solution is passing pathname in UserData member of the parent figure.
When both buttons are in the same figure, hObject.Parent is the handle to the figure, and UserData element is a "preparation" for passing data between GUI objects.
Example:
function pushbutton1_Callback(hObject, eventdata, handles)
hObject.Parent.UserData.pathname = 'abs';
function pushbutton2_Callback(hObject, eventdata, handles)
pathname = hObject.Parent.UserData.pathname; %Value is 'abc'
For more information refer to: https://www.mathworks.com/help/matlab/creating_guis/share-data-among-callbacks.html
Complete code sample without using guide tool:
I created the following sample without using guide tool because there is no simple way passing the fig file of guide in Stack Overflow.
function TestNoGuide()
clear all
close all
% Create figure
hObject = figure('position', [800 400 260 100], 'Toolbar','none');
% create structure of handles
handles = guihandles(hObject);
handles.hObject = hObject;
handles.pushbutton1 = uicontrol('style', 'pushbutton', 'position',[10 20 100 40], 'string' , 'Button1');
handles.pushbutton2 = uicontrol('style', 'pushbutton', 'position',[150 20 100 40], 'string' , 'Button2');
set(handles.pushbutton1, 'callback', {#pushbutton1_Callback, handles});
set(handles.pushbutton2, 'callback', {#pushbutton2_Callback, handles});
%Save the structure
guidata(hObject);
end
function pushbutton1_Callback(hObject, eventdata, handles)
[filename, pathname] = uigetfile({'*.xlsx;*.xls'});
setappdata(0, 'filename', filename);
setappdata(0, 'pathname', pathname);
end
function pushbutton2_Callback(hObject, eventdata, handles)
filename = getappdata(0, 'filename');
pathname = getappdata(0, 'pathname');
waitfor(warndlg(['filename = ', filename, ' pathname = ', pathname]));
end
Check it out, and tell me if it's working on your machine...

Related

How to Call a Function with 'on_press' command inside same class using KIVY button

I'm trying to call a popup and the have the user input text. After hitting the save button inside my popup it updates a new widget.
I have almost everything working but I don't know how to properly call a function inside the same class.
I have two functions inside of my
'class Trackers(Screen):'
how can I make a button that 'on_press' command will trigger another function?
The line of code I need to be fixed is this:
okay = Button(text='Save', on_press=self.addit(str(text_input), num), on_release=pop.dismiss)
Thank you so much.
''''
def addWidget(self):
num = '0'
box = BoxLayout(orientation= 'vertical', padding=40, spacing=5)
pop = Popup(title='Tracker: details', content=box, size_hint=(None,None), size=(300,300))
text_input = TextInput(hint_text='Add Trackers', multiline=False,)
okay = Button(text='Save', on_press=self.addit(str(text_input), num), on_release=pop.dismiss)
box.add_widget(text_input)
box.add_widget(okay)
pop.open()
def addit(self, text_input, num, *args):
if text_input not in self.storage.keys():
self.ids.track.add_widget(Tracker(text=text_input, number=num, data=self.storage))
self.storage[text_input] = '0'
text_input = ''
self.saveData()
else:
box = BoxLayout(orientation= 'vertical', padding=40, spacing=5)
pop = Popup(title=f'Opps: "{text_input}" is already listed below', content=box, size_hint=(None,None), size=(300,180))
try_again = Button(text='Try Again', on_release=pop.dismiss)
box.add_widget(try_again)
pop.open()
''''

Flask file download: filename persists within the session

I have a flask site and a webform that generates excel files. The problem I'm having is, if I send the user back to the form to submit again, the previous file -- with same file name and data -- is downloaded even though new files are generated in the tmp directory. So, I think this has to do with my session variable.
I add a timestamp to the file name with this function to make sure the file names are unique:
def rightnow():
return dt.datetime.now().strftime("%m%d%y%h%m%S%f")
In routes.py, here is the call for the download:
#app.route('/download/', methods=['POST','GET'])
def download_file():
output_file = session.get('new_file', None)
r = send_file(output_file, attachment_filename=output_file, as_attachment=True)
return r
This is the code for the script that generates the excel files:
new_file = 'output_' + rightnow() + '.xlsx'
writer = pd.ExcelWriter('tmp/' + new_file, engine='xlsxwriter')
df.to_excel(writer, sheet_name="data")
writer.save()
session['new_file'] = 'tmp/' + new_file
The download statement from the template page:
<a class="button" href="{{url_for('download_file')}}">Download new data</a>
I have a "Submit Again" button tied to simple javascript
<button onclick="goBack()">Submit Again</button>
<script>//for "revise search" button
function goBack() {
window.history.back();
}
</script>
I have played around with session.clear() with no success.
How can I drop the session when the user click's the "Submit Again" button so the saved file name is dropped?
EDIT: I checked the variables for the filename and the session variable and they are identical, and different from the file name assigned on download. Forinstance, the file is named 'output_May0554733504.xlsx' by the script that I wrote -- I can see it in the tmp directory. But when I go to download the file, the filename is different: 'output_May0536794357.xlsx'
This other file name is not that of a different file in the tmp directory. Any file I download will be 'output_May0536794357.xlsx'.
If session.pop('new_file') doesn't work, you could try session.modified = True to force the change to the session.

The Button.connect syntax in Genie

I want to apply a certain behaviour to a label. When a lateral button is clicked, the corresponding label should rotate 90 degrees. It can be easily done in vala, but I can't discover the particular syntax on genie.
The vala code I am trying to reproduce comes from elementary OS getting started guide:
hello_button.clicked.connect(() =>
{
hello_label.label = "Hello World!";
hello_button.sensitive = false;
});
rotate_button.clicked.connect(() =>
{
rotate_label.angle = 90;
rotate_label.label = "Verbal";
rotate_button.sensitive = false;
});
I actually managed to reproduce almost entirely the code in Genie, for the exception of the rotation. Here is how far I got:
/* ANOTHER GTK EXPERIMENT WITH GENIE BASED ON ELEMENTARY INTRODUCTORY PAGE
** compile with valac --pkg gtk+03.0 layoutgtkexample.gs */
[indent=4]
uses Gtk
init
Gtk.init (ref args)
var window = new Gtk.Window()
window.title = "Hello World!"
window.set_border_width(12)
var layout = new Gtk.Grid ()
layout.column_spacing = 6
layout.row_spacing = 6
var hello_button = new Gtk.Button.with_label("Say Hello")
var hello_label = new Gtk.Label("Hello")
var rotate_button = new Gtk.Button.with_label ("Rotate")
var rotate_label = new Gtk.Label("Horizontal")
// add first row of widgets
layout.attach (hello_button, 0, 0, 1,1)
layout.attach_next_to (hello_label, hello_button, PositionType.RIGHT, 1, 1)
// add second row of widgets
layout.attach(rotate_button, 0,1,1,1)
layout.attach_next_to(rotate_label, rotate_button, PositionType.RIGHT, 1, 1)
window.add(layout)
hello_button.clicked.connect(hello_pushed)
rotate_button.clicked.connect(rotate_pushed)
window.destroy.connect(Gtk.main_quit)
window.show_all ()
Gtk.main ()
def hello_pushed (btn:Button)
btn.label = "Hello World!"
btn.sensitive = false
def rotate_pushed (btn:Button)
btn.label = "Vertical"
//btn.angle = 90
btn.sensitive = false
The problem is to do with where identifiers are valid and is known as "scope".
The Vala example makes use of an anonymous function, also called a lambda expression in Vala. An anonymous function can be a "closure", when the variables in the scope that defines the anonymous function are also available within the anonymous function. This is useful because the callback occurs after the original block of code has been run, but the variables are still available within the callback. So in the Vala example, where both the button and label are defined in the enclosing scope, the button and label are also available in the callback anonymous function.
Unfortunately Genie isn't able to parse anonymous functions as function arguments, in this case within the connect() call. Although some work has been done on this in 2015. So you have rightly used a function name instead. The problem is the callback only passes the button as an argument and not the adjacent label. So to make the label available within the callback function we could use a class:
/* ANOTHER GTK EXPERIMENT WITH GENIE BASED ON ELEMENTARY INTRODUCTORY PAGE
** compile with valac --pkg gtk+-3.0 layoutgtkexample.gs */
[indent=4]
uses Gtk
init
Gtk.init (ref args)
new RotatingButtonWindow( "Hello World!" )
Gtk.main ()
class RotatingButtonWindow:Window
_hello_label:Label
_rotate_label:Label
construct( window_title:string )
title = window_title
set_border_width(12)
var layout = new Grid ()
layout.column_spacing = 6
layout.row_spacing = 6
// add 'hello' row of widgets
var hello_button = new Button.with_label("Say Hello")
_hello_label = new Label("Hello")
layout.attach (hello_button, 0, 0, 1,1)
layout.attach_next_to (_hello_label, hello_button, PositionType.RIGHT, 1, 1)
// add 'rotate' row of widgets
var rotate_button = new Button.with_label ("Rotate")
_rotate_label = new Label("Horizontal")
layout.attach(rotate_button, 0,1,1,1)
layout.attach_next_to(_rotate_label, rotate_button, PositionType.RIGHT, 1, 1)
add(layout)
hello_button.clicked.connect(hello_pushed)
rotate_button.clicked.connect(rotate_pushed)
destroy.connect(Gtk.main_quit)
show_all ()
def hello_pushed (btn:Button)
_hello_label.label = "Hello World!"
btn.sensitive = false
def rotate_pushed (btn:Button)
_rotate_label.label = "Vertical"
_rotate_label.angle = 90
btn.sensitive = false
A few notes:
By placing the definitions of the _hello_label and _rotate_label within the scope of the class they become available to all the functions defined in the class. Definitions like this are often called "fields". The underscore means they are not available outside the class, so in the example you cannot access them from init
construct() is called when the object is created, in the example the line new RotatingButtonWindow( "Hello World!" ) instantiates the object. If you repeat the line you will have two separate windows, that is two instances of the RotatingButtonWindow data type
You will notice that the RotatingButtonWindow type is also defined as a Window type. This means it is adding more detail to the Gtk.Window class. This is why title and set_border_width() can be used within the new class. They have been "inherited" from the parent Gtk.Window class
By using the Gtk namespace with uses Gtk we don't need to prefix everything with Gtk
As your Gtk application gets more complex you probably want to look at GtkBuilder. That allows windows and widgets to be laid out in an external file. Then use GResource to build the file into the binary of your application so there is no need to distribute the UI file separately.

Only one image getting uploaded multiple times

I have been using mechanize gem to scrape data from craigslist, I have a piece of code that uploads multiple image to craigslist, all the file paths are correct, but only single image gets uploaded multiple times what's the reason.
unless pic_url_arry.blank?
unless page.links_with(:text => 'Use classic image uploader').first.blank?
page = page.links_with(:text => 'Use classic image uploader').first.click
end
puts "After classic image uploader"
form = page.form_with(class: "add")
# build full file path before setting like this => file = File.join( APP_ROOT, 'tmp', 'image.jpg')
i = 0
pic_url_arry = pic_url_arry.shuffle
pic_url_arry.each do |p|
form.file_uploads.first.file_name = p
i+= 1
page = form.submit
puts "******#{p.inspect}*******"
puts "******#{page.inspect}*******"
end unless pic_url_arry.blank?
# check if the file uploaded sucessfully with no. of files with no. of imgbox on page.
check_image_uploaded = page.at('figure.imgbox').count
if check_image_uploaded.to_i == i.to_i
# upload failure craiglist or net error.
end
end
AND the pic array has value as ["/home/codebajra/www/office/autocraig/public/uploads/posting_pic/pic/1/images__4_.jpg", "/home/codebajra/www/office/autocraig/public/uploads/posting_pic/pic/2/mona200.jpg", "/home/codebajra/www/office/autocraig/public/uploads/posting_pic/pic/3/images__1_.jpg"].
The form holding filefield is being set only once, which is taking only one image that hits first. So, the updated code will be,
unless pic_url_arry.blank?
unless page.links_with(:text => 'Use classic image uploader').first.blank?
page = page.links_with(:text => 'Use classic image uploader').first.click
end
puts "After classic image uploader"
form = page.form_with(class: "add")
# build full file path before setting like this => file = File.join( APP_ROOT, 'tmp', 'image.jpg')
i = 0
pic_url_arry = pic_url_arry.shuffle
pic_url_arry.each do |p|
form.file_uploads.first.file_name = p
i+= 1
page = form.submit
form = page.form_with(class: "add")
puts "******#{p.inspect}*******"
puts "******#{page.inspect}*******"
end unless pic_url_arry.blank?
# check if the file uploaded sucessfully with no. of files with no. of imgbox on page.
check_image_uploaded = page.at('figure.imgbox').count
if check_image_uploaded.to_i == i.to_i
# upload failure craiglist or net error.
end
end
hoping this will solve the problem.

NodeSchool IO Exercies 3

I've started learning node.js
I'm currently on exercise 3, where we have to, based on a file buffer, calculate the number of new line characters "\n"
I pass the tester but somehow if I create my own file file.txt, I am able to get the buffer, and print out the string, but it is unable to calculate the number of new lines (console.log(newLineNum)) returns 0
Here is the code
//import file system module
var fs = require("fs");
//get the buffer object based on argv[2]
var buf = fs.readFileSync(process.argv[2]);
//convert buffer to string
var str_buff = buf.toString();
//length of str_buff
var str_length = str_buff.length;
var numNewLines = 0;
for (var i = 0; i < str_length; i ++)
{
if(str_buff.charAt(i) == '\n')
{
numNewLines++;
}
}
console.log(numNewLines);
If i understand your question correctly, you are trying to get the line length of current file.
From the documentation:
The first element will be 'node', the second element will be the name
of the JavaScript file.
So you should replace process.argv[2] with process.argv[1].
Edit:
If you are passing a parameter for a file name on command-line like:
node server.py 'test.txt'
your code should work without any problem.
Your code is fine. You should check the file that you are using for the input.

Resources