Open Side Menu Go to the Top

10-26-2012 , 11:33 AM
I was thinking of doing something similar for a new project which is going to have voluminous CSS. Not worrying about the number of style sheets but more about the modularity of them - and then having a build tool to merge them correctly seems like quite a good idea.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
10-26-2012 , 12:18 PM
Quote:
Originally Posted by kerowo
It seems little bit like karma whoring to ask and answer your own question. On second thought, since I have no idea why I need do what I did to get it to work I do have a question. Here it is if anyone is curious: http://stackoverflow.com/questions/1...in-objective-c
well that's a new one: a question where the OP and all answers are -1 score -- there should be a badge for that, kerowo!
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 12:20 PM
Gul, you should take a look at using LESS. It allows you to have a more modular approach to CSS. You can have a 'default' file which sets up all your global variables (HEX values for default colors, default widths, fonts, font size etc), then have separate files for each area of the site. It wont completely solve your problem, but going forward it definitely pushes you towards good practices.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 01:31 PM
Quote:
Originally Posted by gaming_mouse
well that's a new one: a question where the OP and all answers are -1 score -- there should be a badge for that, kerowo!
What the hell? It's not like you can't just throw it into xcode and verify everything in that thread. Oh well, hopefully someone else will find that before the 15 other pages on regexs in objective-c that don't work...
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 01:55 PM
Quote:
Originally Posted by kerowo
What the hell? It's not like you can't just throw it into xcode and verify everything in that thread. Oh well, hopefully someone else will find that before the 15 other pages on regexs in objective-c that don't work...
i brought you guys back up to 0
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 02:28 PM
Thanks!
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 04:58 PM
I think I might have stumbled upon a great startup idea. It's a landgrab (I guestimated some pretty conservative numbers and the market seems pretty huge), an area where two pretty different customer types have a decent amount of pain right now and not too complicated technically.

Would involve a decent bit of nontechnical work but on the plus side you can also grab a submarket first without really attracting much attention and expand which would probably allow you to become profitable somewhat soon (would certainly require VC money eventually due to the landgrab nature but probably not off the bat). Kind of oldschool crossing the chasm style.

You can probably lay some solid groundwork while in stealth mode (especially the nontechnical stuff).
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 05:18 PM
Any hints at all?
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 05:23 PM
I bet it's got a lot of synergy.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 06:44 PM
No hints but if it's as viable as I think I should start banging out code tomorrow
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 07:09 PM
It's all uploaded (and hopefully functioning correctly).

I did a ton of code change and refactoring. I rearranged the database, and used the duo-key values to store the employer and college information, so the schema starts like this (from memory):

(Username varchar, employernumber int, employername varchar default '', duty1 varchar default '', duty ..... primary key (username, employernumber))

That allowed me to set it up with routes to make the requisite data calls. This also will allow me to do the other ideas presented here if I choose to do so in the future. I bounced back and forth on the drop-down and dynamic page stuff, using buttons to add information, but I just couldn't get past the thought that this is feature creep. I'm also in the fortunate position of being someone that is immensely stupid with UI, and I was confused even thinking about how I would use the interface if I was trying to fill it out, so I decided to just keep everything static for now, but at least allow everything to be extensible or easily flexible for further consideration (and better designers, LOL).

I refactored a bunch, which allowed me to solve some issues with the resume-preview page.

The total LOC at this moment: ~1200. I'll let you compare that to whatever it is you would use. To be fair, I could have taken away another 100 - 200 LOC. The preview page is the most long-winded at north of 125 LOC.

Home Page:
http://www.soloresume.com/

Employer Page*:
http://www.soloresume.com/employer-one

*Don't mind all the nulls. They don't show up if the user is logged in. I'll add the redirects for that at a later time.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 07:14 PM
Quote:
Originally Posted by clowntable
I think I might have stumbled upon a great startup idea. It's a landgrab (I guestimated some pretty conservative numbers and the market seems pretty huge), an area where two pretty different customer types have a decent amount of pain right now and not too complicated technically.

Would involve a decent bit of nontechnical work but on the plus side you can also grab a submarket first without really attracting much attention and expand which would probably allow you to become profitable somewhat soon (would certainly require VC money eventually due to the landgrab nature but probably not off the bat). Kind of oldschool crossing the chasm style.

You can probably lay some solid groundwork while in stealth mode (especially the nontechnical stuff).
Rich and Poor have the same pain. One needs this product to buy food and the other needs this product to gamble on the market:

** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 11:35 PM
You should post some of the code dave.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-26-2012 , 11:41 PM
Tell me what part of the code you are interested in seeing and I can post the sample on here or github when I get home.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 12:36 AM
You can also log on as user1 with password as "password" to see the user side of the resume builder.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 08:19 AM
Nothing in specific. Just wanted to get a high level view of a clojure app.

Are you using any of the mutable data wrappers? Like atom, agent, ref, etc..
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 09:09 AM
Quote:
Originally Posted by clowntable
No hints but if it's as viable as I think I should start banging out code tomorrow
Ok, consider this my obligatory keeping your idea secret is silly post.

My 'best' idea for a startup* right now is replacing physical keys with a public-key/rfid system. So everyone carries a dongle type thing that has their private key on it. Locks would then be able to read the dongle and open if the user is authorized to that lock.

The beauty of this is that you get much finer control over who has access to your lock. If you have a friend coming to town you'd just need their equivalent public key and you could add it to your lock for the duration of their visit. If you buy a new house you just need to clear the old public keys and add yours. If you have a cleaning service coming in you could authorize their public keys for a set day every week. And so on.

It's obviously not a totally secure system - but probably more secure than physical keys now. And the idea isn't to have a super secure system but just to match (or better) the security we have now with physical keys but come up with a way more usable system.



* I don't really have the desire to run this company but I'd love if someone started it, made millions, and gave me a million for the idea.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 09:40 AM
10-27-2012 , 09:44 AM
Nice!
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 12:39 PM
I'm not keeping it secret because I think someone will steal the brilliant idea. It's trivial enough. Mostly because I'd rather work on it in silence and once it's released and becomes a multimillion (oh wait billion !!!ONE!) business I want to be able to say..yeah I posted I'd work on that on 2p2. Oh you don't know 2p2? It ain't no HN that's for sure.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 04:57 PM
Pretty good talk I randomly found (Python, don't overuse classes)
https://www.youtube.com/watch?v=o9pEzgHorH0

Cliffs:
1) If you have a class with two methods one of which is __init__ ... refactor to not use a class
2) Don't build for the future i.e. have classes you feel might be needed in the future that just pass
3) Don't create new exceptions if you don't have to
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 05:39 PM
Quote:
Originally Posted by Shoe Lace
Nothing in specific. Just wanted to get a high level view of a clojure app.

Are you using any of the mutable data wrappers? Like atom, agent, ref, etc..
No! Mutation is BAD!

I posted a question on SO about a month ago, and this is what one responder wrote:

Quote:
def inside a function is really nasty - you are altering the global environment, and it can cause all kinds of issues with concurrency. I would suggest storing the results in a map instead.
With that tidbit of knowledge, you can see that using defn, def, atoms, refs, etc, can create unwanted and hard-to-find bugs and this, I imagine, is why Noir created the defpartial and defpage macros. You can see the source for 4Clojure.com to get an idea of how things were done a few years ago.

If there's no defn in the local functions, then what to do? I'm sure that you can appreciate anonymous functions, which are represented as let-bindings in Lisp.

So, this is a shortened version the employer-page page area, where the user can fill out the employment history area. I only deleted the repetitive stuff. I'm not saying this is the top-best stuff, but it does show how what appears to be mutation isn't actually mutation at all.


This is the namespace boiler-plate. If you're not familiar with it yet, you will be soon.

Code:
(ns soloResume.views.emppages
  (:require 
	[soloResume.views.common :as common]
	[noir.response :as resp]
	[soloResume.models.datapass :as db]
	[noir.session :as sesh])
  (:use [noir.core] 
	[korma.core]
	[hiccup.page-helpers]
	[hiccup.form-helpers]))

This initializes the pages I want to have and create and also initializes the routes. I could have actually done this differently, but I did it when I first started working with Clojure before I understood other concepts, but its fine the way it is, IMO.

Code:
(def emp-page-num {:one "one" :two "two" :three "three" :four "four" :five "five"})

This initializes the mapping to the database. The keys are the page numbers one through five. The :suser-x-y is the name of the value I would want to destructure later on. The db/jobxyz maps to the database via Korma, and the :empname, et.al. maps the table colums.

Code:
(def data-input {"one" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"two" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"three" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"four" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"five" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]})

This calls the data-input hash-map above and creates maps to destructure. This is key to calling the map, keeping the routes, and preventing mutation:

Code:
(defpartial data-build [data-key suser page-num]
	(loop [output {}
		items (seq (data-input data-key))]
		(if items
		    (recur
			(let [[kw db fieldname] (first items)]
			    (assoc output kw 
			         (select db 
					(fields fieldname) 
					(where {:username suser :employernumber page-num})))) 
		(next items))
	output)))
This creates the actual form-fields. The paragraph id/class, the name (Employer Name, Duty One, etc), the data-key is the table column name, data-table is the table, information is the information input by the user, the field key is field ID to be called by the form-handler, and the common key is an indicator if what kind of field I want.

Code:
(defpartial form-builder [pid pname data-key data-table information field-key common-key]
    [pid pname	
	[:i (let [{[{val data-key}] data-table} information]
		(format "%s" val))]
	[:br]
	(if (= common-key "")
	    (text-field field-key)
	    (common/menu-build field-key common-key))])
This creates the pages via map at the very top where I defined the pages. I'm still a little slippery on the {:keys [xyz]} stuff, but I'm getting a better handle on it all. I was staring at an issue yesterday that was bound to this very issue.

I would also like to point out how many type-conversions there are in the code. Notice the to-numeral (I had to write that) and the load-string functions to make things more usable. Lots of funny issues surrounding casting types in Clojure. It's not as inconvenient as you may think.

Notice the let-bindings. I had originally made the database calls as defn, which is where the bugs and issues of concurrency are derived. Don't do it because some dude on SO said not to. I'll defer the judgement to him.


Code:
(defpage "/employer-:emp-page-num" {:keys [emp-page-num]}
    (common/res-heads
	(let [suser (sesh/get :uname)]		
	(let [information (load-string (data-build emp-page-num suser (common/to-integer emp-page-num)))]
	[:div.span6.offset1
		(form-to [:post (str "/employer-"emp-page-num)]
		    [:h3 (str "Employment History: Employer " (common/to-numeral emp-page-num))]
			(form-builder :p "Employer Name: " :empname :suser-emp-name information "empname" "")
			(form-builder :p "City: " :city :suser-emp-city information "empcity" "")
		[:input.buttons {:type "submit" :value "Update"}])]))
    [:div.blankDiv [:p]]))

Notice an oddity here? Compare this:

Code:
(defpage "/employer-:emp-page-num" {:keys [emp-page-num]}
To this:

Code:
(form-to [:post (str "/employer-"emp-page-num)]
I have zero idea why I couldn't use the same form as earlier, but for whatever reason, I had to do a string-conversion to make it work. The same issue arises in the response at the bottom of the code piece.

Not sure how this compares to other language, but the page-to-post is a loop. The reason this happens is because the pages in Clojure default to :get, so to get ost, you have to specify a new page with the functions listed as keys. This simply checks to see if the fields are blank and if not, enters the information into the database.

Originally, I was having the new information shown in the fields, but then I realized that this increases the database calls needlessly, then I started thinking about using refs and promises, but then decided this was complecting.


Code:
(defpage [:post "/employer-:emp-page-num"] {:keys [emp-page-num empname empcity empstate emppos startmonth startyear endmonth endyear dutyone dutytwo dutythree dutyfour dutyfive]}
    (let [suser (sesh/get :uname)]
	(if (not (= empname ""))
	    (update db/jobhunteremployers 
		(set-fields {:empname empname})
		(where {:username suser :employernumber (common/to-integer emp-page-num)})))
	(if (not (= empcity ""))
	    (update db/jobhunteremployers 
		(set-fields {:city empcity})
		(where {:username suser :employernumber (common/to-integer emp-page-num)})))
    (resp/redirect (str "/employer-"emp-page-num))))
That's basically how I get this effect without blowing up my database:





The full code if you want to look at it on your favorite editor:

Code:
(ns soloResume.views.emppages
  (:require 
			[soloResume.views.common :as common]
			[noir.response :as resp]
			[soloResume.models.datapass :as db]
			[noir.session :as sesh])
  (:use [noir.core] 
		[korma.core]
		[hiccup.page-helpers]
		[hiccup.form-helpers]))		
		
(def emp-page-num {:one "one" :two "two" :three "three" :four "four" :five "five"})

(def data-input {"one" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"two" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"three" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"four" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]
					  
				"five" [[:suser-emp-name db/jobhunteremployers :empname] 
					  [:suser-emp-city db/jobhunteremployers :city]]})
					  					  
(defpartial data-build [data-key suser page-num]
		  (loop [output {}
				 items (seq (data-input data-key))]
			(if items
			  (recur
				(let [[kw db fieldname] (first items)]
				  (assoc output kw 
						(select db 
							(fields fieldname) 
								(where {:username suser :employernumber page-num})))) 
				(next items))
			  output)))

(defpartial form-builder [pid pname data-key data-table information field-key common-key]
	[pid pname	
		[:i (let [{[{val data-key}] data-table} information]
				(format "%s" val))]
	[:br]
	(if (= common-key "")
		(text-field field-key)
		(common/menu-build field-key common-key))])	  

(defpage "/employer-:emp-page-num" {:keys [emp-page-num]}
	(common/res-heads
		(let [suser (sesh/get :uname)]		
		(let [information (load-string (data-build emp-page-num suser (common/to-integer emp-page-num)))]
			[:div.span6.offset1
				(form-to [:post (str "/employer-"emp-page-num)]
					[:h3 (str "Employment History: Employer " (common/to-numeral emp-page-num))]
						(form-builder :p "Employer Name: " :empname :suser-emp-name information "empname" "")
						(form-builder :p "City: " :city :suser-emp-city information "empcity" "")
						[:input.buttons {:type "submit" :value "Update"}])]))
							[:div.blankDiv [:p]]))

(defpage [:post "/employer-:emp-page-num"] {:keys [emp-page-num empname empcity empstate emppos startmonth startyear endmonth endyear dutyone dutytwo dutythree dutyfour dutyfive]}
	(let [suser (sesh/get :uname)]
		(if (not (= empname ""))
			(update db/jobhunteremployers 
				(set-fields {:empname empname})
				(where {:username suser :employernumber (common/to-integer emp-page-num)})))
		(if (not (= empcity ""))
			(update db/jobhunteremployers 
				(set-fields {:city empcity})
				(where {:username suser :employernumber (common/to-integer emp-page-num)})))
	(resp/redirect (str "/employer-"emp-page-num))))
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 05:40 PM
Quote:
Originally Posted by clowntable
Pretty good talk I randomly found (Python, don't overuse classes)
https://www.youtube.com/watch?v=o9pEzgHorH0

Cliffs:
1) If you have a class with two methods one of which is __init__ ... refactor to not use a class
2) Don't build for the future i.e. have classes you feel might be needed in the future that just pass
3) Don't create new exceptions if you don't have to
I don't have to see the video to agree with all of this.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 07:30 PM
if the sum of all i values to n values is equal to: n(n+1)/2 which is the same as big-theta(n^2)

is the sum of all values of i to n-1 equal to: (n-1)x((n-1)+1)/2 and is that the same as big-theta(n-1^2)??


im assuming as the value of n gets larger the -1 gets ignored as the difference is tiny so its big-theta(n^2) still? correct or?



sorry for basic question, im just a bit confused as in a book it just says: sum of i to n is equal to n(n+1)/2 which is same as big-theta(n^2) without any explantion how its the same. (is it because its the same as ((n^2)+(1n))/2 but the 1n and /2 is dropped as it doesnt make much difference to the runnign time as n gets very large or?? =/ )

Last edited by Burnss; 10-27-2012 at 07:34 PM. Reason: this post seems way to long for what im actually asking for haha
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
10-27-2012 , 07:33 PM
Quote:
Originally Posted by clowntable
3) Don't create new exceptions if you don't have to
What's the reason for this? I don't create a ton of exceptions but I generally do whenever I have a new exception case that I'm going to want to handle somewhere else in my code.
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD ** Quote
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **
$25m Guaranteed WPM on CoinPoker
Join the action now
Daily Rewards • Splash Pots • CoinRaces
** UnhandledExceptionEventHandler :: OFFICIAL LC / CHATTER THREAD **

      
m