I am trying to make a GUI application in common lisp with ltk, and there is one thing I just cannot figure out. I know I can set options of ltk widgets with configure, but I cannot figure out a way to read the values.
For example, I create an instance of a canvas with
(make-instance 'canvas :width 400 :height 400)
Then I want to write a method that will use the width and height in some calculations. How do I access these?
I've asked this same question in the ltk user list and got an answer.
In short, the cget function is the counterpart of configure
So, to set the canvas width you do (configure canvas :witdh value) and to retrieve it you do (cget canvas :width).
Regards,
André
(require :ltk)
(in-package :ltk-user)
(defparameter *can*
(make-instance 'canvas :width 400 :height 400))
Indeed the width and height are stored in the string.
I don't know if your can adjust this afterwards. Maybe ask on the ltk mailing list.
#<CANVAS {1005A00C21}>
--------------------
Class: #<STANDARD-CLASS CANVAS>
--------------------
Group slots by inheritance [ ]
Sort slots alphabetically [X]
All Slots:
[ ] INIT-COMMAND = "canvas ~A -height 400 -width 400"
[ ] MASTER = NIL
[ ] NAME = "wc"
[ ] SCROLLREGION-X0 = NIL
[ ] SCROLLREGION-X1 = NIL
[ ] SCROLLREGION-Y0 = NIL
[ ] SCROLLREGION-Y1 = NIL
[ ] WIDGET-CLASS-NAME = "canvas"
[ ] WIDGET-PATH = NIL
[ ] XSCROLL = NIL
[ ] YSCROLL = NIL
[set value] [make unbound]
Related
I want to delete a collection in smalltalk so when the user selects the option again it is newly created.
This is my code:
"opcion 7"
/opc = 7) ifTrue: [
masDeUno:= OrderedCollection new.
cant:= b1 tam.
1 to: cant do: [:cta |
comp := cta verNumero.
i:= 1.
(i+1) to: cant do: [:cta |
(comp = cta verApellido) ifTrue: [
masDeUno add: comp.
break.
] "fin condicion"
] "fin todo interno"
]. "fin todo"
Transcript show: (masDeUno)printString .
"eliminar la coleccion para la proxima vez"
]. "fin op7"
With automatic garbage collection any unreferenced object will be automatically deleted if there are no references to the object. In your code the variable masDeUno is not referenced after the ifTrue: block finishes so you don't need to "delete" it (in fact, there is no way to explicitly delete Smalltalk objects).
I have a map object I need to check if it contain a given key. I tried like below but it always return false. Also how to pull value on inside map replyMessage,
map=%{
Envelope: %{
Body: %{
replyMessage: %{
cc: %{
"amount" => "100.00",
"reasonCode" => "100",
},
decision: "ACCEPT",
invalidField: nil,
purchaseTotals: %{"currency" => "CAD"},
reasonCode: "100",
}
}
}
}
Map.has_key?(map, %{Envelope: %{Body: %{replyMessage: replyMessage}}})= false
You have two possibilities: Kernel.match?/2 to check whether the key exists and/or Kernel.get_in/2 to deeply retrieve the value.
iex|1 ▶ match?(%{Envelope: %{Body: %{replyMessage: _}}}, map)
#⇒ true
iex|2 ▶ get_in(map, [:Envelope, :Body, :replyMessage])
#⇒ %{
# cc: %{"amount" => "100.00", "reasonCode" => "100"},
# decision: "ACCEPT",
# invalidField: nil,
# purchaseTotals: %{"currency" => "CAD"},
# reasonCode: "100"
# }
Beware of Kernel.get_in/2 would return nil if the key exists, but has nil value, as well as if the key does not exist.
Map.has_key?/2 is not recursive by any mean, it works with the keys of the map, passed as an argument; that said, the first level only.
Sidenote: one might easily build a recursive solution themselves, based on Map.has_key/2
defmodule Deep do
#spec has_key?(map :: map(), keys :: [atom()]) :: boolean()
def has_key?(map, _) when not is_map(map), do: false
def has_key?(map, [key]), do: Map.has_key?(map, key)
def has_key?(map, [key|tail]),
do: Map.has_key?(map, key) and has_key?(map[key], tail)
end
Deep.has_key?(map, [:Envelope, :Body, :replyMessage])
#⇒ true
I am trying to save data into a collection of some sort, but the program that I have is saving everything into a separate map. I want to make it one map.
(defn readFile []
(map (fn [line] (clojure.string/split line #";"))
(with-open [rdr (reader "C:/Users/Rohil/Desktop/textfile.txt")]
(doseq [[idx line] (map-indexed vector(line-seq rdr))]
(if(.contains line "201609")
(if(not(.contains line "TBA"))
(println(assoc table :code(nth(clojure.string/split line #";")3) :instructor(nth(clojure.string/split line #";")19)))
)
)
)
)
)
)
)
Any help will be appreciated.
Looks like you are adapting to clojure :-) I went to the same process. Hang on, it will be worth it!
First: it is important to realize that map will save the result of the function into a new collection. Like cfrick mentions, println returns nil and assoc does not change a map.
I'm guessing a bit here what you are trying to do: You want to have a collection of dicts, where every dict has two keys, like so:
[
{ :code 1 :instructor "blah"}
{ :code 2 :instructor "boo" }
]
You need these values to come from a file, but you only want to save the lines where the line contains "201609" but not "TBA"
First some general remarks:
You probably want to split this function into smaller parts. One could be the check for lines (contains 201609 but not tba ), another could read the file...
I know it is the title of your question, but most likely there is a better way than to change a global variable. Maybe you could make the function readFile return the table?
try if you can pass in arguments to your function.
I'm not sure what you are trying to do with the line (doseq [[... Please give us more context there. I will ignore it
Here is a possible solution:
(ns test
(:require [clojure.string :as s]
[clojure.java.io :as io]))
(defn line-filter [include exclude line]
(and (not (s/includes? line exclude))
(s/includes? line include)))
(defn process-line [line]
(let [line-parts (s/split line #";")
code (nth line-parts 3)
instructor (nth line-parts 19)]
{:code code :instructor instructor}))
(defn read-file [file-name]
(s/split (slurp (io/resource file-name)) #"\n"))
(defn parse-lines [lines]
(map process-line lines))
(defn read-file-and-parse
"This function will read a file, process the lines, and output a collection of maps"
[filename search-for exclude]
(parse-lines
(filter #(line-filter search-for exclude %)
(read-file filename))))
you could now call this function like this: (read-file-and-parse "test.txt" "201609" "TBA")
If you want to add the result of this function into your table, you can use concat. But again, this will return a new version of your list (with new entries added) and not change the one you defined earlier.
Welcome to functional programming :-)))
USING: accessors html.parser.analyzer io kernel math namespaces
present regexp sequences ;
IN: all-roads-to-wiki
SYMBOL: G
: match-good-pages ( a -- ?/f )
R/ \/wiki\/[^:]*$/ first-match ;
: filter-urls ( tags -- urls )
find-hrefs [ present ] map
[ match-good-pages ] filter
[ match-good-pages seq>> ] map ;
: findpath ( url -- url )
G get =
[
! false
]
[ scrape-html nip
[
dup "title" find-by-name drop 1 + swap nth
text>> R/ - Wikipedia,/ re-split first print
]
[
"bodyContent" find-by-id-between filter-urls [ findpath ] map
] bi
] if ; inline recursive
: allroads-entry ( -- a )
readln "http://en.wikipedia.org/wiki/" prepend G set-global
"enwp.org/Special:Random" findpath ; inline
The above code will recurse over every link on Wikipedia until it finds the one it's looking for.
That's okay, because (hopefully) findpath will eventually "return" (i.e. not call itself again) and leave a huge nested data structure on the stack. But when I try to compile this, I get an unbalanced-recursion error:
The recursive word “findpath” leaves with the stack having the wrong height
unbalanced-recursion: Thrown when stack effect inference determines that an inline recursive word has an incorrect stack effect declaration.
No matter what I do, Factor (understandably) complains about the stack effect not matching up. What do I have to do to get this to recurse properly?
Look closely at the find-path word. I'll add comments so that you can see what is on the stack:
: findpath ( url -- url )
! 1 item: { url }
G
! 2 items: { url G }
get
! 2 items: { url value-of-G }
=
! 1: item { t/f }
[
! 0 items!!!!
! false
]
[ scrape-html nip
[
dup "title" find-by-name drop 1 + swap nth
text>> R/ - Wikipedia,/ re-split first print
]
[
"bodyContent" find-by-id-between filter-urls
[ findpath ] map
] bi
] if ; inline recursive
The if combinator consumes the last item on the stack so this code can't possibly work. Here is working code for the findpath word:
: page-title ( seq -- title )
dup "title" find-by-name drop 1 + swap nth
text>> R/ - Wikipedia,/ re-split first ;
: page-links ( seq -- links )
"bodyContent" find-by-id-between filter-urls ;
: scrape-en-wiki-url ( wiki-url -- seq )
"https://en.wikipedia.org" prepend
dup print flush scrape-html nip ;
: found-url? ( wiki-url -- ? )
G get [ = ] [ drop t ] if* ;
: findpath ( wiki-url -- seq/f )
dup found-url?
[ drop f G set f ] [
scrape-en-wiki-url
[ page-title print flush ] [
page-links [ findpath ] map
] bi
] if ; inline recursive
Also take a look at the Wikipedia vocab which is meant for tasks like these.
I want to be able to handle a form which uses a dynamic amount of form fields
e.g.
(form :action "/theaction"
:method "post"
(input :type "text" :name "firstinput") (:br)
(dotimes (i n)
(:input :type "text" :name (FORMAT nil "INPUT~a" i)))
(:input :type "submit" :value "submit" :name "submit"))
how can I define the handler as the &rest is not accepted and would not allow me to access the variable names which I obviously need for further processing.
(define-easy-handler (theaction :uri "/theaction") (&special-rest all-params)
(log-message* :INFO "~a" all-params))
-> "(("firstinput" . "value") ("INPUT0" . "value") ("INPUT1" . "value") ...)"
A possibility would be to pre-define all variables up to e.g. 100, but this would seem rather cumbersome and unintuitive.
The lambda-list of define-easy-handler is just a shortcut for using lower-level calls. You can get more extensive access to parameters by using functions like like GET-PARAMETER and POST-PARAMETER. You can get an alist of all parameters by using get-parameters* (or post-parameters*) in the body of the handler.