Jeez, seriously guys. It feels like I've forgotten how to tie my laces, or ride a bike.
I opened up Visual Studio, almost 12mths to the day after I last did, and wow. Talk about noob.
Where do you start? I reckon I could do some basic stuff but how far could I go before I need to yell for help on http://www.aspadvice.com ?
I recall now once an ex-boss saying ".NET, how hard can it be? We can train this guy up in 6weeks no?". I nearly resigned that day. There's things that make it easier than what it was like 5yrs ago, but there's so much new stuff now that you think, "Where do I start?????"
I always found the best way to learn something is to have a goal in mind. There's no point just keep looking at snippets and MSDN movies if they are just random bits of knowledge - you have to have some purpose in mind in order that your head-guy can put it in the right pigeon hole. So. Here's my mini requirements.
I recently passed the Police sergeants exam (Yay!). We all received our feedback the other day and basically, the exam was split into 4 sections (Crime, traffic etc). Each one required a 55% pass rate
(
And before you all go 55%??!!! - the exam is rock hard. Multiple choice and the choices are sometimes
a) Believe
b) Suspect
c) Know
d) Reasonably suspect
)
However. Some people managed to get like 4% for some sections and I was (like you) thinking - how??? Its multiple choice. What are the chances of getting less than say 20% in an exam with 140 questions? And there's my first learning project.
Write a system that
· Creates 140 random questions, in one of 4 categories, with a random right answer for each (Q1 (CAT1), Answer a. Q2(CAT2) Answer b, Q3(CAT1) Answer b etc). Those categories had a set number of questions in
· Dump them in a database.
· Run a random sequence of answers for 7783 candidates (eg - how many sat the English Sergeants exam in March 2005)
· Dump them in the database
· Compare the averages with those actually achieved in the exams (ie - highest score, lowest score, averages per category, etc)
· Make some bar charts?
· Look at frequencies??
· Did one category do any better than any of the others?
· And so on.
So. To begin. Make the database - dead simple schema, and as my SQL is ok (I'm hoping..!), I don't need to brush up on it too much so I won't go overboard.
USE [Exam]
GO
/****** Object: Table [dbo].[question] Script Date: 05/21/2005 13:39:41 ******/
CREATE TABLE [dbo].[question](
[question_q_id] [int] IDENTITY(1,1) NOT NULL,
[question_category] [int] NOT NULL,
[question_answer] [int] NOT NULL
) ON [PRIMARY]
GO
As you can see, I'm not putting the actual questions or answers in, this is just for sake of art.
I now need a process thats going to create my questions, based on the weightings
CAT1 - 25 Q's
CAT2 - 34 Q's
CAT3 - 43 Q's
CAT4 - 38 Q's
There are a number of ways of doing this, I considered a view to make this dynamic for the future, but I reckon easiest would be to just hardcode it in the insertion routine
So (Cracking knuckles), I finally get to open Visual Studio 2005 with a purpose in mind. Lets make a form app. My first immediate thing is that once again the design form is locked at the left and the Toolbox opens on top of it. I *hate* that. Hate hate hate. I like the new shadowed anchors though that tell you were to drop the window in order for it to add itself to the right hand bar.
I want to click a button, see whats going into the database, then see the state of the database after that insertion (ie, how many categories have been used up, how many questions generated etc.). Buttons are the same, labels too but what's DataGridView??? I know what a datagrid is but this looks sexy. How good is the wizard? Lets see..
Choose data source, none available so it tells me to make one.
Add Project data source
New Connection... all good so far
Test, choose data objects to go in the datagrid, Done.
<Insert_amazed_expletive_of_choice> here... If that works first time I'll be well impressed.
I can't tell you how long that would have taken in notepad!
Me.Vw_categories_leftTableAdapter.Fill(Me.ExamDataSet.vw_categories_left)
Awesome... :D
Aaaaaaaand - it works!!!!
Sexy shit indeed.
Damnit – daughter has rebooted my machine. Grrr…it’s not saved. Never mind
Next step is to insert the random questions, which means I need to generate them first, which means I need a question object first?? Where do I build a question object? I recall vaguely it went in Main() .. gimme a sec.
Solution Explorer, Add New Item..
(Splash screen?!)
(Just seen module, I think my function needs to go in there..)
Class?
Holy crap, this is getting far too complex now. I need help. Scrap the objects for now, revert back to simple code (eg, hide head in sand).
Make a random number between 1 and 4 – how easy could that be? Snippet?
Yes!
Dim generator As New Random
Dim randomValue As Integer
' Generates numbers between 1 and 5, inclusive.
randomValue = generator.Next(1, 6)
Hmm, not really random if memory serves me correctly (it doesn’t) but it’ll do. We used to do it using the current time as the seed. Ctype(System.datetime.now..ermm something something)
Public Function make_random_number(ByVal iCat As Integer) As Integer
Dim generator As New Random(CType(System.DateTime.Now.Ticks Mod System.Int32.MaxValue, Integer))
' Generates numbers between 1 and 5, inclusive.
Return generator.Next(1, 5)
End Function
Seems to work J - HOWEVER – its not as good as just using New Random() on its own???!!!
So now I need to know how to insert into the database. I’ll definitely have to look this one up.
Looking at the snippets it seems the best way is to make a datatable from my random numbers and then update the database with that. I just want to get this working though now, getting tired. Simple insert?
There's a snippet for an update which should work, if I add the sqlConnection object and change the update to an insert.
Dim oConnection As New SqlClient.SqlConnection("Data Source=yoda;Initial Catalog=Exam;Integrated Security=True")
Dim UpdateStatement As String = " "INSERT INTO [Exam].[dbo].[question] ([question_category],[question_answer]) VALUES (" & iCat & " ," & iRan & ")""
Dim UpdateCommand As New SqlClient.SqlCommand(UpdateStatement, oConnection)
Try
oConnection.Open()
Dim rowCount As Integer
rowCount = UpdateCommand.ExecuteNonQuery()
Catch ex As Exception
Throw ex
Finally
oConnection.Close()
End Try
I **LOVE** the way the snippet thing iterates down and changes the object names as you type them in. Well thought out for noobs and pro’s alike.
After a few runs of my amateur routine its quite clear that the questions aren’t being randomly generated. The time element of the generator is too fast, so I added in a threading.thread.sleep(randomNumber) to make it livelier. Then I discovered that the random generator actually produced MORE random numbers than doing it the old way with system.time etc. The whole thing now looks like this:
Imports System.Data
Public Class Form1
Private Sub btn_Start_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btn_Start.Click
' Cat1 = 25, 2=34, 3=43, 4=38
lbl_Progress.Text = "Working.."
Dim iCtr As Integer = 25
For iCtr = 1 To 25
If iCtr = 1 Then
insert_question_to_database(1, make_random_number(5), True)
Else
insert_question_to_database(1, make_random_number(5), False)
End If
Next
For iCtr = 1 To 34
insert_question_to_database(2, make_random_number(5), False)
Next
For iCtr = 1 To 43
insert_question_to_database(3, make_random_number(5), False)
Next
For iCtr = 1 To 38
insert_question_to_database(4, make_random_number(5), False)
Next
lbl_Progress.Text = "Done. Reload the view"
Me.Vw_categories_leftTableAdapter.Fill(Me.ExamDataSet1.vw_categories_left)
End Sub
Public Function make_random_number(ByVal max_Num As Integer) As Integer
Dim generator As New Random()
' Generates numbers between 1 and 5, inclusive.
Return generator.Next(1, max_Num)
End Function
Public Function insert_question_to_database(ByVal iCat As Integer, ByVal iRan As Integer, ByVal bFirstRun As Boolean) As Boolean
Dim oConnection As New SqlClient.SqlConnection("Data Source=yoda;Initial Catalog=Exam;Integrated Security=True")
Dim UpdateStatement As String
‘ if this is the first run, delete the contents of Exam.
If bFirstRun = True Then
UpdateStatement = "Truncate table question; " & "INSERT INTO [Exam].[dbo].[question] ([question_category],[question_answer]) VALUES (" & iCat & " ," & iRan & ")"
Else
UpdateStatement = "INSERT INTO [Exam].[dbo].[question] ([question_category],[question_answer]) VALUES (" & iCat & " ," & iRan & ")"
End If
Dim UpdateCommand As New SqlClient.SqlCommand(UpdateStatement, oConnection)
Try
oConnection.Open()
Dim rowCount As Integer
rowCount = UpdateCommand.ExecuteNonQuery()
Catch ex As Exception
Throw ex
Finally
oConnection.Close()
End Try
Return True
End Function
End Class
Ok, a bit simplistic but it’s done what I want without too much fuss. Heavy on the SQL, too much traffic over the wire, too many inserts as opposed to one dataset update but I’m happy with it, considering it’s my second day on the job. I WILL HOWEVER BE GRATEFUL FOR POINTERS ON THE NEW WAY OF DOING THINGS (Ta).
Now, keeping the same logic, I’ll add in the 7783 random entries and see if the averages reflect those of the actual exam and whether virtual monkeys could have achieved better results…
For iCtr = 1 To 7783
For iQ = 1 To 140
insert_answer_to_database(iCtr, iQ, make_random_number(5), False)
Next
Next
?? Pffft Lol. After about 2mins of grinding along I realised just how_bad this method was.
What did I miss?? 7783*140 = 1,089,620 inserts.
Did I destroy the connection object? NO (Slap).
Makes no difference though.
I think I’m going to have to dig into objects, create a dataset, hold it in memory and then update the table using the dataset.
OR, I could go shopping instead.
‘goes shopping….One hour later its almost finished…. OKAY! I’ll do a bloody collection…
This took me an afternoon to blunder through. Its quite clear to me (now) that I really need to brush up on my collections, OOP and datasets/views/etc before I can make something halfway decent. I suppose my next ramblings will be about collections. As a sneak preview, the highest random score was 56%, which means there’s some really thick coppers in England lol.