clog
clog copied to clipboard
Working time tracking tool using CLOG (programming noob)
Hej,
I recently wrote on reddit, asking for a way to find out the screen resolution.
Trying to give a bit more context, maybe it will be easier to understand what I am trying to achieve, as I still struggle to formulate in proper terms what I require for my program.
I am currently trying to design and program a user interface which gives users (my coworkers and me) the possibility to input working time data, especially regarding the spread of working time over two types of categories: (1) pedagogical work/preparation of that work/administration (2) a specification of what was chosen for (1). Using this, I want to gather data in order to pressure my superiors into either accepting that we have way more administrative chores then they see, or changing something about this problem. Because it is a problem when we are supposed to have 20% of our working time in administration and I find myself since more than one year having around 40%.
The user interface mainly revolves around two sections which could be dubbed "Input" and "Output".
Input
- In the Input section, the users are supposed to enter their data: date, working time span (e.g. 10-18:00), the place where you work (I work in two different places) and the distribution of working time ( (1) from above). This data is written to an array slot and stored locally.
- I want to offer two options for Input: one that is quick and requires said data for an entire day, and one which is exhaustive and requires the data for each time span within the working day (e.g. 10:00-11:00, pedagogical work, homework support). This is supposed to help with another administrative chore where we have to evaluate, at the end of the year, how we expended our working time.
- On the GUI side, I consider this a bit special: while the "quick" method requires only few text fields (they ideally should have labels above them), the "exhaustive" method should feature a "+" sign at the end of each new row to create a new row right below (I normally have something between 4 and 8 slots per day, but the users' mileage may vary).
Output
- In the Output section, I want to show the aggregated data to the user. The program reads the array and aggregates matching entries (I already wrote a working prototype, will probably have to adapt to gui). On the one hand, I want the show the user, for the current {month,quarter,year}, how much working time has been expended in which category. I'm not set on the details of this, as depending on whether the user customarily chooses "quick" or "exhaustive" Input, the Output could get very big and messy (I always use "exhaustive" and employ around 20 different specification categories).
- On the other hand, I want to allow for PDF export which can be much more verbose and show the distribution for each month or quarter, and for the entire year. As you might have guessed by now, I hope to use this as a tool to put pressure on my superiors to do something about the amount of administration that is part of my (and my colleagues') everyday life as pedagogical professionals. Because every minute that is spent on administration is a minute that cannot be expended working with children (our job), and currently it feels like it's pretty much the other way around.
So, I guess this should do as an explanation for a start. The code already present is public and can be found over at gitlab: https://gitlab.com/hapster/azvdoc . The repo is a bit messy because I am still learning how to use it and how to manage a repo. Most of the work happens in the files "construct-transform", "date", "day", "time" and "save-restore". I am also in the process of experimenting how to structure my program, since it is the first "real" program I write (excercise programs don't count in my opinion).
I hope I am not taking too much of your time with this issue where I'm basically asking for spoonfeeding and already want to thank you for the offer to discuss (here or over on reddit doesn't make a difference for me). Have a good day and thanks for your contribution to the community with clog, the resources you offer (tutorials etc) and your willingness to help people.
Have a good day :)
Look at https://github.com/rabbibotton/clos-contact Also see the tutorial https://www.reddit.com/r/lisp/comments/t61sib/clog_builder_tutorial_4_a_complete_database_app/ Even if you do not use the builder that should give you some ideas of how to work with clog-gui
Let me know how you are doing on that :)
Hej,
I have now arrived at tutorial 4 and can see why you suggested it ;-) Also, I believe it is a good idea that you don't immediately answer, for quite often I am able to find the problem by myself. The problem I posted yesterday was that the DB file couldn't be opened... turns out, I put the wrong path in there :exploding_head:
Yet, the old question remains, and I am confident that I found a typo in the tutorial:
Typo
In Step 7 of the CLOG Builder Tutorial 4, a database listbox is created. The related table name
is event_types
. However, insofar as event_types
relates to the tables created in the sqlite database, it has to be event_type
(not event_typeS).
Not a major error, but since I am a hardcore noob I trip over every banana lying on the ground and fall :sweat_smile:
Question In the beginning of the tutorial, everything happens in CLOG builder: new windows are created, properties are defined etc. Thus, whenever a change has happened in CLOG builder, I could save to a CLOG file and then render to a LISP file.
However, later on, this way of working changes: function definitions are input in emacs, in the same file that CLOG builder used to operate on (if I understand correctly).
After working on the LISP file manually, I cannot use the RENDER functionality in CLOG builder because this will overwrite the contents of the LISP file.
What is the correct way to work side-by-side in CLOG builder and emacs?
I am asking because for some time I had a DIV centering the elements (that's what I'd seen in an earlier tutorial, can't recall which one). Then, when I first ran into the error above, I decided to remove it (less deviation from the tutorials equals less sources of error, I thought). I did remove it in CLOG builder, but now I don't know how to make changes appear in the LISP file in emacs.
I mean there is a way to do that: copying the manually written functions, RENDER the CLOG file to a LISP file, paste the manually written functions. But this seems unintuitive, is there a better way to do this?
QUESTION 2 After some time reading and re-reading the tutorial (in particular, step 7), I've hit another road block. I was unable to have the list box table control ("Listbox table lookup" in the Builder's database category, no?) be pinned as was described in the tutorial (positioning absolute, top/bottom 45px, left/right 15px, height/width 0). Maybe I forgot a minor setting here or there?
The database connection stuff works, at least partly. I can enter and delete entries and changes are shown in the listbox. However, all new listbox entries are NIL - even though, as per sqlitebrowser, there are actual entries in the event_type
table. And I mean non-NIL entries reflecting what I had input originally.
I don't really know how to debug this one, because there is no error message in the REPL. The only indication I get when I hit RUN in CLOG Builder is a warning message.
EVAL RESULT (window name) WARNING: redefining CLOS-CONTACT::CREATE-CONFIG-EVENT-TYPES in DEFUN =>NIL
My *Messages*
buffer in emacs tells me that
[sly] Evaluation aborted on NIL
At first I thought this was due to me moving code in and out from the file as I SAVE/RNDR in CLOG, but from what I can gather that's not the problem. I mean if I had manually changed CREATE-CONFIG-EVENT-TYPES
, I could understand that problem, but AFAIK this function is literally written by CLOG itself.
QUESTION 3 Maybe it is time for another bit of context info and a related question. If I understand correctly, what you did for the tutorial you did in one sitting and incrementally, right? That's unfortunately not possible for me because on the one hand I am a noob and make a fair bit of mistakes, and on the other hand I have 45-60minutes per working day to work on this. This means that I have been working on tutorial 4 in like 5 different sessions by now (as you might guess, debugging and writing these questions is part of my "work time").
Thus, is it necessary to follow particular steps (I don't mean starting CLOG/TOOLS or CLOS-CONTACT) to ensure you are in "the same environment" as you used to be in the last time you worked on it? Because now for instance I wonder if the content of QUESTION 2 (a problem of having a function redefined) might be related to this problem or not.
Thanks, have a good time :)
<<Typo In Step 7 of the CLOG Builder Tutorial 4, a database listbox is created. The related table name is event_types. However, insofar as event_types relates to the tables created in the sqlite database, it has to be event_type (not event_typeS).>> Fixed- Thanks!!
<<However, later on, this way of working changes: function definitions are input in emacs, in the same file that CLOG builder used to operate on (if I understand correctly).
After working on the LISP file manually, I cannot use the RENDER functionality in CLOG builder because this will overwrite the contents of the LISP file.>>
You do modify files that were created with the Application Templates, but should never be directly editing any of the lisp files generated by the builder. So if you add an event for example you would not be adding that it the generated files but other files in your application.
So in the builder you are entering in the control events the names of functions from your code.
question 2 - if can send me a zip of your project and would help me understand the question better
question 3 - will help to see how you are going about things in code for me. So end me that zip and I'll see about some steps to make this easier. I really appreciate you taking the time to work thought the tutorials and try them and get stuck :( and write. It really helps me to make the whole process understandable and easier for all my goal. So we end up with a product that is super easy to create apps with.
BTW in case didn't know - the completed tutorial is also at - https://github.com/rabbibotton/clos-contact
Okay, first things first: thanks for the headsup regarding the completed clos-contact tutorial. It shows quite clearly the point you are making: no manual code in builder-created files. Unfortunately, it does not solve the problem underlying Question 2, which I had initially hoped.
I think it generally makes sense to put a kind of warning or reminder somewhere (e.g. on the github page itself, or the documentation of the builder, or as a footnote to tutorial 4 since I feel like it was not so much of an issue in earlier tutorials). If there is such a reminder and I have failed to notice it, please pardon my ignorance. If you haven't already, I believe the way you phrased it in your comment above pretty much nails it.
Either way, the tutorial seems a bit misleading in this regard. The first phrase of Step 8 seems to suggest that the new definitions for cet-on-new
etc. are to be put in the config-event-types.lisp
file.
NILs in config-event-types table
Checking out your code for clos-contact, I found the problem which caused NILs being added to my table. In CLOG builder, the Listbox table lookup
comes with pre-made values for the table row id name
and table columns
(both set to rowid). Since those two are not mentioned in the tutorial, I figured "Well, those should be fine I guess". However, in the project uploaded on git, the value for table columns
is "rowid description". I'm by now rather certain that this property relates to the columns of the sqlite database which should be displayed in the listbox.
If that's the case, I believe this information should be visible in the tutorial. I mean, again, this is something a seasoned programmer and/or sql data scientist might not struggle with, but I have gone to greats lengths to figure out the problem which now turns out to simply be an omission on one CLOG builder field on my part.
Since I can now continue following the tutorial, it is no more necessary for you to check my project (it features no code apart from the tutorial code). Thanks for offering it, though :-)
Pinning the listbox table lookup
(builder tutorial 4, step 7/8)
The tutorial seems to suggest that removing the height and width of the listbox table lookup
will result in pinning the window according to the size of the window itself - alas, it will be bigger if the window is enlarged. The screenshots in step 7 and 8 both support this.
However, I have found this not to be the case, neither in my current tutorial "run" nor in the one before, nor in code provided for the tutorial in github. Instead, when the height and width is removed, a standard value (168 or 169) is input for the height. Afterwards, height and width seem to dependent upon the size of the content. That is, when I have a short string like "falcon" the width will be small, and with a long string like "I would like to have a good idea for a long string but I don't", the width will be bigger.
Maybe I overlooked a setting that you made. I'd love to know how "pinning" works properly because it seems like such a useful technique for gui programming because you don't have to bother with particular heights or widths.
The description of how to use Find
It took me quite some time to figure out that the tutorial is quite literal giving its example for how to use find. I tried many combinations BEFORE I just "copy pasted" what you put into parentheses: name like 'david%'
. I mean, maybe this is, again, a problem of me being new to programming and/or sql, but I believe it makes sense to try to make the search parameters more transparent or clear. For me personally, a bash-style description or some more examples would have helped tremendously: COLUMNNAME like 'SEARCH%'
, or name like 'david%'
/ phone like 555
(with some kind of highlighting).
Thank you so much, all of this gives me many perspectives in how to improve everything for those approaching it the first time. My ultimate goal is to make everything stupid simple so a pointy hared boss man could even do much of the programming work.
Providing "style guideline" in tutorial In Tutorial 1 you mentioned that using a "div" to align several elements - div in "relative" positioning, the (text) elements either "static" or "absolute" - is often times what you want. I am trying to adopt this habit because I find it a nightmare to manually adjust the elements and still look "right". Wouldn't it make sense to suggest this use further along in the other tutorials or to show that you are using this in later tutorials? Because it seemed kinda off to me that while your GUI windows always look kinda lit, you never apply the suggestion you made yourself.
Saving CLOG Builder layouts The more I work with CLOG the more I wish there would be a way to memorize the way I arrange the windows I work with. I am so used to it from working with music programs where you can store layout presets that you can make the default and load etc.
Is there a way this is coming to CLOG Builder eventually?
I would recommed that you consider the tutorials as version 1 and that additional revisions might be appropriate to improve them. Having read all of the written tutorials my self, they also skip a bunch of information and assume you have learned from previous tutorials to just get the project done.
What this means is that, in my reading, we would benefit by NOT changing the existing tutorials much at all, only fixing grammar, spelling and maybe a bit wording here or there. The reason for that recommendation is that all tutorials have a target audience, no tutorial can ever satisfy all audiences because everyone is at a different part of the learning curve and therefore the tutorials are perfect for their intended audience: slightly more than basic to kind of intermediate audience that is enthusiastic and is willing to look things up.
I would also, therefore, suggest that we put together a set of guides and best practices. For example, the one that I wanted to write was the one that deals with the use of a main relative dive and the child divs as static or absolute as necessary. I am testing out creating of templates that look modern right now in order to figure out how to write this tutorial in a way that is somewhat based on trying to make real things.
The other tutorial that needs writing is how to read the documentation and translate that into code. I am starting to get it but as I am not a full time Lisp programmer I am still guessing. This should be straight forward in terms of explanation the bulk of the work being done to provide examples for each item in the documentation.
Then, I would like to build some template libraries and so forth so that people can take a look and see how they are built and improve them.
Your suggestion is fine but there are better ways to accomplish what you are suggesting other than changing the main tutorials. I thank my lucky stars we have all of this documentation, tutorials and so forth.
How you doing :) Making progress? any issues?
Hej david, thanks for keeping in touch!
The last two weeks I was busy with other stuff and it is only now that I get back at it (finally!).
I am approaching the end of the tutorial, which means that I will soon bombard you with questions because I am starting to ACTUALLY get into programming the GUI for my program ;-)
Step 13/14: Problem with create-contact-report, report-contacts undefined PLACEHOLDER, WILL COME BACK TOMORROW!
Question: How are values typed in form elements passed to "local" functions? So in the contact manager tutorial, you are working with a database. Even though I see the merits of this approach, I have decided against rewriting my program from the ground up, also because I am afraid the database might add complexity which leads to more errors down the line (might consider using sql for a second project I got in mind though ;-)).
Thus, I wonder how values are passed from the GUI to the functions I wrote in advance. I will have two different GUI windows which serve the same purpose but with different levels of detail. The purpose is to specify how much working time has been expended in which of these three areas of work: (1) pedagogic work, (2) the preparation of pedagogic work, (3) administration.
In the simpler case, this will boil down to around 4 form input
elements: (1) date (2-4) working time for the three areas of work. To those corresponds a function that creates a plist
. The function and the resulting plist
look like this (PK, OV2 and OV1 are the names for the work areas):
(defun construct-timespan (&optional start end pause place pk ov2 ov1)
"Constructs an arbitrary timespan with the given parameters.
Applicable for TIMESPAN, DAY, MONTH, QUARTER, YEAR."
(list :start start
:end end
:pause pause
:place place
:pk pk
:ov2 ov2
:ov1 ov1))
(:START 162 :END nil :PAUSE nil :PLACE nil :PK 2 :OV2 2 :OV1 1)
Now, I'd love to understand how the information input into the form inputs
is transferred to the function. I have a vague idea and will start experimenting with it (maybe it's obvious), but this was the first conundrum I hit when approaching my GUI in thought.
You set-on-click for a button that says ready to get the form contents, you then just access the form contents directly (text-value some-control) there are more ways but that is a good starting place.
https://github.com/rabbibotton/clog/blob/main/tutorial/17-tutorial.lisp
I started to design my GUI and ran into problems not related to my earlier question. Thanks a bunch for the link!
EDIT: For clarity, I move "done" or "solved" issues in the first post, and current ones in a second one. I hope this makes it easier to see where problems arise and not get confused by stuff already past.
SOLVED: How to set $ELEMENT (table) borders in Builder
If I understand correctly, it is possible to set both borders and outlines for clog elements via an elements' builder settings. The settings for both outline and borders consists of three elements: size, type and color.
Now, I've tried to change those settings to something like (for border): 5px medium rgb(0, 0, 0
. So far, with Builder, the values would change as soon as I leave the value cell of said element. However, for border and outline, nothing happens.
Changing the element focus to another element and back to the element with border, I realised that somehow Builder didn't take the values but has reverted to the default values.
EDIT: Found solution in w3-bordered
KINDA SOLVED: How to align GUI elements in Builder?
Essentially I am wondering how I can manage to have the elements in Builder aligned (as if they were in a table). I might be OCD'ish about this, but I cant deal with manually setting GUI elements with absolute
positioning. And it seems like static
positioning seems to produce problems of its own: while margins
and padding
slots work when it comes to working with labels
, they don't work as I'd expect them to when using the date-picker
. For instance, padding
makes the date-picker
element expand in either the horizontal or the vertical direction, while the margin
setting makes it expand in all four cardinal directions.
I'd love to be able to insert a specified "space" between elements, or to have them stick to grids (like in a table) - or be able to have a margin in but one direction. Currently, my approach to the GUI shebang is that each portion of the GUI has a div
. For instance, when I have a "date picker" label
and date-picker
, they will be in a "date picker"-div
. I feel like I am committing a grave sin by manually "spacing" the elements out with a text label which consists of a bunch of spaces (those which divide the words).
EDIT: I just found a working-ish solution with "my" method. I'm still not 100% satisfied, but using relative
instead of static
works fine after some experimentation. What tripped me up at first is that it is seemingly necessary to manually reset the values for top
, left
, bottom
, right
to 0px and start from there.
Praise
Also, I finally managed to get to the newest version of CLOG (Builder) using UltraLisp (had been waiting on QuickLisp for like 2 months, lol). You're doing a great job, I'm kinda stoked by the pace of development!
SOLVED: How to access form contents via (text-value some-control)
pt2
I finally got busy with fetching GUI input. Progress being made, yay!
So I though to myself: before I try the "heavyweight" stuff (interacting with files on the system, the programs array, ...), I might use a (confirm-dialog ...)
to make sure that values are read and parsed properly. It turns out that I am using (text-value some-control)
wrong, since whenever I try to preview the input, I receive this error
There is no applicable method for the generic function #<STANDARD-GENERIC-FUNCTION CLOG:TEXT-VALUE (4)> when called with arguments (AZVDOC::PK).
This is my code for the function that is in the on-click
slot of a button in Builder.
(defun input-simple-preview (panel)
(confirm-dialog panel
(format nil "Correct? ~A" (text-value (pk-input panel)))
(lambda (answer)
(if answer 'yes 'no))))
Some explanations: in builder, there is an input form called pk-input
. The name on form
slot is set to "pk". I've tried to invoke (text-value ...)
with "pk-input" as well as "pk", as a symbol, a string and without anything (text-value pk-input)
.
At first, I thought the problem is that I have not input anything in the pk-input
form, but it turned out this is not the issue.
EDIT: It took me a while, but the CLOG builder tutorial 4 showed me the way: (text-value (clog-object panel))
. In my case, it was (text-value (pk-input panel))
. Not that it matters, but I updated the code above to reflect that. I would love to learn more about the "logic" behind CLOG. I am slowly understanding that somehow I have to not refer to a clog-element such as pk-input
on its own, but in a separate form, (pk-input panel)
. While having understood that, I have no idea why that is the case, which severely limits my capacity to generalise - essentially, I have to re-acquaint myself with similar problems every time because I don't know if I can transfer my current knowledge.
Why does table column alignment stop working as soon as I start using form inputs?
I am starting to experiment with the table elements to which IIUC corresponds HTMLs variants. Thus, a table consists of those elements:
- table
- table head/table body
- table row for each row in head/body
- table heading for each desired column in head row
- table column for each desired column in body row
So far, when I worked with only headings and columns, everything went fine. The column dividers (how to make them visible!?) would adjust to the size of the inserted element so that the overall formatting does not get screwed.
When I added a first form input, this still worked, the column size was adjusted accordingly. However, as soon as I added a second form input in one row, this mechanism stopped working. Also, it seemed like with the second form input added, the correspondence ONE ELEMENT-ONE COLUMN has been broken, because both form inputs appeared in the first column.
Why is this, and is there a possibility to change that?
How to make font bold in Builder?
I am trying to make the text of a label bold. How do I do that? I have seen the font properties slot and experimented with it but have been unable to get what I wanted.
How to insert a linebreak in a tooltip?
I discovered that it is possible to use placeholder text and tooltips to supply more information in one window and I gotta say I love it.
So I started creating tooltips in places where I deem it important. However, I don't see the possibility to insert linebreaks. Guessing I might have to input a HTML command (because many things in CLOG are) I tried <br>
in the tooltip value area but without success.
Is this possible, and if so, how?
How to change the date format settings?
I am still experimenting with a function that shows the data input before submitting it. Currently, when picking a date in the Date Picker
, it represents the date (probably according to my locale settings for Germany) in the DD.MM.YYYY format (which is the norm). However, when I get the Date Picker
value with (value (date-picker panel))
, it is represented in another format, YYYY-MM-DD.
Since the program targets a german-speaking audience, I would like the date to be represented in a familiar fashion - some of my colleagues are oldies and I want to lower barriers of entry as much as possible. Thus, I need a way to change date format settings.
I have not found a variable or function for CLOG that does this, and the only variable which seemed close enough was trivial-backtrace:*date-time-format*
. However, changing this variable didn't yield the desired results: I've (setf trivial-backtrace:*date-time-format* "%d.%m.%Y %H:%M")
in the repl, refreshed the window holding the CLOG Builder test window and tried again. Nothing happened.
Would it make a difference if I set this variable somewhere in my package's code? Do I need another value-fetching function?
Is it possible to generate CLOG elements "on the spot" using a button?
My program features two ways of representing working time. A very quick one, which has only four elements per day: (1) date, (2)-(4): working time in hours for different categories. I already have a corresponding GUI window done, more or less.
However, the second way is A LOT more verbose. Essentially, it breaks down one working day into several time spans. Each time span in one day (e.g. 10:00h -- 11:00h) will feature, apart the time span start (1) and end (2), the three categories (3)-(5) and a specifying sub-category (6). When I am using this method on paper (which I do since about 2 years now), the number of time span entries I use ranges somewhere between four and ten for one working day.
Now, I can think of two different approaches: the first would be to supply a specified amount of available time span entries (say, 15), and to ignore those entries which do not contain any data when "transferring" the form input data to my program's calculating functions.
The second approach, which I deem more elegant, would have just one time span present, and something like a "+" sign button at the end of the row. When pressed, this button "produces" a new time span row, and, if necessary, the gui window grows accordingly. Then, there could be another "-" sign button which allows one to delete one row if necessary. The capacity to ignore empty entries should be possible here as well.
<<Why does table column alignment stop working as soon as I start using form inputs?>> I speak code better :)
<<How to make font bold in Builder?>>
- (best way) Add the word bold to start of the font property "bold 15px / 22.5px Verdana, sans-serif"
- Scroll down to the last property say in a label and you can add .. around your label's text. (when you save the clog file and reload it you will see the bold tags are added as controls)
<<How to change the date format settings?>> The format you get/set is always yyyy-mm-dd but the format the the user sees is always based on his local set on the machine or in the browser. There are ways to override "local"s but not a good idea and not sure if privacy will allow anymore.
<<Is it possible to generate CLOG elements "on the spot" using a button?>> The beauty of CLOG is you can always do anything. Just create an on-click handler and use create-* to create what you want.
I don't really understand the rest, perhaps a code sample.
making progress?
Table-stuff
I don't know how static
and relative
positioning differ from one another programmatically, but using relative
for the table allowed me to build the kind of GUI window I wanted.
Linebreak in tooltip
So when I make a label, it has a tooltip
slot. When I insert a linebreak in this tooltip, the two lines separated by line-break are collated to one another.
However, I'd love to have a hover-over label that HAS line-breaks. I guess I will then have to use control-events, right?
Relative means to treat the item as static - but let you position it as absolute. It is key to allowing a control to be used in flex-box and other layouts. Usually I recommend when making controls to use relative as the layout of an outer div around the control. https://www.reddit.com/r/Common_Lisp/comments/w4zwm3/common_lisp_repl_style_dev_visually_with_clog/
You are probably best off making a div as your tool tip and showing it on hover and hiding out when going out of control, that give you real control over the tool tip.
making progress?
hej,
again, I much appreciate that you don't just forget about this project, even after these many months.
I currently don't work on the project since it is tied to work and after an accident-induced wrist injury that will take a good few months to heal I don't work. Also because of the wrist injury I can't type nor program properly (one-handed).
If you would like to close the issue, that's completely fine by me. I can also close it.
However, if you don't mind too much, I'll open a new issue as soon as I get back to work and stumble across a problem I deem related to clog.
In the meantime, I will read Practical Common Lisp, I hope that afterwards my journey becomes a bit easier.
Have a good time, good fellow :)
Hope you are doing well! I am going to close the issue but feel free to open another or still ask here.