I wanted to write a class about integers but I can't seem to get to think in oop. I think I'm just writing procedural code
but the only difference is that I drop the functions in a class.
The second is I need to implement the array control code in the class and in the test program.
So it's not slik an neat solution primeraly because I can't use the print function inside a class
Also isnt there something neather to get an array back from a method to the test program?
After some searching on the internet. The way to good understand oop programming is to read a book about refactoring.
If so can one of you guys recommend me a good book. Im now using vb6 how to program from deitel.
class CIntegerSet
Code:
Option Explicit
Dim twist As New CIntegerSet
Private myarray(101) As Boolean
Private newarray(101) As Boolean
Public Function insertElement(ByVal i As Integer)
If i >= 0 And i < UBound(myarray) Then
myarray(i) = 1
End If
End Function
Public Property Get givenewArray() As Boolean()
Dim i As Integer
For i = 0 To UBound(newarray)
If myarray(i) Then
newarray(i) = True
End If
givenewArray = newarray()
Next i
End Property
Public Function deleteelement(ByVal i As Integer)
If i >= 0 And i < UBound(myarray) Then
newarray(i) = False
End If
End Function
Public Function giveArray() As Boolean()
giveArray = myarray()
End Function
Public Property Get isSet(ByVal i As Integer) As Boolean
If i >= 0 And i < UBound(myarray) Then
If myarray(i) = True Then
isSet = True
End If
End If
End Property
Public Function isEmpty(ByVal i As Integer) As Boolean()
For i = 0 To UBound(myarray)
If isSet(i) Then
isEmpty = False
End If
Next i
End Function
Public Function union(ByVal i As Integer) As Boolean
If i >= 0 And i < UBound(myarray) Then
If myarray(i) = True Then
newarray(i) = True
union = newarray(i)
End If
End If
End Function
Public Function intersection(ByVal i As Integer) As Boolean
If i >= 0 And i < UBound(myarray) Then
intersection = myarray(i)
End If
End Function
Public Function tostring(ByVal i As Integer) As String
For i = 0 To UBound(myarray)
myarray(i) = True
tostring = i
Next i
End Function
Public Function isequalto(ByVal i As Integer) As Boolean
For i = 0 To UBound(myarray)
myarray(i) = True
isequalto = myarray(i)
Next i
End Function
TestIntegerSet
Code:
Dim even As New CIntegerSet
Dim odd As New CIntegerSet
Dim calc As New CIntegerSet
Dim i As Integer
Dim myarray() As Boolean
Dim myarray2() As Boolean
Dim newarray() As Boolean
Private Sub Form_Load()
Me.Show
For i = 0 To 10
calc.insertElement (i)
If i Mod 2 = 0 Then
even.insertElement (i)
Else
odd.insertElement (i)
End If
Next i
myarray2() = odd.giveArray
Print "smallodds: "
Print "[Set:";
For i = 0 To UBound(myarray2)
If odd.isSet(i) = True Then
Print " "; i;
End If
Next i
Print "]"
myarray() = even.giveArray
Print "smallevens: "
Print "[Set:";
For i = 0 To UBound(myarray)
If even.isSet(i) = True Then
Print " "; i;
End If
Next i
Print "]"
newarray() = calc.givenewArray
Print "union"
For i = 0 To UBound(newarray)
If even.union(i) Or odd.union(i) Then
Print i;
End If
Next i
Print "]"
Print "intersection"
For i = 0 To 10
If even.intersection(i) = True Or odd.intersection(i) = False And even.intersection(i) = False Or odd.intersection(i) = True Or even.intersection(i) = False And odd.intersection(i) = False Then
' myarray(i) = False
isEmpty (myarray(i))
ElseIf even.intersection(i) = True And odd.intersection(i) Then
Print myarray(i);
End If
Next i
If myarray(i) = False Then
Print "---"
End If
Print "deleteelement"
For i = 0 To UBound(myarray)
Print calc.deleteelement(i);
Next i
Print "]"
Print "tostring"
For i = 0 To 10
If odd.tostring(i) Then
Print i;
End If
Next i
Print "]"
Print "isequalto"
For i = 0 To 10
If even.isequalto(i) And odd.isequalto(i) Then
Print i;
End If
Next i
Print "]"
End Sub
And here's the exercise question :
Create class CIntegerSet. Each object of the class can hold Integers in the range 0
through 100. A set is represented internally as an array of ones and zeros. Array element a(i) is 1
if integer i is in the set. Array element a(j) is 0 if integer j is not in the set.
Provide the following methodes: Method UnionOfIntegerSets creates a third set which
is the set-theoretic union of two existing sets (i.e., an element of the third set's array is set to 1 if that
element is 1 in either or both of the existing sets; otherwise, the element of the third set is set to 0).
Method IntersectionOfIntegerSets creates a third set which is the set-theoretic intersection
of two existing sets (i.e., an elementof the third set's array is set to 0 if that element is 0 in either
or both of the existing sets; otherwise, the element of the third set is set to 1). Method insertElement
inserts a new Integer k into a set (by setting a(k) to 1). Method DeleteElement deletes
Integer m (by setting a(m) to 0). Method ToString returns a String containing a set as a list
of numbers separted by spaces and prints only those elements that are present in the set or --- for
an empty set. Method IsEqualTo determines if two sets are equal. Write a program to test your
CIntegerSet class. Instantiate several CIntegerSet objects. Test that all your methods work properly
That was a long post hope you'll guys can bear with me
At first look:
There is a reason i dislike "Dim MyArray(101) As Integer"
A "Dim MyArray(0 To 100) As Integer" is more clear in regards to your requirement.
Then your test against it is just "If i>=0 And i<=UBound(MyArray)." It's more clear, too
Next: Use "Sub" instead of "Function" if you don't expect a result back ("insertElement" and "deleteElement")
For the rest i don't have the time now to understand everything
Last edited by Zvoni; Tomorrow at 31:69 PM.
----------------------------------------------------------------------------------------
One System to rule them all, One Code to find them,
One IDE to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------------------
People call me crazy because i'm jumping out of perfectly fine airplanes.
---------------------------------------------------------------------------------
Code is like a joke: If you have to explain it, it's bad
I'll probably get strung up for this but here goes anyways: You're going to have a hard time trying to apply OOP principles to VB6 because VB6 isn't completely OOP-centric. It has some OOP qualities, but not enough in my opinion to make it sufficient learning tool for OOP. It can handle somethings like interfaces and polymorphism quite well, but when you get into subclassing, it becomes a larger chore. It's also possible I'm biased because I learned my OOP basics outside of VB (long before VB was even a thing to be precise), so my recommendation is that if you're looking to pickup OOP principles in general, may consider another language to do it in, and not VB6.
That said... You're actually not that far off, yes, some refactoring is needed (good luck finding one on VB6 at this point in time), so a few notes on the code:
1) Functions return values... none of yours do. So they should either be methods, or they should return something. If you want, you could return True if the item was successfully added to the array, False if it wasn't (like if it's out of range or something).
2) Your property for the array... not needed. The point of the methods & functions of the class is to hide away the implementation of the data underneath. Here you're copying it, then passing back that copy... unnecessary, because you shouldn't be passing through a property.
3) Method names. These should be action words. "Add" "Remove" "Find" If you look at other implementations of structures like you're doing (look at the methods and properties of the simple Collection) you'll see they have simple action verbs like .Add and .Remove. The fact that it is an element or a record or key or a string is irrelevant.
4) Returning the array. your giveArray should be the right way to do that. Although I'd call it .toArray (which is the norm), or .getArray.. .why is this better than the property? It has to do with how it's passed around. The property will pass back the reference, which is why you needed to copy it, so that changes outside wouldn't affect it. But passing it back through a function by default will pass by value... a copy... so changes outside will only affect the outside copy. Also makes it read-only and they can't set it directly.
5) Your isSet and isEmpty functions need default values... what happens if i is outside of the range? What happens if none of the values are set. Personally, I never rely on the default values returned by a function. When ever I start a function I use this pattern:
Code:
Dim retValue as Boolean
retValue = {what ever the default should be: true or false}
{code}
myFunc = retValue
That way I'm guaranteed a return value from the function no matter what (barring an error happening).
Public Function union(ByVal i As Integer) As Boolean
If i >= 0 And i < UBound(myarray) Then
If myarray(i) = True Then
newarray(i) = True
union = newarray(i)
End If
End If
End Function
newarray can be changed to myarray and of course change te function to sub am I right ?
Shrug... beats me... depends on what the union is supposed to do. IF all it is doing is setting an element, then sure, that's all that's needed. But if the intent is to do what the name implies, union two arrays, then the parameters (to me) are off. Your class should only be dealing with one array. That's all it's resonsibility should be for. IF you then want to union it with another array, then that second one should be passed in. The call would look like this:
Code:
even.union(someArray)
The union method would then take care of what it needs to do to union the two arrays together.
The union method would then take care of what it needs to do to union the two arrays together.
At least in my mind that's how it should work.
-tg
This is what I'm talking about the tricky stuff. I have now one array and it's working fine.
Wish there was some more reading or example code about classes and arrays.
I'm thinking I would declare the Union Function like this.
Code:
Public Function union(Set_In As CIntegerSet) As CIntegerSet
'I'll let you figure out what the code in the function should be.
End Function
The function would return a CIntegerSet object that contains the Union of the Set you're calling the method of and the Set being passed to it.
i.e.
Code:
Private a As CIntegerSet, b As CIntegerSet, abUnion As CIntegerSet.
'Assume you have code that has preset sets a and b
abUnion = a.union(b) 'abUnion is now the Union of sets a and b
abUnion = b.union(a) 'should give you the same result.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
After some searching on the internet. The way to good understand oop programming is to read a book about refactoring.
You can hardly write any program in VB6 without "OOP." I think you have been wildly mislead by those with a very weak grasp on the subject. Almost everything in VB is an object or a class.
Refactoring is another bogus buzzword often abused by cargo cult coders, but it has nothing to do with a school homework project like this. From the description it's just a bonehead "make a simple Class" assignment. Not a lot to it, really.
If this is really a classroom homework assignment then don't look at this example. The entire point of taking a class is to learn a skill other than copy/pasting other people's work.
IntegerSet.cls:
Code:
Option Explicit
'NOTE: May be bugs, just a quick and dirty example.
'In a real program this would be far more optimized. For example we could
'track FirstElement/LastElement to limit the range of looping.
'
'Lots could be done better, but this is more of an "introductory classroom"-friendly
'version.
Private Bits(100) As Byte 'We could also pack tighter but we'll take the simpler path
'here to simplify the code.
'While this is a Friend Property that should never be called from client code...
'this Class was implemented locally rather than published in a separate
'registered DLL. This means it is exposed but client code should still not
'call it:
Friend Property Get HasElement(ByVal Element As Integer) As Boolean
'Range check not needed because Friends should not be called by client code
'and we validate our own values within this Class.
HasElement = Bits(Element) <> 0
End Property
Public Sub DeleteElement(ByVal Element As Integer)
If 0 > Element Or Element > 100 Then Err.Raise 5
Bits(Element) = 0
End Sub
Public Sub InsertElement(ByVal Element As Integer)
If 0 > Element Or Element > 100 Then Err.Raise 5
Bits(Element) = 1
End Sub
Public Sub IntersectionOfIntegerSets(ByVal ISet1 As IntegerSet, ByVal ISet2 As IntegerSet)
Dim I As Integer
For I = 0 To 100
If ISet1.HasElement(I) And ISet2.HasElement(I) Then
InsertElement I
Else
DeleteElement I
End If
Next
End Sub
Public Function IsEqualTo(ByVal ISet As IntegerSet) As Boolean
Dim I As Integer
For I = 0 To 100
If HasElement(I) Xor ISet.HasElement(I) Then Exit Function
Next
IsEqualTo = True
End Function
Public Function ToString() As String
Dim I As Integer
For I = 0 To 100
If HasElement(I) Then
If Len(ToString) = 0 Then
ToString = CStr(I)
Else
ToString = ToString & " " & CStr(I)
End If
End If
Next
If Len(ToString) = 0 Then ToString = "---"
End Function
Public Sub UnionOfIntegerSets(ByVal ISet1 As IntegerSet, ByVal ISet2 As IntegerSet)
Dim I As Integer
For I = 0 To 100
If ISet1.HasElement(I) Or ISet2.HasElement(I) Then
InsertElement I
Else
DeleteElement I
End If
Next
End Sub
Yeah, I wouldn't look too far or hard on anything about refactoring. All it means is to rewrite your code. That's all it it. Hopefully the rewrite is for the better. But that's not always the case. I've seen code refactored for the sake of being able to check a box "Code refactored: check" sigh... Honestly, if you want to get a grasp on OOP, do it in a language agnostic way. Personally I think that's the best way, then the nuances of the languages don't get in the way. Then once you've got the principles down, you can applly it to any language, or any object, or any situation/.
Also, you will never look at an apple, orange, or a car the same ever again.
Why only one set_in for the function ? You need to compare two !
abUnion = a.union(b) I don't understand a thing about what you are doing here. Only get 438 object no property or method.
This is what I'm using :
evenoddUnion = even.union(odd)
In my case, I expect it to compare set a and set b. The function compares its own set with the set passed in, and returns a new set.
So, I'm saying thirdSet = firstSet.unionWith(secondSet).
Code:
Public Function unionWith(Set_In As CIntegerSet) As CIntegerSet
Dim i As Integer
For i = 0 to 100
unionWith.myArray(i) = myArray(i) Or Set_In.myArray(i)
Next
End Function
dilettante's code takes a different approach, which is probably clearer, i.e. you have a set object and you pass it two sets, so it sets itself to the union of the two sets passed in.
thirdSet.UnionOfIntegerSets( firstSet, secondSet)
Just different approaches to get the same result in the end.
Note the code above was just typed into the post, and not tested in an actual application.
p.s. I may also be naive in proper class capabilities in VB6 and best practices, so perhaps my example may actually work in VB6
Last edited by passel; Mar 4th, 2021 at 03:29 PM.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930
I'd think if a Class like this was useful it would probably do those operations by combining itself with a 2nd instance, but I was trying to stick more closely to the requirements.
This sort of Class might also benefit from a Clone method returning a new copy of itself. Maybe even ClearAll and SetAll methods. Or even a Copy(OtherInstance) method.
What code do you need to get this working :
evenoddUnion = even.union(odd) what am I doing wrong here ?
I can understand what an array is and what you can do with it but what do i do with evenoddUnion ?
Can it been print out with print statement or do I have to use something like toString.
Note that I've updated my post, and also added a p.s.
What I suggested may not work the way I expected in VB6. I've done minimal work writing classes in VB6. You can ignore what I've said, unless someone can make it work. Even if it worked, it might either overexpose the set to outside manipulation, or actually be slower because of having to go through the property interface repeatedly to access each element of the array.
When it comes to VB6 and Class modules, I should resist the urge to post.
"Anyone can do any amount of work, provided it isn't the work he is supposed to be doing at that moment" Robert Benchley, 1930