OCaml Format: how to indent the automatic line breaks - formatting

I'm trying to use OCaml's Format module to pretty print some structures. According to the tutorial, I just need to use boxes and specify break points where it is appropriate to have new lines. However, I'm unable to get the indentation right.
For example:
# open Format;;
# fprintf std_formatter "bar = foo(#[<hv 1>lkjlkjlkj: lkjlkjlkj,# lkjlkjlkjlj: lkjlkjlkjlkj,# lkjj: lkjlk#])";;
bar = foo(
lkjlkjlkj: lkjlkjlkj,
lkjlkjlkjlj: lkjlkjlkjlkj,
lkjj: lkjlk)
- : unit = ()
However, I'm expecting to get:
bar = foo(lkjlkjlkj: lkjlkjlkj,
lkjlkjlkjlj: lkjlkjlkjlkj,
lkjj: lkjlk)
How do I get it to indent the arguments correctly?

If I am not mistaken, the source of your problem is the maximum indentation limit; if your code begins with a Format.set_margin 20 then it has the side-effect of also setting the maximum indentation limit to 10.
This means that boxes which should have been opened with an indentation greater than 10 are pushed to a new line and are opened with an indentation of 0.
In other words,
Format.set_margin 20;;
Format.printf "bar = foo(#[<hv 1>lkjlkjlkj: lkjlkjlkj,# lkjlkjlkjlj: lkjlkjlkjlkj,# lkjj: lkjlk,# aze: azeioajze#])#.";;
yields:
bar = foo(
lkjlkjlkj: lkjlkjlkj,
lkjlkjlkjlj: lkjlkjlkjlkj,
lkjj: lkjlk)
Setting the maximum indentation limit to 11 after setting the margin partially fixes the issue:
Format.set_margin 20; Format.set_max_indent 11;
Format.printf "bar = foo(#[<hv 1>lkjlkjlkj: lkjlkjlkj,# lkjlkjlkjlj: lkjlkjlkjlkj,# lkjj: lkjlk,# aze: azeioajze#])#.";;
yields
bar = foo(lkjlkjlkj: lkjlkjlkj,
lkjlkjlkjlj: lkjlkjlkjlkj,
lkjj: lkjlk)
In other words, the hv box was opened without needing a line break; but the indentation was not increased.
Setting max_indent to a value between 12 and 18
Format.set_margin 20; Format.set_max_indent 12;
Format.printf "bar = foo(#[<hv 1>lkjlkjlkj: lkjlkjlkj,# lkjlkjlkjlj: lkjlkjlkjlkj,# lkjj: lkjlk,# aze: azeioajze#])#.";;
completely fixes this issue:
bar = foo(lkjlkjlkj: lkjlkjlkj,
lkjlkjlkjlj: lkjlkjlkjlkj,
lkjj: lkjlk)
The take-away message here is probably that you should alway set the margin and the maximum indentation limit at the same time (and in this order ).

I can't reproduce. I get this:
# Format.fprintf Format.std_formatter "bar = foo(#[<hv 1>lkjlkjlkj: lkjlkjlkj,# lkjlkjlkjlj: lkjlkjlkjlkj,# lkjj: lkjlk,# aze: azeioajze#])";;
bar = foo(lkjlkjlkj: lkjlkjlkj,
lkjlkjlkjlj: lkjlkjlkjlkj,
lkjj: lkjlk,
aze: azeioajze)- : unit = ()
Which is expected. Opening a box doesn't cause a cut, so if you want a newline after foo(, you should write #[<hv>#,.

Related

How do I delay the execution of a function within tkinter button command

I am trying to simulate a computer player "clicking" a button after a human user clicks a button In a grid of buttons. If I use the .after method the 'state' of the button change is delayed but it executes my check_state() method which doesn't detect the change. When I try time.sleep() method it prolongs the human click but still immediately invokes the 'auto' click regardless of where I put it in my code. I want a delay between the human click and 'auto' click.
I have tried widget.after(1000) which gives the desired delay of 'auto' click, but doesn't allow my the change to be seen by my check_state() function. I have tried time.sleep() which delays the execution of the human button click but the 'auto' click is still immediately invokes regardless of which order I place the sleep() function in relation to the call to auto_click(). I know there are better practices for this code implementation like using class based structure which I plan on using once my logic and functionality issues are resolved. My code is as follows:
import tkinter as tk
import random
def app():
def auto_click():
grid_state = get_grid_state()
possible_clicks = []
for i in range(0, len(grid_state)):
if grid_state[i] == " ":
possible_clicks.append(i)
#debug.config(text=possible_moves)
click = random.choice(possible_clicks)
buttons[click].after(1000, lambda: buttons[click].config(text = "auto", state=tk.DISABLED))
#time.sleep(1)
check_grid_state()
check_grid_full()
debug.config(text="test")
def onclick(*arg):
global is_full
buttons[arg[0]].config(text = "clicked", state=tk.DISABLED)
check_grid_state()
check_grid_full()
if not is_full:
auto_click()
def check_grid_full():
global is_full
result=[]
for i in range(len(buttons)):
result.append(buttons[i].cget('state'))
r = [*set(result)]
if r == ['disabled']:
is_full = True
grid_status.config(text=is_full)
else:
is_full = False
Retrieve the current state of the grid
def get_grid_state():
grid_state =[]
for i in range(len(buttons)):
grid_state.append(buttons[i].cget('text'))
return grid_state
Check grid state
def check_grid_state():
grid_states.config(text=get_grid_state())
Global Variables
is_full = False
buttons = []
c=0
Window
root = tk.Tk()
root.title("Title")
Heading
label = tk.Label(root, text="grid state", font = ("Ariel black",22, "bold"))
label.pack()
Grid Frame
frame = tk.Frame(root)
frame.pack()
for row in range(3):
for column in range(3):
buttons.append(tk.Button(frame, text=f" ", font=("arial", "22"), state=tk.ACTIVE, height=2, width=2, command=lambda c=c: onclick(c)))
buttons[c].grid(row=row, column=column)
c += 1
Status bar
grid_states = tk.Label(root, text=f"")
grid_states.pack()
grid_status = tk.Label(root, text=f"")
grid_status.pack()
#btn_is = tk.Label(root, text=f"")
#btn_is.pack()
Debugging output label
debug = tk.Label(root, text="debug")
debug.pack()
Event loop
root.mainloop()
if name == "main":
app()

Pine Script: " Can't call 'security' inside: 'if', 'for' "

because I cant find any way to test my Pine Script strategy on multiple symbols, I created a way to loop through my whole Script.
In This I made 10 variables for 10 different Symbols like this:
ersteTicker = "AAPL"
zweiteTicker = "MSFT"
dritterTicker = "..."
Than I loopedfrom 1 to 10 and made 10 If-querys, which give me in every loop the right symbol like this:
a = 1
for i = 0 to 10
if a == 1
tickerID = ersteTicker
if a == 2
tickerID = .....
Now I thougt everything should be all right, but now the console gives back an error message called:
line 75: Can't call 'security' inside: 'if', 'for'
Does anybody know how to bypass this problem??
best regards
Christian
P.S.: I already tested a small other script and in this script the console doesn't give me back this error message, even if I also made a for loop with a security function in it..
(looks like this)
//#version=3
strategy("Meine Strategie", overlay=true)
tickerID = "ADS"
vergleichstimeframe = "D"
TaesRSLPeriode = 200
a = 1
myEma() => ema(close, TaesRSLPeriode)
for i = 0 to 10
if ( a == 1)
Daily_ema = security(tickerID, vergleichstimeframe, myEma())
//plot(Daily_ema*TagesRSLGrenzwert)
longCondition = crossover(sma(close, 14), sma(close, 28))
if (longCondition)
strategy.entry("My Long Entry Id", strategy.long)
shortCondition = crossunder(sma(close, 14), sma(close, 28))
if (shortCondition)
strategy.entry("My Short Entry Id", strategy.short)
Here's an example of global security. The security must not be inside of neither for nor if statements. If you need more symbols - use more securities. But bear in mind, that you can't choose a symbol from a set of symbols and call security with that symbol (because it'll be mutable variable and you cannot use them with security):
//#version=3
strategy("Meine Strategie", overlay=true)
tickerID = "ADS"
vergleichstimeframe = "D"
TaesRSLPeriode = 200
a = 1
myEma() => ema(close, TaesRSLPeriode)
// this always must stay global
Daily_ema = security(tickerID, vergleichstimeframe, myEma())
// here you could put more secureties:
//Daily_ema1 = security(tickerID1, vergleichstimeframe, myEma())
//Daily_ema2 = security(tickerID2, vergleichstimeframe, myEma())
//Daily_ema3 = security(tickerID3, vergleichstimeframe, myEma())
// ...
for i = 0 to 10
if a == 1
if Daily_ema > Daily_ema[i] // actual using of the security's result
strategy.entry("My Long Entry Id", strategy.long)
In general and according to previous comments, the strategy tester isn’t accurate. Just view an indication for the operation. Maybe the only benefit of the testing strategy is to determine the value of (SL, TP). Meanwhile the strategy depends on trusted intermittent periods, you can increase the SL 10 to avoid the temporary reflections

Set width of toolbar button defined in cl_gui_toolbar

I've got a toolbar defined with class cl_gui_toolbar which is displayed in a container (which got created via class cl_gui_custom_container). I've added some buttons and button groups into it.
Now my user wants one of those button groups to be bigger, because the user might not recognize that the button is there. Is there any method to set the width of the button-group?
Here is my current code:
METHOD init_toolbar.
DATA: lt_buttons_data TYPE ttb_button,
ls_button_data TYPE LINE OF ttb_button.
go_toolbar_container = NEW cl_gui_custom_container( container_name = 'TOOLBAR_1000' ).
go_toolbar = NEW cl_gui_toolbar( parent = go_toolbar_container ).
" Some other buttons
" ...
" ...
CLEAR ls_button_data.
CLEAR lt_buttons_data.
ls_button_data-function = 'DBFILTER'.
ls_button_data-icon = '#EX#'.
ls_button_data-quickinfo = 'Quickinfo'.
ls_button_data-text = 'SmallText'.
ls_button_data-butn_type = cntb_btype_menu.
APPEND ls_button_data TO lt_buttons_data.
go_toolbar->add_button_group( data_table = lt_buttons_data ).
CLEAR ct_expand.
ct_expand = NEW cl_ctmenu( ).
ct_expand->add_function( fcode = '1' text = '1' checked = abap_false ).
ct_expand->add_function( fcode = '2' text = '2' checked = abap_false ).
ct_expand->add_function( fcode = '3' text = '3' checked = abap_false ).
CLEAR wa_ctxmenu.
wa_ctxmenu-function = 'DBFILTER'.
wa_ctxmenu-ctmenu = ct_expand.
APPEND wa_ctxmenu TO table_ctxmenu.
go_toolbar->assign_static_ctxmenu_table( table_ctxmenu = table_ctxmenu ).
ENDMETHOD.
Do you know a way how to set the width of this button-group?
PS: I just got the info, that the text of the button ( e. g. "smallText" ) can be replaced if a longer text, if there is no other way .
It's not possible to customize the width of a button in class CL_GUI_TOOLBAR as a number of pixels.
As a workaround:
Enter a longer text. Maybe enter "non-breaking spaces" at the end of your text. This is the Unicode character U+00A0 (CL_ABAP_CONV_IN_CE=>UCCP( '00A0' )).
Instead of CL_GUI_TOOLBAR, use the class CL_GUI_HTML_VIEWER to define the buttons with HTML code and CSS styles. But I doubt it's worth spending time for that.

How to read PHP output row by row and create HTML-links from each row

I'm having this PHP-script:
<?php
$old_path = getcwd();
chdir('/var/www/html/SEARCHTOOLS/');
$term1 = $_POST['query1'];
$term2 = $_POST['query2'];
$var = "{$term1} {$term2}";
$outcome = shell_exec("searcher $var");
chdir($old_path);
echo "<pre>$outcome</pre>";
?>
On a searchpage two searchwords are written and the searchbutton is pushed. The search result turns up as a webpage like this:
/var/www/html/SEARCHTOOLS/1974-1991.pdf:1
/var/www/html/SEARCHTOOLS/1974-1991.pdf:3
/var/www/html/SEARCHTOOLS/1974-1991.pdf:7
/var/www/html/SEARCHTOOLS/1974-1991.pdf:7
/var/www/html/SEARCHTOOLS/1974-1991.pdf:9
/var/www/html/SEARCHTOOLS/1974-1991.pdf:13
/var/www/html/SEARCHTOOLS/1974-1991.pdf:13
The result shows links to individual PDF-files and pagenumber in that file, but are not clickable.
Is there a way to make these links clickable so that it opens up for instance in Evince or Acrobat at the correct page number?
Many thanks in advance.
/Paul
I found a correct answer to my problem. It took some time, but here it is:
<?php
// Get current working directory and put it as variable
$old_path = getcwd();
// Change directory
chdir('/var/www/html/SEARCHTOOLS/');
// Create first variable as result of first searchword on searchpage
$term1 = $_POST['query1'];
// Create second variable as result of second searchword on searchpage
$term2 = $_POST['query2'];
// Create a variable combining first AND second variable
$var = "{$term1} {$term2}";
// Create a variable as the result of the executed search using command "sokare" and variable "$var"
$outcome = shell_exec("sokare $var");
// Return to starting directory
chdir($old_path);
// Split the varible "$outcome" per line representing every page in PDF-file where variable "$var" is found
foreach(preg_split("/((\r?\n)|(\r\n?))/", $outcome) as $line){
// Create a variable out of the given pagenumber in PDF-file
$end = substr($line, strpos($line, ":") + 1);
// Trim the line by removing leading directories from line
$line2 = str_replace('/var/www/html', '', $line);
// Change a string from lower to upper case
$line2 = str_replace('searchtools', 'SEARCHTOOLS', $line2);
// Remove the colon and anything behind it from line
$line2 = array_shift(explode(':', $line2));
// Add suffix to line to facilitate linking to pagenumber in PDF-file
$line3 = str_replace(" ", "_", $line2).'#page=';
// Add pagenumber from the variable "$end"
$line3 = str_replace(" ", "_", $line3).$end;
// Print each line as a correct URL-link
echo "<pre><a href=$line3>$line3</a></pre>";
}
?>
The search results will now turn up as (and are clickable):
/SEARCHTOOLS/1974-1991.pdf#page=1
/SEARCHTOOLS/1974-1991.pdf#page=3
/SEARCHTOOLS/1974-1991.pdf#page=7
Just a small edit. The line ....
// Add suffix to line to facilitate linking to pagenumber in PDF-file
$line3 = str_replace(" ", "_", $line2).'#page=';
...works better with:
// Add suffix to line to facilitate linking to pagenumber in PDF-file
if (substr($line2, -3) == 'pdf') {
$line3 = $line2.'#page=';
}

Photoshop Automation of alignment of text layer with image

I have never scripted in photoshop before, so I am wondering if this is possible. The following is currently done manually for over than 300 files. The next time round is for 600 files, therefore I am looking into automating it.
Steps:
Make Image Size to 54pixels Hight and 500px Width -- Found that this is doable.
Align Image Left.
Create a text layer and insert text -- Found that this is doable.
Align Text layer 1px to the right of the image.
Trim empty space.
Would appreciate any help and pointers. Thanks.
This script will get you started: Note that in your request you didn't mention what what the original image was going to be and shrinking it to 500 x 54 is going to stretch it one way or another. Step 2, Align the image left, was omitted as you didn't mention what you are aligning this image to. I suspect you are dealing with a large image and what to shrink it down (as long as it's not smaller than 500 x 54) and work from there. I've also omitted stage 4 as I've hard coded the position of the text to be 1 px from the right hand edge (and it vertically centered with Arial font size 18)
Anhyoo.. you should be able to alter the script to your needs.
// set the source document
srcDoc = app.activeDocument;
//set preference units
var originalRulerPref = app.preferences.rulerUnits;
var originalTypePref = app.preferences.typeUnits;
app.preferences.rulerUnits = Units.POINTS;
app.preferences.typeUnits = TypeUnits.POINTS;
// resize image (ignoring the original aspect ratio)
var w = 500;
var h = 54;
var resizeRes = 72;
var resizeMethod = ResampleMethod.BICUBIC;
srcDoc.resizeImage(w, h, resizeRes, resizeMethod)
//create the text
var textStr = "Some text";
createText("Arial-BoldMT", 18.0, 0,0,0, textStr, w-1, 34)
srcDoc.activeLayer.textItem.justification = Justification.RIGHT
//set preference units back to normal
app.preferences.rulerUnits = originalRulerPref;
app.preferences.typeUnits = originalTypePref;
//trim image to transparent width
app.activeDocument.trim(TrimType.TRANSPARENT, true, true, true, true);
// function CREATE TEXT(typeface, size, R, G, B, text content, text X pos, text Y pos)
// --------------------------------------------------------
function createText(fface, size, colR, colG, colB, content, tX, tY)
{
// Add a new layer in the new document
var artLayerRef = srcDoc.artLayers.add()
// Specify that the layer is a text layer
artLayerRef.kind = LayerKind.TEXT
//This section defines the color of the hello world text
textColor = new SolidColor();
textColor.rgb.red = colR;
textColor.rgb.green = colG;
textColor.rgb.blue = colB;
//Get a reference to the text item so that we can add the text and format it a bit
textItemRef = artLayerRef.textItem
textItemRef.font = fface;
textItemRef.contents = content;
textItemRef.color = textColor;
textItemRef.size = size
textItemRef.position = new Array(tX, tY) //pixels from the left, pixels from the top
}
Everything you listed is doable in a script. I suggest you start by reading 'Adobe Intro To Scripting' in your ExtendScript Toolkit program files directory (e.g. C:\Program Files (x86)\Adobe\Adobe Utilities - CS6\ExtendScript Toolkit CS6\SDK\English)