ZH's software thread

Place to talk about all that new hardware and decaying software you have.

Moderator: General Mods

Post Reply
ZH/Franky

Post by ZH/Franky »

Alright, I've been messing around with functions, and decided to go back and try to improve some of my programs.
ISBN-13 Validator (you'll also see that I've removed the need for arrays in this program, if you compare it to the previous version):

Code: Select all

Option Explicit On
Module Module1

    Dim isbn As String
    Function verify_checksum(ByRef x As String) As Boolean
        Dim total, check As Integer
        verify_checksum = True
        total = 0
        For pos = 2 To 12 Step 2
            total = total + (Convert.ToInt32(Mid(x, (pos - 1), 1))) + (3 * (Convert.ToInt32(Mid(x, pos, 1))))
        Next
        check = (10 - (total Mod 10)) Mod 10
        If check <> Convert.ToInt32(Mid(x, 13, 1)) Then
            verify_checksum = False
        End If
    End Function

    Sub Main()
        Console.WriteLine("ISBN-13 Validation")
        Console.WriteLine("To exit, type 'quit' and hit return")
        Console.WriteLine()
        Do
            Call isbn13_validate_input()
            If verify_checksum(isbn) <> True Then
                Console.WriteLine("Invalid ISBN-13 number")
            Else
                Console.WriteLine("Valid ISBN-13 number")
            End If
        Loop
    End Sub

    Sub isbn13_validate_input()
        Do
            Console.Write("?: ")
            isbn = Console.ReadLine()
            If isbn = "quit" Then
                End
            ElseIf isbn = "" Then
            ElseIf isbn Like "#############" Then
                Exit Do
            Else
                Console.WriteLine("Invalid input")
            End If
        Loop
    End Sub

End Module
Also got bored again and wrote a binary counter:

Code: Select all

Option Explicit On
Module Module1

    Function dec2bin(ByVal a As Double) As String
        dec2bin = ""
        Do Until a = 0
            If ((a / 2) - Int(a / 2)) <> 0 Then
                dec2bin = "1" + dec2bin
            Else
                dec2bin = "0" + dec2bin
            End If
            a = Int(a / 2)
        Loop
    End Function

    Sub Main()
        Dim digit, mem As Double
        Do
            mem = 0
            Do
                mem = mem + 1
                digit = mem
                Console.WriteLine(dec2bin(digit))
                System.Threading.Thread.Sleep(100)
                If mem = (2 ^ 32) Then
                    Exit Do
                End If
            Loop
        Loop
    End Sub

End Module
I want to start looking at structures soon, to try and create my own data types. I feel like trying my hand at database programming.
sweener2001
Inmate
Posts: 1751
Joined: Mon Dec 06, 2004 7:47 am
Location: WA

Post by sweener2001 »

grinvader wrote:
sweener2001 wrote:exception handling was thrown out pretty quick, while he was still grasping some basics. unless recursion is the devil, nobody bothered to mention that factorials are like 3 lines of C++ using recursion instead of the paragraphs he was posting. but exception handling, which is kind of advanced, was thrown out immediately.
Learning how to make short code can wait.
Learning how to make good code is prioritary.

Once you have coded stuff without any user-input validation for 5 years, you're reluctant to start adding that tedious (yet essential) part of code, and you end up writing stuff like all those proggies with buffer overflow exploits and whatnots.

Better learn early to do the tiring stuff so you're used to it and code/check for it automatically.

Writing clean and short can wait, since you'll eventually be interested in that and will (should) naturally improve over time.
i agree with learning early, that wasn't the issue. it just seemed like he's not ready to actually learn it yet. it was the placement in the learning process. but i suppose that's entirely an opinion thing.
[img]http://i26.photobucket.com/albums/c128/sweener2001/StewieSIGPIC.png[/img]
ZH/Franky

Post by ZH/Franky »

sweener2001 wrote:
grinvader wrote:
sweener2001 wrote:exception handling was thrown out pretty quick, while he was still grasping some basics. unless recursion is the devil, nobody bothered to mention that factorials are like 3 lines of C++ using recursion instead of the paragraphs he was posting. but exception handling, which is kind of advanced, was thrown out immediately.
Learning how to make short code can wait.
Learning how to make good code is prioritary.

Once you have coded stuff without any user-input validation for 5 years, you're reluctant to start adding that tedious (yet essential) part of code, and you end up writing stuff like all those proggies with buffer overflow exploits and whatnots.

Better learn early to do the tiring stuff so you're used to it and code/check for it automatically.

Writing clean and short can wait, since you'll eventually be interested in that and will (should) naturally improve over time.
i agree with learning early, that wasn't the issue. it just seemed like he's not ready to actually learn it yet. it was the placement in the learning process. but i suppose that's entirely an opinion thing.
Well, validation is pretty much independant of actual programming. I mean let's say you want to enter a peice of data in a certain notation: you know what's valid and what is not. So you can think like a computer (if, elseif, else, while, until, etc, etc) and actually write that in code. From what I've learnt, exception handling isn't exactly rocket science either.

I mean, try: ok, let's try something.
catch exception: ok, clearly I'm raping myself, so I need to do something about it.
finally: regardless of whether an error occurs, I do something else.
And you can entwine exception handling statements with each other. E.g.

Code: Select all

try
  something = something_else / some_other_thing
catch ex as exception
  ' oops, I'm raping myself
  do something about the problem
finally
  ok, let's do this
  try
    Oi oi, let's do some of THIS crazy shit
  catch self_rape
    oh fuck, I'm raping myself again
    let's do this
  end try
end try
blah blah blah
Obviously there's more to exception handling, but I can fully understand what I'm doing with the current error handling routines I write.


I'm actually going to create my own motto:
"Programming is as hard as the problem at hand"
Last edited by ZH/Franky on Sun Nov 30, 2008 4:29 am, edited 1 time in total.
ZH/Franky

Post by ZH/Franky »

Alright, today I've definitely realized that functions are awesome. I've added more awesomation to my ISBN-13 validator:

Code: Select all

Option Explicit On
Module Module1

    Dim isbn As String

    Function verify_checksum(ByRef x As String) As Boolean
        Dim total, check As Integer
        verify_checksum = True
        total = 0
        If x Like "#############" Then
            For pos = 2 To 12 Step 2
                total = total + (Convert.ToInt32(Mid(x, (pos - 1), 1))) + (3 * (Convert.ToInt32(Mid(x, pos, 1))))
            Next
            check = (10 - (total Mod 10)) Mod 10
            If check <> Convert.ToInt32(Mid(x, 13, 1)) Then
                Console.WriteLine("Invalid ISBN-13 number")
                verify_checksum = False
            End If
        Else
            Console.WriteLine("Invalid input")
            verify_checksum = False
        End If
    End Function

    Sub Main()
        Console.WriteLine("ISBN-13 Validation")
        Do
            Console.Write("?: ")
            isbn = Console.ReadLine()
            If verify_checksum(isbn) = True Then
                Console.WriteLine("Valid ISBN-13 number")
            End If
        Loop
    End Sub

End Module
EDIT:

Code: Select all

Option Explicit On
Module Module1

    Dim isbn As String

    Function verify_checksum(ByRef x As String) As Boolean
        Dim total, check As Integer
        verify_checksum = True
        total = 0
        If x Like "#############" Then
            For pos = 2 To 12 Step 2
                total = total + (Convert.ToInt32(Mid(x, (pos - 1), 1))) + (3 * (Convert.ToInt32(Mid(x, pos, 1))))
            Next
            check = (10 - (total Mod 10)) Mod 10
            If check <> Convert.ToInt32(Mid(x, 13, 1)) Then
                Console.WriteLine("Invalid ISBN-13 number")
                verify_checksum = False
            End If
        Else
            Console.WriteLine("Invalid input")
            verify_checksum = False
        End If
    End Function

    Sub Main()
        Console.WriteLine("ISBN-13 Validation")
        Do
            Do
                Console.Write("?: ")
                isbn = Console.ReadLine()
            Loop Until verify_checksum(isbn) = True
            Console.WriteLine("Valid ISBN-13 number")
        Loop
    End Sub

End Module
EDIT 2: OMFG,

Code: Select all

Option Explicit On
Option Strict On
Module Module1

    Dim isbn As String

    Function verify_checksum(ByRef x As String) As Boolean
        Dim total, check As Integer
        verify_checksum = True
        total = 0
        If x Like "#############" Then
            For pos As Integer = 2 To 12 Step 2
                total = total + (Convert.ToInt32(Mid(x, (pos - 1), 1))) + (3 * (Convert.ToInt32(Mid(x, pos, 1))))
            Next
            check = (10 - (total Mod 10)) Mod 10
            If check <> Convert.ToInt32(Mid(x, 13, 1)) Then
                Console.WriteLine("Invalid ISBN-13 number")
                verify_checksum = False
            End If
        Else
            Console.WriteLine("Invalid input")
            verify_checksum = False
        End If
    End Function

    Sub Main()
        Console.WriteLine("ISBN-13 Validation")
        Do
            Do
                Console.Write("?: ")
                isbn = Console.ReadLine()
            Loop Until verify_checksum(isbn) = True Or isbn = "quit"
            Console.WriteLine("Valid ISBN-13 number")
        Loop Until isbn = "quit"
    End Sub

End Module
EDIT 3:

Code: Select all

Option Explicit On
Option Strict On

Module Module1

    Function verify_checksum(ByRef x As String) As Boolean
        Dim total, check As Integer
        verify_checksum = True
        total = 0
        If x Like "#############" Then
            For pos As Integer = 2 To 12 Step 2
                total = total + (Convert.ToInt32(Mid(x, (pos - 1), 1))) + (3 * (Convert.ToInt32(Mid(x, pos, 1))))
            Next
            check = (10 - (total Mod 10)) Mod 10
            If check <> Convert.ToInt32(Mid(x, 13, 1)) Then
                Console.WriteLine("Invalid ISBN-13 number")
                verify_checksum = False
            End If
        Else
            Console.WriteLine("Invalid input")
            verify_checksum = False
        End If
    End Function

    Sub Main()
        Dim isbn As String
        Console.WriteLine("ISBN-13 Validation")
        Console.WriteLine("To exit, type 'quit' and hit return")
        Do
            Do
                Console.Write("?: ")
                isbn = Console.ReadLine()
            Loop Until verify_checksum(isbn) = True Or isbn = "quit"
            Console.WriteLine("Valid ISBN-13 number")
        Loop Until isbn = "quit"
    End Sub

End Module


I have a new motto:
"Simple is complex"
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

Franky wrote:

Code: Select all

Loop Until verify_checksum(isbn) = True Or isbn = "quit"
Testing for true is not necessary.

Code: Select all

Loop Until (isbn = "quit") Or verify_checksum(isbn)
Btw. you'll later see that it's better to separate the user interface from the main logic from the algorithms. In this case, using "Console.WriteLine" in the "verify_checksum" function makes the function less usable. What if you want to verify a checksum in an application that doesn't use text output?
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
sweener2001
Inmate
Posts: 1751
Joined: Mon Dec 06, 2004 7:47 am
Location: WA

Post by sweener2001 »

are we all about Hungarian notation?
[img]http://i26.photobucket.com/albums/c128/sweener2001/StewieSIGPIC.png[/img]
funkyass
"God"
Posts: 1128
Joined: Tue Jul 27, 2004 11:24 pm

Post by funkyass »

creaothceann wrote:
Franky wrote:

Code: Select all

Loop Until verify_checksum(isbn) = True Or isbn = "quit"
Testing for true is not necessary.

Code: Select all

Loop Until (isbn = "quit") Or verify_checksum(isbn)
no. testing for true here is implicit. he is just being verbose.
Does [Kevin] Smith masturbate with steel wool too?

- Yes, but don’t change the subject.
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

Franky wrote:"Programming is as hard as the problem at hand"
Except a given problem can be solved in many different ways, some hard and some easy.
Programming is as hard as your own take on the problem.

Mine might be shorter or longer, faster or slower, simpler or more complex. Which is best depends on what points you focus on. Good, cheap, fast, choose two.
sweener2001 wrote:are we all about Hungarian notation?
we're all blowing our nose in its general direction
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
ZH/Franky

Post by ZH/Franky »

creaothceann wrote:
Franky wrote:

Code: Select all

Loop Until verify_checksum(isbn) = True Or isbn = "quit"
Testing for true is not necessary.

Code: Select all

Loop Until (isbn = "quit") Or verify_checksum(isbn)
Btw. you'll later see that it's better to separate the user interface from the main logic from the algorithms. In this case, using "Console.WriteLine" in the "verify_checksum" function makes the function less usable. What if you want to verify a checksum in an application that doesn't use text output?
Ah, I see. Yes, the function would be pretty useless in a GUI. I'm under the impression that if it was used in a GUI, and the user enters an invalid ISBN-13 number, the program would make a little CL window popup saying so (and that it would immediatly disappear). I considered your advice about not checking for "verify_checksum(isbn) = true", but I like to be direct and thorough in what I do. Anyway, I've changed some of the code around:

Code: Select all

Option Strict On
Option Explicit On
Module Module1

    Function verify_checksum(ByRef x As String) As Boolean
        Dim total, check As Integer
        verify_checksum = True
        total = 0
        If x Like "#############" Then
            For pos As Integer = 2 To 12 Step 2
                total = total + (Convert.ToInt32(Mid(x, (pos - 1), 1))) + (3 * (Convert.ToInt32(Mid(x, pos, 1))))
            Next
            check = (10 - (total Mod 10)) Mod 10
            If check <> Convert.ToInt32(Mid(x, 13, 1)) Then
                verify_checksum = False
            End If
        Else
            verify_checksum = False
        End If
    End Function

    Sub Main()
        Dim isbn As String = ""
        Console.WriteLine("ISBN-13 Validation")
        Console.WriteLine("To exit, type 'quit' and hit return")
        Do Until isbn = "quit"
            Console.Write("?: ")
            isbn = Console.ReadLine()
            isbn = isbn.ToLower
            If verify_checksum(isbn) <> True Then
                Console.WriteLine("Invalid ISBN-13 number")
            Else
                Console.WriteLine("Valid ISBN-13 number")
            End If
        Loop
    End Sub

End Module
(Added one tiny little line that converts the user-inputted isbn to lowercase. This is so that if they enter "quit" in all-caps, it will still quit).
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

grinvader wrote:
sweener2001 wrote:are we all about Hungarian notation?
we're all blowing our nose in its general direction
Only Systems Hungarian though.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
ZH/Franky

Post by ZH/Franky »

Hungarian notation? I didn't know what that was, so I went on google and read about it; I can immediatly see why it's a good idea.

Here's my ISBN-13 validator again:

Code: Select all

Option Strict On
Option Explicit On
Module Module1

    Function bVerifyChecksum(ByRef s As String) As Boolean
        Dim iMax, iSum As Integer
        bVerifyChecksum = True
        iMax = 0
        If s Like "#############" Then
            For j As Integer = 2 To 12 Step 2
                iMax = iMax + (Convert.ToInt32(Mid(s, (j - 1), 1))) + (3 * (Convert.ToInt32(Mid(s, j, 1))))
            Next
            iSum = (10 - (iMax Mod 10)) Mod 10
            If iSum <> Convert.ToInt32(Mid(s, 13, 1)) Then
                bVerifyChecksum = False
            End If
        Else
            bVerifyChecksum = False
        End If
    End Function

    Sub Main()
        Dim sISBN As String = ""
        Console.WriteLine("ISBN-13 Validation")
        Console.WriteLine("To exit, type 'quit' and hit return")
        Do Until sISBN = "quit"
            Console.Write("?: ")
            sISBN = Console.ReadLine()
            sISBN = sISBN.ToLower
            If bVerifyChecksum(sISBN) <> True Then
                Console.WriteLine("Invalid ISBN-13 number")
            Else
                Console.WriteLine("Valid ISBN-13 number")
            End If
        Loop
    End Sub

End Module
Do you guys think this adheres well to the Hungarian Notation convention?
creaothceann
Seen it all
Posts: 2302
Joined: Mon Jan 03, 2005 5:04 pm
Location: Germany
Contact:

Post by creaothceann »

See the link in my last post: Use the semantic type (purpose), not the data type.
vSNES | Delphi 10 BPLs
bsnes launcher with recent files list
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

Honestly, systems hung is good when the language sucks (and has no data types).
Apps hung is so fucking vague it's like those patents patenting the action of moving limbs to achieve a random purpose - anything matches it.

Anything that's not moronic or intended obfuscation follows apps hungarian's spirit. When everything's special, nothing is - and since it's that vague, it's not worth mentionning to begin with.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
ZH/Franky

Post by ZH/Franky »

Well, I've made my decision. Things like "iMax", "usInput", etc are stupid because as far as the person observing someone else's code is concerned, they are quite hard to know the meaning of.

Therefore, I've made a decision: somewhat adhere to systems hungarian, and somewhat (maybe?) to apps hungarian. E.g.
bVerifyChecksum,
bVerifyDate,
iMeanAge
iCalculateTax,
bSearch_arruBookTitles,
etc.

Also, functions are a lot of fun:

Code: Select all

Option Strict On
Option Explicit On
Module Module1

    Function bin2dec(ByRef sBin As String) As Double
        bin2dec = 0
        For j As Integer = sBin.Length To 1 Step -1
            If Mid(sBin, j, 1) = "1" Then
                bin2dec = (2 ^ (sBin.Length - j)) + bin2dec
            End If
        Next
    End Function

    Function bVerifyBinary(ByRef usBin As String, ByRef iAddress As Integer) As Boolean
        bVerifyBinary = True
        If usBin = "" Then
            bVerifyBinary = False
        Else
            If usBin.Length > iAddress Then
                bVerifyBinary = False
            Else
                For j As Integer = 1 To usBin.Length
                    If Mid(usBin, j, 1) <> "1" And Mid(usBin, j, 1) <> "0" Then
                        bVerifyBinary = False
                        Exit For
                    End If
                Next
            End If
        End If
    End Function

    Sub Main()
        Do
            Console.WriteLine("Invalid binary?")
            System.Threading.Thread.Sleep(300)
        Loop Until bVerifyBinary("1001010110101", 32) = True
        Console.WriteLine("Actually, that Binary is valid. Please, proceed.")
        Console.WriteLine("If you're interested, that is " + bin2dec("1001010110101").ToString + " in decimal")
        Console.WriteLine("Terminating in...")
        For j As Integer = 10 To 1 Step -1
            If j = 1 Then
                Console.WriteLine(j.ToString)
            Else
                Console.Write(j.ToString + ", ")
            End If
            System.Threading.Thread.Sleep(1000)
        Next
    End Sub

End Module
Slightly changed some of my ISBN-13 validator (just changed some of the variable names really):

Code: Select all

Option Strict On
Option Explicit On
Module Module1

    Function bVerifySum(ByRef usISBN13 As String) As Boolean
        Dim iMax, iSum As Integer
        bVerifySum = True
        iMax = 0
        If usISBN13 Like "#############" Then
            For j As Integer = 2 To 12 Step 2
                iMax = iMax + (Convert.ToInt32(Mid(usISBN13, (j - 1), 1))) + (3 * (Convert.ToInt32(Mid(usISBN13, j, 1))))
            Next
            iSum = (10 - (iMax Mod 10)) Mod 10
            If iSum <> Convert.ToInt32(Mid(usISBN13, 13, 1)) Then
                bVerifySum = False
            End If
        Else
            bVerifySum = False
        End If
    End Function

    Sub Main()
        Dim sISBN13 As String = ""
        Console.WriteLine("ISBN-13 Validation")
        Console.WriteLine("To exit, type 'quit' and hit return")
        Do
            Console.Write("?: ")
            sISBN13 = Console.ReadLine()
            sISBN13 = sISBN13.ToLower
            If bVerifySum(sISBN13) <> True Then
                Console.WriteLine("Invalid ISBN-13 number")
            Else
                Console.WriteLine("Valid ISBN-13 number")
            End If
        Loop Until sISBN13 = "quit"
    End Sub

End Module
ZH/Franky

Post by ZH/Franky »

(Just for fun) I decided to write an ISBN-10 validator too (contains my ISBN-13 validator, my new ISBN-10 validator, and an interface to choose between the two):

Code: Select all

Option Strict On
Option Explicit On
Module Module1

    Dim sISBN13 As String = ""
    Dim sISBN10 As String = ""

    Function bVerifySum13(ByRef usISBN13 As String) As Boolean
        Dim iMax, iSum As Integer
        bVerifySum13 = True
        iMax = 0
        If usISBN13 Like "#############" Then
            For j As Integer = 2 To 12 Step 2
                iMax = iMax + (Convert.ToInt32(Mid(usISBN13, (j - 1), 1))) + (3 * (Convert.ToInt32(Mid(usISBN13, j, 1))))
            Next
            iSum = (10 - (iMax Mod 10)) Mod 10
            If iSum <> Convert.ToInt32(Mid(usISBN13, 13, 1)) Then
                bVerifySum13 = False
            End If
        Else
            bVerifySum13 = False
        End If
    End Function

    Function bVerifySum10(ByRef usISBN10 As String) As Boolean
        Dim iMax As Integer
        iMax = 0
        bVerifySum10 = True
        If usISBN10 Like "##########" Or usISBN10.Length = 10 And Mid(usISBN10, 1, 9) Like "#########" And Mid(usISBN10, 10, 1) = "x" Then
            For j = 10 To 2 Step -1
                iMax = iMax + ((Convert.ToInt32(Mid(usISBN10, (10 - (j - 1)), 1))) * j)
            Next
            If Mid(usISBN10, 10, 1) <> "x" Then
                iMax = iMax + Convert.ToInt32(Mid(usISBN10, 10, 1))
            Else
                iMax = iMax + 10
            End If
            If (iMax Mod 11) <> 0 Then
                bVerifySum10 = False
            End If
        Else
            bVerifySum10 = False
        End If
    End Function

    Sub Main()
        Dim sInputChoice As String = ""
        Call DisplayOptions()
        Do Until sInputChoice = "quit"
            Call Console.Write("?: ")
            sInputChoice = Console.ReadLine()
            Select Case sInputChoice
                Case "quit"
                    End
                Case "disp"
                    Call DisplayOptions()
                Case "x10"
                    Call InterfaceISBN10()
                Case "x13"
                    Call InterfaceISBN13()
                Case Else
                    Call Console.WriteLine("Invalid option")
            End Select
        Loop
        End
    End Sub

    Sub InterfaceISBN10()
        Call Console.WriteLine()
        Call Console.WriteLine("ISBN-10 Validation")
        Call Console.WriteLine("(To exit back to main menu, type 'r' and hit return)")
        Do Until sISBN10 = "r"
            Call Console.Write("?10: ")
            sISBN10 = Console.ReadLine()
            sISBN10 = sISBN10.ToLower
            If sISBN10 <> "r" And bVerifySum10(sISBN10) <> True Then
                Call Console.WriteLine("Invalid ISBN-10 number")
            ElseIf sISBN10 <> "r" And bVerifySum10(sISBN10) = True Then
                Call Console.WriteLine("Valid ISBN-10 number")
            End If
        Loop
        Call Console.WriteLine()
        Call DisplayOptions()
    End Sub

    Sub InterfaceISBN13()
        Call Console.WriteLine()
        Call Console.WriteLine("ISBN-13 Validation")
        Call Console.WriteLine("(To exit back to main menu, type 'r' and hit return)")
        Do Until sISBN13 = "r"
            Call Console.Write("?13: ")
            sISBN13 = Console.ReadLine()
            sISBN13 = sISBN13.ToLower
            If sISBN13 <> "r" And bVerifySum13(sISBN13) <> True Then
                Call Console.WriteLine("Invalid ISBN-13 number")
            ElseIf sISBN13 <> "r" And bVerifySum13(sISBN13) = True Then
                Call Console.WriteLine("Valid ISBN-13 number")
            End If
        Loop
        Call Console.WriteLine()
        Call DisplayOptions()
    End Sub

    Sub DisplayOptions()
        Call Console.WriteLine("Options:")
        Call Console.WriteLine("x10 - ISBN10 validation")
        Call Console.WriteLine("x13 - ISBN13 validation")
        Call Console.WriteLine("disp - display these options")
        Call Console.WriteLine("quit - exit this program")
    End Sub

End Module
Last edited by ZH/Franky on Mon Dec 01, 2008 7:43 pm, edited 4 times in total.
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

sweener2001 wrote:unless recursion is the devil, nobody bothered to mention that factorials are like 3 lines of C++ using recursion
It's like 3 lines of C++ code either way.

If you're doing factorials recursively to save space in code, your brain has completely malfunctioned, and you shouldn't be allowed to write code, because you don't have a clue what you're doing.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
ZH/Franky

Post by ZH/Franky »

Nach wrote:
sweener2001 wrote:unless recursion is the devil, nobody bothered to mention that factorials are like 3 lines of C++ using recursion
It's like 3 lines of C++ code either way.

If you're doing factorials recursively to save space in code, your brain has completely malfunctioned, and you shouldn't be allowed to write code, because you don't have a clue what you're doing.
Would this be what you consider the result of a "malfunctioned brain"?:

Code: Select all

    Function factorial(ByVal a As Double) As Double
        factorial = 0
        If a = 0 Or a = 1 Then
            factorial = 1
            Exit Function
        ElseIf a > 1 Then
            For j As Double = a To 2 Step -1
                a = (j - 1) * a
                factorial = a
            Next
        End If
    End Function
You have to realize that some of the people who write pages of code for something like factorials aren't stupid; they're probably new to programming, like I was. That said, I'm certainly no expert; that'll take at least another 6 years from now.
odditude
Official tech support dood
Posts: 2122
Joined: Wed Jan 25, 2006 7:57 am

Post by odditude »

Franky wrote:

Code: Select all

    Function factorial(ByVal a As Double) As Double
        factorial = 0
        If a = 0 Or a = 1 Then
            factorial = 1
            Exit Function
        ElseIf a > 1 Then
            For j As Double = a To 2 Step -1
                a = (j - 1) * a
                factorial = a
            Next
        End If
    End Function
you're doing integer math, so you have no reason to use floating point numbers. ditto for loop indices. (read: use int or long, not float or double.)

not sure how cleanly VB handles it, but some (most?) languages can't compare floating-point types for equality - only for greater or less. in C, it won't throw an error, but it will always return false.

the line "factorial = 0" is not necessary, since that variable is always explicitly assigned a value in the following code that doesn't depend on its original value.

Code: Select all

Function factorial2(ByVal x As Long) As Long
   factorial2 = 1
   If x < 2 Then Exit Function
   For i As Long = x to 1 Step -1
      factorial2 *= i
   Next
End Function

Code: Select all

long int factorial(const long int x) {
   long int result = 1;
   if x > 1 for (long int i = x; x > 1; x++) result *= i;
   return result;
}
three lines, assuming I didn't do anything stupid (nach?).
replace "long int" with whatever the hell is defined in the headers nowadays (uint32_t ?).
Last edited by odditude on Mon Dec 01, 2008 8:59 pm, edited 1 time in total.
Why yes, my shift key *IS* broken.
Deathlike2
ZSNES Developer
ZSNES Developer
Posts: 6747
Joined: Tue Dec 28, 2004 6:47 am

Post by Deathlike2 »

odditude wrote:
Franky wrote:

Code: Select all

    Function factorial(ByVal a As Double) As Double
        factorial = 0
        If a = 0 Or a = 1 Then
            factorial = 1
            Exit Function
        ElseIf a > 1 Then
            For j As Double = a To 2 Step -1
                a = (j - 1) * a
                factorial = a
            Next
        End If
    End Function
you're doing integer math, so you have no reason to use floating point numbers. ditto for loop indices. (read: use int or long, not float or double.)
Imagine the potential for disasters.
Continuing [url=http://slickproductions.org/forum/index.php?board=13.0]FF4[/url] Research...
ZH/Franky

Post by ZH/Franky »

ok,

Code: Select all

    Function factorial(ByVal a As Long) As Long
        factorial = 0
        If a = 0 Or a = 1 Then
            factorial = 1
            Exit Function
        ElseIf a > 1 Then
            For j As Long = a To 2 Step -1
                a = (j - 1) * a
                factorial = a
            Next
        End If
    End Function

Code: Select all

    Function factorial(ByVal a As Integer) As Integer
        factorial = 0
        If a = 0 Or a = 1 Then
            factorial = 1
            Exit Function
        ElseIf a > 1 Then
            For j As Integer = a To 2 Step -1
                a = Convert.ToInt32(j - 1) * a
                factorial = a
            Next
        End If
    End Function
If I use long, it only does factorials of up to 20, and if I use integers, it only does factorials of up to 12. After that, it crashes, and if I'm in debugging mode it says "OverflowException was unhandled" and "Arithmetic operation resulted in an overflow".
I know what error handling is and how to use it, but I'm not sure how to handle this error. When I use double, it doesn't do this, hence why I've used it, but the only annoying this is that when the factorial is too high, it is stored and displayed as an exponential (because of what a "double" variable is; a double-precision number stored as an exponential). This happens to me when I use odditude's:

Code: Select all

Function factorial2(ByVal x As Long) As Long
   factorial2 = 1
   If x < 2 Then Exit Function
   For i As Long = x to 1 Step -1
      factorial2 *= i
   Next
End Function
code (that is, only displays factorials of up to 20, since he's using long integers).

I'm being serious, can you guys help?

As a side note, I should also post something that makes me happy, to balance things out (I've added ISBN10 to ISBN13 conversion to my ISBN10/ISBN13 validator):

Code: Select all

Option Strict On
Option Explicit On
Module Module1

    Dim sISBN13 As String = ""
    Dim sISBN10 As String = ""

    Function bVerifySum13(ByRef usISBN13 As String) As Boolean
        Dim iMax, iSum As Integer
        bVerifySum13 = True
        iMax = 0
        If usISBN13 Like "#############" Then
            For j As Integer = 2 To 12 Step 2
                iMax = iMax + (Convert.ToInt32(Mid(usISBN13, (j - 1), 1))) + (3 * (Convert.ToInt32(Mid(usISBN13, j, 1))))
            Next
            iSum = (10 - (iMax Mod 10)) Mod 10
            If iSum <> Convert.ToInt32(Mid(usISBN13, 13, 1)) Then
                bVerifySum13 = False
            End If
        Else
            bVerifySum13 = False
        End If
    End Function

    Function bVerifySum10(ByRef usISBN10 As String) As Boolean
        Dim iMax As Integer
        iMax = 0
        bVerifySum10 = True
        If usISBN10 Like "##########" Or usISBN10.Length = 10 And Mid(usISBN10, 1, 9) Like "#########" And Mid(usISBN10, 10, 1) = "x" Then
            For j = 10 To 2 Step -1
                iMax = iMax + ((Convert.ToInt32(Mid(usISBN10, (10 - (j - 1)), 1))) * j)
            Next
            If Mid(usISBN10, 10, 1) <> "x" Then
                iMax = iMax + Convert.ToInt32(Mid(usISBN10, 10, 1))
            Else
                iMax = iMax + 10
            End If
            If (iMax Mod 11) <> 0 Then
                bVerifySum10 = False
            End If
        Else
            bVerifySum10 = False
        End If
    End Function

    Function sConvertN10toN13(ByRef usISBN10 As String) As String
        Dim iMax As Integer = 0
        sConvertN10toN13 = "978" + Mid(usISBN10, 1, 9)
        For j As Integer = 2 To 12 Step 2
            iMax = (iMax + (Convert.ToInt32(Mid(sConvertN10toN13, (j - 1), 1))) + (3 * (Convert.ToInt32(Mid(sConvertN10toN13, j, 1)))))
        Next
        sConvertN10toN13 = sConvertN10toN13 + ((10 - (iMax Mod 10)) Mod 10).ToString
    End Function

    Sub Main()
        Dim sInputChoice As String = ""
        Call DisplayOptions()
        Do Until sInputChoice = "quit"
            Call Console.Write("?: ")
            sInputChoice = Console.ReadLine()
            Select Case sInputChoice
                Case "quit"
                    End
                Case "disp"
                    Call DisplayOptions()
                Case "10"
                    Call InterfaceISBN10()
                Case "13"
                    Call InterfaceISBN13()
                Case "10to13"
                    Call InterfaceISBN10ToISBN13()
                Case "13to10"
                    Call InterfaceISBN13ToISBN10()
                Case Else
                    Call Console.WriteLine("Invalid option")
            End Select
        Loop
        End
    End Sub

    Sub InterfaceISBN10()
        Call Console.WriteLine()
        Call Console.WriteLine("ISBN-10 Validation")
        Call Console.WriteLine("(To exit back to main menu, type 'r' and hit return)")
        Do Until sISBN10 = "r"
            Call Console.Write("?10: ")
            sISBN10 = Console.ReadLine()
            sISBN10 = sISBN10.ToLower
            If sISBN10 <> "r" And bVerifySum10(sISBN10) <> True Then
                Call Console.WriteLine("Invalid ISBN-10 number")
            ElseIf sISBN10 <> "r" And bVerifySum10(sISBN10) = True Then
                Call Console.WriteLine("Valid ISBN-10 number")
            End If
        Loop
        Call Console.WriteLine()
        Call DisplayOptions()
    End Sub

    Sub InterfaceISBN13()
        Call Console.WriteLine()
        Call Console.WriteLine("ISBN-13 Validation")
        Call Console.WriteLine("(To exit back to main menu, type 'r' and hit return)")
        Do Until sISBN13 = "r"
            Call Console.Write("?13: ")
            sISBN13 = Console.ReadLine()
            sISBN13 = sISBN13.ToLower
            If sISBN13 <> "r" And bVerifySum13(sISBN13) <> True Then
                Call Console.WriteLine("Invalid ISBN-13 number")
            ElseIf sISBN13 <> "r" And bVerifySum13(sISBN13) = True Then
                Call Console.WriteLine("Valid ISBN-13 number")
            End If
        Loop
        Call Console.WriteLine()
        Call DisplayOptions()
    End Sub

    Sub InterfaceISBN10ToISBN13()
        Call Console.WriteLine("ISBN10 to ISBN13 conversion")
        Call Console.WriteLine("(To exit back to the main menu, type 'r' and hit return)")
        Do
            Call Console.Write("?10: ")
            sISBN10 = Console.ReadLine()
            If sISBN10 <> "r" And bVerifySum10(sISBN10) <> True Then
                Call Console.WriteLine("Invalid input")
            ElseIf sISBN10 <> "r" And bVerifySum10(sISBN10) = True Then
                Call Console.WriteLine("As an ISBN13 number, this is " + sConvertN10toN13(sISBN10))
                Call System.Threading.Thread.Sleep(1200)
                Call Console.WriteLine("Verification of newly converted ISBN13 number...")
                Call System.Threading.Thread.Sleep(300)
                If bVerifySum13(sConvertN10toN13(sISBN10)) <> True Then
                    Call Console.WriteLine("Oops, it seems that this is invalid")
                Else
                    Call Console.WriteLine("Everything A-OK")
                End If
            End If
        Loop Until sISBN10 = "r"
    End Sub

    Sub InterfaceISBN13ToISBN10()
        Call Console.WriteLine("This subprocedure has not been written yet,")
        Call Console.WriteLine("but I put the skeleton here for the sake of")
        Call Console.WriteLine("preparation.")
    End Sub

    Sub DisplayOptions()
        Call Console.WriteLine("Options:")
        Call Console.WriteLine("10 - ISBN10 validation")
        Call Console.WriteLine("13 - ISBN13 validation")
        Call Console.WriteLine("10to13 - ISBN10 to ISBN13 conversion")
        Call Console.WriteLine("13to10 - ISBN13 to ISBN10 conversion (not yet written)")
        Call Console.WriteLine("disp - display these options")
        Call Console.WriteLine("quit - exit this program")
    End Sub

End Module
Last edited by ZH/Franky on Mon Dec 01, 2008 9:43 pm, edited 1 time in total.
odditude
Official tech support dood
Posts: 2122
Joined: Wed Jan 25, 2006 7:57 am

Post by odditude »

nope, can't really help there. big integer numbers are not your standard processor's (or programming language's) forte - you'd need a custom solution.
Why yes, my shift key *IS* broken.
ZH/Franky

Post by ZH/Franky »

odditude wrote:nope, can't really help there. big integer numbers are not your standard processor's (or programming language's) forte - you'd need a custom solution.
Yes, that's one of the things I was thinking; the number is too large for my processor to handle (and because of this, made a limitation of VB.Net). However, I've written a factorial finder in python before, and it displayed really large numbers such as 437689350708234756390845083094590345539046304789035789034083475689079034785 without crashing. So this leads me to another question: what do you mean by "custom solution"?
Nach
ZSNES Developer
ZSNES Developer
Posts: 3904
Joined: Tue Jul 27, 2004 10:54 pm
Location: Solar powered park bench
Contact:

Post by Nach »

Okay regarding factorial, regarding basic C++ (as this is taken straight out of a teacher's slide for basic C++ for newbies)

Recursive:
Image

Iterative:
Image

Both are small and simple. And both are beginner.
Notice it's page 21 and 22 respectively.
May 9 2007 - NSRT 3.4, now with lots of hashing and even more accurate information! Go download it.
_____________
Insane Coding
grinvader
ZSNES Shake Shake Prinny
Posts: 5632
Joined: Wed Jul 28, 2004 4:15 pm
Location: PAL50, dood !

Post by grinvader »

odditude wrote:

Code: Select all

long int factorial(const long int x) {
   long int result = 1;
   if x > 1 for (long int i = x; x > 1; x++) result *= i;
   return result;
}
three lines, assuming I didn't do anything stupid (nach?).
replace "long int" with whatever the hell is defined in the headers nowadays (uint32_t ?).
Meh

Code: Select all

uberlong fact(uberlong val) { return (val ? val*fact(val-1) : 1); }
USE THE POWER, KIDS

[alternatively...]

Code: Select all

uberlong straightfact(notverybiginteger val)
{
  uberlong out = val ? val : 1;
  while (--val) { out *= val; } // why are you always using FOR ?
  return (out);
}
3 lines, the short way.
Franky wrote:However, I've written a factorial finder in python before, and it displayed really large numbers such as 437689350708234756390845083094590345539046304789035789034083475689079034785 without crashing. So this leads me to another question: what do you mean by "custom solution"?
How did they count to more than 65536 before they had 32 bit CPUs ? The same way you'd do with that.

Make a custom data type and define what happens when you add, multiply... to it, breaking down to existing operations.
C++ is really shining there, but C exclusives can cope just fine and not that much more bulk with a couple tricks.
Last edited by grinvader on Mon Dec 01, 2008 10:27 pm, edited 2 times in total.
皆黙って俺について来い!!

Code: Select all

<jmr> bsnes has the most accurate wiki page but it takes forever to load (or something)
Pantheon: Gideon Zhi | CaitSith2 | Nach | kode54
funkyass
"God"
Posts: 1128
Joined: Tue Jul 27, 2004 11:24 pm

Post by funkyass »

carry bit.

I wouldn't be surprised if there is a library in .net that does handle large integers.
Does [Kevin] Smith masturbate with steel wool too?

- Yes, but don’t change the subject.
Post Reply