Scilab - gui - many unknown variables error messages - scilab
Still trying to understand the logic of Scilab, I created a small calculation tool for a mechanical element. The main problem I have is finding the right order (or syntax) for the calculation code... I get a lot of "unknown variable" errors and I don't understand why?
I tried to change the order of definitions for the functions, declare the variables as global, etc. but nothing seems to help.
The code for the calculation is not long and also not complicated, but the gui was built using guibuilder, so the uicontrols definitions are probably much longer than they need to be.
Could somebody help me make this code working, as I would learn and understand a lot by this example, althought it contains more than one "problem zones"?
Here what I've done:
G = 78500;
table_titles = ["" "Wire diameter" "Wp" "Tau alwd" "M alwd" "Angle alwd"];
f=figure('figure_position',[910,163],'figure_size',
[903,537],'auto_resize','on','background',[33],'figure_name','Graphic
window number %d');
//////////
delmenu(f.figure_id,gettext('File'))
delmenu(f.figure_id,gettext('?'))
delmenu(f.figure_id,gettext('Tools'))
toolbar(f.figure_id,'off')
handles.dummy = 0;
handles.sl_dwire=uicontrol(f,'unit','normalized','BackgroundColor',
[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma',
'FontSize',[12],'FontUnits','points','FontWeight','normal',
'ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',
[],'Max',[12],'Min',[0],'Position',
[0.0058208,0.77875,0.124375,0.06875],'Relief','default','SliderStep',
[0.1,1],'Style','slider','String',"Wire diameter",'Value',
[6],'VerticalAlignment','middle','Visible','on','Tag','sl_dwire',
'Callback','sl_dwire_callback(handles)')
handles.ed_dwire=uicontrol(f,'unit','normalized','BackgroundColor',
[-1,-1,-1],'Enable','off','FontAngle','normal','FontName','Tahoma',
'FontSize',[12],'FontUnits','points','FontWeight','normal',
'ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left','ListboxTop',
[],'Max',[1],'Min',[0],
'Position',[0.0058208,0.71875,0.124375,0.06875],'Relief',
'default','SliderStep',[0.01,0.1],'String',"wire diameter: " +
msprintf('%2.1f',handles.sl_dwire.Value) + "mm",'Style','text',
'Value',[0],'VerticalAlignment','middle','Visible','on','Tag',
'ed_dwire','Callback','auto')
handles.sl_wangle=uicontrol(f,'unit','normalized','BackgroundColor',
[-1,-1,-1],'Enable','on','FontAngle','normal','FontName','Tahoma',
'FontSize',[12],'FontUnits','points','FontWeight','normal',
'ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left',
'ListboxTop',[],'Max',[180],'Min',[5],'Position',
[0.0090625,0.5191667,0.25625,0.0645833],'Relief','default',
'SliderStep',[0.1,1],'String','Working angle','Style','slider','Value',
[50],'VerticalAlignment','middle','Visible','on','Tag','sl_wangle',
'Callback','sl_wangle_callback(handles)')
handles.ed_wangle=uicontrol(f,'unit','normalized','BackgroundColor',
[-1,-1,-1],'Enable','off','FontAngle','normal','FontName','Tahoma',
'FontSize',[12],'FontUnits','points','FontWeight','normal',
'ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left',
'ListboxTop',[],'Max',[1],'Min',[0],'Position',
[0.0090625,0.4591667,0.25625,0.0645833],'Relief','default',
'SliderStep',[0.01,0.1],'String',"Working angle: " +
msprintf('%2.1f',handles.sl_wangle.Value) + "°",'Style','text',
'Value',[0],'VerticalAlignment','middle','Visible','on','Tag',
'ed_wangle','Callback','auto')
handles.sl_activel=uicontrol(f,'unit','normalized',
'BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal',
'FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight',
'normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left',
'ListboxTop',[],'Max',[1000],'Min',[10],'Position',
[0.0090625,0.365,0.25625,0.0645833],'Relief','default',
'SliderStep',[0.1,1],'String','Active length' ,'Style','slider',
'Value',[10],'VerticalAlignment','middle','Visible','on','Tag',
'sl_activel','Callback','sl_activel_callback(handles)')
handles.ed_activel=uicontrol(f,'unit','normalized',
'BackgroundColor',[-1,-1,-1],'Enable','off','FontAngle','normal',
'FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight',
'normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left',
'ListboxTop',[],'Max',[1],'Min',[0],'Position',
[0.0090625,0.305,0.25625,0.0645833],'Relief','default',
'SliderStep',[0.01,0.1],'String','Active length: ' +
msprintf('%2.1f',handles.sl_activel.Value) +
"mm",'Style','text','Value',[0],'VerticalAlignment','middle','Visible',
'on','Tag','ed_activel','Callback','auto')
handles.ax_graph= newaxes();handles.ax_graph.margins = [ 0 0 0 0];
handles.ax_graph.axes_bounds = [0.4274266,0.0619266,0.3995485,0.5191743];
handles.tab_param=uicontrol(f,'unit','normalized','BackgroundColor',
[-1,-1,-1],'Enable','on','FontAngle','normal','FontName',
'Tahoma','FontSize',[12],'FontUnits','points','FontWeight','normal',
'ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left',
'ListboxTop',[],'Max',[1],'Min',[0],
'Position',[0.4308126,0.1690826,0.3950339,0.2178899],'Relief',
'default','SliderStep',[0.01,0.1],'String',string(table_param),'Style',
'table','Value',[0],'VerticalAlignment','middle','Visible',
'on','Tag','tab_param','Callback','tab_param_callback(handles)')
handles.sl_sfactor=uicontrol(f,'unit','normalized',
'BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal',
'FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight',
'normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left',
'ListboxTop',[],'Max',[1],'Min',[0],
'Position',[0.0058208,0.6525688,0.124375,0.06875],'Relief','default',
'SliderStep',[0.01,0.1],'String',"Safety factor",'Style',
'slider','Value',[0.58],'VerticalAlignment','middle','Visible','on',
'Tag','ed_sfactor','Callback','sl_sfactor_callback(handles)')
handles.ed_sfactor=uicontrol(f,'unit','normalized',
'BackgroundColor',[-1,-1,-1],'Enable','off','FontAngle','normal',
'FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight',
'normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment',
'left','ListboxTop',[],'Max',[1],'Min',[0],'Position',
[0.0058208,0.5925688,0.124375,0.06875],'Relief','default',
'SliderStep',[0.01,0.1],'String',"Safety factor : " +
msprintf('%2.1f',handles.sl_sfactor.Value),'Style',
'text','Value',[0.58],'VerticalAlignment','middle','Visible','on',
'Tag','ed_dwire','Callback','auto')
handles.popm_wtype=uicontrol(f,'unit','normalized',
'BackgroundColor',[-1,-1,-1],'Enable','on','FontAngle','normal',
'FontName','Tahoma','FontSize',[12],'FontUnits','points','FontWeight',
'normal','ForegroundColor',[-1,-1,-1],'HorizontalAlignment','left',
'ListboxTop',[],'Max',[1],'Min',[0],'Position',
[0.0058208,0.8618349,0.124375,0.0639450],'Relief','default',
'SliderStep',[0.01,0.1],'String',gettext("SL/DL|SM/DM|SH/DH"),'Style',
'popupmenu','Value',[2],'VerticalAlignment','middle','Visible','on',
'Tag','popm_wtype','Callback','popm_wtype_callback(handles)')
//////////
// Callbacks are defined as below. Please do not delete the comments
as it will be used in coming version
//////////
function sl_sfactor_callback(handles)
sf=handles.sl_sfactor.Value;
handles.ed_sfactor.String="Safety factor: " + msprintf('%3.2f',sf);
endfunction
function sl_dwire_callback(handles)
wd=handles.sl_dwire.Value;
Wp = %pi*wd^3/16;
Ip =%pi*wd^4/32;
Kt = G*%pi*Ip/(180*L);
Talwd = sf * calcform;
Malwd = Wp * Talwd;
alphaalwd = Malwd / Kt;
x=0:0.1:alphaalwd*1.5;
plot(x,Kt*x);
handles.ed_dwire.String="Wire diameter: " +
msprintf('%2.1f',wd) + "mm";
endfunction
function popm_wtype_callback(handles)
//Write your callback for popm_wtype here
if selected == 1 then
calcform =(1845 - 700*log10(wd));
elseif selected == 2 then
calcform =(2105 - 780*log10(wd));
elseif selected == 3 then
calcform = (2220 - 820*log10(wd));
end
endfunction
function sl_wangle_callback(handles)
handles.ed_wangle.String="Working angle: " +
msprintf('%2.1f',handles.sl_wangle.Value) + "°";
endfunction
function sl_activel_callback(handles)
//Write your callback for sl_activel here
handles.ed_activel.String="Active length: " +
msprintf('%2.1f',handles.sl_activel.Value) + "mm";
L=handles.sl_activel.Value;
endfunction
function tab_param_callback(handles)
//Write your callback for tab_param here
table_values = string([ wd Wp Talwd Malwd alphaalwd]);
table_param = [table_titles; [table_values]];
endfunction
I expect the code to dynamically update the graph and the parameters table according to the positions of input sliders and popup-menu.
Again, it would be very helpful if somebody could help me get this code working, as I would get answers for a lot of my questions concerning programming with scilab.
Thank you very much in advance!
First of all, your code is not directly executable, caused by the linebreaks. Please add ... after each line of a statement. This improves also the readability.
As mentioned by #luispauloml, you try to use variables, which exist just inside of another function. For example you try to reach table_param, which is just alive in tab_param_callback(handles).
To get rid of this, you have to define the output for the function:
function [table_values, table_param] = tab_param_callback(handles)
table_values = string([ wd Wp Talwd Malwd alphaalwd]);
table_param = [table_titles; [table_values]];
endfunction
Now you can call this function to get the variable:
string(tab_param_callback(handles))
I corrected just this case and added the dots as explained. For the other variables, it can be done analogously. Furthermore, I moved the function definition to the beginning of the code. Because if your scrips crashed in the middle, the compiler has no chance to read the function definitions.
Please find the code in this file .
I hope this helps. Good luck!
Related
Function keeps repeating in Octave
My code is written in a file "plot.m". If I put the following code in "plot.m", when I call plot("20%"), the Octave GUI will keep opening a new window with a new figure indefinitely. function X = plot(folderName) X = 0; data = ([folderName, "\\summary.txt"]); NUM_SURVIVED = data(1); NUM_DATA = size(data)(1)-1; FINAL_WEALTH = data(2 : NUM_DATA); %plot FINAL_WEALTH figure; plot(1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2); xlabel('x'); ylabel('FINAL_WEALTH'); end However, if I put the following code in "plot.m" and run it, the program works as intended and will plot data from "summary.txt". data = ("20%\\summary.txt"); NUM_SURVIVED = data(1); NUM_DATA = size(data)(1)-1; FINAL_WEALTH = data(2 : NUM_DATA); %plot FINAL_WEALTH figure; plot(1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2); xlabel('x'); ylabel('FINAL_WEALTH'); Any idea what I am doing wrong in the first section of code? I would like to write it as a function so that I can call it multiple times for different folder names.
When you call plot from the function plot, you get endless recursion. Rename your function and its file.
Just adding to Michael's answer, if you really wanted to name your function as "plot" and override the built-in plot function, but still wanted to be able to call the built-in plot function inside it, this is actually possible to do by using the builtin function to call the built-in version of plot. Your code would then look like this: function X = plot (folderName) % same code as before figure; builtin ("plot", 1:numel(FINAL_WEALTH), FINAL_WEALTH, '-b', 'LineWidth', 2); xlabel ('x'); ylabel ('FINAL_WEALTH'); end Obviously, whether it's a good idea to overload such a core function in the first place is an entirely different discussion topic. (Hint: don't!)
Javascript / Googlescript using set.Formula with complex formulas
I have researching this but cannot find a suitable solution. The following formula works fine at the formula level when placed in a sheet cell. The issue is I want the formula to run at the script level. The options I am aware of include running a script to: (1) set.Formula('=complex formula') or (2) rewriting the entire formula as a script I am new to GAS, and have messed around with both methods. There seems to be a syntax error when using option (1), usually in the form of a missing ")" that I cannot debug. Employing option (2) is currently above my skill level. Any help on either option would be greatly appreciated. Here is the formula in question: =ARRAYFORMULA(QUERY({UI!A:G,YEAR(UI!A:A),MONTH(UI!A:A), TEXT(UI!A:A, "MMMM"), TEXT(UI!A:A, "MMM-YY"), REPLACE(UI!A:A,1,1000,"GRAND TOTAL")}, "SELECT * WHERE Col1 IS NOT NULL AND Col2 IS NOT NULL LABEL Col8 'Year',Col9 'MonthMO#',Col10 'MonthMO',Col11 'MonthMOYR',Col12 'GRAND TOTAL'"))
Answer Formulas doesn't run "at script level" so you will have to rewrite your formula as a Google Apps Script / JavaScript function. Escaping formula apostrophes in scripts In case that you want a script to add your complex formula to a cell bear in mind that writing complex formulas in one line makes harder to debug them. Try dividing your formula by functions and parameters and use a tab to align them. IMHO this prevents that the use of \ makes the script unreadable (Leaning toothpick syndrome). Below is a onEdit() function that inserts the complex formula in the question to the cell to the right of a cell where 'Yes' is wrote. Look to the use of \ to escape the apostrophes used in the second parameter of the query function (select statement). function onEdit() { var ss = SpreadsheetApp.getActive(); var rng = ss.getActiveRange(); var trg = rng.offset(0, 1); var formula = '=ARRAYFORMULA(' + 'QUERY({' + 'UI!A:G,YEAR(UI!A:A),MONTH(UI!A:A),' + 'TEXT(UI!A:A, "MMMM"), ' + 'TEXT(UI!A:A, "MMM-YY"), ' + 'REPLACE(UI!A:A,1,1000,"GRAND TOTAL")' + '},' + '"SELECT * WHERE Col1 IS NOT NULL AND Col2 IS NOT NULL LABEL Col8 \'Year\', ' + 'Col9 \'MonthMO#\', Col10 \'MonthMO\', Col11 \'MonthMOYR\', ' + 'Col12 \'GRAND TOTAL\'"' + ')' + ')'; if(rng.getValue() == 'Yes') trg.setFormula(formula); }
initialization of variable in pre in Modelica
I wrote the codes in Modelica as below: model TestIniitial extends Modelica.Icons.Example; parameter Integer nWri= 2; Real u[nWri](each start= 10, fixed=false); Real uPre[nWri]; parameter Real _uStart[nWri] = fill(10, nWri); parameter Modelica.SIunits.Time startTime = 0; parameter Modelica.SIunits.Time samplePeriod = 1; Boolean sampleTrigger "True, if sample time instant"; initial equation u[1] = 1; u[2] = 2; equation sampleTrigger = sample(startTime, samplePeriod); when sampleTrigger then for i in 1: nWri loop uPre[i] = pre(u[i]); end for; end when; for i in 1:nWri loop u[i] = (i+1)*time; end for; end TestIniitial; Basically I want to initialize the u before simulation. However, I got below complaints(the initialization of u is over-specified) from translation: The Modelica Language Specification 3.2.1 specifies that if a real variable, v, is appearing in an expression as pre(v), but not assigned by a when equation, then the equation v = pre(v) should be added to the initialization problem. For this problem the following equations were added: u[1] = pre(u[1]); u[2] = pre(u[2]); I can't understand the complaints since pre(v) was assigned in when equation already. What can I do if I want to initialize the u in above codes? Thanks.
Looking at this, my guess is that the error message is trying to provide you some diagnostics but it is incorrect about the source. I suspect (again, I do not know for sure) that it sees the fact that pre(u) appears in the model and that there is an initialization problem and assumes a specific issue. My guess is that the issue stems from the fact that you have fixed=true set on u. I see no reason to do that and my guess is that it will lead to too many constraints on the initialization problem as well. Get rid of the fixed=true and see what happens. Report back if that doesn't address the problem. Good luck.
Can LLDB data formatters call methods?
I'm debugging a Qt application using LLDB. At a breakpoint I can write (lldb) p myQString.toUtf8().data() and see the string contained within myQString, as data() returns char*. I would like to be able to write (lldb) p myQString and get the same output. This didn't work for me: (lldb) type summary add --summary-string "${var.toUtf8().data()}" QString Is it possible to write a simple formatter like this, or do I need to know the internals of QString and write a python script? Alternatively, is there another way I should be using LLDB to view QStrings this way?
The following does work. First, register your summary command: debugger.HandleCommand('type summary add -F set_sblldbbp.qstring_summary "QString"') Here is an implementation def make_string_from_pointer_with_offset(F,OFFS,L): strval = 'u"' try: data_array = F.GetPointeeData(0, L).uint16 for X in range(OFFS, L): V = data_array[X] if V == 0: break strval += unichr(V) except: pass strval = strval + '"' return strval.encode('utf-8') #qt5 def qstring_summary(value, unused): try: d = value.GetChildMemberWithName('d') #have to divide by 2 (size of unsigned short = 2) offset = d.GetChildMemberWithName('offset').GetValueAsUnsigned() / 2 size = get_max_size(value) return make_string_from_pointer_with_offset(d, offset, size) except: print '?????????????????????????' return value def get_max_size(value): _max_size_ = None try: debugger = value.GetTarget().GetDebugger() _max_size_ = int(lldb.SBDebugger.GetInternalVariableValue('target.max-string-summary-length', debugger.GetInstanceName()).GetStringAtIndex(0)) except: _max_size_ = 512 return _max_size_
It is expected that what you tried to do won't work. The summary strings feature does not allow calling expressions. Calling expressions in a debugger is always interesting, in a data formatter more so (if you're in an IDE - say Xcode - formatters run automatically). Every time you stop somewhere, even if you just stepped over one line, all these little expressions would all automatically run over and over again, at a large performance cost - and this is not even taking into account the fact that your data might be in a funny state already and running expressions has the potential to alter it even more, making your debugging sessions trickier than needed. If the above wall of text still hasn't discouraged you ( :-) ), you want to write a Python formatter, and use the SB API to run your expression. Your value is an SBValue object, which has access to an SBFrame and an SBTarget. The combination of these two allows you to run EvaluateExpression("blah") and get back another SBValue, probably a char* to which you can then ask GetSummary() to get your c-string back. If, on the other hand, you are now persuaded that running expressions in formatters is suboptimal, the good news is that QString most certainly has to store its data pointer somewhere.. if you find out where that is, you can just write a formatter as ${var.member1.member2.member3.theDataPointer} and obtain the same result!
this is my trial-and-error adaptation of a UTF16 string interpretation lldb script I found online (I apologise that I don't remember the source - and that I can't credit the author) Note that this is for Qt 4.3.2 and versions close to it - as the handling of the 'data' pointer has since changed between then and Qt 5.x def QString_SummaryProvider(valobj, internal_dict): data = valobj.GetChildMemberWithName('d')#.GetPointeeData() strSize = data.GetChildMemberWithName('size').GetValueAsUnsigned() newchar = -1 i = 0 s = u'"' while newchar != 0: # read next wchar character out of memory data_val = data.GetChildMemberWithName('data').GetPointeeData(i, 1) size = data_val.GetByteSize() e = lldb.SBError() if size == 1: newchar = data_val.GetUnsignedInt8(e, 0) # utf-8 elif size == 2: newchar = data_val.GetUnsignedInt16(e, 0) # utf-16 elif size == 4: newchar = data_val.GetUnsignedInt32(e, 0) # utf-32 else: s = s + '<unexpected char size - error parsing QString>' break if e.fail: s = s + '<parse error:' + e.why() + '>' break i = i + 1 if i > strSize: break # add the character to our string 's' # print "char2 = %s" % newchar if newchar != 0: s = s + unichr(newchar) s = s + u'"' return s.encode('utf-8')
Simplifying device creation in sip.conf
I often have to define many similar devices in sip.conf like this: [device](!) ; setting some parameters [device01](device) callerid=dev01 <01> [device02](device) callerid=dev02 <02> ; ... [deviceXX](device) callerid=devXX <XX> The question is perhaps I could avoid setting device-name specific parameters by using some variable like following? [device](!) callerid=dev${DEVICE_NAME:-2} <${DEVICE_NAME:-2}> ; setting some parameters [device01](device) [device02](device) ; ... [deviceXX](device) P.S. It would be perfect, if there was some device constructor, so I could reduce the script to following, but, I think, that is not possible in Asterisk. [device](!) callerid=dev${DEVICE_NAME:-2} <${DEVICE_NAME:-2}> ; setting some parameters ;[device${MAGIC_LOOP(1,XX,leading_zeroes)}](device)
I've had good results writing a small program that takes care of it. It checks for a line saying something like ------- Automatically generated ------- and whatever is after that line, it's going to be regenerated as soon as it detects that there are new values for it (it could be from a database or from a text file). Then, I run it with supervisor and it checks every XX seconds if there are changes. If there are changes, it issues a sip reload command after updating the sip.conf file I wrote it in python, but whatever language you feel comfortable with should work just fine. That's how I managed that and has been working fine so far (after a couple of months). I'd be extremely interested in learning about other approaches though. It's basically this (called from another script with supervisor): users = get_users_logic() #get the data that will me used on the sip.conf file data_to_be_hashed = reduce(lambda x, y: x + y, map(lambda x: x['username'] + x['password'] + x['company_prefix'], users)) m = hashlib.md5() m.update(str(data_to_be_hashed).encode("ascii")) new_md5 = m.hexdigest() last_md5 = None try: file = open(os.path.dirname(os.path.realpath(__file__)) + '/lastMd5.txt', 'r') last_md5 = file.read().rstrip() file.close() except: pass # if it changed... if new_md5 != last_md5: #needs update with open(settings['asterisk']['path_to_sip_conf'], 'r') as file: sip_content = file.read().rstrip() parts = sip_content.split(";-------------- BEYOND THIS POINT IT IS AUTO GENERATED --------------;") sip_content = parts[0].rstrip() sip_content += "\n\n;-------------- BEYOND THIS POINT IT IS AUTO GENERATED --------------;\n\n" for user in users: m = hashlib.md5() m.update(("%s:sip.ellauri.it:%s" % (user['username'], user['password'])).encode("ascii")) md5secret = m.hexdigest() sip_content += "[%s]\ntype = friend\ncontext = %sLocal\nmd5secret = %s\nhost = dynamic\n\n" % ( user['username'], user['company_prefix'], md5secret) #write the sip.conf file f = open(settings['asterisk']['path_to_sip_conf'], 'w') print(sip_content, file=f) f.close() subprocess.call('asterisk -x "sip reload"', shell=True) #write the new md5 f = open(os.path.dirname(os.path.realpath(__file__)) + '/lastMd5.txt', 'w') print(new_md5, file=f) f.close()