Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Pochoclo
Feb 4, 2008

No...
Clapping Larry
Sup guys. I'm trying to make a function that will take three inputs and output a single numeric "weight", to use as an ordering criteria. Two are arbitrary and vary wildly, from 0 to 100000. One of those is, on average, a tenth of the other (they're "views" and "likes" basically, but they're just numbers for our purposes). The third parameter is a Unix epoch (amount of seconds since the 1st of January of 1970) timestamp.
This is supposed to be a "weight" function, where time must have the biggest weight, but the other two amounts are also important. So, of these two: (10000; 100000; 1341405030) and (3000; 30000; 1343222270), the second must have more weight than the first.
I've tried a bunch of number shufflings, including adding up the first two, and dividing the timestamp by 600000 (roughly the amount of seconds in a week) and multiplying them blindly, but it's just not working and I don't know any math majors. Anyone know how to do something like this?
Using a divided timestamp as a first ordering criteria and a weight with only the views/likes as the second, is what I'm doing in the meantime, but it's not very smooth - there are of course noticeable "jumps" where a time-dividing-period ends and the next begins.

Adbot
ADBOT LOVES YOU

rolleyes
Nov 16, 2006

Sometimes you have to roll the hard... two?
Well on a really basic level you could do something like:

code:
int weighting(int a, int b, int c)
{
  return (a*b) + (c^2)
}
That gives a and b equal weighting while skewing the overall result hugely towards the value of c. E.g.:

weighting(10000, 10000, 1341405030) = 1799367454609300900
weighting(3000, 3000, 1343222270) = 1804246066632952900


You might want to just take the 5 most significant figures or something in order to end up with a not-ridiculously-huge number. You can play with the operations to skew less or more but you're already skewed significantly towards c as it's generally 5 orders of magnitude larger than a and b individually.


edit:
What exactly is the ordering you want end up with anyway? With the example I've given above you're effectively ordering your results by time (as the timestamp has the greatest weighting) and then by a and b. It would take an astronomical number of 'likes' and 'views' to overcome the weighting given to the timestamp so your weighting would tend to be by day.

rolleyes fucked around with this message at 14:54 on Jul 25, 2012

Jewel
May 2, 2009

rolleyes posted:

edit:
What exactly is the ordering you want end up with anyway? With the example I've given above you're effectively ordering your results by time (as the timestamp has the greatest weighting) and then by a and b. It would take an astronomical number of 'likes' and 'views' to overcome the weighting given to the timestamp so your weighting would tend to be by day.

I think it's more the situation of "If someone gets 10000 likes in a month and someone gets 1000 likes in a day, the latter is obviously much more popular, and should be sorted that way". I'm too tired to work out the math to do that though right now :(

Pochoclo
Feb 4, 2008

No...
Clapping Larry
Thanks for the answers. I managed to get ahold of a maths major, and he gave me a possible solution:

code:
ALPHA = 0.2 (outdating speed factor)

SCORE = ALPHA*TIME/86400 + log(VIEWS) + log(LIKES)
He also elaborated on a more complex solution involving views per hour, but with a bit of tweaking, this function looks like it might work.

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


How do you interpret the scores? Or are they just dimensionless values that you can compare?

Pochoclo
Feb 4, 2008

No...
Clapping Larry

ultrafilter posted:

How do you interpret the scores? Or are they just dimensionless values that you can compare?

They're just values to use for sorting, i.e. "ORDER BY score DESC", so yes, the latter.

PDP-1
Oct 12, 2004

It's a beautiful day in the neighborhood.

Pochoclo posted:

Thanks for the answers. I managed to get ahold of a maths major, and he gave me a possible solution:

code:
ALPHA = 0.2 (outdating speed factor)

SCORE = ALPHA*TIME/86400 + log(VIEWS) + log(LIKES)
He also elaborated on a more complex solution involving views per hour, but with a bit of tweaking, this function looks like it might work.

You might want to check out the ranking function Reddit uses. It has a similar notion of 'likes' in terms of upvotes and is designed to bubble new popular stories to the top of the list and then let them gradually decline in rank after they've been around for a while regardless of how many votes they got. (Assuming that's how you want your system to work)

rjmccall
Sep 7, 2007

no worries friend
Fun Shoe

Otto Skorzeny posted:

void for functions which take no arguments was called an 'abomination' by Brian KernighanDennis Ritchie iirc

The committee should never have standardized unprototyped functions. They should've just said, "Look, we know this is what you wrote before, but stop doing it and use proper prototypes, because we're not going to bless that poo poo." Alas.

nintendo65
Oct 16, 2008

Two universes separated by a membrane! It causes gravity! I have a uni degree in SCIENCE!!1!
I have a question for php developers out there, is anyone aware of a modern php and jquery/ajax plugin that allows bbcode-like functionality that I could add to the forms on my website, so that posters can add links or change color of the text more easily? I guess I'm looking for a toolbar similar to an email client's that can quickly be plugged into my site and converts the code to html.

nintendo65 fucked around with this message at 20:12 on Jul 25, 2012

Fruit Smoothies
Mar 28, 2004

The bat with a ZING
Not sure if this is the right thread, but I have an abstract programming question.


I'm currently editing a PHP site which has a system that's effectively a mail merge; it generates HTML "letters" etc. It's for a holiday company, so the correspondence API has to be able to handle letters pertaining to client bookings, hotel availability and flights - as well as whatever is added down the line.
At the moment, a REGEX function replaces set variables like %BOOKINGID% within a HTML template. This is so that the company can easily add / remove / translate templates accordingly.

The trouble is, different letters obviously use different parts of the database. My current thoughts involve making a letter class that has a list of available variables:

PHP code:
$letter = new Letter();
$letter->addSetting("%BOOKINGID%", $bookingID);
This involves creating a huge case statement that is difficult for the company to expand without a developer's help:

PHP code:
	switch($letterType) {
		case "bookingConfirmClient": {
			//pseudo function to demonstrate validation
			$bookingID = isBooking($_GET['bookingID']);
			$letter = new Letter();
			$letter->addSetting("%BOOKINGID%",$bookingID);
			break;
		}
		case "flightConfirm": {
			$flightID = isFlight($_GET['flightID']);
			$bookingID = isBooking($_GET['bookingID']);
			$letter = new Letter();
			$letter->addSetting("%BOOKINGID%",$bookingID);
			$letter->addSetting("%FLIGHTID%",$flightID);
			break;
		}
		...
	}
That is incredibly ugly. Additionally, that just covers the IDs involved. Each case will have to pass booking services, names, contacts etc.
Furthermore, some of the "settings" will be arrays. Not every booking has the same number of services. This means that %SERVICELIST% will have to loop through the settings using its own HTML table template: one row per service thus:

PHP code:
	$letter->addSetting("%SERVICELIST%", "<table><tr>...</tr></table>");
I don't want an absolute, coded answer to the problem. I just want tips on how to solve modular parts of a system like this without having to write my own mini interpreted language inside it.
Thanks.

Sab669
Sep 24, 2009

This is really a dumb question, but I've never really thought about it before.

What's the general consensus on what data type to use to store an encrypted password? Still just varchar? And what length should you allow, then. I suppose that probably varies depending on the type of encryption?

pokeyman
Nov 26, 2006

That elephant ate my entire platoon.

Fruit Smoothies posted:

I'm currently editing a PHP site which has a system that's effectively a mail merge; it generates HTML "letters" etc. It's for a holiday company, so the correspondence API has to be able to handle letters pertaining to client bookings, hotel availability and flights - as well as whatever is added down the line.
At the moment, a REGEX function replaces set variables like %BOOKINGID% within a HTML template. This is so that the company can easily add / remove / translate templates accordingly.

These requirements scream template system to me. My favourite is Mustache.

quote:

The trouble is, different letters obviously use different parts of the database. My current thoughts involve making a letter class that has a list of available variables.

In template system parlance, you would pass an instance of this class in as the context for the template. So when the template refers to a variable "foo", the template system would look for a property or method called "foo" on your context object.

quote:

Furthermore, some of the "settings" will be arrays. Not every booking has the same number of services. This means that %SERVICELIST% will have to loop through the settings using its own HTML table template: one row per service thus:

PHP code:
	$letter->addSetting("%SERVICELIST%", "<table><tr>...</tr></table>");

Any template system will have some way of dealing with looping. In Mustache you'd do something like
code:
<table>
{{#services}}
<tr>...</tr>
{{/services}}
</table>
There are many different template systems around, so have a gander and find something you like.

a cat
Aug 8, 2003

meow.

Sab669 posted:

This is really a dumb question, but I've never really thought about it before.

What's the general consensus on what data type to use to store an encrypted password? Still just varchar? And what length should you allow, then. I suppose that probably varies depending on the type of encryption?

I hope you're not planning to store plaintext passwords! Regardless, these two links should help:

http://codahale.com/how-to-safely-store-a-password/
http://stackoverflow.com/questions/5881169/storing-a-hashed-password-bcrypt-in-a-database-type-length-of-column

edit: woops I just realized you mentioned the passwords would be encrypted. But yeah it depends on the kind of encryption and you probably shouldn't be using anything worse than bcrypt anyway.

a cat fucked around with this message at 00:53 on Jul 26, 2012

Sab669
Sep 24, 2009

Er, I said encyrpted :v:
But thanks for the links, I'll check them out. And it's for a project for school- not something for live production heh.

Johnny Cache Hit
Oct 17, 2011

Sab669 posted:

Er, I said encyrpted :v:
But thanks for the links, I'll check them out. And it's for a project for school- not something for live production heh.

Don't store encrypted passwords. Don't store encrypted passwords.

Encrypted means recoverable. Use a secure password hashing scheme like bcrypt, PBKDF2, drepper's SHA stretching (see man crypt on a glibc system)...

But don't store encrypted passwords.

Bruegels Fuckbooks
Sep 14, 2004

Now, listen - I know the two of you are very different from each other in a lot of ways, but you have to understand that as far as Grandpa's concerned, you're both pieces of shit! Yeah. I can prove it mathematically.

Sab669 posted:

This is really a dumb question, but I've never really thought about it before.

What's the general consensus on what data type to use to store an encrypted password? Still just varchar? And what length should you allow, then. I suppose that probably varies depending on the type of encryption?
The one big gotcha I ran into with encryption is serialization. If your API is giving you back a bit array and you want to message pass using strings, you need to base64 encode the cyphertext before you pass the message or you'll have problems (don't encode ciphertext or hashes as unicode or ascii, it'll get mangled). The data type for storage doesn't matter as long as the whole internet can't see it though.

Sab669
Sep 24, 2009

Alright, thanks for the info. I was planning on using phpass.

Janitor Prime
Jan 22, 2004

PC LOAD LETTER

What da fuck does that mean

Fun Shoe

Kim Jong III posted:

Don't store encrypted passwords. Don't store encrypted passwords.

Encrypted means recoverable. Use a secure password hashing scheme like bcrypt, PBKDF2, drepper's SHA stretching (see man crypt on a glibc system)...

But don't store encrypted passwords.

Just want to nitpick and say that not all passwords need to be hashed and unrecoverable. For instance the outbound server's SMTP password can be stored encrypted in a database so that the system can later use it to actually send emails. Obviously when talking about user passwords then you need to hash them.

Fruit Smoothies
Mar 28, 2004

The bat with a ZING

pokeyman posted:

In template system parlance, you would pass an instance of this class in as the context for the template. So when the template refers to a variable "foo", the template system would look for a property or method called "foo" on your context object.

Thanks for that link.

I'm not sure how this class system removes the need for programming when a new letter is made. I'd really like to be able to avoid changing the code simply to add a new letter.

Am I stuck having to do it this way, though?

Zhentar
Sep 28, 2003

Brilliant Master Genius
The class you pass into the template contains values (or can retrieve values) for all of the supported variables. You then create a new letter by creating a new template. If your new letter needs some information not supported by your context class, well, then you need programming, but there's no way around that (you can invest man years creating a crazy system that doesn't look like programming but requires all of the same skills and knowledge though!)

Hughmoris
Apr 21, 2007
Let's go to the abyss!
What obscure or old languages are out there and have a ton of market value that someone could teach themselves?

double sulk
Jul 2, 2010

Hughmoris posted:

What obscure or old languages are out there and have a ton of market value that someone could teach themselves?

C

Hughmoris
Apr 21, 2007
Let's go to the abyss!

I was thinking that or maybe COBOL.

darthbob88
Oct 13, 2011

YOSPOS
Algorithm/data structure problem. I'm working on a job queueing system, that orders jobs/customers/orders by the length of the job and the patience of the customer; small jobs for people in a hurry get handled before big jobs for patient people. The problem is the ordering and sorting system; I want to find a job/customer ordering such that sum(Pi * Wi) is minimized, where Pi is the value customer i places on their time, and Wi is the time they wait, equal to the sum of the lengths of preceding jobs, which is where things get complicated.

The simplest way to do this is obviously to brute force it and just check every permutation, but that gets unwieldy quickly. Possibly better would be some kind of backtracking algorithm, if only to reduce the number of trials to brute-force, and Hamiltonian paths seem like an interesting possibility, unfortunately I'm not familiar enough with either method to make them work correctly, and there probably exists a better way to solve this problem.

Before somebody suggests it, yes, I am using a priority queue, it works well, but the sorting leaves something to be desired, hence the question. I'm also storing jobs in a Job class, which contains length of job, price of customer's time, wait time before the job gets handled, and a few other fluff details.

duck monster
Dec 15, 2004

This doesnt really belong anywhere so I'll leave it here. Found on slashdot. CSS to correctly render sarcasm tags.

code:
@namespace url([url]http://www.w3.org/1999/xhtml[/url]);
sarcasm {
text-decoration: blink !important;
}
I have no idea why I found this so funny.

Carthag Tuek
Oct 15, 2005

Tider skal komme,
tider skal henrulle,
slægt skal følge slægters gang



darthbob88 posted:

Algorithm/data structure problem. I'm working on a job queueing system, that orders jobs/customers/orders by the length of the job and the patience of the customer; small jobs for people in a hurry get handled before big jobs for patient people. The problem is the ordering and sorting system; I want to find a job/customer ordering such that sum(Pi * Wi) is minimized, where Pi is the value customer i places on their time, and Wi is the time they wait, equal to the sum of the lengths of preceding jobs, which is where things get complicated.

The simplest way to do this is obviously to brute force it and just check every permutation, but that gets unwieldy quickly. Possibly better would be some kind of backtracking algorithm, if only to reduce the number of trials to brute-force, and Hamiltonian paths seem like an interesting possibility, unfortunately I'm not familiar enough with either method to make them work correctly, and there probably exists a better way to solve this problem.

Before somebody suggests it, yes, I am using a priority queue, it works well, but the sorting leaves something to be desired, hence the question. I'm also storing jobs in a Job class, which contains length of job, price of customer's time, wait time before the job gets handled, and a few other fluff details.

Maybe something like setting an initial priority based on some factor involving patience/job length. Then increase their priorities at some set interval, increasing impatient ones more than patient ones. That way jobs won't get stale in the queue as eventually they will have the highest priority.

This would obviously result in some continual re-evaluation of which job has the highest priority so if that is too expensive, it's probably a bad idea.

tef
May 30, 2004

-> some l-system crap ->

darthbob88 posted:

Algorithm/data structure problem. I'm working on a job queueing system, that orders jobs/customers/orders by the length of the job and the patience of the customer; small jobs for people in a hurry get handled before big jobs for patient people. The problem is the ordering and sorting system; I want to find a job/customer ordering such that sum(Pi * Wi) is minimized, where Pi is the value customer i places on their time, and Wi is the time they wait, equal to the sum of the lengths of preceding jobs, which is where things get complicated.

The simplest way to do this is obviously to brute force it and just check every permutation, but that gets unwieldy quickly. Possibly better would be some kind of backtracking algorithm, if only to reduce the number of trials to brute-force, and Hamiltonian paths seem like an interesting possibility, unfortunately I'm not familiar enough with either method to make them work correctly, and there probably exists a better way to solve this problem.

Before somebody suggests it, yes, I am using a priority queue, it works well, but the sorting leaves something to be desired, hence the question. I'm also storing jobs in a Job class, which contains length of job, price of customer's time, wait time before the job gets handled, and a few other fluff details.

Can you break down the larger jobs into smaller jobs?

Jabor
Jul 16, 2010

#1 Loser at SpaceChem

tef posted:

Can you break down the larger jobs into smaller jobs?

Assuming no value is gained from a partially-completed job, the only time this is ever worthwhile is if you suspend a job when a newly-arrived one is better to spend processing time on.

In all other cases, the result is strictly worse than if you were to process one task to completion before moving on to the next.

shrughes
Oct 11, 2008

(call/cc call/cc)

darthbob88 posted:

Algorithm/data structure problem. I'm working on a job queueing system, that orders jobs/customers/orders by the length of the job and the patience of the customer; small jobs for people in a hurry get handled before big jobs for patient people. The problem is the ordering and sorting system; I want to find a job/customer ordering such that sum(Pi * Wi) is minimized, where Pi is the value customer i places on their time, and Wi is the time they wait, equal to the sum of the lengths of preceding jobs, which is where things get complicated.

The easy and obvious way to order things somewhat sensibly is to do jobs in the order that decreases unhappiness as fast as possible, sorting jobs by Pi/Di, where Di is the duration of the job.

This might even be optimal, consider the case where Pi/Di are equal:

P1=10, D1=10
P2=1, D2=1

If we do job 1 first, we get pain 10*10 + 1*11 = 111. If we do job 2 first, we get pain 1*1 + 10*11 = 111. So it looks promising that that's optimal.

Can we show that P1*D1+P2*(D1+D2) is less than P2*D2 + P1*(D1+D2) if and only if P1/D1 is greater than P2/D2? Well... the following inequality manipulation is reversible, and you can flip the inequality sign or make it an equals sign and it's still true.

P1/D1 > P2/D2
D2*P1 > P2*D1
(P1*D1 + P2*D2) + D2*P1 > (P1*D1 + P2*D2) + P2*D1
P2*D2 + P1*(D1 + D2) > P1*D1 + P2*(D1+D2)

This means that looking at two jobs it's better to take the one that has greater P/D ratio first.

What about permutations of jobs? Well, swapping any two adjacent jobs can be treated in isolation of all the other customers. It always makes sense to go with the job that has the greater P/D ratio first.

This means that every permutation with a pair of adjacent jobs in the wrong order can be improved.

(Ignoring equal P/D values) there's only one permutation that has no adjacent jobs in the wrong order, and none of the other permutations can possibly be the optimal permutation. Which means the permutation sorted by P/D is optimal.

(If there are groups equal P/D values then you just have multiple optimal permutations where the jobs are sorted but the individual groups can be shuffled in any order.)


tl;dr: Sort jobs by the value Pi/Di, where Di is the duration of the job, in decreasing order.



Edit: You should be warned that Pi isn't really a constant per customer -- customers can get more irate over time.

shrughes fucked around with this message at 09:18 on Jul 27, 2012

baquerd
Jul 2, 2007

by FactsAreUseless

shrughes posted:

Edit: You should be warned that Pi isn't really a constant per customer -- customers can get more irate over time.

Yeah, add an aging function that logarithmically increases Pi over time or something.

Nifty
Aug 31, 2004

Is there a way to view the code or purpose of a .cmd file

leper khan
Dec 28, 2010
Honest to god thinks Half Life 2 is a bad game. But at least he likes Monster Hunter.

Nifty posted:

Is there a way to view the code or purpose of a .cmd file

Open a text editor?

Sab669
Sep 24, 2009

Yea, right click -> Open with Notepad...

qntm
Jun 17, 2009

darthbob88 posted:

Algorithm/data structure problem. I'm working on a job queueing system, that orders jobs/customers/orders by the length of the job and the patience of the customer; small jobs for people in a hurry get handled before big jobs for patient people. The problem is the ordering and sorting system; I want to find a job/customer ordering such that sum(Pi * Wi) is minimized, where Pi is the value customer i places on their time, and Wi is the time they wait, equal to the sum of the lengths of preceding jobs, which is where things get complicated.

The simplest way to do this is obviously to brute force it and just check every permutation, but that gets unwieldy quickly. Possibly better would be some kind of backtracking algorithm, if only to reduce the number of trials to brute-force, and Hamiltonian paths seem like an interesting possibility, unfortunately I'm not familiar enough with either method to make them work correctly, and there probably exists a better way to solve this problem.

Before somebody suggests it, yes, I am using a priority queue, it works well, but the sorting leaves something to be desired, hence the question. I'm also storing jobs in a Job class, which contains length of job, price of customer's time, wait time before the job gets handled, and a few other fluff details.

As stated, this is a pretty simple question. Let's give Pi a "cost" unit like "dollars per second", then you can see that you want to minimise the total "cost" accrued over the course of running all the jobs.

You want to minimise the total cost of running all the jobs. That takes a fixed amount of time. At any given instant in time, the rate at which cost is increasing is sum(Pi) over all of the customers i still waiting for their jobs to complete.

To minimise this rate, you obviously just need to handle jobs in cost order, starting with the most "expensive" jobs and finishing with the least.

EDIT: Wait, ignore this.

qntm fucked around with this message at 17:33 on Jul 27, 2012

Doctor Malaver
May 23, 2007

Ce qui s'est passé t'a rendu plus fort
Let's say I want to make a soccer player transfer site. I would fill a database with all the transfers I can find. Then a user would come and select their club and transfer parameters they are interested in. For instance - the user picks Real Madrid and wants to know about transfers to this club from Italian Serie A, from Arsenal if they are over $xx, and from any club in Sweden if the player is a forward.

The user could then see recent transfers that match this criteria and could subscribe to be informed about future transfers (which again match this criteria) by email.


How would I go about organizing this? Can Wordpress do this all? Could an average web developer set it up without help from some database admin and how much time (in very broad terms) in man/hours would it take?

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
I'm working with some legacy FORTRAN 77–style code. Fixed with, comment lines starting with 'c' and continuation marks as the 6th character and so on. It's a lovely situation but nothing I can do about it.

I use Vim and something that's really annoying is when there's a comment like

code:
c The quick brown fox didn't jump over the lazy dog.

[some code here]
That ' mark completely messes up my syntax highlighting. Everything changes color, possibly because it's waiting for a closing ' mark. I'm using the Solarized theme if this makes any difference.

Is there a setting or something I can adjust to fix this? Right now what I do is just delete the offending ' mark, but it's a little bit annoying because I have to remember to add it back before I commit or else other people complain about it when I push it upstream.

little munchkin
Aug 15, 2010

Doctor Malaver posted:

How would I go about organizing this?
Use a web scripting language, like Python or PHP, to write a bunch of ways to request and display the data, find a way to scrape transfer information from another website or database, and insert it into your own, and find a way to update the transfers without accidental duplicates or anything.

Doctor Malaver posted:

Can Wordpress do this all?
You could probably find a way to make that work, but it's blogging software and not really meant for what you're talking about.

Doctor Malaver posted:

Could an average web developer set it up without help from some database admin.
You wouldn't need an expert, but it will require that kind of knowledge. Django is a web framework that lets you work with databases without writing any SQL, so that might be a good option for you.

Doctor Malaver posted:

how much time (in very broad terms) in man/hours would it take?

In very broad terms, 5-1000 hours.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

oops, didn't refresh.

darthbob88
Oct 13, 2011

YOSPOS

shrughes posted:

tl;dr: Sort jobs by the value Pi/Di, where Di is the duration of the job, in decreasing order.

Edit: You should be warned that Pi isn't really a constant per customer -- customers can get more irate over time.

That's actually what I'm already doing, and I just thought it was a naive comparison that could be done better. Apparently it can't, so I'll just keep on with that. Thanks for the help.

Yeah, in real life, Pi would be slowly increasing, I'd just assumed a fairly constant value and patience. Will have to add that to the model.

Adbot
ADBOT LOVES YOU

The Collector
Aug 9, 2011

I've seen things you people wouldn't believe.
Rats raining down in the night during the Stanley Cup finals.
All those moments will be lost in time, like tears in rain.
Pillbug
I started learning sql a while back by using this site http://sqlzoo.net/ (among other things). I had to stop for a bit, and I'm starting to pick it up again. Are there any similar/better sites out there or is this my best bet?

apologies if this is the wrong thread :ohdear:

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply