<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1309019001069154774</id><updated>2011-10-14T17:04:22.014-07:00</updated><category term='budowanie zbiorcze'/><category term='testowanie'/><category term='strona www'/><category term='ja'/><category term='odbicie'/><category term='PKgui'/><category term='sieci neuronowe'/><category term='programowanie'/><category term='InVectorGadget'/><category term='Swing'/><category term='C++'/><category term='dag'/><category term='PDP'/><category term='Learning Journal'/><category term='CDT'/><category term='gra wielooobowa'/><category term='set'/><category term='warstwy'/><category term='SDL'/><category term='TD'/><category term='SAH'/><category term='GIMP'/><category term='algorytm'/><category term='egzamin'/><category term='eclipse'/><category term='ewolucja'/><category term='kontener'/><category term='projektowanie'/><category term='JoeMonster'/><category term='mózg'/><category term='ASD'/><category term='humor'/><category term='dziedziczenie'/><category term='muzyka'/><category term='cartoon'/><category term='Nine inch nails'/><category term='Loki'/><category term='wskaźniki'/><category term='bookmarks'/><category term='Java'/><category term='uczelnia'/><category term='gry'/><category term='CMS'/><category term='językoprotokół'/><category term='selection'/><category term='rozrywka'/><category term='nin'/><category term='cartoonization'/><category term='język angielski'/><category term='eigenfaces'/><category term='google'/><title type='text'>paklosblog</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>33</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1986604178358984731</id><published>2011-07-16T06:14:00.000-07:00</published><updated>2011-07-16T06:42:25.704-07:00</updated><title type='text'>Congregation gown</title><content type='html'>What is the congregation gown most useful for?&lt;br /&gt;a) As a cover for a bike-based lawn mower.&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/-uA4t7yBqZ48/TiGPDplhJLI/AAAAAAAAAK8/2c_iSNQNenc/s1600/bike-mower-6_mod.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 200px; height: 148px;" src="http://3.bp.blogspot.com/-uA4t7yBqZ48/TiGPDplhJLI/AAAAAAAAAK8/2c_iSNQNenc/s200/bike-mower-6_mod.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5629938302055425202" /&gt;&lt;/a&gt;&lt;br /&gt;b) As a cover for the remains of the Polish presidential plane, crashed near Smolensk in April 2010. &lt;br /&gt;&lt;a href="http://smolensk-2010.pl/wp-content/uploads/2010/10/wrak-tupolewa-pod-brezentem-1.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 625px; height: 468px;" src="http://smolensk-2010.pl/wp-content/uploads/2010/10/wrak-tupolewa-pod-brezentem-1.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;br /&gt;c) As an outfit for a weird, vintage, freemason-looking ceremony at the University of Bristol.&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/-1HhrE1JPvGQ/TiGVFX6z3cI/AAAAAAAAALE/g_FeOVEdVO0/s1600/IMG_7264.jpg"&gt;&lt;img style="float:right; margin:0 0 10px 10px;cursor:pointer; cursor:hand;width: 150px; height: 200px;" src="http://4.bp.blogspot.com/-1HhrE1JPvGQ/TiGVFX6z3cI/AAAAAAAAALE/g_FeOVEdVO0/s200/IMG_7264.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5629944928742399426" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Yeah, you guessed well.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1986604178358984731?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1986604178358984731/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2011/07/congregation-gown.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1986604178358984731'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1986604178358984731'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2011/07/congregation-gown.html' title='Congregation gown'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/-uA4t7yBqZ48/TiGPDplhJLI/AAAAAAAAAK8/2c_iSNQNenc/s72-c/bike-mower-6_mod.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-3760144560709653516</id><published>2011-01-16T12:48:00.000-08:00</published><updated>2011-01-16T14:44:43.188-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='GIMP'/><category scheme='http://www.blogger.com/atom/ns#' term='cartoon'/><category scheme='http://www.blogger.com/atom/ns#' term='selection'/><category scheme='http://www.blogger.com/atom/ns#' term='cartoonization'/><title type='text'>Cartoonization in GIMP</title><content type='html'>Hi, I'm pasting a few pictures I cartoonized in GIMP from my own photos.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://4.bp.blogspot.com/_MjVCmxw3xsg/TTNburb4t2I/AAAAAAAAAKc/o5CyOaLzPic/s1600/tn_IMG_0620_2_poor.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 240px; height: 320px;" src="http://4.bp.blogspot.com/_MjVCmxw3xsg/TTNburb4t2I/AAAAAAAAAKc/o5CyOaLzPic/s320/tn_IMG_0620_2_poor.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5562890822224492386" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://3.bp.blogspot.com/_MjVCmxw3xsg/TTNbYHv5CeI/AAAAAAAAAKU/l3JfghzUlWg/s1600/tn_IMG_0607_2_poor.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://3.bp.blogspot.com/_MjVCmxw3xsg/TTNbYHv5CeI/AAAAAAAAAKU/l3JfghzUlWg/s320/tn_IMG_0607_2_poor.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5562890434687601122" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href="http://1.bp.blogspot.com/_MjVCmxw3xsg/TTNasmIpQzI/AAAAAAAAAKM/e9fqEZa6-FU/s1600/tn_IMG_3507_2_poor.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 240px;" src="http://1.bp.blogspot.com/_MjVCmxw3xsg/TTNasmIpQzI/AAAAAAAAAKM/e9fqEZa6-FU/s320/tn_IMG_3507_2_poor.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5562889686930244402" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;The images above were created by dividing a photograph into a few sections, each with unique hue. Then each section was cartoonized by reducing the number of colors, colorizing and finally applying the artistic/cartoon filter.&lt;br /&gt;&lt;br /&gt;Here's a tutorial on how to do it. I know its impossible to describe it clearly without a video, so If you don't know how to do something, either ask here in a comment or find an appropriate tutorial on YouTube.&lt;br /&gt;&lt;br /&gt;- If your photo is in a format that does not support transparency channel, for example jpg or bmp (unless its 32bit bmp), you will have to do seemingly useless action: duplicate the current layer and then delete the original one. This way, you will get an alpha channel for you photo.&lt;br /&gt;- Apply unspotting filter on your image (Filters/Enhance/Despeckle). Even if you have only a bit of noise on the image, this will make selection by color much faster and remove unwanted black dots from final result of cartoonization. Which settings you should choose? You have to see the preview and make sure noise is removed and the existence of edges and important details is preserved.&lt;br /&gt;- Think about what hues exist on the image. For example in case of the cat above there is green (for the grass) and orange (for the cat), as well as brown (for the fence).&lt;br /&gt;- Think about the best way to select the area with given color. There is no robust way to select areas on any possible image. You have to find one that takes fairly short time. If it takes more than about 25 minutes, than there is a faster way, so don't bother going on and rethink you tactics. For example if a border between areas is fairly short, "Intelligent Scissors" will do fine. If there are, however, multiple inclusions and crossings or blurry areas, the length of the border may be enormous and then you would rather do "Select By Color". Look at the options for this tool. Think what is the feature of colors that differentiate your areas most. It will probably be hue ("Hue" in GIMP), brightness ("Value" in GIMP), or all color data in composite ("Composite" in GIMP). Don't be affraid to change the default "Composite" option. Experiment with the degree of similarity, so that the selection does not select too much on the image. Remember that you can add selections by holding SHIFT or subtract by holding CTRL key. Combine this with "Select By Color" to create a powerful selection tool for the whole image. Try to add selections so that no unwanted pixels end up selected. If it happens, undo and try with different settings. Observe the current selection. If you see that from now you can finish selecting by, for example, extending current selection by 1-2 pixels or manually adding or removing an area, do it, otherwise continue selecting by color. &lt;br /&gt;- When you are done selecting, do Select/Float and then in the Layers tab right click on the Floating Selection and make a new layer out of it.&lt;br /&gt;- If you have only 2 areas with distinct hue (as with one of the cat images above), then you are done dividing your image, otherwise extract all the other areas you need.&lt;br /&gt;- Now is a good time to save your work as xcf file. This is a native GIMP format that contains whole history of changes, selections and layers so that you can open it &lt;br /&gt;- For each area do the following:&lt;br /&gt;A) In the Layers tab select the layer you want to work with (e.g. layer with an orange cat). Make other layers invisible by clicking the eye button in the Layers menu (for example do it so that cat is visible and grass is not).&lt;br /&gt;B) Pick a representative color. To achieve this use the Color Picker Tool. In the tool options select "sample average" to make sure color represents average color of the current area, rather than an anomaly on the pixel you click on. Click on the current area on the image to pick the color (e.g. on a cat). It is NOT important to get the average brighness or intensity right, you just need the average hue. Keep this in mind when choosing point to pick color from.&lt;br /&gt;C) Do color reduction (Colors/Posterize), selecting "5" on the slider (that doesn't actually reduce number of colors to 5, its a more involved maths, but you should see areas filled with consistent colors rather than gradients). Look at edges between colors on your image. If they look torn and clunky, undo and apply Gaussian Blur to the layer (Filters/Blur/Gaussian Blur). The radius of 4 pixels should be fine. Then do the color reduction. Your area should now be comprised of a few areas filled with unique color.&lt;br /&gt;D) Turn your layer into shades of grey (Colors/Desaturation). As you do it, make sure you change the default "Lightness" to "Average". This will ensure that colors of the layer end up sufficiently distinct when turned to grey.&lt;br /&gt;E) Now be careful because it is a very important stage. You need to colorize your layer. Do you remember picking a representative color? Now this color should be your Forgound Color in the color menu. Double click on it to open the color dialog. READ the hue. This is the number at the top right of the dialog, next to the top-most slider with "H" letter. Now close the color dialog and open Colors/Colorize. Set the "Hue" slider to the value you remember. Set the "Intensity" slider to maximum value. Then set the brightness to something sensible, so that the layer looks cool. Note that later you will be adding black cartoon-like lines, which will make image darker. Therefore you need a slightly bigger brightness than normal.&lt;br /&gt;F) Increase contrast a bit (Colors/Brightness-Contrast) to make the layer look a bit more vivid.&lt;br /&gt;E) Apply the Cartoon filter (Filters/Artistic/Cartoon). Good numbers to try are 5 for the "Mask Radius" and 0.7 for the "Percent Black", but you may need to experiment so that the black lines do not darken the color of the layer too much but are visible at the same time.&lt;br /&gt;&lt;br /&gt;- Make all layers visible to observe the final result.&lt;br /&gt;- Depending on how sharp were your selections and how much blur and unspotting you applied, you may see a strange, semi-transparent-looking borders between your areas. To get rid of them you may for example create a completely new black layer and put it below all your layers. &lt;br /&gt;- Save/Export the image as you wish. If exporting as jpg, select quality very close to 100%, otherwise artefacts will be visible on the cartoon image.&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-3760144560709653516?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/3760144560709653516/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2011/01/cartoonization-in-gimp.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/3760144560709653516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/3760144560709653516'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2011/01/cartoonization-in-gimp.html' title='Cartoonization in GIMP'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_MjVCmxw3xsg/TTNburb4t2I/AAAAAAAAAKc/o5CyOaLzPic/s72-c/tn_IMG_0620_2_poor.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1795724001081611362</id><published>2010-10-08T11:50:00.000-07:00</published><updated>2010-10-09T09:55:56.108-07:00</updated><title type='text'>postcondition verification</title><content type='html'>Hello reader!&lt;br /&gt;&lt;br /&gt;I have just made a program that takes a function or method signature with comments and generates a function that verifies postconditions of the function.&lt;br /&gt;Download &lt;a href="http://www.wuala.com/poliklosio/dzielone/cppAutoPostCon.exe"&gt;here&lt;/a&gt;(windows only so far). Click "Download 'cppAutoPostCon.exe' to your computer" at the bottom of the page.&lt;br /&gt;Source &lt;a href="http://www.wuala.com/poliklosio/dzielone/cppAutoPostConSource.zip"&gt; here&lt;/a&gt;. Note that the only piece of code which is not inter platform is in the clipboard.cpp file. Feel free to port the code or use it for any purpose. Also note that with the source comes a project file for Code::Blocks IDE. Consult it if you want to build the code yourself because the set up is not trivial. Also note that the code has been compiled with GCC 4.4.1 and requires the Boost library v. 1.43.0 to be installed.&lt;br /&gt;&lt;br /&gt;For example, it turns this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;//some text&lt;br /&gt;//{{{ { a_setting_stuff ;;; a} {b} &lt;br /&gt;// {c_setting_stuff ;;; c} }}}&lt;br /&gt;///some more text&lt;br /&gt;ret_type do_sth(arg1,arg2,arg3)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;into this:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;bool verify_do_sth(ret_type _result,arg1,arg2,arg3)&lt;br /&gt;{&lt;br /&gt;    {&lt;br /&gt;        a_setting_stuff;&lt;br /&gt;        if(!(a))&lt;br /&gt;            return false;&lt;br /&gt;    }&lt;br /&gt;    if(!(b))&lt;br /&gt;        return false;&lt;br /&gt;    {&lt;br /&gt;        c_setting_stuff;&lt;br /&gt;        if(!(c))&lt;br /&gt;            return false;&lt;br /&gt;    }&lt;br /&gt;    return true;&lt;br /&gt;}&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Usage: &lt;br /&gt;In your text editor select a function header with a comment.&lt;br /&gt;Copy it to clipboard.&lt;br /&gt;Run the program. (It will end in fraction of a second.)&lt;br /&gt;The resulting verification function is now in the clipboard.&lt;br /&gt;If the function could not be generated, the clipboard contains C++-style comment with an appropriate error message.&lt;br /&gt;&lt;br /&gt;//edit 9th October&lt;br /&gt;Now the program does much better job at formatting generated code, so that no line is too long to be legible and the indentation is acceptable.&lt;br /&gt;&lt;br /&gt;Have fun verifying results of your function calls! (Yes, I know it sounds ridiculous. But the program is useful anyway.)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1795724001081611362?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1795724001081611362/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/10/postcondition-verification.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1795724001081611362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1795724001081611362'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/10/postcondition-verification.html' title='postcondition verification'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-8219234190935445803</id><published>2010-08-28T01:04:00.000-07:00</published><updated>2010-08-28T06:26:17.984-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SAH'/><title type='text'>nlog(n)log(n) kd-tree construction using SAH</title><content type='html'>Disclaimer:&lt;br /&gt;   I don't know if anyone has ever invented this algorithm yet or not. A much more important fact is that I haven't found any intuitive explanation of it in the internet. Here is my attempt. Note that this article is inspired by a real piece of code, executing in my ray tracer.&lt;br /&gt;&lt;br /&gt;Introduction&lt;br /&gt;&lt;br /&gt;    KD tree is a data structure, based on a space subdivision scheme. It is useful for fast search for shapes intersecting with a line in 3D space. Ray tracing is an obvious application of kd trees. The defining principle of a kd tree is that an axis-aligned bounding box of all shapes is split recursively into two child boxes, using an axis aligned plane. Each child box is going to have a list of all shapes that intersect with it. The split plane is positioned according to some kind of a sensible heuristic calculation. One of the best heuristics is the Surface Area Heuristic (SAH for short).&lt;br /&gt;    In this post I am not going to waste time repeating wildly accessible general information about kd trees and SAH. It is the fast use of geometry that is interesting in my method. Instead I would like to point the reader to materials that in my opinion explain it clearly enough:&lt;br /&gt;&lt;br /&gt;&lt;a href=http://en.wikipedia.org/wiki/Kd-tree&gt;http://en.wikipedia.org/wiki/Kd-tree&lt;/a&gt;&lt;br /&gt;&lt;a href=http://www.devmaster.net/articles/raytracing_series/part7.php&gt;http://www.devmaster.net/articles/raytracing_series/part7.php&lt;/a&gt; (skip the beginning and go to 'kd trees' section)&lt;br /&gt;&lt;a href=http://www.devmaster.net/forums/showthread.php?t=15004&gt;http://www.devmaster.net/forums/showthread.php?t=15004&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Now I assume that the reader knows how is kd-tree structured, what principles is SAH based on and what is the simple, naive algorithm for building the tree using SAH.&lt;br /&gt;&lt;br /&gt;General outline of the method (also the naive method):&lt;br /&gt;&lt;br /&gt;1. Find all position of the split planes which are worth consideration.&lt;br /&gt;2. For each split position P:&lt;br /&gt;2.1. Compute the coordinates that define the two boxes: one to the left and one to the right of the split plane.&lt;br /&gt;2.2. Find the number NL of shapes that intersect left box and the NR of shapes that intersect the right box.&lt;br /&gt;2.3. Calculate the SAH as NL*[the area of sides of the left box] + NR*[the area of sides of the right box]. There are usually some additional constants in this formula for adjusting the number of shapes per leaf, but they are not significant for the purpose of this post.&lt;br /&gt;2.4. If the computed SAH value is the best so far, save it, together with the split position.&lt;br /&gt;3. Take the best SAH value and check of it makes sense to split this node. If it is the case, compute the coordinates of the left and right box, create two children of this node and insert the intersecting shapes to them.&lt;br /&gt;&lt;br /&gt;The most expensive step of the naive version is 2.2. In the naive version it involves checking if an intersection exists between each shape and the left/right box. This is O(n) step in an O(n) loop, which lifts the time complexity to O(n*n). It is done in each node of a tree, whose expected depth is O(log(n)), so the total expected complexity of the naive version of tree building is O(n*n*log(n)).&lt;br /&gt;&lt;br /&gt;Lets assume, without the loss of generality, that the split axis is X (the split axis is the axis orthogonal to the splitting plane). My modification is based on observation that its not necessary to traverse all shapes for all possible split positions on X axis. Instead, I compute intersection (common part) of each shape with the node box and create two lists of all shapes, sorted by one of the extreme X positions of the intersection. First list is sorted by the minimal X values (later called 'Min'), second by the maximum X values (later called 'Max'). Note that for any split position P, all shapes which have Min &lt;= P are going to intersect with the left child box (where 'left' is defined as having Xs smaller than P). Also, all shapes which have Max &gt;= P are going to intersect the right box. The shape counts in the left and right box are simply the shape counts before and after certain elements on the Min and Max sorted lists. I can find those 'certain elements' in log(n) time if I use appropriate implementations of those lists.&lt;br /&gt;&lt;br /&gt;Here is a more specific explanation of my modification. &lt;br /&gt;I do additional precomputation in step 0:&lt;br /&gt;&lt;br /&gt;0. For each shape compute the Min and Max coordinates of its intersection with box of the node. By intersection I mean common points of the shape and the box. For example an intersection of a box and a plane could be a rectangle. Only the coordinates on the axis orthogonal to the splitting plane are needed, so for each shape there will be just one pair of coordinates. &lt;br /&gt;Create two sorted maps, containing all shapes:&lt;br /&gt;&amp;nbsp;&amp;nbsp;[Min]-&gt;[(shape pointer; an integer variable C, equal to 0)],&lt;br /&gt;&amp;nbsp;&amp;nbsp;[Max]-&gt;[(shape pointer; an integer variable C, equal to 0)].&lt;br /&gt;Notation: In [a]-&gt;[b] a is a key, b is value and '-&gt;' means 'maps to'. (a;b) is a pair of elements a and b.&lt;br /&gt;In fact, the maps above have to be multimaps, since min or max may be equal for multiple shapes. Any decent programming language should provide an abstraction of a sorted (multi)map, with logarithmic insertion and search operations. If your language provides a map, but does not provide multimap, you can use a map in which values are arrays of the pairs. If you use the C language, you can implement it as a balanced binary tree (e.g. red-black tree) or a skip list.&lt;br /&gt;So far, the contents of the 0 step may be easily implemented by creating empty maps before the loop and inserting the shapes to them as soon as the min and max values are computed in each loop cycle. Then comes the assignment to the integer variables in the map: &lt;br /&gt;&amp;nbsp;&amp;nbsp;Initialize 'i' to 0.&lt;br /&gt;&amp;nbsp;&amp;nbsp;For each entry 'e' in the map:&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Set 'e'.value.C to 'i'.&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Increment 'i'.&lt;br /&gt;This way each shape's map entry contains the number of shapes that preceed it in the map. Hence, the maps become:&lt;br /&gt;&amp;nbsp;&amp;nbsp;[Min]-&gt;[(pointer to S; count of shapes before S in this map)],&lt;br /&gt;&amp;nbsp;&amp;nbsp;[Max]-&gt;[(pointer to S; count of shapes before S in this map)].&lt;br /&gt;&lt;br /&gt;Now the step 2.2 becomes:&lt;br /&gt;&lt;br /&gt;2.2.Please, recall that we are interested in computing NL and NR, i.e. the counts of the shapes that intersect the left/right child box. Also recall that we are currently considering split position P. &lt;br /&gt;Lets introduce integer Nt - the total shape count in the box (in other words: in both child boxes together). The calculation of NL an NR is as follows:&lt;br /&gt;2.2.1 NL.&lt;br /&gt;In the Min map find the first entry 'e' whose key is greater than P. &lt;br /&gt;NL value will be equal to 'e'.value.C. &lt;br /&gt;If there is no such entry (because P is greater than all Min keys), NL is equal to Nt.&lt;br /&gt;2.2.2 NR.&lt;br /&gt;In the Max map find first entry 'e', whose key is greater or equal to P. &lt;br /&gt;NR value will be equal to Nt-('e'.value.C). &lt;br /&gt;If there is no such entry (because P is greater than all Max keys), NR will be 0.&lt;br /&gt;&lt;br /&gt;Any decent sorted map abstraction should provide a way of searching for the entries whose keys are most similar to given value, so I am not going to cover such search here. Note, however, that the complexity of 2.2.1 and 2.2.2 in a sorted map is log(n).&lt;br /&gt;&lt;br /&gt;The rest of the algorithm stays the same. Actually, I think that this may also be implemented using a sorted array and binary search instead of the multimap, but I didn't want to obfuscate the explanation with too much generality, so I chose to refer to multimap concept consistently.&lt;br /&gt;&lt;br /&gt;In the next post I am going to describe one more thing that may not be immediately obvious: how to compute the polygon created by intersecting a triangle with box. I am not going to cover shapes other than triangles since I solely use triangles, so I would not be writing from experience.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-8219234190935445803?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/8219234190935445803/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/08/nlognlogn-kd-tree-construction-using.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/8219234190935445803'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/8219234190935445803'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/08/nlognlogn-kd-tree-construction-using.html' title='nlog(n)log(n) kd-tree construction using SAH'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-2298460805974112654</id><published>2010-05-18T12:26:00.000-07:00</published><updated>2010-05-20T15:49:39.087-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='CDT'/><category scheme='http://www.blogger.com/atom/ns#' term='bookmarks'/><title type='text'>Boolmarks in Eclipse</title><content type='html'>This post is a credit of how shitty is the bookmarking functionality in Eclipse.&lt;br /&gt;For the first, lets introduce the way bookmarking works there.&lt;br /&gt;There are multiple ways of setting a bookmark:&lt;br /&gt;&lt;br /&gt;Way 1: In the menu click Edit/Add Bookmark. Type something in the window that pops up. Click OK in it.&lt;br /&gt;Way 2: Press ALT+E+K (a shortcut to the above). Type something in the window that pops up. Click OK in it.&lt;br /&gt;Way 3: Right click on the strap to the left of where line numbers are present in the editor window (If you do not have line numbers, shame on you. In this case go to Window/Preferences/General/Editors/Text Editors and check "Show line numbers"). Choose Add bookmark from the drop down list. Type something in the window that pops up. Click OK in it.&lt;br /&gt;&lt;br /&gt;Of course, as you might imagine, the whole reason why this functionality is shitty is the "Type something..." part in the above ways. This makes it completely unusable, since placing the bookmark is hardly worth the time and distraction spent on typing something and clicking OK in the pop-up. For example, when I'm coding, I want to bookmark 5 places where I need to make a modification, then jump to each, one by one, and make a modification.&lt;br /&gt;&lt;br /&gt;It seems that the eclipse developers use bookmarks to jump to globally crucial places in whole projects. For those it may make sense to have names, since it is then easier to locate them from special place in the editor. The best reason for me to use bookmarks is to navigate in a single file.&lt;br /&gt;&lt;br /&gt;For this reason I would like to introduce a naming convention: "global bookmarks" for the kind of thing implemented in Eclipse and "local bookmark" for the kind of thing I want to use (present e.g. in Code::Blocks, Borland and Visual Studio). &lt;br /&gt;According to this naming convention, local bookmarks are missing from Eclipse. No more self-delusion, Eclipse developers!&lt;br /&gt;This is something that definitely should be fixed. For the completeness of this post, I must mention that there is a bookmarks plugin at &lt;a href="http://etc.to"&gt;etc.to&lt;/a&gt; website, but its seems to be only for the Java version of Eclipse.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-2298460805974112654?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/2298460805974112654/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/05/boolmarks-in-eclipse.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/2298460805974112654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/2298460805974112654'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/05/boolmarks-in-eclipse.html' title='Boolmarks in Eclipse'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-5017395553998237559</id><published>2010-04-15T02:14:00.000-07:00</published><updated>2010-04-15T03:02:14.416-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eclipse'/><category scheme='http://www.blogger.com/atom/ns#' term='CDT'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>My rant on Eclipse+CDT</title><content type='html'>Eclipse is non-trivial to use for C++ and not designed for it. I am using Eclipse Galileo.&lt;br /&gt;Problems:&lt;br /&gt;&lt;br /&gt;CTD build system is a bit of a failure. It rebuilds project at wrong moments (e.g. sometimes after launching eclipse, even though the object files still exist. This makes it unusable for big projects. At some point I found out that this is caused by "use parallel builds" option, checked by default. This fact should be advertised as I am sure that it distracts many people.&lt;br /&gt;&lt;br /&gt;In many cases CDT does not rebuild things properly which causes strange runtime errors. Somehow it assumes that programmer should know which sources to rebuild, which is a bad assumption because, if something can be automated, why not automate it? Things that confuse CDT seem to be more advanced language features, like complicated templates, together with static functions, global data, overloading, conditional compilation etc, in other words the further code is from pure C code, the more problems exist. Code::Blocks IDE always knows what to rebuild, probably because it uses make in less clever way.&lt;br /&gt;&lt;br /&gt;Try do do "Project/Clean" without rebuilding. Guess what the eclipse shows in the console at the bottom?&lt;br /&gt;Answer: "Build complete"&lt;br /&gt;(The project is only cleaned, the message is confusing).&lt;br /&gt;&lt;br /&gt;Right click an occurence of a function name. How do you go to definition? &lt;br /&gt;Answer: You have to choose "Open Declaration".&lt;br /&gt;Click the name in the definition and choose "Open Declaration" again. Where does it take you? &lt;br /&gt;Answer: To the declaration. &lt;br /&gt;Right click the declaration, choose "Open Declaration". &lt;br /&gt;Answer: To the definition.&lt;br /&gt;&lt;br /&gt;You are viewing a non-console window at the bottom, e.g. "Properties" or "Type Hierarchy". Click the launch button. What do you see at the bottom?&lt;br /&gt;Still error log. The IDE should show the console since something is happening there.&lt;br /&gt;&lt;br /&gt;When launching eclipse, the window which has the progress bar is behind applications that you already run (e.g. behind windows explorer).&lt;br /&gt;&lt;br /&gt;Trying to launch debugger with errors in the code launches it.&lt;br /&gt;&lt;br /&gt;After termination of an application, eclipse does not show the exit code. I have to switch to debug view to see it.&lt;br /&gt;&lt;br /&gt;After pressing the "run" button Eclipse checks if there is anything to build, which often takes long time. I have lost many minutes of my life this way. It seems that there is no way of switching this off. It would be very convenient to just run the last built executable.&lt;br /&gt;&lt;br /&gt;The first time you run the debugger you are asked about what kind of debugging you want. What the heck do the options mean?&lt;br /&gt;&lt;br /&gt;When pressing SHIFT+CTRL+Right, editor selects part of the identifier, instead of the whole thing. When you double click using mouse pointer, it selects the whole thing, but there seems to be no way of doing it via keyboard. Perhaps this is good for Java, but its not for C++ where there are longer identifiers as well as different spelling conventions. Particularly, with the underscores between words, half of such partial selections are not what user wants, due to "landing" on the wrong side of the underscore. It seems sensible to have an option in editor to switch to selecting whole identifier.&lt;br /&gt;&lt;br /&gt;When the "Project Explorer" tab looses focus (this happens frequently), Eclipse somehow does not know which is the active project, so, for example, the "build" and "launch" buttons don't know which project to build or launch. This is silly since I believe most people work on single project most of the time. This also causes possible slip mistakes when user selects things in the dialog boxes that appear when he presses the buttons.&lt;br /&gt;&lt;br /&gt;After excluding a file from build (right click on file in Project Explorer and choosing "Exclude from Build", it is not clear how to bring it back, because there is no symmetric "Include to Build" option. An unaware programmer may get stuck in the middle of a task (as I did). The option is available after the same right click, in "Properties" menu in "C/C++ Build" section.&lt;br /&gt;&lt;br /&gt;BTW, I am using Eclipse anyway due to rich semantic help, rich set of keyboard shortcuts, syntax analysis which points out syntax errors immediately and showing compile errors in many places in IDE.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-5017395553998237559?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/5017395553998237559/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/04/my-rant-on-eclipsecdt.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/5017395553998237559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/5017395553998237559'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/04/my-rant-on-eclipsecdt.html' title='My rant on Eclipse+CDT'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-4071882438190555768</id><published>2010-04-09T12:38:00.000-07:00</published><updated>2010-04-15T03:03:59.994-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='budowanie zbiorcze'/><title type='text'>sprytniejsze budowanie zbiorcze</title><content type='html'>Jest sobie duży projekt w C++? Jest problem z czasem kompilacji z powodu dużej liczby jednostek translacji(plików cpp)? Oto proste rozwiązanie, oparte na znanej idei budowania zbiorczego, czyli "unity build" (zwanej też "uber build" albo "bulk build"), polegającej na #includowaniu plików cpp do zbiorczego pliku cpp i kompilowaniu jego zamiast rzeczonych plików.&lt;br /&gt;&lt;br /&gt;Cechą unikatową rozwiązania, które zaraz opiszę jest to, że:&lt;br /&gt;A) Nie trzeba męczyć się z ręcznym wybieraniem plików, które mają być skompilowane. Po prostu kompilujemy wszystkie pliki cpp (w przeciwieństwie do powyżej realizacji "unity build").&lt;br /&gt;B) Można dowolnie przełączać pomiędzy "unity build" a normalną kompilacją.&lt;br /&gt;&lt;br /&gt;Cały mechanizm zadziała automatycznie, jedyną rzeczą, która sygnalizuje chęć skorzystania z unity build jest dodanie jednej opcji polecenia wywołującego linker.&lt;br /&gt;&lt;br /&gt;Aby zaimplementować mechanizm, wystarczy zrobić 2 rzeczy:&lt;br /&gt;A) W każdym pliku cpp dopisać na początku (przed poleceniami #include)&lt;br /&gt;  &lt;i&gt;#if defined(IN_COLLECTIVE) or not defined(BUILD_COLLECTIVELY)&lt;/i&gt;&lt;br /&gt;   a na końcu &lt;br /&gt;  &lt;i&gt;#endif&lt;/i&gt;&lt;br /&gt;B) W każdym folderze zrobić plik zbiorczy collective.cpp, wyglądający mniej więcej tak:&lt;br /&gt;&lt;i&gt;#ifdef BUILD_COLLECTIVELY&lt;br /&gt;#define IN_COLLECTIVE&lt;br /&gt;#include"A.cpp"&lt;br /&gt;#include"B.cpp"&lt;br /&gt;#include"C.cpp"&lt;br /&gt;#include"D.cpp"&lt;br /&gt;#include"E.cpp"&lt;br /&gt;#undef IN_COLLECTIVE&lt;br /&gt;#endif&lt;/i&gt;&lt;br /&gt;&lt;br /&gt;Oczywiście A,B,C,D,E to nazwy plików cpp w folderze, gdzie znajduje się plik z powyższym kodem.&lt;br /&gt;&lt;br /&gt;W efekcie, jeśli dodamy do opcji linkera makrodefinicję BUILD_COLLECTIVELY, to program zbuduje nam się kilka razy szybciej. Jeżeli nie, to wszystko będzie po staremu. Podkreślam, że BUILD_COLLECTIVELY możemy dodać do wywołania linkera, np. &lt;br /&gt;g++ -DBUILD_COLLECTIVELY ..., nie musimy w żadnym pliku nagłówkowym.&lt;br /&gt;Nie będę tu gęsto tłumaczył dlaczego to przyspiesza kompilację, ani nie będę wymieniał wszystkich zalet i wad "unity build", najlepiej odeślę do materiałów poglądowych:&lt;br /&gt;&lt;a href=http://buffered.io/2007/12/10/the-magic-of-unity-builds/&gt;http://buffered.io/2007/12/10/the-magic-of-unity-builds/&lt;/a&gt;&lt;br /&gt;&lt;a href=http://stackoverflow.com/questions/861707/is-reducing-number-of-cpp-translation-units-a-good-idea&gt;http://stackoverflow.com/questions/861707/is-reducing-number-of-cpp-translation-units-a-good-idea&lt;/a&gt;&lt;br /&gt;a tutaj tylko zakreślę przyczynę: chodzi głównie o to, że wszystkie includowane nagłówki są przetwarzane tylko raz, a nie tyle razy, ile jest plików cpp.&lt;br /&gt;&lt;br /&gt;W pierwszym linku powyżej są opisywane rozwiązania polegające na wyłączeniu z kompilacji wszystkich plików cpp poza zbiorczym lub też tworzeniu osobnego projektu do budowania zbiorczego. Moje rozwiązanie stanowi ulepszenie w stosunku do nich, dlatego, że w praktyce jeżeli pliki są wyłączane z projektu w ulubionym IDE lub kod jest wyłączony kompilacją warunkową, ciężko jest zmusić IDE do włączenia w takim kodzie pomocy kontekstowej, podświetlania znaczeniowego i innych udogodnień. W moim rozwiązaniu do wygodnej pracy nad tym kodem wystarczy nie zdefiniować BUILD_COLLECTIVELY (czyli tak naprawdę nie trzeba robić nic). &lt;br /&gt;&lt;br /&gt;    Zauważ, że rozwiązanie jest całkowicie transparentne, tzn jeżeli kolega zacznie pracować nad naszym kodem i utworzy sobie do tego celu nowy projekt, to domyślnie będzie miał stary, znany mu sposób budowania, pomoc kontekstową i nie będzie musiał nic dodatkowo ustawiać, żeby w ogóle zacząć pracę.&lt;br /&gt;&lt;br /&gt;    Zauważ również, że w wymienionych wymienionych powyżej krokach nie ma nic, czego nie mógłby dopisać prosty skrypt, można więc z łatwością zaimplementować to rozwiązanie w naprawdę dużym projekcie.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-4071882438190555768?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/4071882438190555768/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/04/sprytniejsze-budowanie-zbiorcze.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4071882438190555768'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4071882438190555768'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/04/sprytniejsze-budowanie-zbiorcze.html' title='sprytniejsze budowanie zbiorcze'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1895593140304062390</id><published>2010-03-04T14:33:00.000-08:00</published><updated>2010-03-04T15:22:03.286-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='eigenfaces'/><title type='text'>_________</title><content type='html'>________&lt;br /&gt;&lt;br /&gt;PS.&lt;br /&gt;Nawiasem mówiąc, ten demotywator dwa wpisy wcześniej "Eigenfaces..." mógłby chyba wygrać konkurs na najbardziej niszowy demotywator w historii (proszę, wyprowadźcie mnie z błędu, pokażcie jeszcze lepszy!). Nie dość, że dotyczy bardzo wąskiej dziedziny (uczenie się maszyn), to jeszcze zakłada posiadanie zawoalowanej wiedzy praktycznej z zakresu maszynowego rozpoznawania twarzy, a do tego jest tak pięknie niejednoznaczny, że jednocześnie chyba wymaga rozumienia poezji. Dla niekumatych dodam, że "eigenfaces" to takie pomocnicze reprezentacje twarzy, pomagające np. w określaniu, czy twarz ze zdjęcia to twarz konkretnej osoby (w dużym uproszczeniu). W demotywatorze chodzi o to, że student spał i śniły mu się, jak mu się wydawało, diabelnie nieprawdopodobne rzeczy, godne mar sennych, ale, jak się okazuje, te rzeczy są jak najbardziej rzeczywiste, w zasięgu dzisiejszej nauki. Te nieprawdopodobne rzeczy, to automatyczne wykrywanie twarzy śpiących studentów wśród innych, nieśpiących, używając przykładowych zdjęć i określenia, czy przykłady przedstawiają śpiących, czy nie. Twarz tego diabełka, to tytułowy eigenface, z dodatkiem różków i kłów. Diabelność ma podkreślać nierzeczywistość. Słowa "sleeping student" mają już ostatecznie zwrócić uwagę na sen, co ma ułatwić wpadnięcie na to, że student na w drugiej części właśnie się obudził. Aha, tak dla wyjaśnienia, pomyślałem, że komentarz do wpisu nie zasługuje na osobny wpis, więc piszę to w "PS".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1895593140304062390?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1895593140304062390/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/03/blog-post.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1895593140304062390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1895593140304062390'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/03/blog-post.html' title='_________'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-213145186404386518</id><published>2010-02-11T05:41:00.001-08:00</published><updated>2010-02-11T05:43:30.961-08:00</updated><title type='text'>Reklama na tvn24.pl</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_MjVCmxw3xsg/S3QJKNpHFFI/AAAAAAAAAJg/cs3WwtD2u40/s1600-h/Screenshot.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;width: 320px; height: 58px;" src="http://2.bp.blogspot.com/_MjVCmxw3xsg/S3QJKNpHFFI/AAAAAAAAAJg/cs3WwtD2u40/s320/Screenshot.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5436980721208464466" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Dzieciom życzymy kochających nowych właścicieli.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-213145186404386518?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/213145186404386518/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/02/reklama-na-tvn24pl.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/213145186404386518'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/213145186404386518'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/02/reklama-na-tvn24pl.html' title='Reklama na tvn24.pl'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_MjVCmxw3xsg/S3QJKNpHFFI/AAAAAAAAAJg/cs3WwtD2u40/s72-c/Screenshot.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-8782910945560400932</id><published>2010-02-08T15:54:00.000-08:00</published><updated>2010-02-27T06:51:43.908-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='dag'/><category scheme='http://www.blogger.com/atom/ns#' term='projektowanie'/><category scheme='http://www.blogger.com/atom/ns#' term='programowanie'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='wskaźniki'/><title type='text'>Refleksje na temat inteligentnych wskaźników w C++ i projektowania programu.</title><content type='html'>Czy je polecam?&lt;br /&gt;Tylko początkującym.&lt;br /&gt;Czy coś dają?&lt;br /&gt;I tak i nie.&lt;br /&gt;&lt;br /&gt;Czemu "tak"?&lt;br /&gt;&lt;br /&gt;Chciałbym zwrócić uwagę czytelnika na zaletę tych wskaźników, &lt;br /&gt;nie będącą kolejnym powtarzaniem, że umożliwiają niepisanie 'delete'.&lt;br /&gt;&lt;br /&gt;W przeciwieństwie do referencji z Javy czy C# inteligentne wskaźniki nadal wymuszają dobry projekt programu, robiąc problemy ze względu na cykle referencji. Konkretnie, w przypadku cyklu A-B-A wymuszają, żeby np. obiekt A miał inteligentny wskaźnik do B a B tylko zwykły wskaźnik do A. To jawnie wskazuje, który obiekt jest właścicielem &lt;br /&gt;drugiego. To nie daje tylko destrukcji we właściwej kolejności. To również wymusza strukturę właścicielską.&lt;br /&gt;&lt;br /&gt;Nazwijmy słowem "właściciel" jakiś obiekt, który ma inteligentny wskaźnik na inny obiekt. Program zbudowany w ten sposób jest acyklicznym grafem skierowanym (DAGiem) z właścicielem wszystkiego jako korzeń. Nad takim kodem dużo łatwiej jest zapanować niż nad dowolnym grafem, gdzie użycie jakiegoś konkretnego elementu jest bardzo utrudnione bo nigdy nie wiadomo, jakie obiekty trzeba mu dać, gdzie go stworzyć, w jakiej kolejności wykonać inicjalizację itd. W dagu, jak jest właściciel, to &lt;br /&gt;można go poprosić o stworzenie jakiejś posiadłości. To właśnie właściciel albo od razu potrafi stworzyć posiadłość, bo miał wymuszoną inicjalizację, albo ma dobrą dokumentację i jakieś asercje uniemożliwiające tworzenie rzeczy w niewłaściwej kolejności.&lt;br /&gt;&lt;br /&gt;Dag wykazuje duże podobieństwo do drzewa, zatem łatwo go, albo jakiś jego sektor w drzewo zamienić, czyniąc projekt jeszcze bardziej eleganckim. Przeprojektowanie dagu też jest prostsze, niż zwykłego grafu, bo zmiany będą miały wpływ tylko na określony podgraf, nie na cały system. W przypadku zaś, gdy robimy program współbieżny, daje to możliwość uruchomienia współbieżnie podgrafów tam, gdzie się rozłączają, bez obaw że gdzieś poza wspólnym właścicielem są jakieś współdzielone dane, które wymagają synchronizacji.&lt;br /&gt;&lt;br /&gt;Kwestia poprawnego zaprojektowania programu mogłaby być przez kogoś zrozumiana jako zrobienie takiego programu, gdzie poprawnie działają tworzenie i niszczenie obiektów i dzięki temu nie ma np.odniesienia przez wskaźnik z adresem null lub przedwczesnego niszczenia obiektu. Problem w tym, że niektóre tego typu błędy wynikają ze złego projektu a niektóre to po prostu zwykłe usterki techniczne, spowodowane np. nienapisaniem 'delete'. Inteligentne wskaźniki, eliminując niektóre proste błędy pozwalają oddzielić te dwa zagadnienia. Jako efekt uboczny, możliwe jest łatwiejsze eksperymentowanie ze strukturą programu, bez obaw że gdzieś zapomni się 'delete'.&lt;br /&gt;&lt;br /&gt;    Czemu "nie"?&lt;br /&gt;&lt;br /&gt;Jeśli potrafi się dobrze projektować program jako dag, to nie dadzą dużo, bo kolejność destrukcji jest jak najbardziej spójna i problem sprowadza się do napisania 'delete' dla każdego 'new', a to można osiągnąć zwykłym opakowaniem, nie wspierającym inteligentnego współdzielenia obiektu.&lt;br /&gt;&lt;br /&gt;Inteligentne wskaźniki zabierają jednak trochę czasu, bo są z nimi czasami duże problemy. Problemem może być np. to, że jakiś obiekt jest przedwcześnie niszczony, gdy inteligentny wskaźnik przez przypadek na moment zamienia się na zwykły po to, by zaraz znowu przemienić się w inteligentny. Wtedy obiekt jest niepotrzebnie niszczony i ciężko jest potem znaleźć taki błąd, często objawiający się gdzieś daleko od zręcznie zakamuflowanego przez niejawne wywołanie destruktora miejsca zniszczenia. Gdzieś spotkałem się nawet z określeniem "smark pointers", nawiązującym do tego problemu. &lt;br /&gt;&lt;br /&gt;Innym problemem są częste problemy z debugowaniem niszczenia obiektów, które są niszczone przez destruktory obiektów globalnych. Brak jawności destrukcji sprawia wtedy więcej szkody niż pożytku, bo pisząc ją jawnie mamy przynajmniej pewność, że jeżeli wszystko zadziała, to zadziała w określony przez nas sposób.&lt;br /&gt;&lt;br /&gt;Jest jeszcze inny problem. Konkretnie to może się zdarzyć, że inteligentny wskaźnik na dany obiekt może zostać stworzony więcej niż raz, nie kopiowaniem wskaźnika, tylko z surowego adresu. To również powoduje przedwczesne zniszczenie obiektu. Jest strategia zapobieżenia temu, konkretnie stworzenie globalnej mapy (adres-&gt;licznik odniesień), gdzie wskaźniki sprawdzałyby liczbę odniesień, zamiast przechowywać ją bezpośrednio samemu. To jednak wymaga danych globalnych i przez to sprawia olbrzymie problemy we współbieżnym kodzie.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Werdykt&lt;br /&gt;&lt;br /&gt;Ostatecznie mój werdykt jest następujący: nie używać inteligentnych wskaźników, które utrudniają życie i nie przerzucać się na Javę, gdzie wszyscy współpracownicy będą uprawiać w projekcie wolną Amerykankę, rzygając w czasach kryzysu obiektami NullPointerException. Projektować dobrze program i używać w klasie-właścicielu opakowania (np. auto_ptr) na posiadany obiekt. &lt;br /&gt;&lt;br /&gt;EDIT: (Żeby nie wywoływać świętej wojny Java kontra C++, dodam, że mam zastrzeżenia do zbyt luźnego modelu orientowania obiektowego w Javie, natomiast nie mam ich samej Javy jako platformy, bo ilość bibliotek standardowych sprawia, że każdy powinien przynajmniej rozważyć Javę jako język do swojego nowego projektu).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-8782910945560400932?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/8782910945560400932/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2010/02/refleksje-na-temat-inteligentnych.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/8782910945560400932'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/8782910945560400932'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2010/02/refleksje-na-temat-inteligentnych.html' title='Refleksje na temat inteligentnych wskaźników w C++ i projektowania programu.'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-7980061127628161534</id><published>2009-12-03T18:44:00.001-08:00</published><updated>2009-12-03T18:45:36.865-08:00</updated><title type='text'>Eigenfaces...</title><content type='html'>&lt;a href="http://2.bp.blogspot.com/_MjVCmxw3xsg/Sxh3tFd7BuI/AAAAAAAAAJU/7Ho6IHFEDhE/s1600-h/dev4.PNG"&gt;&lt;img style="float:left; margin:0 10px 10px 0;cursor:pointer; cursor:hand;width: 273px; height: 320px;" src="http://2.bp.blogspot.com/_MjVCmxw3xsg/Sxh3tFd7BuI/AAAAAAAAAJU/7Ho6IHFEDhE/s320/dev4.PNG" border="0" alt=""id="BLOGGER_PHOTO_ID_5411206568731150050" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-7980061127628161534?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/7980061127628161534/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/12/eigenfaces.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7980061127628161534'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7980061127628161534'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/12/eigenfaces.html' title='Eigenfaces...'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_MjVCmxw3xsg/Sxh3tFd7BuI/AAAAAAAAAJU/7Ho6IHFEDhE/s72-c/dev4.PNG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-5331777299643912077</id><published>2009-10-28T12:32:00.000-07:00</published><updated>2009-10-28T16:53:18.364-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASD'/><category scheme='http://www.blogger.com/atom/ns#' term='programowanie'/><category scheme='http://www.blogger.com/atom/ns#' term='dziedziczenie'/><title type='text'>ASD Polemic</title><content type='html'>This post is a polemic with &lt;br /&gt;&lt;a href=http://www.cookingcoder.com/2009/10/caveats-this-is-110-opinion.html&gt;this&lt;/a&gt;. This is why it's in English.&lt;br /&gt;&lt;br /&gt;Just to provide enough context, I'll quote a lecture slide (I hate you for not doing this in your post; I've wasted so much time trying to figure out what do you mean, e.g. what is the factory supposed to create or where is your point of view in the system that you develop).&lt;br /&gt;The lecture slide says:&lt;br /&gt;"&lt;br /&gt;In some situations, using the new keyword to construct&lt;br /&gt;new objects of a given class is NONO&lt;br /&gt;    Connection con = new Connection(db);&lt;br /&gt;This suffers from tight coupling. If, later on, you want&lt;br /&gt;to issue connections from a pre-existing pool of&lt;br /&gt;objects, rather than creating a new one every time, this&lt;br /&gt;code prevents you. Instead, use a 'factory' approach:&lt;br /&gt;    Connection con = Connection.get(db);&lt;br /&gt;"&lt;br /&gt;First lets make things clear.&lt;br /&gt;First of all note that this example is there to making people aware that there exists a thing called a factory method and that it may help when sharing objects. When an noob reader reads this slide, he grasps those two ideas and everything's OK, because those general ideas are OK. On the other hand, when someone who really knows something about those things read this, he will almost certainly say "ugh!", because it is not a good example of factory. This is a bit useless pattern called factory method, because: &lt;br /&gt;1. This method is defined when the Connection class gets written, noone can change it later &lt;br /&gt;2. Noone can create objects of the subclasses of Connection (assuming constructors are private).&lt;br /&gt;3. It may give you the same object many times when you don't want that.&lt;br /&gt;4. It is a &lt;b/&gt;static&lt;/b&gt; method so it in general cannot rely on having any information about context in which it is called.&lt;br /&gt;&lt;br /&gt;The example on the slide is really bad because a method of class A creates objects of class A, which makes the problems 1 and 2 very true, so it is even worse than using the constructor directly. If it was another class, which would allow this method to be non-static, you could probably inherit from it, redefine the method and get the desired behaviour.&lt;br /&gt;ASIDE: Note that I do not say "using new operator", but "using constructor" to demonstrate how much I dislike the fact that the lectures are so Java-oriented.&lt;br /&gt;&lt;br /&gt;What overcomes all those problems is the abstract factory pattern.&lt;br /&gt;&lt;br /&gt;After a tough but thorough analysis of your stream of conciousness I arrived at a conclusion that you are actually arguing agains the above constraints of the factory method pattern.&lt;br /&gt;You correctly argue with the problems 1 and 3 in about half of your post, starting with:&lt;br /&gt;"For example, say you have a database connection object and you want to set up a pool of X objects that you want to reuse. Rather than use the factory method, you could edit the Connection object such that is composed of e.g. a DatabaseSocket which interfaces with the database directly. Connection's constructor grabs a DatabaseSocket from the pool, and existing methods on the Connection object forward themselves to the DatabaseSocket. (delegation!)"&lt;br /&gt;You basically found an example in which you need to modify the way Connection is defined with (pardon my English (as French say) if it's not a comprehensible sentence). Additionally, you could probably have "interface Connection" and a subclass of it defined to solve your specific problem with multithreading. This would overcome problem 3.&lt;br /&gt;You argue with the problem 4 in:&lt;br /&gt;"Consider the case where there is contention for a limited resource. With a factory method that directly hands you an object, the onus is usually on you to properly handle sharing and locking for that object."&lt;br /&gt;A proper object oriented factory could handle that because you would define the way of creating objects and you could use available information about how to share and lock particular objects. You would just give that knowledge as an argument to the constructor of the factory. Now I should describe the abstract factory design pattern but other people have done it before, so I will not repeat the effort. You can find it on Wikipedia.&lt;br /&gt;&lt;br /&gt;"'do you want a brand new object of your very own, or are you happy being given an object to achieve what you want?' If you're doing anything with mutable state outside your program logic, you probably don't need to track any extra data outside of whatever exists externally, and you should ask whatever subsystem you are dealing with for appropriate objects to this effect. However, if you want additional data with your ice-cream sundae, the former is actually a sensible thing to do, and doesn't preclude you from changing the implementation of the created class so that it grabs the 'real' object elsewhere behind the scenes."&lt;br /&gt;Very true. However, note that with the abstract factory you can pretty much have the advantages of both things, so if any one of the above solutions is too limited, there is another way!&lt;br /&gt;To conclude, you are generally right, but you are a bit cherry-picking a particular example from the slide and you are missing the point a bit, as you praise a normal idea agains a bad one, when there is a really good one (the abstract factory), that solves what the bad one was supposed to solve.&lt;br /&gt;&lt;br /&gt;---&lt;br /&gt;Different issue:&lt;br /&gt;"Inheritance has its uses, but you need to be careful about what it really means. It's not about extending functionality as much as it is about telling people "Hey, I have a cool object here with special features I can use, but since it behaves exactly like this more basic object, you guys get to play with the same instance as me!"."&lt;br /&gt;So you are talking about extending the inheritance hierarchy upwards (introducing another subclass such that "you guys" (i.e. another code) can start using the object). This is one way of taking advantage of inheritance and it is a very good one because we build up the hierarchy after we actually have an implementation of a base class. Therefore we know what polimorphic methods will be needed and what are necessary generality constrains of the base class to make the implementation feasible. This usually leads to introducing something that Java calls an interface. Note, however, that if a class is really designed to extend it (e.g. because it is part of a framework), then extending functionality can be a good idea as well. It is really important, however, to distinguish between extending existing functionality and/or data (not a good idea in most cases) and implementing interface. &lt;br /&gt;The main problem of inheritance is CONFUSION, MISUSE and MIXING of those two ideas. Using any one of them is not a problem. The whole idea of inheritance is also not a big problem, on the contrary to what Ian tries to squash into students' minds (Yes, I know that inheritance is sometimes inflexible because you cannot add methods to base classes, but this is not the argument that Ian uses. At least he stresses it an order of magnitude weaker than all the other arguments).&lt;br /&gt;&lt;br /&gt;The lecture slide says:&lt;br /&gt;"The extends word wrongly suggests "add more fields&lt;br /&gt;to" or "reuse the implementation of""&lt;br /&gt;&lt;br /&gt;I think that there is a big problem with naming, because "inheritance" really does not describe a result of using a programming concept, but way of implementing both of the two concepts described above by a programming language. That's why in C++, which is quite old now, there is syntactically just one way of inheriting (the ":" operator; OK, you can write "private", "protected" or "virtual" after it but nobody uses the first two and the third is broken). In Java, which is a bit younger, there is a separation of extending classes and implementing interfaces. There is a problem with the extending mechanism, particularly with the illusion of being able to extend anything and override every method of it, but the "extends" keyword is a good word. It reminds the writer that it whatever is extended should really be extendable. In my opinion it is more like telling the coder: "You are going to EXTEND something. Are you sure?" rather than "You are writing 'extends', so whatever you are trying to extend must be designed for extending.". It's silly, why would anyone think something like this? There is the problem with how easy it is to write "extends" that compiles, not with the word itself. This is a problem with Java, not with extending.&lt;br /&gt;&lt;br /&gt;Thanks for the paragraph about traits!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-5331777299643912077?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/5331777299643912077/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/10/asd-polemic.html#comment-form' title='Komentarze (1)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/5331777299643912077'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/5331777299643912077'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/10/asd-polemic.html' title='ASD Polemic'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1864498096648200306</id><published>2009-10-15T15:10:00.000-07:00</published><updated>2010-04-15T03:03:14.768-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='odbicie'/><category scheme='http://www.blogger.com/atom/ns#' term='kontener'/><category scheme='http://www.blogger.com/atom/ns#' term='set'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><title type='text'>PKreversed_set</title><content type='html'>Stwierdziłem, że wrzucę przydatny kawałek kodu, który zrobiłem kilka dni temu.&lt;br /&gt;Problem: istnieje implementacja jakiegoś algorytmu w C++ i chcemy, żeby mógł działać też w odwrotnym kierunku, np od końca do początku. Algorytm jest skomplikowany i nie chce się pisać go ponownie. Rozwiązanie problemu metodą Copiego i Pasta + zastąpienie iteratorów iteratorami odwrotnymi nie jest atrakcyjne (bo powstają dwie kopie tego samego kodu do utrzymania itd). Moje rozwiązanie jest eleganckie:&lt;br /&gt;- Zrobić z algorytmu szablon algorytmu, sparametryzowany typem kontenera.&lt;br /&gt;- Zrobić opakowanie na kontener, którego funkcjonalność jest odbiciem lustrzanym funkcjonalności oryginalnego kontenera, np. end() jest zastąpione rend(), typ 'iterator' to tak naprawdę 'reverse_iterator' oryginału itd.&lt;br /&gt;- Wywoływać algorytm raz dla oryginalnego kontenera a raz dla opakowania.&lt;br /&gt;&lt;br /&gt;Kod zawiera odbicie lustrzane kontenera std::set.&lt;br /&gt;Można go pobrać &lt;a href="http://klosio.neostrada.pl/mojeprogramy.html"&gt;tu&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1864498096648200306?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1864498096648200306/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/10/pkreversedset.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1864498096648200306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1864498096648200306'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/10/pkreversedset.html' title='PKreversed_set'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-2041085617330231511</id><published>2009-10-09T18:46:00.000-07:00</published><updated>2009-10-09T19:47:07.303-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='gry'/><category scheme='http://www.blogger.com/atom/ns#' term='uczelnia'/><category scheme='http://www.blogger.com/atom/ns#' term='gra wielooobowa'/><category scheme='http://www.blogger.com/atom/ns#' term='TD'/><title type='text'>Tower Defense dla wielu graczy.</title><content type='html'>(już napisałem "w multiplayerze", ale zmieniłem, żeby nie zgrzytać spolszczonymi anglicyzmami) &lt;br /&gt;Mamy taki przedmiot "Advanced Software Developement". Jedynym kryterium oceny końcowej jest projekt programistyczny do zrobienia w parach. Bardzo mi to odpowiada, para jest chyba najlepsza do tworzenia programów, bo całkiem sporo można razem zrobić, jest wzajemna motywacja, a jednocześnie nie rozmywa się odpowiedzialność, a wizja jest bardziej spójna (to taka dygresja). Do rzeczy: podczas naszej burzy mózgów dzisiaj, kiedy to powinno nam przyjść do głowy jak najwięcej pomysłów, a przyszły tylko 3, udało mi się przekonać kumpla do zrobienia gry w Javie, gry typu Tower Defence. Wyróżnianie się gry na tle zawartości zagraconego internetu ma być osiągnięte dzięki temu, że będzie w niej gra wieloosobowa (zmowu zmieniłem z "multiplayer") asymetryczna. Co to znaczy? Z grubsza tyle, że każdy gracz ma zupełnie inne zadania do wykonania: jeden gracz utrzymuje bazę i chroni ją przed atakami, budując ostrzeliwujące wieże, a drugi mówi oddziałom, jaką ścieżkę mają wybrać, wybiera typ żołnieża i rozkazuje mu zniszczyć wyżej wymienioną bazę.&lt;br /&gt;Asymetryczna? Nie przekonałem kolegi do tego pomysłu, nalegał na zrobienie trybu gry, gdzie każdy gracz ma swoją bazę a drugi wysyła na niego odziały. Wymanewrowałem z tej niezręcznej sytuacji argumentując, że najpierw zrobimy tryb asymetryczny, a potem po prostu walniemy na mapę obiekty w trybie asymetrycznym oraz ich odbicie lustrzane, tworząc w zasadzie tryb symetryczny. To stwierdzenie to był jednak tylko sprytny wybieg. Idea jest taka, że jak kolega przekona się do trybu asymetrycznego, zapomni o swoich zmartwieniach. Skąd ta pewność? &lt;br /&gt;Zacząłem dzisiaj analizować fakt, że gry TD są tak popularne; wciągają myślące osoby w wir zadania, a jednocześnie nie męczą. Są to tak naprawdę klasyczne strategie czasu rzeczywistego, ale niepełne, bez tworzenia oddziałów, złożonego dowodzenia i niszczenia nimi bazy wroga.&lt;br /&gt;Przypomniawszy sobie kilka rozgrywek, stwierdziłem że wciąganie w grę polega na pozwoleniu graczowi skupić się na pojedynczym zadaniu, udoskonalać techniki jego wykonywania do granic możliwości. Gry TD to umożliwiają, a wypasione strategie w pudełkach po 100zł już często nie (choć jest to temat na inną dyskusję).  Zaletą grania w TD jest więc łatwość, płynność. Dokładniej to analizując, stwierdziłem, że w grze TD można zobaczyć jak zmienienie czegoś w linii obrony wpływa na wynik rozgrywki, to "zobaczenie" jest niczym nieprzerywane, a do tego następstwo przyczynowo skutkowe jest rownoznaczne z bezpośrednim następstwem czasowym. To znaczy, że myśli z łatwością nadążają za tym, co widzimy, a jednocześnie to, co widzimy nadąża za myślami, zmieniając się od razu! Co więcej, dzięki powtarzającym się falom ataków, można z łatwością wyciągać wnioski nie tylko z pojedynczych ataków, ale z całych serii. Dzięki temu dodatkowo unika się losowości wyniku gry, widocznej w komejcyjnych strategiach, gdzie jeden lub dwa ataki decydują tak naprawdę o wyniku. &lt;br /&gt;Ta magia gier TD jest zbyc cenna, żeby można było ją stracić. Niech w grze wieloosobowej jeden gracz gra tak, jak w jednoosobowej, a drugi w zupełnie nowy sposób, też zaprojektowany dla jednej osoby.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-2041085617330231511?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/2041085617330231511/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/10/tower-defense-dla-wielu-graczy.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/2041085617330231511'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/2041085617330231511'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/10/tower-defense-dla-wielu-graczy.html' title='Tower Defense dla wielu graczy.'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-8154775290977946629</id><published>2009-10-09T05:37:00.000-07:00</published><updated>2009-10-09T14:24:19.835-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='algorytm'/><category scheme='http://www.blogger.com/atom/ns#' term='SDL'/><category scheme='http://www.blogger.com/atom/ns#' term='ewolucja'/><category scheme='http://www.blogger.com/atom/ns#' term='mózg'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='sieci neuronowe'/><category scheme='http://www.blogger.com/atom/ns#' term='PKgui'/><title type='text'>Sieci Neuronowe.</title><content type='html'>Jednak to napiszę. Podjąłem się niedawno nauki sieci neuronowych. Efekt można zobaczyć &lt;a href="http://www.youtube.com/watch?v=Nu_8t3QJBeg"&gt;tu&lt;/a&gt;. &lt;br /&gt;  Wprowadzenie:&lt;br /&gt;Jest prostokątny samochodzik i trasa, poza którą fizycznie nie da się wyjechać. Samochodzik może kontrolować swoje przyspieszenie oraz skręt kół. Jeżeli uda mu się przejechać przez całą trasę, ma najlepszy wynik, jeżeli nie ruszy się z miejsca lub cofnie, najgorszy. Przejazd zostaje przerwany jeśli samochodzik uderzy w granicę trasy (musi jechać wewnątrz).&lt;br /&gt;  Zadanie: &lt;br /&gt;Zrobić program, który potrafi nauczyć samochodzik jechać po (prawie) dowolnej trasie.&lt;br /&gt;Żeby była jasność: &lt;br /&gt;- Nie programuję samochodziku samemu, używając własnej wiedzy o tym jak jeździć. Program ma sam zebrać tę wiedzę. &lt;br /&gt;- Program nie zbiera wiedzy o konkretnej trasie, tylko ogólnie o tym, jak jechać.&lt;br /&gt;  Wykonanie:&lt;br /&gt;Ewolucyjne wyznaczenie sieci neuronowej rozwiązującej problem, czyli sterującej samochodzikiem.&lt;br /&gt;Dane wejściowe: bieżąca pozycja, prędkość, to, co "widzi" samochodzik (odległość od granic toru w różnych kierunkach).&lt;br /&gt;Dane wyjściowe: przyspieszenie (4 wyjścia: duże przyspieszenie, mniejsze przysp., duże spowolnienie, mniejsze spowol.), skręt kół (podobne 4 wyjścia).&lt;br /&gt;Algorytm ewolucyjny działa na populacji 50 "mózgów samochodzików". Są wybierane 3 losowe mózgi. Te, które jeszcze nie były sprawdzone w praktyce, są sprawdzanie: kierują przejazdem samochodziku na trasie. Są porównywane ich wyniki. Najgorszy mózg jest wywalany, pozostałe są krzyżowane dyskrenie i tak stworzony mózg jest włączany do populacji.&lt;br /&gt;&lt;br /&gt;Filmik przedstawia kilkanaście spośród około pięciu tysięcy przejazdów treningowych wykonych przez program. Pokazane są tylko te, które poprawiają maksymalny wynik, osiągany przez samochodzik.&lt;br /&gt;Program jest napisany w C++ z użyciem biblioteki PKgui.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-8154775290977946629?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/8154775290977946629/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/10/sieci-neuronowe.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/8154775290977946629'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/8154775290977946629'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/10/sieci-neuronowe.html' title='Sieci Neuronowe.'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-6713680996288826036</id><published>2009-08-13T03:29:00.000-07:00</published><updated>2009-08-13T04:09:24.661-07:00</updated><title type='text'>Witam</title><content type='html'>Od czasu ostatniego posta miałem dużo ciekawych pomysłów, jednak niewiele przeszło w fazę realizacji. Ale to wcale nie oznacza, że mało zrealizowałem - głównie tworzyłem PKgui (swoją bibliotekę interfejsu użytkownika). Czuję się jednak zobowiązany napisać tego posta. Głównym powodem jest stan wyżej wymienionej biblioteki - jej struktura, nazewnictwo i podstawowa, niskopoziomowa funkcjonalność jest już ustabilizowana. Wciąż brakuje bezbłędnej obsługi skupienia widgetów za pomocą klawisza TAB, kilku podstawowych klas widżetów, pełnej obsługi skórek i kilku innych rzeczy. Można natomiast z powodzeniem używać biblioteki do tworzenia prostych aplikacji - program PKCASim, czyli Piotr Klos's Cellular Automaton Simulator jest tego świetnym przykładem. Niestety program nie jest jeszcze dostępny, ale pierwsza wersja jest ukończona, więc niedługo go opublikuję.&lt;br /&gt;Rzeczy, które zrobiłem od ostatniego posta dla PKgui:&lt;br /&gt;- ukończenie rozszerzania bibliotegi o możliwość dołączania własnych kontekstów renderowania&lt;br /&gt;- postawienie repozytorium na www.assembla.com, uregulowanie spraw licencyjnych, commit biblioteki&lt;br /&gt;- ulepszenia w nazewnictwie, stosowaniu konwencji, dokumentacji (jest dostępna dokumentacja wygenerowana przez doxygen)&lt;br /&gt;- usunięcie wielu błędów&lt;br /&gt;- funkcjonalność: &lt;br /&gt;-- bitmapowe czcionki, ich wczytywanie i używanie zamiennie z czcionkami TTF, modyfikacje, takie jak zamiana koloru obrazka na inny, a także mechanizm powiadamiania używających font obiektów o zmianach w foncie; &lt;br /&gt;-- gradienty prostokątne w OpenGL&lt;br /&gt;-- ulepszenie loga błędów, umożliwiające jego wyłączenie&lt;br /&gt;-- poprawne skalowanie GUI, wraz ze wszystkimi widżetami&lt;br /&gt;-- dodałem sposób na zarządzanie layoutem (rozkładem) widgetów w kompozycie&lt;br /&gt;- zamiana wszystkich tabów na spacje&lt;br /&gt;- zmiany umożliwiające kompilację najnowszym stabilnym GCC pod linuksem&lt;br /&gt;W sumie dużo się tego nazbierało, ale mimo to GUI pozostaje trochę niedoszlifowane.&lt;br /&gt;W tej chwili uczę się do poprawek i pracuję nad prostym programem, w którym samochodziki będą jeździć po torze myśląc wyewoluowaną siecią neuronową...&lt;br /&gt;&lt;br /&gt;PS. Dla zainteresowanych: projekt PKgui ma repozytorium tutaj &lt;br /&gt;http://code.assembla.com/pkgui/subversion/nodes&lt;br /&gt;Niech Cię nie zwiedzie fakt, że wersji PKgui było tylko 42. Projekt dostał repozytorium dopiero ostatnio; gdyby miał od samego początku, wersji byłoby pewnie około 400. W zakładce "Wiki" jest opis projektu i podstawowe instrukcje kompilacji.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-6713680996288826036?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/6713680996288826036/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/08/witam.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6713680996288826036'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6713680996288826036'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/08/witam.html' title='Witam'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-4385006230074607067</id><published>2009-06-30T12:37:00.000-07:00</published><updated>2009-06-30T13:40:27.613-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Nine inch nails'/><category scheme='http://www.blogger.com/atom/ns#' term='nin'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='muzyka'/><title type='text'>migawka moich zainteresowań</title><content type='html'>Tak sobie oglądałem nagranie z konferencji w Google na YouTubie&lt;br /&gt;(www.youtube.com/watch?v=ifmZSC8ca6Q) i tą drogą odkryłem zespół Nine Inch Nails. Gorąco polecam. Oto link do aplikacji, za pomocą której można śledzić na bierząco wiadomości wysyłane przez fanów zespołu: http://access.nin.com/&lt;br /&gt;Wykorzystują plugin Google Earth do przeglądarki internetowej, żeby pokazać, skąd pochodzi wiadomość i do różnych innych rzeczy.&lt;br /&gt;To link do strony domowej zespołu: http://www.nin.com/&lt;br /&gt;Rozdają swoją muzykę za darmo! Ściągnąłem w formacie .flac, odtwarzam Winampem i jestem bardzo zadowolony z jakości.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-4385006230074607067?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/4385006230074607067/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/06/migawka-moich-zainteresowan.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4385006230074607067'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4385006230074607067'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/06/migawka-moich-zainteresowan.html' title='migawka moich zainteresowań'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1526830258375808355</id><published>2009-06-14T10:14:00.001-07:00</published><updated>2009-06-14T13:46:11.508-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='testowanie'/><category scheme='http://www.blogger.com/atom/ns#' term='PKgui'/><title type='text'>Bootstrapping automatycznego testowania GUI</title><content type='html'>Odpoczywam sobie właśnie w Polsce po sesji i myślę o tym, jak można by zabrać się za napisanie zestawu automatycznych testów do mojego systemu GUI. Chodzi konkretnie o to, żeby kod widżetów w trybie debug mógł sprawdzić, czy nadal jest rysowane to, co trzeba. Takie sprawdzanie byłoby bardzo przydatne, a wręcz niezbędne zwłaszcza wtedy, gdy zmieniane są szczegóły implementacji niskopoziomowych komponentów. Wcześniej, gdy struktura GUI ulegała dużym zmianom, robienie testów wymagałoby ciągłego ich zmieniania. Teraz problem nieistnienia zestawów testów daje się we znaki, a zmiany strukturalne GUI nie są znaczące. &lt;br /&gt;&lt;br /&gt;    Mimo to pisanie ręcznie testów sprawdzających dokładny wygląd GUI nie wydaje się najlepszym pomysłem. Jest to ogromny wysiłek, który mógłby być przeznaczony na coś dużo bardziej produktywnego. Ponadto koszt utrzymania takiego kodu jest ogromny przy najdrobniejszych zmianach wprowadzonych do podstawowych komponentów.&lt;br /&gt;&lt;br /&gt;    Dużo lepszym wyjściem jest pisanie testów sprawdzających po kilka najbardziej narażonych na niezgodności punktów - rogów, czubków itd. To jest do przyjęcia, jeśli chodzi o ilość potrzebnego wysiłku, jednak niedokładność jest oczywista. Taki kod nie zawsze wykryje, że coś się zmieniło, a o to przecież chodzi w automatycznym testowaniu.&lt;br /&gt;&lt;br /&gt;    Niezależnie od tego, co obejmują napisane testy, są one narażone na błędy w samych testach. Są możliwe do wykrycia i naprawienia, ale jednak dokładają roboty.&lt;br /&gt;&lt;br /&gt;    Wpadłem więc na pomysł, aby napisać te wyrywkowe testy, uruchomić je, sprawdzić wzrokowo, czy rysuje się to, co trzeba i zapisać obrazki z wizerunkami widżetów do plików. &lt;br /&gt;&lt;br /&gt;    Później automatyczny kod testujący mógłby sprawdzać zgodność tego, co się wyrysuje (za pomocą króciutkiego kodu) z tymi obrazkami. W ten sposób, praktycznie nie pisząc kodu do poszczególnych przypadków mam sprawdzanie dokładności rysowania GUI co do piksela, sprawdzanie zmian i automatyczne generowanie testów. Tak, mam automatyczne generowanie testów, bo po każdej poprawce będę mógł wywołać funkcję 'generate_tests', która utworzy mi obrazki ze wszystkimi widżetami. Nie będę musiał zmieniać setek linii kodu, najwyżej kilkanaście, ale tylko wtedy, gdy poprawka będzie usuwała błąd ujęty w zestawie napisanych testów. Ponadto testy obrazkowe są niewrażliwe na błędy w kodzie testującym, zamiast kodu testującego jest bowiem obrazek, skontrolowany wzrokowo wcześniej, podczas tworzenia widżeta (lub późniejszego naprawiania usterki).&lt;br /&gt;&lt;br /&gt;    Przedstawione rozwiązanie kusi swoją prostotą ale trzeba rozważyć jeszcze kilka rzeczy. Najważniejsze: ogólność. Dla wielu trybów rysowania może być wiele obrazków, które muszą zostać sprawdzone, żeby było pewne, że naprawdę wszystko jest tak, jak trzeba. Jako tryb rysowania można podać rysowanie z wygładzaniem krawędzi lub bez. To stawia pod znakiem zapytania całą metodę, ponieważ rozmiar tych obrazków na dysku może być potężny. Po przyjęciu stosowania odpowiednich, prostych tekstur i kompresowania do formatu PNG będzie znacznie mniejszy, jednak nadal będzie zależny od iloczynu wszystkich sposobów rysowania dla różnych trybów. Rozwiązaniem mogłoby być tworzenie obrazków tylko dla niektórych trybów przy cichym założeniu, że dla wszystkich innych możliwości wszystko będzie w porządku bo są już przetestowane we własnym podstawowym zestawie testów. Można też wybierać różne konfiguracje dla różnych widżetów. &lt;br /&gt;&lt;br /&gt;    Inny problem: Można zapytać, czy warto utrzymywać zestaw ręcznie napisanych testów dla danego komponentu po upewnieniu się, że rysuje się co do piksela. Napisane testy przechowują wiedzę o tym, co zostało przetestowane dokładnie, a co tylko wizualnie. Co ważniejsze są też kodem, który można łatwo przerobić i wykorzystać do przetestowania po poprawkach konkretnych wartości na rysunku komponentu. Testowanie po zmianach jest niezbędne, więc wydaje się oczywiste, że taki kod powinien być zachowany. Utrzymanie go nastręcza jednak dodatkowego wysiłku. Można go zachować i nie uruchamiać, żeby nie robić sobie kłopotów, jednak wtedy nie będzie gwarancji, że działa tak, jak należy. Wobec takiego stanu rzeczy najlepsze wydaje się zachowanie go i uruchamianie na żądanie wtedy, kiedy trzeba upewnić się, że nadal działa. To rozwiązanie problemu nadal nie jest jednak idealne, bo przy każdej zmianie będzie tworzyć pokusę, żeby nie działający kod testujący po prostu zignorować i wyrzucić, a test oprzeć na sprawdzaniu obrazka.&lt;br /&gt;&lt;br /&gt;    Jeszcze jedno pytanie wymaga odpowiedzi: Czy traktować obrazki jako testy poprawności, czy tylko jako testy zmian w wyświetlaniu, a do testowania poprawności utrzymywać testy napisane ręcznie. Sugestie mile widziane.&lt;br /&gt;&lt;br /&gt;    W tym poście trzeba jeszcze wyjaśnić skąd "bootstrapping" w tytule. Wikipedia wyjaśnia, co oznacza to słowo, a ja tylko dodam, że tutaj zostało użyte przez analogię do bootstrappingu kompilatorów. Tak, jak kompilator podzbioru reguł języka X zostaje użyty do napisania kompilatora języka X, tak częściowo przetestowane GUI Y zostaje użyte do wytworzenia pełnych testów do GUI Y.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1526830258375808355?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1526830258375808355/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/06/bootstrapping-automatycznego-testowania.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1526830258375808355'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1526830258375808355'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/06/bootstrapping-automatycznego-testowania.html' title='Bootstrapping automatycznego testowania GUI'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1243209867763091536</id><published>2009-05-20T09:01:00.001-07:00</published><updated>2009-06-01T14:41:56.639-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><category scheme='http://www.blogger.com/atom/ns#' term='JoeMonster'/><category scheme='http://www.blogger.com/atom/ns#' term='PDP'/><category scheme='http://www.blogger.com/atom/ns#' term='warstwy'/><category scheme='http://www.blogger.com/atom/ns#' term='egzamin'/><category scheme='http://www.blogger.com/atom/ns#' term='PKgui'/><title type='text'>Dziś</title><content type='html'>Dostarczyłem wczoraj tekst zdefiniowany w poście "Personal Development Planning". Piszę to, żeby ewentualny czytelnik nie doszukiwał się informacji na ten temat.&lt;br /&gt;&lt;br /&gt;Pracuję dziś trochę nad PKgui (wbudowuję wsparcie dla różnych celów rysowania do komponentów coraz wyżej w hierarchii), ale głównie uczę się algorytmów i struktur danych na egzamin. Ciekawe to... &lt;br /&gt;&lt;br /&gt;Muszę pomyśleć nad taką strukturą GUI, żeby warstwy nie używały komponentów z warstw najniższych. Wtedy będzie można wprowadzać do GUI dużo więcej zmian na różnych poziomach. Nie jest to jednak takie proste... Jakieś sugestie?&lt;br /&gt;&lt;br /&gt;Mój komentarz na JoeMonsterze dostał wczoraj 9 "OK".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1243209867763091536?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1243209867763091536/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/05/dzis.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1243209867763091536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1243209867763091536'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/05/dzis.html' title='Dziś'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-6059688186998125047</id><published>2009-05-18T04:53:00.000-07:00</published><updated>2009-05-18T05:00:08.695-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='język angielski'/><category scheme='http://www.blogger.com/atom/ns#' term='rozrywka'/><category scheme='http://www.blogger.com/atom/ns#' term='humor'/><title type='text'>Ale ja nie chcę...</title><content type='html'>http://www.engrish.com/2009/03/do-must-let/&lt;br /&gt;&lt;br /&gt;Ja nie chcę być w małej zabawce, w której nie można dotykać ognia, gdyż nie zadziałałby wtedy ultrafioletowy kaloryfer, tym bardziej że muszę pozwolić dziecku bawić się pod dorosłym. &lt;br /&gt;&lt;br /&gt;Polecam tę stronę wszystkim, którzy uważają, że ich angielski jest słaby.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-6059688186998125047?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/6059688186998125047/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/05/ale-ja-nie-chce.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6059688186998125047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6059688186998125047'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/05/ale-ja-nie-chce.html' title='Ale ja nie chcę...'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-853026836504950300</id><published>2009-05-16T11:43:00.000-07:00</published><updated>2009-06-01T14:41:16.687-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Learning Journal'/><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><category scheme='http://www.blogger.com/atom/ns#' term='uczelnia'/><category scheme='http://www.blogger.com/atom/ns#' term='PDP'/><category scheme='http://www.blogger.com/atom/ns#' term='InVectorGadget'/><category scheme='http://www.blogger.com/atom/ns#' term='CMS'/><title type='text'>Ten nasz projekt grupowy</title><content type='html'>Ten wpis powstaje z myślą o zadaniu na Career Management Skills, wartym 30% końcowej oceny, a mianowicie "Learning Journal". Wpis zawiera opis projektu grupowego, który mieliśmy w tym roku. Jest wiele rzeczy, które są warte przytoczenia, najważniejsze jednak aby praca była w kolejności chronologicznej i zawierała wgląd w to, co się działo w głowach i co można by było zrobić inaczej. Opiszę kilka dni lub wydarzeń w drugim półroczu projektu na podstawie emaili, które wciąż jeszcze rezydują w mojej skrzynce pocztowej. Wprowadzenia do projektu należy szukać kilka postów wcześniej pod nazwą Personal Development Planning.&lt;br /&gt;    1 Maj 2009 Oddanie Raportów.&lt;br /&gt;    Od kilku dni pisaliśmy raporty. Każdy miał do napisania 9 stron raportu grupowego i 5 stron indywidualnego, razem około 5000 słów i kilka obrazków.    Przygotowania do wydarzeń dzisiejszego dnia polegały na wysłaniu do siebie kilku maili w sprawach organizacyjnych, które jasno stwierdzały, co powinno być gotowe na wczoraj, a co robimy dziś. Ja byłem odpowiedzialny za tabelkę z rozkładem zadań składających się na ten projekt i przykładowy kod z wyjaśnieniem. Dzisiejszy dzień to była istna gonitwa. Okazało się, że Mat i Mark nie mają jeszcze dokończonych swoich części raportu. Sam dokończyłem swoje rano, ale przynajmniej miałem je gotowe zanim przyszedłem. Dodatkowo Mark próbował jeszcze zmieniać coś w kodzie, przy czym wytknąłem mu, że nie jest to najlepszy moment, ale widocznie wierzył w siebie, bo pisał dalej. W czasie gdy pisali, miałem czas napisać jeszcze manual do programu. Adrian napisał wcześniej manual do strony internetowej. Postawa drużyny uniemożliwiła zrobienie przyzwoitego raportu, gdyż całość została złożona na ostatnią chwilę, więc nie została przeczytana. Gdybym miał czas to zrobić, nie podpisałbym się pod tym tekstem, nie wprowadzając kilku istotnych poprawek. Kilka sztandarowych błędów w raporcie:&lt;br /&gt;- Adrian w swoim raporcie indywidualnym napisał "meats" zamiast "mates".&lt;br /&gt;- W mojej sekcji "breakdown of tasks" obliczona liczba godzin przeznaczonych na projekt nie zgadza się z sumą liczb godzin przeznaczonych przez poszczególnych członków drużyny.&lt;br /&gt;- Sekcja "group marking" zawiera tylko i wyłącznie procent wkładu w projekt przez każdą osobę, bez żadnego komentarza i zajmuje całą stronę, której reszta jest pusta.&lt;br /&gt;- Adrian zrobił mnóstwo błędów gramatycznych, które nie zostały poprawione. Mimo to, że Matthew zadeklarował, że przeczyta i poprawi teksty nieanglików, nie zrobił tego, prawdopodobnie z braku czasu.&lt;br /&gt;- Ogólny chaos, brak tytułów sekcji, numeracji, niejasne, powtarzające się teksty.&lt;br /&gt;- Zapomnieliśmy dodać do raportu manual, który napisałem.&lt;br /&gt;Ogólnie rzecz biorąc, schrzaniliśmy ten raport. Jestem zadowolony ze swojego raportu indywidualnego, ale większość oceny dostanę za cały projekt, z czego większość jest przyznawana na podstawie grupowego raportu. Po dostarczeniu raportu poszliśmy na piwo i rozeszliśmy się do domów.&lt;br /&gt;    Wieczorem wysłaliśmy kod źródłowy naszego programu. Oczywiście musiałem dodać kilka rzeczy potrzebnych do uruchomienia aplikacji, bo Mark, który zadeklarował, że to zrobi nie pomyślał o tym. Wysłaliśmy również kod php naszej strony. Nie wiem, czy beze mnie grupa wysłałaby to, ale lobbowałem za tym i przekonałem Adriana, żeby wysłał także oświadczenie, że tego kodu (php) nie da się uruchomić bez wielkiego trudu, a strona nie została opublikowana. Ustalaniem takich spraw powinien się zająć menedżer, ale widocznie robił coś innego o tej porze. Ten dzień był niezapomnianym przeżyciem. Nie podoba mi się postawa Mata, który od tygodnia nalegał na skoncentrowanie się na raportach, zamiast na kodzie, a tak naprawdę nic w tej sprawie nie robił, zostawiając wszystko na ostatnią chwilę. Ja też zostawiłem raporty na koniec. Ja zrobiłem tak samo ale miałem swoją część raportu gotową kilka godzin wcześniej i nie ukrywałem swoich intencji.&lt;br /&gt;    7 Maj 2009 Przygotowania do prezentacji.&lt;br /&gt;Nie ukrywam, że nie udało mi się zorganizować dla siebie czasu na to, aby przyjść dziś na uczelnię i przygotować z kolegami jutrzejszą prezentację efektów całego roku pracy nad naszym projektem. Naraziłem w ten sposób projekt na katastrofę, tak samo jak inni, którzy też nie przyszli. Inni też nie byli bez winy. Mark wysłał dziś maila do drużyny z zapytaniem, co robić, kiedy się spotkać. Adrian zadzwonił do mnie wczoraj aby poprosić mnie o przyjście dziś na uczelnię. Odmówiłem gdyż mam do zrobienia bardzo dużą część kompilatora na Language Engineering. Powinienem był zrobić go podczas długiej (miesięcznej) przerwy wielkanocnej, zamiast tworzyć PKgui. Mógłbym kontynuoać swój projekt teraz, gdybym miał gotowy kompilator.&lt;br /&gt;Odpowiedziałem Markowi na maila, poruszając przy okazji kwestię laptopa, na którym będziemy robić prezentację. Nasz menedżer Matthew nie odpowiedział na mojego poprzedniego maila wysłanego dwa dni wcześniej w tej sprawie. (wpisane następnego dnia) Dowiedziałem się, że nasz menedżer przeczytał mojego maila i w ten sposób dowiedział się, że prezentacja nie może być uruchomiona na jego laptopie, gdyż ma Linuxa, a skonfigurowanie na nim bazy danych MySQL nie jest realistyczne, gdyż Adrian, który jest za to odpowiedzialny musiał spędzić dni na tym, żeby postawić ją na Windowsie. Jest to oczywiście błąd menedżera, bo gdyby laptop Adriana popsuł się drugi raz, musielibyśmy załatwić jakiś inny, na co nie ma czasu. Pomimo problemów "proceduralnych" udało nam się umówić na następny dzień na przygotowanie prezentacji. Muszę przyznać, że nie sprawdziłem dzisiaj skrzynki mailowej, przez co też naraziłem się na nieporozumienie, jednak dowiedziałem się o naszym spotkaniu rozmawiając przez telefon z Adrianem.&lt;br /&gt;    8 Maj 2009&lt;br /&gt;Z rana poszedłem na uniwersytet, aby dopracować z kolegami ostatnie szczegóły projektu przed prezentacją. Szkoda, że nie zrobiliśmy tego wcześniej, przed wysłaniem kodu do oceny. Matthew zapewnił mnie że to jest dozwolone i nie mam powodu, żeby mu nie wierzyć, jednak takie dopisywanie czegoś na ostatnią chwilę nie jest mądre, bo może się nie udać to zrobić na czas tak, żeby działało. Sam zrobiłem błąd nie pracując nad projektem w poprzednich dniach, jednak wynikało to z innych prac do zrobienia. Nie przewidziałem podczas przerwy świątecznej, jaka gonitwa czeka mnie po niej... A właściwie to przewidziałem, jednak nie mogłem się zmobilizować, aby ją zacząć wcześniej. Odpoczywałem w Polsce i nic mi się nie chciało, spędziłem tylko około 20 godzin nad naszym projektem, co i tak uważałem za sukces. Nie powinniśmy byli olać kilka pierwszych tygodni na początku roku. Dziś pracowaliśmy od około 10tej do naszej prezentacji o 15.50, aby zrobić to, co chcieliśmy zrobić i przećwiczyć prezentację. Zrobiliśmy co w naszej mocy, aby zwrócić uwagę na to, co działa i z czego jesteśmy dumni i odwrócić uwagę od błędów, które dawały się we znaki podczas używania programu. Nie dołączył do nas rano Mark, za co jestem mu raczej wdzięczny, gdyż gdyby on zaczął wprowadzać zmiany do kodu dzisiaj, popsułby program, gdyż jego kod jest bardzo skomplikowany. Nie mam mu tego za złe, po prostu taka jest specyfika modułów, które stworzył. Mam mu natomiast troszeczkę za złe, że nie ubrał się wystarczająco oficjalnie na prezentację. Prezentacja przebiegła ogólnie bardzo dobrze. Matthew wykonał świetną robotę, wprowadzając oceniających do świata grafiki wektorowej i zakreślając perspektywy biznesowe naszego projektu. Największe pretensje mam do siebie, gdyż demonstracja programu w moim wykonaniu była nieco pozbawiona płynności, choć z drugiej strony cieszę się, że udało mi się podkreślić dobre cechy programu i uniknąć pokazywania błędów, co nie było łatwe. Nieco mniejsze pretensje mam do naszego menedżera, który mówił rzeczy, które nie były całkowicie zgodne z rzeczywistością na temat jednej rzeczy, którą ja zrobiłem (RoundPopupMenu). Nie udawał, po prostu pomylił się. Mam pretensje, ponieważ gdyby oceniający (3 wykładowców) zadali pewnie uszczegóławiające pytania na ten temat, okazałoby się, że prezentujący mija się z prawdą, co popsułoby ogólne wrażenie.&lt;br /&gt;&lt;br /&gt;    Ostatecznie moja rola w projekcie ukształtowała się jako rola programisty, ale też trochę menedżera. Nie chcę kreować się na jakiegoś bohatera, ale było wiele rzeczy, które powinien zrobić Matthew a zrobiłem ja. Można powiedzieć, że trochę próbowałem narzucić zaangażowanie innym członkom drużyny, jak również zorganizować lepiej nasze wysiłki. Niestety nie przyniosło to moim zdaniem wystarczających rezultatów.&lt;br /&gt;    Myślę, że nauczyłem się, jak NIE być menedżerem projektu (ja nim nie byłem, tak dla ścisłości). Bycie menedżerem wymaga bowiem przyjęcia na siebie dużo odpowiedzialności za powodzenie całości. Mówiąc bardziej szczegółowo, menedżer musi dbać o to, żeby członkowie drużyny właściwie się komunikowali, kiedy trzeba zrobić coś, co jest wymagane żeby projekt się udał. Kiedy na przykład kawałek kodu źródłowego, który musi mieć wysoką jakość, bo będzie potrzebny w przyszłości jest nie najlepszy, menedżer powinien interweniować, niezależnie od obaw o zniechęcenie do siebie ludzi. Kiedy moduł ma mieć taką budowę, żeby można było bezpiecznie wywoływać dowolne jego publiczne funkcje, a nie ma, menedżer powinien zainterweniować. Powinien sprawdzić, co zniechęca programistę do pisania właściwie. Problemem mogą być na przykład wymagania innego programisty, który używa tego modułu. Wtedy menedżer powinien porozmawiać z oboma. Nasz menedżer nie wykonywał tych zadań należycie. Największym jego problemem było to, że nie wymuszał stosowania odpowiednich technik inżynierii oprogramowania, na przykład automatycznych testów, zapisywania błędów, czy stosowania komentarzy dokumentujących. Tego nie da się nadrobić pod koniec projektu, więc powinien był wykazać inicjatywę na początku. Nie zrobił tego. Każdy pisał, jak chciał i efekt był oczywisty. Muszę dodać, że mój kod był pod tym względem nieco lepszy od innych ze względu na nieco większą staranność w pisaniu komentarzy.&lt;br /&gt;    Nauczyłem się też, jak współpracować w drużynie. Poświęcę tej sekcji trochę czasu, gdyż Tracy (nasz wykładowca) podkreślała istotność takich rzeczy. Nauczyłem się nieufności do ludzi, gdyż miało być nas pięciu ale piąty, Guy, mimo składanych deklaracji nie włączył się w proces implementacji projektu. Spowodowało to niezdolność dokończenia produktu mimo najszczerszych chęci. Projekt był ambitny dla czterech, nie mówiąc już o pięciu. Nauczyłem się również komunikacji. Wiem już kiedy wykazać inicjatywę, pisząc maila, bo upewniłem się, że nie warto czekać aż inni wpadną na ten pomysł. Na początku projektu mogłem wydawać się nieco nieuprzejmy. Teraz nie wydaję się nieuprzejmy, tylko lekko wkurzający, ale trzymający rękę na pulsie. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-853026836504950300?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/853026836504950300/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/05/ten-nasz-projekt-grupowy.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/853026836504950300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/853026836504950300'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/05/ten-nasz-projekt-grupowy.html' title='Ten nasz projekt grupowy'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-4859134040455571480</id><published>2009-05-16T08:27:00.000-07:00</published><updated>2009-07-13T14:43:56.291-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><category scheme='http://www.blogger.com/atom/ns#' term='uczelnia'/><category scheme='http://www.blogger.com/atom/ns#' term='PDP'/><category scheme='http://www.blogger.com/atom/ns#' term='Loki'/><category scheme='http://www.blogger.com/atom/ns#' term='CMS'/><category scheme='http://www.blogger.com/atom/ns#' term='C++'/><category scheme='http://www.blogger.com/atom/ns#' term='PKgui'/><title type='text'>Refleksje o PKgui</title><content type='html'>Ten post jest długi. Zawiera wyrywkową historie mojego projektu, który tworzę po godzinach od blisko 3 lat. Piszę ten post z myślą o pracy pisemnej, którą muszę oddać. Projekt został rozpoczęty gdy nauczyłem się C++, zafascynowałem się programowaniem w nim i, nie mając pojęcia o czasie jaki zajmuje napisanie czegoś dużego, stwierdziłem, że napiszę moduł do mojego programu, który zajmie się interfejsem użytkownika. Inną, jakże istotną przyczyną utworzenia własnej biblioteki była chęć nauczenia się przyzwoitego programowania (co osiągnąłem) i fatalne problemy z konfiguracją gotowych bibliotek GUI. Później dowiedziałem się, dlaczego programiści C++ przechodzą piekiełko konfiguracji takich bibliotek zamiast stworzyć samemu komponenty potrzebne do programu, nawet jeśli to tylko mały podzbiór komponentów dostępnych w wybranej bibliotece - po prostu tworzenie i tak zajmuje dużo więcej czasu.&lt;br /&gt;    Cała ta biblioteka przechodziła wiele przemian w samym projekcie, nie mówiąc już o implementacji szczegółów. Początkowo szacowany czas zwiększał się z jednego miesiąca, poprzez 3, 6 i 12 miesięcy aż doszedłem do wniosku, że, wzorując się na niektórych deweloperach, skończę jak będzie gotowe. Zabrakło na początku jednoznacznej specyfikacji tego, co będzie, a czego nie będzie w projekcie. Ciągle wydawało mi się, że jak dołożę jeszcze jedną rzecz, to będzie lepiej, a ponieważ obecny projekt nie ułatwia takiego rozszerzenia, powinno się go nieco przeprojektować, bo to wstyd pokazywać taki kod komukolwiek. W dużej części była to prawda, ponieważ dopiero uczyłem się programować i projektować i duże części kodu rzeczywiście były nieczytelne, skopiowane, nieudokumentowane i zbyt skomplikowane. Często powodem było niewłaściwe użycie technik, takich jak szablony, przeładowanie funkcji czy polimorfizm. Było kilka rzeczy, z których byłem w pewnym sensie dumny, a które później okazały się beznadziejne w użyciu. &lt;br /&gt;    Sztandarowym przykładem czegoś, nad czym zmarnowałem dużo czasu jest właściwość biblioteki, dzięki której można wywoływać tę samą funkcję dla wielu widżetów na raz (widżet - element interfejsu, np napis albo przycisk). To umożliwiałoby np. zmianę stylu interfejsu. Próbowałem różnych rozwiązań. Idealne rozwiązanie byłoby nieintruzywne, tzn unikałoby zmieniania czegokolwiek w widżetach kiedy trzeba wywołać dla wielu z nich funkcję, która nie była jeszcze tak wywoływana. Sprawę komplikuje jednak fakt, że aby wywołać funkcję dla hierarchii widżetów (każdy widżet ma dzieci, one mają swoje dzieci itd), trzeba znać dzieci widżeta, czyli pobrać od niego dane. Idealne rozwiązanie byłoby też ogólne, tzn takie, żeby nie trzeba było definiować żadnych specjalnych komponentów dla każdej funkcji, którą chcemy wywołać. Ostatecznie rozwiązanie używa zewnętrznej biblioteki zwanej Loki. Ostatecznie ten mechanizm nie jest tak często używany, chyba że użytkownik programu zapragnie zmienić styl (skórkę) interfejsu. Na początkowe, częściowo intruzywne rozwiązania zmarnowałem dużo czasu, zanim zdałem sobie sprawę do czego tak naprawdę jest a do czego nie jest przewidziany język C++, którego używam. Pewnych rzeczy po prostu nie da się łatwo zrobić i dlatego tak błądziłem. Tak, żeby dodać smaczku do tej historii dodam, że obecnie rozważam całkowite porzucenie tego rozwiązania, bo ono używa biblioteki Loki, która ma różne niepożądane efekty uboczne, głównie zwiększenie czasu kompilacji i rozmiaru wynikowego kodu z powodu polegania na szablonach.&lt;br /&gt;    Krótkie omówienie tego, czego się nauczyłem dzięki temu projektowi.&lt;br /&gt;Nauczyłem się technik inżynierii oprogramowania, hamowania swoich ambicji i planowania zadań. Nauczyłem się, ile jestem w stanie stworzyć w normalnych okolicznościach i jak wygląda praca po godzinach. Nauczyłem się, ile problemów mogą stworzyć niespodziewane szczegóły techniczne i jak ważne jest, żeby nie zapomnieć o tym, co się zrobiło. Najlepiej dokumentować wszystko, co się tworzy. Mogą to być komentarze w kodzie, ale nie stracą one na wartości jeżeli znajdą się na przykład na blogu. Na podstawie rozwiązań użytych w PKgui można by napisać co najmniej kilka ciekawych artykułów i żałuję, że ich nie napisałem. Stworzenie tego projektu wymagało też wielokrotnego zwracania się o pomoc na forum, dzięki czemu nauczyłem się skutecznie pytać, co przydaje mi się nie tylko na forum.&lt;br /&gt;    Mógłbym spędzić czas nad czymś bardziej wartościowym, np. nad wymyślaniem algorytmów ewolucyjnych, nauką na uniwersytecie w celu otrzymania lepszych ocen, czy projektem prowadzonym z kolegami, który dałby dużo więcej, bo mielibyśmy gotowy produkt, który można by było np. sprzedać.&lt;br /&gt;Czy zmarnowałem czas, pisząc to GUI? Zupełnie naturalną reakcją byłoby powiedzenie, że nie żałuję bo się dużo nauczyłem, bla bla terefere. Jednak nie mam w zwyczaju tak się nad sobą rozczulać, więc nie będę, tym bardziej, że ten projekt nie był żadnym traumatycznym przeżyciem, o którym można by zrobić stereotypowy rozczulający materiał dla na staczającym się ostatnio TVN24. Żałuję, że nie wykorzystałem tego czasu inaczej, jestem natomiast zadowolony z ilości i jakości kodu, którym teraz dysponuję i nie mogę się doczekać dokończenia projektu, pokazania kodu światu, przyjęcia komentarzy, jakiekolwiek one nie będą i rozpoczęcia pracy nad czymś innym, co będzie wydawać się mniej trywialne i da bardziej "namacalne" efekty działania. Ciekawą ideę opisałem w swoim raporcie na temat rozwoju kariery, który oddałem na Career Management Skills, jednak nie będę jej tu opisywał, bo ten post i tak już jest długi. Ten paragraf uzasadnia wniosek z całego projektu: Nie angażować się w coś, co nie jest zupełnie ulubionym zajęciem, czymś, o czym się marzy.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-4859134040455571480?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/4859134040455571480/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/05/refleksje-o-pkgui.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4859134040455571480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4859134040455571480'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/05/refleksje-o-pkgui.html' title='Refleksje o PKgui'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1416108501342590049</id><published>2009-05-15T10:29:00.001-07:00</published><updated>2009-05-15T11:29:25.083-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='PKgui'/><title type='text'>OpenGL w moim GUI</title><content type='html'>Cześć (Oddaję Tobie), czytelniku,&lt;br /&gt;&lt;br /&gt;Pierwszy paragraf tak dla wyjaśnienia:&lt;br /&gt;    Jakieś dwa miesiące temu postanowiłem wprowadzić przyspieszenie sprzętowe i kompatybilność z OpenGL do mojej biblioteki GUI. Zrobiłem już Wysokopoziomowy interfejs rysujący i blitujący, który będzie wykorzystany w reszcie systemu GUI. Ten zestaw klas i funkcji deleguje żądania rysowania do kontekstu SDL (który jest tak naprawdę opakowaniem jakiegoś kontekstu odpowiedniego dla platformy, np. WinGDI) lub do OpenGL. Właściwymi miejscami do implementacji rysowania po ekranie bezpośrednio przez OpenGL lub SDL są klasy dziedziczące po PKgraphics_provider. PKgraphical_data zaś to klasa, która przechowuje bieżący obiekt PKgraphics_provider i umożliwia używanie zasobów, które muszą być wytworzone przy pomocy obiektu PKgraphics_provider, czyli zestawów tekstur klasy PKtexture_unit.&lt;br /&gt;Mam już działające obiekty PKtexture_unit z wieloma teksturami (dla OpenGL) lub powierzchniami (dla SDL) wewnątrz. Powierzchnie graficzne, z których zostały stworzone tekstury są przywiązane do tych obiektów PKtexture_unit.&lt;br /&gt;    A teraz do rzeczy. Otóż z wprowadzenia do GUI tych machinacji wyniknął problem, mianowicie współdzielenie powierzchni (graficznych) przez różne obiekty w GUI nie wystarczy, bo są jeszcze obiekty PKtexture_unit, które nie są współdzielone (do samego współdzielenia obiektów używam inteligentnego wskaźnika). Wynika z tego fakt, że jeśli będzie 10 widżetów (np. przycisków) z tą samą teksturą, to w karcie graficznej będzie 10 kopii tej tekstury. To jest duży problem, zwłaszcza że GUI bywają bogate w widżety. Właśnie wymyśliłem rozwiązanie: flaga "immutable" w obiektach PKsurface, przechowujących powierzchnie graficzne. Jaki to ma związek? Rozumowanie jest proste: jeśli mam pewność, że powierzchnia nie będzie zmieniana, to mogę tworzyć z niej wiele obiektów PKtexture_unit i wszystkie będą takie same. A jeżeli wszystkie byłyby takie same, to można zamiast tego zrobić jeden i go współdzielić. To rozwiązanie jest dla mnie bardzo atrakcyjne, bo kod który teraz mam umożliwia bardzo łatwe zablokowanie wszelkich zmian w danej powierzchni, jeżeli jest w niej taka flaga. Wprowadza to jednak poważny problem: powierzchnia będzie niezmienna :) W takim razie powierzchnia jest właściwie "wymieniana" na teksturę. Można sobie wyobrazić funkcjonalność, która "oddaje" nam powierzchnię, gdy tekstura jest zwalniana. Idealne rozwiązanie polegałoby na wprowadzaniu wszystkich zmian powierzchni w teksturze, ale to oznaczałoby zmienianie dużej ilości kodu.&lt;br /&gt;Muszę przyznać, ciekawi mnie, jak rozwiązano ten problem w innych GUI. &lt;br /&gt;    Po co piszę to na blogu? Po to, żeby uświadomić sobie, co tak naprawdę robię. Po krótkim przemyśleniu sprawy doszedłem do wniosku, że flaga "immutable" powinna być tam niezależnie od tego, czy obiekty PKtexture_unit są współdzielone, więc... kod, który teraz mam jest błędny. Kolejny wniosek to taki, że jeśli lepiej by było w ogóle nie "zaprzyjaźniać" powierzchni z teksturami. Istnienie powierzchni ma o tyle sens, że do niej można wczytać obrazek z pliku, albo można na niej coś łatwo narysować. Po przekształceniu w teksturę można ją natomiast wyrzucić. Po co zaśmiecać pamięć. Utrzymywanie powierzchni zaprzyjaźnionej z teksturą chyba ma sens tylko jeśli implementacja "odbija" na teksturze wszelkie zmiany popełnione na powierzchni. Wtedy jednak bardziej stosowna byłaby tekstura schowana w powierzchni, a nie odwrotnie.&lt;br /&gt;Jeszcze inną sprawą jest to, że powierzchnia jest potrzebna np. do przeskalowania GUI. Sama tekstura nie wystarczy, bo powierzchnia może być np. złożona z wielu małych, co wymusza zupełnie inny algorytm skalowania niż rozciąganie. Skomplikowana sprawa.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1416108501342590049?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1416108501342590049/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/05/opengl-w-moim-gui.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1416108501342590049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1416108501342590049'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/05/opengl-w-moim-gui.html' title='OpenGL w moim GUI'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-7002622271369559212</id><published>2009-04-22T08:00:00.000-07:00</published><updated>2009-04-22T11:33:47.650-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><category scheme='http://www.blogger.com/atom/ns#' term='PDP'/><category scheme='http://www.blogger.com/atom/ns#' term='CMS'/><title type='text'>Personal Development Planning</title><content type='html'>To jest post na temat PDP - Personal Development Planning, czyli Planowania Osobistego Rozwoju. Po co pisać posty na tak niedorzecznie nudne tematy? Wymagają na uczelni. Właściwie to nie wymagają pisania posta na blogu, ale każą napisać "Learning Journal", czyli "dziennik nauki". Co ciekawe, nie ma to być dziennik nauki użytecznej, akademickiej, czy takiej ZZZ, ale nauki o do niedawna kosmicznym tworze, zwanym samoświadomością. Dalej nazywam ja SŚ, nie z sympatii do organizacji o podobnym skrócie, ale z lenistwa do pisania o ludziach i psychologii. Co prawda pisać o SŚ można tylko w kontekście życia, w którym ją się stosuje, więc wymagają, żeby opisywać dowolne inne wydarzenia, ale tak naprawdę skupić się na skutkach dla rozwoju SŚ. Trochę już zajmuję się tym tematem i mam dla czytelnika dobrą radę: Nie czytaj tego! zajmij się czymś pożytecznym, a nie odkładaniem wszystkiego na później.&lt;br /&gt;Mam na to zadanie od teraz około miesiąca, ale muszę zacząć najpóźniej teraz, bo ten utwór ma udokumentować postępy w rozwijaniu SŚ, które powinny być potwierdzone jakimiś dobrze opisanymi przykładami.&lt;br /&gt;&lt;br /&gt;Pod wpływem niejasnych, niepraktycznych i tatusiowatych materiałów na stronach internetowych uniwersytetu postanowiłem ustalić sobie jasno i napisać zwięźle to, czego tam nie dopisali: czym jest w praktyce samoświadomość. Inaczej mówiąc, co konkretnie może zostać poprawione przez stosowanie PDP. Myślę, że jest kilka aspektów tego zjawiska, które muszą być poruszone w moim dzienniku:&lt;br /&gt;- ogólna odpowiedzialność, czyli zdolność podejmowania wysiłku wtedy, kiedy to konieczne, bez pozytywnej motywacji;&lt;br /&gt;- umiejętności organizacyjne: ustalanie czasu, kolejności prac, proporcji czasu na różne etapy zadania, dzielenie się zadaniem z innymi itp;&lt;br /&gt;- zdolność efektywnej pracy w grupie, czyli wyniesienie się poza pierwotne instynkty i natychmiastowe emocje i obmyślanie nie tylko CO, ale też JAK to powiedzieć innym, żeby dobrze wykonać robotę;&lt;br /&gt;(jestem pewien, że działalność głowy naszego państwa znacznie podniosła świadomość Polaków na ten temat);&lt;br /&gt;- wiedza o swoich możliwościach, kwalifikacjach, zdrowiu, wpływie życia prywatnego na zawodowe itp;&lt;br /&gt;&lt;br /&gt;Wymienię projekty, o których mam zamiar pisać w tym sosie i powody umieszczenia ich w dzienniku.&lt;br /&gt;&lt;br /&gt;1. Projekt grupowy InVectorGadget, tworzony z kolegami od kilku miesięcy (teoretycznie od października) w ramach jednego z przedmiotów na uniwerku.&lt;br /&gt;Powody:&lt;br /&gt;- mój pierwszy, naprawdę grupowy projekt - mogę skomentować wzrost umiejętności pracy w grupie;&lt;br /&gt;- mój pierwszy duży projekt nie tworzony z pobudek osobistych - potrzebne umiejętności motywacyjne;&lt;br /&gt;- potrzebna umiejętność planowania długoterminowego;&lt;br /&gt;&lt;br /&gt;2. Projekt osobisty PKGUI, tworzony od 2,5 roku, prawie dojrzały (chyba wrzucę go na SourceForge, może ktoś się zainteresuję, zanim będę miał wersję 1.0, choć wątpię).&lt;br /&gt;- wiele się nauczyłem na temat organizacji czasu'&lt;br /&gt;- projekt dał mi umiejętności programistyczne, poznałem więc znaczenie angażowania się w takie rzeczy dla własnego rozwoju;&lt;br /&gt;- rezultat jest pod różnymi względami lepszy, niż to, co widzę w innych GUI, zatem zaraziłem się pasją do niego, mimo to, że nie mam tak naprawdę czasu na jego robienie; nauczyłem się, kiedy podejmować tego typu wyzwania, kiedy nie warto, a kiedy nie można; &lt;br /&gt;- pomógł mi zdecydować, co będę robił w życiu; miał różny wpływ na moją motywację, umysłowe zmęczenie, dał więc wiedzę potrzebną do szacowania swoich (ale też cudzych) możliwości;&lt;br /&gt;&lt;br /&gt;Smutne, że muszę spędzać czas na opisywaniu wpływu projektu na mnie zamiast zająć się nim samym i opublikować go. Dwu i pół letni PKGUI zawiera dużo ponad 2 MB kodu, dla porównania InVectorGadget, robiony 8 miesięcy przez 4 osoby ma ok 450 KB. Daje to pojęcie o tym, jakie znaczenie ma dla mnie PKGUI i jak daleko jestem od porzucenia tej idei.&lt;br /&gt;&lt;br /&gt;Zakończę na dzisiaj pewnym spostrzeżeniem na temat przedmiotu, na którym wymagają takich rzeczy. Otóż, na Career Management Skills wymagają udowodnienia swoich postępów w kształtowaniu SŚ. Jest to bardzo prywatny temat, temat o którym nie porozmawiałbym pewnie z członkiem rodziny, bo zacząłby zadawać pytania, na które wolałbym nie odpowiadać. Aby udowodnić, że wyciągam wnioski muszę zaznaczyć, co poszło nie tak, komu mam to za złe, dlaczego, czemu się przejmuję niektórymi rzeczami, a innymi nie. Dyrektorka tego przedmiotu nie jest natomiast psycholożką, tylko doradcą do spraw kariery, nie sądzę, żeby obowiązywała ją jakaś oficjalna tajemnica lekarska. Czuję się z tym niekomfortowo. Stwierdziłem, że skoro i tak to mówię, komuś, komu nie chcę, to można by całkowicie ujawnić moje poglądy na tym blogu. Dodatkowo piszę po polsku, więc żadna osoba, którą te informacje będą dotyczyć nie obrazi się na mnie :) Jeśli natomiast któraś z nich czegoś się dowie, to po wakacjach, więc będziemy mieli czas na wyjaśnienie sobie wszystkiego.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-7002622271369559212?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/7002622271369559212/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/04/personal-development-planning.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7002622271369559212'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7002622271369559212'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/04/personal-development-planning.html' title='Personal Development Planning'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-6099815692754999189</id><published>2009-04-21T05:55:00.000-07:00</published><updated>2009-06-01T14:52:02.233-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><title type='text'>Sen</title><content type='html'>Tematem tego wpisu będzie mój wczorajszy sen. Jako że rzadko pamiętam swoje sny, tym razem jest to dla mnie ciekawe wydarzenie. Wczoraj obudziłem się około 7.00, po 6 godzinach snu przez hałasy w domu i mój umysł nadal przetwarzał urojone obrazy. &lt;br /&gt;&lt;br /&gt;Śniła mi się moja była szkoła podstawowa. Szedłem sobie po ciemnym, podziemnym korytarzu, jak zwykle szybkim krokiem, wokoło wielki harmider. Przyśnił mi się sklepik szkolny w rogu tegoż korytarza, ten sam sprzedawca, te same czerwone półki i ta słodka bułka, której nigdy nie potrafiłem nazwać. Chciałem ją kupić, zapytałem się więc, jak się nazywa. Otrzymałem wyczerpującą odpowiedź, którą sprzedawca wygłosił z uśmiechem na ustach, lecz nie do końca w moim kierunku, a że wokół był duży harmider, znowu nie usłyszałem, jak się nazywa. Następnie wszedłem na ostatnie (drugie lub trzecie) piętro po schodach i spotkałem przechadzającego się na dyżurze wykładowcę z Uniwersytetu w Bristolu. Najlepsze miało jednak dopiero nastąpić. &lt;br /&gt;Trafiłem przez przypadek do jakiejś klasy, częściowo wyludnionej, z kilkoma uczniami czekającymi w kolejce do biurka nauczycielki. Miałem takie poczucie, jakbym był tam przez pomyłkę, z błahego powodu, chcąc się może o coś zapytać. Nauczycielka z wyglądu była stereotypową podstarzałą babą, z ciemnymi włosami i brzydką mordą. Kiedy odszedł ostatni uczeń podszedłem do niej, a ona spojrzała do wielkiej puszki stojącej na stole. Spojrzałem tam również i zobaczyłem, jak w cienkiej warstwie sosu własnego pływają sobie kawałeczki warzyw, głównie kukurydza. Powiedziała oschle:&lt;br /&gt;- Dzień dobry, no wreszcie!&lt;br /&gt;Nie pamiętam, co jej odpowiedziałem, ale byłem zakłopotany, próbując wytłumaczyć, że ja to nie jestem uczniem tej klasy. Odparła mi niskim głosem i obojętnym tonem, pasującym do niej, ale nie do treści wypowiedzi:&lt;br /&gt;- Co pan mi tu mówi, przecież tu jest wyraźnie napisane. - Powiedziała, wskazując palcem trzy ziarnka kukurydzy, unoszące się samotnie prze ciemnym, śliskim brzegu puszki.&lt;br /&gt;Poczułem wstyd. Czułem, że robię się czerwony. Zacząłem panikować, że zapyta mnie o jakiś materiał. Patrzyła na mnie z obrzydzeniem. Zaczęła.&lt;br /&gt;- Proszszsz. Podstawy współczesnej kosmologii.&lt;br /&gt;Przez chwile gapiłem się do góry, próbując coś przyciągnąć do głowy, po chwili zaś spojrzałem na dziennik, który trzymała i zobaczyłem, jak wpisuje "ndst.".&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-6099815692754999189?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/6099815692754999189/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/04/sen.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6099815692754999189'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6099815692754999189'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/04/sen.html' title='Sen'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-6825614526998035179</id><published>2009-04-20T04:17:00.000-07:00</published><updated>2009-04-22T07:43:02.693-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><category scheme='http://www.blogger.com/atom/ns#' term='Swing'/><title type='text'>Paranoiczna Biblioteka Standardowa Java.</title><content type='html'>Nie mam ostatnio czasu na wpisy, choć jak nie ma czasu, to oznacza, że dzieje się najwięcej ciekawych rzeczy. Niestety, takie życie. Ostatnio przeglądam sobie kod źródłowy biblioteki stardardowej Javy i napotykam na różne kwiatki. Już dawno zdałem sobie sprawę, że moja decyzja o stworzeniu własnej biblioteki GUI była pójściem z motyką na słońce, a to, co wyczytuję w dziełach programistów z za oceanu ostatecznie już dobija mnie i rozgniata. Nie dość, że implementacja nie jest okomentowana i nie można tam nic wyczytać, w niemal każdej klasie spotyka się coś w stylu "this is a workaround...", to jeszcze autorzy sami do końca nie zdaje sobie sprawy, po co piszą to, co piszą.&lt;br /&gt;Przeglądam sobie klasę ToolTipManager i w metodzie showTipWindow() widzę takie coś:&lt;br /&gt;&lt;br /&gt;            // Just to be paranoid&lt;br /&gt;            hideTipWindow();&lt;br /&gt;&lt;br /&gt;Z tej okazji wszystkim programistom GUI życzę z całego serca pięknych partnerek, dbających paranoicznie o ich zdrowie psychiczne.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-6825614526998035179?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/6825614526998035179/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/04/paranoiczna-biblioteka-standardowa-java.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6825614526998035179'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6825614526998035179'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/04/paranoiczna-biblioteka-standardowa-java.html' title='Paranoiczna Biblioteka Standardowa Java.'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-4016518938555863593</id><published>2009-04-08T05:23:00.000-07:00</published><updated>2009-04-08T05:33:00.296-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><title type='text'>Jacek Utko - TED talk</title><content type='html'>Poruszyła mnie i zainspirowała do działania konkluzja wystąpienia projektanta gazet, Jacka Utko na konferencj TED, dostępnego pod tym linkiem.&lt;br /&gt;http://www.ted.com/index.php/talks/jacek_utko_asks_can_design_save_the_newspaper.html&lt;br /&gt;&lt;br /&gt;"You can live in a small, poor country, like me, you can work in a small company, in a boring branch, you can have no budgets, no people, but you can put your work to the highest possible level. And everybody can do it. You just need an inspiration, vision and determination. And to remember that to be good is not enough."&lt;br /&gt;&lt;br /&gt;Nic do dodania (poza lekką niezgodą z "small, poor country" :) ).&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-4016518938555863593?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/4016518938555863593/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/04/jacek-utko-ted-talk.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4016518938555863593'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/4016518938555863593'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/04/jacek-utko-ted-talk.html' title='Jacek Utko - TED talk'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-7689610741787870875</id><published>2009-03-17T06:03:00.000-07:00</published><updated>2009-04-22T07:50:25.023-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='językoprotokół'/><title type='text'>reszta językoprotokołu</title><content type='html'>To ciekawy temat. Miałem jeszcze wiele przemyśleń ale nie mogę ostatnio znaleźć czasu, żeby to wszystko napisać. Z drugiej strony zależy mi też na spisaniu tych rzeczy, bo to może się przydać, po pewnych modyfikacjach, jako pomysł na biznes. Jeżeli komuś spodobałby się pomysł, to zapraszam do dyskusji. Po to publikuję to na blogu, żeby zabrać jakieś opinie. Ale do rzeczy. &lt;br /&gt;Zakładając, że problemy z doborem alfabetu liter i głosek zostały rozwiązane, należy jeszcze określić reguły tworzenia słów. Oczywiście każdemu, kto miał do czynienia z nauką obcego języka przyszłyby do głowy różne sposoby, np. tworzenie innego słowa przez dodanie końcówki do starego. To jednak tylko część historii, bo tradycyjne sposoby nie gwarantują spójności języka wystarczającej dla maszyn.&lt;br /&gt;&lt;br /&gt;Trzeba by było zidentyfikować reguły tworzenia słów, które umożliwiałyby spójne utworzenie całego języka. &lt;br /&gt;Pierwsza reguła: żeby nie było sytuacji takiej, że słowo tworzone dla jakiegoś znaczenia, na podstawie innych, istniejących słów może mieć nadane dwa różne ciągi znaków.&lt;br /&gt;Na przykład w języku polskim mamy niejednoznaczne reguły tworzenia słów dla wynalazków przychodzących z zagranicy. Dla znaczenia 'komputer' można by utworzyć słowo "obliczacz", ale też można by wziąć słowo "computer" i spolszczyć je i mówić "komputer". Mamy więc dwie reguły, które prowadzą do nazwania tego samego znaczenia, co w jezykoprotokole spowodowałoby większą niedeterministyczność języka, a zatem zmieszanie i powolniejszą naukę u ludzi, i odcięłoby kolejny sposób automatyzacji rozwiązań w komputerach. &lt;br /&gt;Zakładając, że udałoby się opracować dobre reguły tworzenia słów od istniejących, to które ma być tworzone od którego? Jeżeli przyjmiemy np. regułę tworzenia słowa o znaczeniu przeciwnym przez dodanie przedrostka 'mal', jak w Esperanto, to nadal jest problem, a mianowicie: czy mówić "zły" i "malzły", czy "dobry" i "maldobry". Trzeba by było np. przyjąć, że jest wybierane to ze znaczeń przeciwnych, które oznacza, że czegoś jest więcej, a jeśli to się nie nadaje, to wybieramy znaczenie uznawane za bardziej pozytywne (uzyskalibyśmy "dobry" i "maldobry"). Nie wierzę, że udałoby się wyodrębnić pozbawione uznaniowości reguły wybierania znaczeń. Obawiam się, że jest to zupełnie niemożliwe, ale można by pewnie podjąć próbę i objąć jasnymi regułami większość języka.&lt;br /&gt;Druga reguła tworzenia języka brzmiałaby więc: dla każdego znaczenia powinno dać się jasno stwierdzić, czy przyporządkowane mu słowo będzie autonomiczne, czy utworzone od innych.&lt;br /&gt;&lt;br /&gt;Można by iść w tych rozmyślaniach dalej w stronę opisania struktury procesu tworzenia słów. Gdyby wyobrazić sobie drzewo decyzyjne, które służyłoby na nadawania znaczeniom słów, można by określić, w jaki sposób to drzewo powinno być rozszerzane. Jeżeli ten proces miałby być zautomatyzowany (kusząca perspektywa), to pozostaje też pytanie, jakiego kształtu miałyby być dane wejściowe do tego drzewa. Oczywiście musiałyby to być znaczenia, ale jak byłyby opisane, i jak opisane byłyby relacje między nimi? Jeżeli w języku ludzkim (a do pewnego stopnia tak musiałoby być), to mamy problem jajka i kury, bo do ich opisania trzeba by było opracować sposób reprezentacji podobny do językoprotokołu.&lt;br /&gt;A to na razie tylko słowotwórstwo...&lt;br /&gt;Jeszcze gramatyka (w rozumieniu - "jak użyć razem kilka słów, żeby coś przekazać"). Pewnie musiałaby być podobna do gramatyk języków ludzkich, ale z drugiej strony oparta na znaczeniach. Znam kilka języków programowania, których gramatyki muszą być siłą rzeczy silnie powiązane ze znaczeniami i widzę, że podobieństwo do języka ludzkiego mogłoby być zupełnie nieosiągalne, w przeciwnym wypadku kod źródłowy wyglądałby jak tekst. Jak w językoprotokole poradzono by sobie z grupowaniem znaczeń nawiasami? Wyobrażam sobie, że można by wprowadzić krótkie spójniki o znaczeniu "począwszy od.." i "..skończywszy", więc nie byłoby to znowu takie nieintuicyjne, ale im więcej takich "nieludzkich" elementów, tym mniej atrakcyjny byłby język.&lt;br /&gt;&lt;br /&gt;Gdyby nie głębokość powyższych trudności i duże prawdopodobieństwo podjęcia błędnej decyzji projektowej na początku, można by pokusić się o spisanie reguł i stworzenie internetowego systemu tworzenia tego języka, gdzie ludzie sami wkładaliby znaczenia i tworzyli słowa. Mogłoby się to komuś przydać z powodów wymienionych w poprzednim poście.&lt;br /&gt;Może jak się trochę poduczę gramatyk...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-7689610741787870875?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/7689610741787870875/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/03/reszta-jezykoprotokou.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7689610741787870875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7689610741787870875'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/03/reszta-jezykoprotokou.html' title='reszta językoprotokołu'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-7383019127332927552</id><published>2009-03-10T13:18:00.000-07:00</published><updated>2009-03-10T15:58:06.482-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='językoprotokół'/><title type='text'>językoprotokół człowiek-komputer</title><content type='html'>Uczyłem się metod modelowania danych i natknąłem się na "method of least squares". Pomyślałem sobie "a jak to nazywają Polacy". Otworzyłem więc miłościwie nam panującą Wikipedię i przez linka do polskiej wersji po lewej doszedłem do "metody najmniejszych kwadratów". Ucieszyłem się niezmiernie bo to jedno wyrażenie mniej do nauki. Fajnie by było, gdyby wszystkie wyrażenia i słowa dało się tak dosłownie przetłumaczyć. Potem jeszcze porozmyślałem o problemach w tłumaczeniach i stwierdziłem, że całe trudności wynikają z wieloznaczności i pokrywania się znaczeń słów. Tak doszedłem do wniosku, że bardzo przydałby się język, w którym każde słowo ma jedno znaczenie i każde znaczenie ma jedno słowo. Ale, czy taki język możnaby było utrzymać jako działający w społeczeństwach? Na pewno nie, bo ludzie uwielbiają wymyślać wiele znaczeń dla tego samego słowa, jeżeli więc jakieś jest używane, to prędzej czy później je zepsują. Na tym jest oparta na przykład cała poezja. Wiele znaczeń dla danego słowa oznacza duże prawdopodobieństwo wystąpienia kilku słów dla tego samego znaczenia, bez czego wiersze nie mogłyby być pisane. Pomyślałem nawet, że możnaby wprowadzić pewien standard, określający jakie słowa są oficjalnie używane w pismach urzędowych, czy publikacjach akademickich, jednak to nasuwa zbyt dużo skojarzeń z Orwellem i jego powieścią 1984, gdzie inna idea upraszczania języka (zwana newspeak), prowadząca do zmuszania ludzi do używania pewnych słów zamiast innych jest przykładem represji chorego systemu. Byłoby to istotnie ograniczenie wolności słowa.&lt;br /&gt;Ten fakt zaprowadził mnie do konkluzji, że najlepiej byłoby wykorzystać tę ideę do stworzenia sposobu komunikacji z maszynami, który byłby również w rozsądnym stopniu wygodny dla ludzi. &lt;br /&gt;Przykład 1.&lt;br /&gt;Można by było wydawać głosem skomplikowane rozkazy robotom, które przecież stają się coraz bardziej inteligentne. &lt;br /&gt;Przykład 2.&lt;br /&gt;Zastosowanie bardziej na dzisiejsze czasy, to wykorzystanie w automatycznych translatorach. Przykład: ktoś znający taki język napisałby w nim tekst, następnie ten tekst można by było automatycznie przetłumaczyć na 180 języków (a właśnie, że nie byłoby dużo błędów!) i opublikować na stronie internetowej. &lt;br /&gt;Przykład 3.&lt;br /&gt;Można nawet wyobrazić sobie urządzenie, które służy do rozmowy dwóch ludzi o dowolnych językach. Jak by działało? &lt;br /&gt;Mamu dwóch rozmówców: Pierwszy (P) i Drugi(D).&lt;br /&gt;P coś mówi. Urządzenie wysłuchuje wypowiedziane zdanie i dla każdego słowa, które może mieć więcej niż jedno znaczenie pokazuje P wszystkie znaczenia i każe wybrać. Następnie korzystając z uzyskanych znaczeń tłumaczy zdanie na językoprotokół, z językoprotokołu tłumaczy na język Drugiego i mówi mu (lub pokazuje) rezultat. Analogicznie w drugą stronę. Wreszcie ludzie mogliby się porozumiewać!! Warto zauważyć, że to powyżej nie mogłoby zadziałać między dowolnymi językami, gdyby nie było sporządzonej listy znaczeń i powiązanych z nią przyporządkowań:&lt;br /&gt;(słowo w języku P) - (znaczenia), oraz&lt;br /&gt;(znaczenie) - (słowo w języku D). Oczywiście to wciąż dosyć idealistyczny schemat, według którego dla danego znaczenia wystarczyłoby wziąć dowolne słowo w języku D.&lt;br /&gt;Zakładając jednak, że znaczenia są wystarczająco atomowe, dałoby się dojść dosyć blisko do tego ideału. &lt;br /&gt;&lt;br /&gt;W powyższym przykładzie nr 3 istnienie wymawialnego przez ludzi językoprotokołu wydaje się niekonieczne - znaczenia możnaby na przykład reprezentować kolejnymi liczbami naturalnymi. Nie jest to jednak takie oczywiste, bo jak, nie oferując atrakcyjnego językoprotokołu, skłonić kogokolwiek do spisania wszystkich znaczeń słów, istniejących na Ziemi? I w jakim języku to zrobić? Jeżeli zrobiłoby się to np. po angielsku, to czy rezultaty takiego spisu znaczeń byłyby wystarczająco atomowe? Czy ludzie postrzegający słowo mylnie jako jedno znaczenie (ludzie chyba dążą do myślenia o słowach w ten sposób) nie sprawiliby kłopotu znajomym z Etiopii, którzy mają na te dwa znaczenia dwa różne słowa? A przecież Etiopczyków jest mniejszość, a jeszcze mniej ma dostęp do komputera, więc kto by ich usłyszał?&lt;br /&gt;&lt;br /&gt;Oczywiście słownictwo to nie jest cały język, jest jeszcze gramatyka, słowotwórstwo i inne. Wbrew pozorom słowotwórstwo to problem osobny od słownictwa - jakie brzmienie nadać danemu słowu, jak to nadawanie brzmienia uzależnić od brzmienia istniejących słow. Pozostaje jeszcze wyodrębnienie zbioru głosek składających się na językoprotokół - wszystkie muszą być wymawialne przez ogromną większość ludzi na świecie. Nie może być np. 'l' i 'r' - Japończycy nie widzą różnicy. Jeżeli to samo zastosuje się do innych par dźwięczna - bezdźwięczna, np. 'k' i 'g', 's' i 'z', to taki język byłby jeszcze większym bełkotem, niż język angielski wymawiany przez niektórych Anglików. Można by nawet zaryzykować i zostawić te rozróżnienia, bo jeśli kiedykolwiek ktoś chciałby porozumieć się z innym czlowiekiem za pomocą językoprotokołu i powiedziałby "lagas", a drugi znałby to słowo jako "rakaz", to niezrozumieliby się. Gdyby jednak słuchała maszyna, to lepiej by było, żeby nie było tych rozróżnień, żeby komuś, kto ma wadę wymowy nie wychodziło ciągle "lakas", podczas gdy chodzi mu o "lagas", które miałoby inne znaczenie.&lt;br /&gt;Dosyć tego. W następnym poście przemyślenia o gramatyce i słowotwórstwie.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-7383019127332927552?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/7383019127332927552/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/03/jezykoprotoko-czowiek-komputer.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7383019127332927552'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7383019127332927552'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/03/jezykoprotoko-czowiek-komputer.html' title='językoprotokół człowiek-komputer'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-7554417274073228905</id><published>2009-02-24T03:56:00.000-08:00</published><updated>2009-02-24T05:01:08.059-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><title type='text'>pora wreszcie zacząć pisać!</title><content type='html'>Pora wreszcie zacząć pisać na temat rozwoju kariery i samoświadomości.&lt;br /&gt;Przedmiot, który o tym jest (Carier Management Skills) zaczął się na początku semestru, ale nie mogłem się jakoś skłonić do skrobania tego wszystkiego, mimo to, że miałem sporo przemyśleń. Wykładzik sprzed 5 minut skłonił mnie jednak do wykonania tego zadania. Tak dla porządku, wykład dotyczył tego, jak nie pisać listu motywacyjnego i jaka jest pełna lista tych rzeczy, których szukają pracodawcy u pracowników. Było też kilka praktycznych wskazówek na temat organizacji kariery. Czemu takie nudne rzeczy są takie przydatne? Właściwie to nie wiem, czy takie nudne, bo tak naprawdę jeszcze nie próbowałem porządkować tych spraw. &lt;br /&gt;Tylko od czego zacząć? Może od wykładu nr 1 :)&lt;br /&gt;Był bardzo ciekawy.&lt;br /&gt;Pytanie ze slajdu: co chcesz osiągnąć na tym przedmiocie?&lt;br /&gt;I kilka możliwych odpowiedzi:&lt;br /&gt;"Zdecydować o karierze." Zdecydowanie nie. Jak zdecyduję o karierze podczas drugiego roku studiów, to wyląduję w jakiejś dziurze, robiąc coś, co jest zaledwie w miarę w porządku. Moment ostatecznej decyzji należy odwlekać jak najdłużej, żeby zostawić sobie mośliwości. Trzeba natomiast śledzić, co jest dostępne, co jest na czasie, na co jest popyt, a na co nie i robic to, co naprawdę się lubi.&lt;br /&gt;"Aplikować, albo mieć rozmowę o pracę" W zasadzie to mi wszystko jedno, jeśli rozumieć to tak, że dla samego faktu aplikowania podejmuję się tego przedmiotu. Oczywiście dałoby mi to jakieś doświadczenie, ale nie ma to ogromnego znaczenia, bo i tak pewnie albo będę się samozatrudniał, albo gdzieś wskoczę przez jakiś projekt open source, albo ktoś mnie zarekomenduje, a najważniejsze będą i tak kwalifikacje (co do których mam duże plany). Głupi nie jestem, i podążając za poradami ze slajdów jestem w stanie napisać dobre CV, list i poopowiadać o rzeczach które mnie pasjonują na rozmowie (a jak praca nie będzie pasjonująca, to, jak mam nadzieję, będę mógł poszukać innej, a jak pracodawca nie widzi pasji, to i tak nie zatrudni). Chciałbym gdzieś aplikować, jeśli znalazłaby się płatna (nie koniecznie miliardy :) ) praca, która mi coś da, nie tylko będzie polegała na zrobieniu czegoś, czym nikt (łącznie ze mną) nigdy nie będzie się przejmował, albo polegająca na wykonywaniu czynności, które zaprojektowany przeze mnie na kolanie robot wykonywałby lepiej i taniej.&lt;br /&gt;"Zabezpieczyć sobie pracę po studiach albo latem" Co do pracy po studiach, patrz punkt pierwszy. Co do pracy latem, jak najbardziej tak, ale nie będę wysyłał CV do "makdonaldów". Lepiej już zająć się w tym czasie jakimś projektem open source, który polepszy moje CV i pozwoli na lepiej płatną pracę w przyszłości. Tak na marginesie, mam kilka własnych pomysłów, ale mogę też rozważyć podłączenie się do czegoś większego, np. do rozwijania Code::Blocks.&lt;br /&gt;"Opracować i zrobić swój własny plan samozatrudnienia" Zdecydowanie tak. Jest kilka kontaktów na stronie internetowej CMS. Mam zamiar ich użyć, żeby dowiedzieć się, jak to jest prowadzić, mieć, pracować w, rozwijać działalność w dziedzinie IT. Pozadaję kilka pytań kilku przedsiębiorcom, którzy zgodzili się służyć pomocą studentom na tym przedmiocie. Tak na dobry start. Oczywiście na tym blogu nie zostaną opublikowane żadne materiały, które nie pochodzą ode mnie, napiszę jednak ogólnie, czego się nauczyłem, bez wymieniania żadnych nazw własnych. Spróbuję również zadać kilka pytań mojemu tacie, od którego wiem już sporo, ale tak naprawdę nie wiem, co od niego wiem :)&lt;br /&gt;Mam nadzieję, że będzie mnie trochę wspierał w tej sprawie, choć nieczęsto się ostatnio widzimy.&lt;br /&gt;(Zachciało się cholera emigracji edukacyjnej! Najlepszy sposób na skomplikowanie życia.)&lt;br /&gt;Może to wygląda, jakbym miał nie wiadomo jakie mniemanie o sobie, nie wiem, może praca kelnera albo sklepikarza czegoś by mnie nauczyła, ale nie chcę marnować życia. Ludzie powinni w 21 wieku sterować robotami, wcikać guziki i opalać się na Hawajach, a nie szorować podłogi nie mogąc patrzeć na ziarnko piasku i narzekać, że marnują życie. Im więcej ludzi to zrozumie, tym lepiej. Jak to się znacząco nie zmieni w ciągu kilkunastu lat, to chyba założę partię technokratyczną.&lt;br /&gt;&lt;br /&gt;W (którymś) następnym poście kontynuacja CMS, mam nadzieję, że już z pewnymi wynikami.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-7554417274073228905?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/7554417274073228905/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/02/pore-wreszcie-zaczac-pisac.html#comment-form' title='Komentarze (2)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7554417274073228905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/7554417274073228905'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/02/pore-wreszcie-zaczac-pisac.html' title='pora wreszcie zacząć pisać!'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-1681292158267133154</id><published>2009-02-14T19:32:00.000-08:00</published><updated>2009-02-17T11:10:11.821-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><title type='text'>rastrowo wektorowy motywacyjny kop</title><content type='html'>Piszę sobie ostatnio (formalnie od września 2008 :) ) program z kolegami na uczelni. Stwierdziliśmy, że ma to być program graficzny, żeby odróżnić go od wytworów poprzedniego rocznika, ale nie bardzo wiedzieliśmy, co wymyślić, żeby było oryginalnie, więc doszliśmy po nitce (z niewidzialnej szaty cesarza) do kłębka w postaci "edytora grafiki wektorowej on-line". Wszystko by było pięknie, gdyby to była jakaś gra albo jakieś fajne narzędzie akademickie, zawierające jakieś ciekawe algorytmy, ale grafika wektorowa? Nie muszę dalej tłumaczyć, że nie byłem tym zachwycony. Stwierdziłem, że pomysł ma spory potencjał (i na razie tylko potencjał) i może później znajdę jeszcze jakąś konkretną motywację do pisania tego narzędzia dla trzynastolatków (tak, oksymoron).&lt;br /&gt;I znalazłem!&lt;br /&gt;Poza kilkoma pomysłami na uczynienie z tego programu czegoś przytępnego, o których nie będę się tu teraz rozpisywał, planowałem stworzenie konwertera grafiki rastrowej na wektorową. Uzasadnienie jest oczywiste: dziwnym trafem zwabiony trzynastolatek, nie mający zielonego pojęcia o tym, czym jest grafika wektorowa zacznie gwałtownie próbować różnych przycisków w menu, aż w pewnym momencie ustrzeli "load image" i nagle odkryje, że może tam załadować zdjęcie tatusia po pijaku, wyciąć brutalnie tułów delikwenta i wkleić na dziób Titanika. Do tego wszystko w stylu kreskówkowym.&lt;br /&gt;&lt;br /&gt;Działanie tej konwersji, choć jeszcze niedoszlifowane, zrobiło duże wrażenie na kumplach z teamu. W następnym poście opiszę dokładnie algorytm, którego użyłem. Może komuś się przyda. Choć raczej nie byłoby to odkrycie roku dla zaawansowanego informatyka, to jest taki efektowny drobiazg, który daje motywacyjnego kopa, jak uda się go zaimplementować.&lt;br /&gt;Do zobaczenia!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-1681292158267133154?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/1681292158267133154/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/02/rastrowo-wektorowy-motywacyjny-kop.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1681292158267133154'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/1681292158267133154'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/02/rastrowo-wektorowy-motywacyjny-kop.html' title='rastrowo wektorowy motywacyjny kop'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-2403956909126853718</id><published>2009-02-14T19:28:00.000-08:00</published><updated>2009-03-10T13:16:37.018-07:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='strona www'/><title type='text'>moja strona</title><content type='html'>A tak dla uzupełnienia pierwszego posta, zapraszam na moją stronę domową.&lt;br /&gt;klosio.neostrada.pl&lt;br /&gt;Jeśli ktoś ma jakiekolwiek spostrzeżenia na temat mojej strony, proszę o komentarz tutaj.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-2403956909126853718?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/2403956909126853718/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/02/moja-strona.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/2403956909126853718'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/2403956909126853718'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/02/moja-strona.html' title='moja strona'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1309019001069154774.post-6670819588243887391</id><published>2009-02-03T07:43:00.000-08:00</published><updated>2009-02-03T07:51:57.903-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ja'/><title type='text'>(jakiś nudny, typowy tytuł pierwszego posta)</title><content type='html'>Ten blog powstał z czystego, chorego poczucia obowiązku, wynikającego z nacisku na samoświadomość, który z czystą, obopólną przyjemnością serwuje mi od tego semestru moja uczelnia. Prawdopodobnie nikt nie potrzebuje tego czytać, więc z góry witam wszystkich, którzy tu kiedyś wejdą z czystego podglądacwa, po przeczytaniu jakiegoś posta, który rzeczywiście im się przyda. Miłego czytania.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1309019001069154774-6670819588243887391?l=paklos.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://paklos.blogspot.com/feeds/6670819588243887391/comments/default' title='Komentarze do posta'/><link rel='replies' type='text/html' href='http://paklos.blogspot.com/2009/02/jakis-nudny-typowy-tytu-pierwszego.html#comment-form' title='Komentarze (0)'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6670819588243887391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1309019001069154774/posts/default/6670819588243887391'/><link rel='alternate' type='text/html' href='http://paklos.blogspot.com/2009/02/jakis-nudny-typowy-tytu-pierwszego.html' title='(jakiś nudny, typowy tytuł pierwszego posta)'/><author><name>paklos</name><uri>http://www.blogger.com/profile/17491533931829598418</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://3.bp.blogspot.com/_MjVCmxw3xsg/SdEP2x8s86I/AAAAAAAAAAM/e6KiWAxDUqY/S220/pingwinHQ2.PNG'/></author><thr:total>0</thr:total></entry></feed>
