Array Problems
-
Saturday, September 29, 2012 6:50 AM
Hi there, pretty new to coding in small basic but I'm making some good progress. However I'm having trouble with using arrays. I want to compare the input from the user against the values in an array, and if they match to display a certain line of text, and if not to display a different line of text. Syntax wise there is no problem so I can't see the error. Any help appreciated.
Code:
TextWindow.Write("Login: ")
loginfield = TextWindow.Read()
login[0]["user1"]="root"
login[0]["user2"]="su"
login[0]["user3"]="admin"
If loginfield = login[0] Then
TextWindow.WriteLine("Logged in...")
Else
TextWindow.WriteLine("Login failed...")
EndIf- Edited by tem_php Saturday, September 29, 2012 6:57 AM
All Replies
-
Saturday, September 29, 2012 8:27 AMAnswerer
Welcome tem_php!
login is a 2D array variable; and login[0] is just 1 of its dimension.
if you include -> TextWindow.WriteLine( login[0] ) in the end of code, you'll see this result:
user1=root;user2=su;user3=admin;
Obviously, loginfield would not be equal to that long string, 'cause no user would type that as login. :P
As you can see, in SB, arrays are nothing more than a big string after this model -> index=value; and so on.
Now, SB provides a category to manipulate all things array -> the object Array.
And among those, the one you need is this one -> Array.ContainsValue().
Just replace If loginfield = login[0] Then with this one -> Array.ContainsValue( login[0] loginfield ).
It returns True if login[0] contains any value = loginfield inside it!
Besides that, I'd also advise you to convert all of user typed into lower-case letters.
Replace loginfield = TextWindow.Read() with this -> loginfield = Text.ConvertToLowerCase( TextWindow.Read() ).
So you don't need to worry about whether user used Shift/Caps-Lock anymore.
Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)
- Edited by GoToLoopEditor Saturday, September 29, 2012 8:29 AM
- Edited by GoToLoopEditor Saturday, September 29, 2012 8:30 AM
- Proposed As Answer by Noah Buscher Monday, October 01, 2012 3:16 AM
- Marked As Answer by Ed Price - MSFTMicrosoft Employee, Owner Thursday, October 18, 2012 2:52 AM
-
Saturday, September 29, 2012 8:48 AMThanks for the help, worked perfectly! Like I say I just started using sb recently (well about two days ago) so I'm sure I'll be on here frequently asking for help haha, but its a lot of fun learning about how programs work...in a previous iteration of this code I was just comparing the input to multiple individual values but having to write all that code seemed like a waste when you can parse using arrays. Anyway many thanks for the help again :)
-
Saturday, September 29, 2012 10:21 PM
Alas I'm back with another query. I have two arrays, one with usernames array[0] and one with passwords array[1], if I want soemone to be able to login but only have certain username and password combinations availible how would I do that, I have some example code I wrote but it doesnt quite work...
Code:
'TextWindow Attributes
TextWindow.Title="Terminal" 'Set TextWindow title
TextWindow.ForegroundColor="Green" 'Set text in TextWindow to green
'Login Array setup
user[0]["rootuser"]="root"
user[0]["superuser"]="su"
user[0]["administrator"]="admin"
'Password Array setup
password[1]["rootuser"]="master"
password[1]["superuser"]="super"
password[1]["administrator"]="admin"
'TextWindow welcome
TextWindow.WriteLine("Starting terminal...")
TextWindow.WriteLine("")
TextWindow.WriteLine(Clock.Date)
TextWindow.WriteLine(Clock.WeekDay)
TextWindow.WriteLine(Clock.Time)
TextWindow.WriteLine("")
TextWindow.WriteLine("Welcome to the VMachines Gateway. Please login to continue...")
TextWindow.Write("Login: ")
login = Text.ConvertToLowerCase(TextWindow.Read())
TextWindow.Write("Password: ")
password = Text.ConvertToLowerCase(TextWindow.Read())
'Login conditions
If Array.ContainsValue(user[0]["rootuser"]login) And Array.ContainsValue(password[1]["rootuser"]password) Then
Goto loginaccept
ElseIf Array.ContainsValue(user[0]["superuser"]login) And Array.ContainsValue(password[1]["superuser"]password) Then
Goto loginaccept
ElseIf Array.ContainsValue(user[0]["administrator"]login) And Array.ContainsValue(password[1]["administrator"]password) Then
Goto loginaccept
Else
Goto loginreject
EndIf
'Login welcome screen
loginaccept:
TextWindow.WriteLine("Login successful, please wait...")
'Login rejection screen
loginreject:
TextWindow.WriteLine("Login rejected, closing terminal...") -
Sunday, September 30, 2012 7:37 AM
Change my code a fair bit but still no results, new code:
I just feel that this is too much code to have values in one array to match corresponding values in another array, I've tried lots of variations on this kind of code but to no avail, help desperately needed :)
'Login Array setup
user[0]["root"]="root"
user[1]["superuser"]="su"
user[2]["administrator"]="admin"
'Password Array setup
password[4]["root"]="master"
password[5]["superuser"]="super"
password[6]["administrator"]="admin"
'TextWindow welcome
TextWindow.WriteLine("Starting terminal...")
TextWindow.WriteLine("")
TextWindow.WriteLine(Clock.Date)
TextWindow.WriteLine(Clock.WeekDay)
TextWindow.WriteLine(Clock.Time)
TextWindow.WriteLine("")
TextWindow.WriteLine("Welcome to the VMachines Gateway. Please login to continue...")
Goto logincon
'Login conditions
logincon:
TextWindow.Write("Login: ")
login = Text.ConvertToLowerCase(TextWindow.Read())
If Array.ContainsValue(user[0]login) Then
Goto pass0
ElseIf Array.ContainsValue(user[1]login) Then
Goto pass1
ElseIf Array.ContainsValue(user[2]login) Then
Goto pass2
Else
TextWindow.WriteLine("Invalid login...")
Goto terminalclose
EndIf
'Password conditions
pass0:
TextWindow.Write("Password: ")
password = Text.ConvertToLowerCase(TextWindow.Read())
If Array.ContainsValue(password[4]password) Then
Goto loginaccept
Else
Goto loginreject
EndIf
pass1:
TextWindow.Write("Password: ")
password = Text.ConvertToLowerCase(TextWindow.Read())
If Array.ContainsValue(password[5]password) Then
Goto loginaccept
Else
Goto loginreject
EndIf
pass2:
TextWindow.Write("Password: ")
password = Text.ConvertToLowerCase(TextWindow.Read())
If Array.ContainsValue(password[6]password) Then
Goto loginaccept
Else
Goto loginreject
EndIf
'Login welcome screen
loginaccept:
TextWindow.WriteLine("Login successful, please wait...")
Goto systemload
'Login rejection screen
loginreject:
TextWindow.WriteLine("Login rejected, closing terminal...")
Goto terminalclose
'Terminal Close
terminalclose:
Program.Delay(1000)
Program.End() -
Sunday, September 30, 2012 8:05 AM
Just changed the password conditions code to this:
The system works now, but I would really like to know if there is some way that I can condense the code down as the way it stands, there is so much code that it seems pointless to use arrays for the login names and passwords, as it would be similar amounts of code by asking if the user input matches an exact string ala If password = ("....")
'Password conditions
pass0:
TextWindow.Write("Password: ")
password0 = Text.ConvertToLowerCase(TextWindow.Read())
If Array.ContainsValue(password[0]password0) Then
Goto loginaccept
Else
Goto loginreject
EndIf
pass1:
TextWindow.Write("Password: ")
password1 = Text.ConvertToLowerCase(TextWindow.Read())
If Array.ContainsValue(password[1]password1) Then
Goto loginaccept
Else
Goto loginreject
EndIf
pass2:
TextWindow.Write("Password: ")
password2 = Text.ConvertToLowerCase(TextWindow.Read())
If Array.ContainsValue(password[2]password2) Then
Goto loginaccept
Else
Goto loginreject
EndIf
-
Sunday, September 30, 2012 8:38 AMAnswerer
Hey again!
I still haven't taken the time to analyze your code. But with a quick look, I was able to spot some interesting issues:
Most obvious one is that you use Goto to leap onto sections of your code!
Goto is considered the bane of good programming for good reasons; for it creates what most programmers call spaghetti code! You lose track where the code have to return from after a task very easily.
I see that your code is well organized in sections like: TextWindow welcome, Login conditions, Password conditions and so on.
What's missing is that you turn all of them into subroutines! For that, you put that section of code within a block Sub ... EndSub. See the example below:
Sub Welcome TextWindow.WriteLine("Starting terminal...") TextWindow.WriteLine("") TextWindow.WriteLine(Clock.Date) TextWindow.WriteLine(Clock.WeekDay) TextWindow.WriteLine(Clock.Time) TextWindow.WriteLine("") TextWindow.WriteLine("Welcome to the VMachines Gateway. Please login to continue...") EndSubNow, you just need to use Welcome() in any place within your program to call the code section above. After the subroutine finishes, execution returns right after the Welcome() line!
Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)
- Edited by GoToLoopEditor Sunday, September 30, 2012 8:39 AM
- Marked As Answer by Ed Price - MSFTMicrosoft Employee, Owner Thursday, October 18, 2012 2:52 AM
-
Sunday, September 30, 2012 8:57 AM
Thanks for the Sub tip :) I've quickly realized that you really have to break a program up into many 'modules' of code to keep everything looking neat and manageble, the first iteration of this program was basically one long block of code with no breaks! I was using a lot of Goto statements because I was always thinking of the Goto (linenumber) command from the other more traditional BASIC languages, but I'll go back through and rewrite in those subroutines. I guess even though I am a beginner I just have the 'ambition' to try and make everything as concise and efficient as possible...I have read through the small basic literature from Microsoft but there are a lot of things I wish to do that they don't cover in as much detail as I hoped. Anyway back to the keyboard, thanks again...
I could always send you the files for the program if you wanted to see in more detail.
Many thanks!
EDIT: Just wrote a tiny bit of code using the subroutine stuff to test it out, works very nice! Code:
Sub Welcome
TextWindow.WriteLine("Welcome to the system")
EndSub
Sub Goodbye
TextWindow.WriteLine("Goodbye")
EndSub
TextWindow.Write("Login: ")
login=TextWindow.Read()
If login="happy" Then
Welcome()
Else
Goodbye()
EndIf- Edited by tem_php Sunday, September 30, 2012 9:21 AM
-
Sunday, September 30, 2012 10:05 AMAnswerer
... there is so much code that it seems pointless to use arrays for the login names and passwords, as it would be similar amounts of code by asking if the user input matches an exact string ala If password = ("....")
Well, here comes 2nd part:
Databases need some planning ahead to implement. Studying your code, I think you were intending to have 3 field categories -> user, pass & rank.
Like this one -> "su" as user login, "super" as its password and "superuser" as its access rank or something like that. :P
So here's what I did to lay the idea:
Sub Credentials logins[1]["user"] = "root" logins[2]["user"] = "su" logins[3]["user"] = "admin" logins[1]["rank"] = "root" logins[2]["rank"] = "superuser" logins[3]["rank"] = "administrator" logins[1]["pass"] = "master" logins[2]["pass"] = "super" logins[3]["pass"] = "admin" loginCount = Array.GetItemCount(logins) ' <--- number of "system" user logins EndSub
As you can see, each index number has 3 category fields -> ["user"], ["rank"] & ["pass"]
loginCount stores the current number of users registered within system database logins[][].
Now, the trick to check each one is to use a For ... EndFor loop w/ loginCount as the number of iterations:
For index = 1 To loginCount If user = logins[index]["user"] Then hasFound = "True" ' <--- flags we've found a match! index = loginCount ' <--- a hack trick to make For Loop finish earlier! EndIf EndForAnd finally the full source code. Study it & enjoy!
'###################################################' ' Login Example ' http://social.msdn.microsoft.com/Forums/en-US/smallbasic '/thread/3355d96e-9eb6-48ab-9ec9-377f1024d04c '###################################################' '_________________________________________________________________________' TextWindow.ForegroundColor = "Black" TextWindow.BackgroundColor = "Yellow" TextWindow.Clear() TextWindow.Title = "Login Example" LF = Text.GetCharacter(10) Credentials() While isLogged <> "True" AskLogin() EndWhile TextWindow.WriteLine(LF + user + " logged in as " + rank + " class operator!" + LF) TextWindow.Title = user + " as " + rank '_________________________________________________________________________' Sub Credentials logins[1]["user"] = "root" logins[2]["user"] = "su" logins[3]["user"] = "admin" logins[1]["rank"] = "root" logins[2]["rank"] = "superuser" logins[3]["rank"] = "administrator" logins[1]["pass"] = "master" logins[2]["pass"] = "super" logins[3]["pass"] = "admin" loginCount = Array.GetItemCount(logins) ' <--- number of "system" user logins EndSub '_________________________________________________________________________' Sub AskLogin TextWindow.WriteLine("Type in user: " + LF) user = Text.ConvertToLowerCase( TextWindow.Read() ) hasFound = "False" For index = 1 To loginCount If user = logins[index]["user"] Then hasFound = "True" ' <--- flags we've found a match! index = loginCount ' <--- a hack trick to make For Loop finish earlier! EndIf EndFor If hasFound Then AskPassword() Else TextWindow.WriteLine(LF + user + " is not in our database!" + LF) Sound.PlayBellRing() EndIf EndSub '_________________________________________________________________________' Sub AskPassword TextWindow.WriteLine(LF + "Type in password: " + LF) pass = Text.ConvertToLowerCase( TextWindow.Read() ) hasFound = "False" For index = 1 To loginCount If pass = logins[index]["pass"] Then hasFound = "True" ' <--- flags we've found a match! isLogged = "True" ' <--- finally logged in! rank = logins[index]["rank"] ' <--- gets user's access rank Sound.PlayChime() index = loginCount ' <--- a hack trick to make For Loop finish earlier! EndIf EndFor If hasFound <> "True" Then TextWindow.WriteLine(LF + "Wrong password ! You have to try again!!!" + LF) Sound.PlayBellRing() EndIf EndSub '_________________________________________________________________________'
Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)
- Edited by GoToLoopEditor Sunday, September 30, 2012 10:13 AM
- Edited by GoToLoopEditor Sunday, September 30, 2012 10:20 AM
- Marked As Answer by Ed Price - MSFTMicrosoft Employee, Owner Thursday, October 18, 2012 2:53 AM
- Edited by GoToLoopEditor Thursday, October 18, 2012 10:43 AM
-
Monday, October 01, 2012 6:23 AM
Thanks for the sample code...had a pretty busy day today so I haven't had much time to go over it and investigate the structure but will sure implement this kind of code in my program. will probably post the rectified code tommorow sometime so watch out :)
How long have you been programming using sb?
-
Thursday, October 18, 2012 2:53 AMOwner
-
Thursday, October 18, 2012 3:26 AMAnswererJust re-sent an e-mail for you again!
Click on "Propose As Answer" if some post solves your problem or "Vote As Helpful" if some post has been useful to you! (^_^)

