QB64 Phoenix Edition
Some Noob (to QB64) Questions - Printable Version

+- QB64 Phoenix Edition (https://qb64phoenix.com/forum)
+-- Forum: QB64 Rising (https://qb64phoenix.com/forum/forumdisplay.php?fid=1)
+--- Forum: Code and Stuff (https://qb64phoenix.com/forum/forumdisplay.php?fid=3)
+---- Forum: Help Me! (https://qb64phoenix.com/forum/forumdisplay.php?fid=10)
+---- Thread: Some Noob (to QB64) Questions (/showthread.php?tid=363)

Pages: 1 2


Some Noob (to QB64) Questions - TarotRedhand - 05-07-2022

I am in the process of trying to convert my old QB 4.5 code to QB64 and have a number of questions I hope can be answered. I will try to keep this thread focused by limiting the number of my questions in a post. If you decide to answer could you please include code  snippets as I find that to be the easiest way to learn. Anyway here is my first question.

I have a number of small graphics programs that work fine in QB64 but I would like them to utilise more of my 1080 monitors screen. By utilise I mean that I would like to have access to the individual pixels and not just stretch them to fit using _FULLSCREEN. Preferably I would like the graphics to display in a window with the close button like they currently do in the various SCREEN modes. Is this possible? Not a criticism but TBH I am a little surprised that SCREEN hasn't been expanded to include HD 720, HD 1080 or 4K.

Thanks in advance.

TR


RE: Some Noob (to QB64) Questions - SMcNeill - 05-07-2022

Add one line to the top of your code and compile:

$RESIZE:SMOOTH

Then grab a corner and size that window to whatever you want it to be.


RE: Some Noob (to QB64) Questions - TarotRedhand - 05-07-2022

Sorry, but it appears that I wasn't clear on one point. Is it possible to have the window open full screen (without stretching the graphics) automatically?

TR


RE: Some Noob (to QB64) Questions - bplus - 05-07-2022

You can use every pixel available to your screen without distortion from shrink or stretch with first line of following,

except the tool bar gets in way, maybe a widow always on top and centered too?

But try _Fullscreen from that, might not have distorion? Because 1 to 1 ratio screen to desktop. Do you get distortion?
Code: (Select All)
Screen _NewImage(_DesktopWidth, _DesktopHeight, 32) ' the 32 gives you millions of _RGB32( red, green, blue) colors
xmax = _Width
ymax = _Height
Print xmax, ymax, "zzz... sleeping press a key"
Sleep
_FullScreen
Print xmax, ymax, " IDK distortion?"
PSet (0, 0)
PSet (_Width - 1, _Height - 1)
Sleep

EDIT/UPDATE: better test, added 2 dots at the critical screen corners top left and bottom right should be visible.


RE: Some Noob (to QB64) Questions - bplus - 05-07-2022

BTW there is a loss of graphics performance with screens above 1024 in width. Terry Richey first made discovery and confirmed by Fellippe.


RE: Some Noob (to QB64) Questions - TarotRedhand - 05-12-2022

Right, next question. I have a few libraries that definitely worked in QB4.5 that I am having problems getting to work with QB64. So here is the thing they are setup along the lines of a BI file, a BAS file and a demo program. The BI file holds the sub/function prototypes, constants and user-defined types. Even after removing the sub/function prototypes from the BI I still get errors. For the demo program(s) I have the modified BI file '$INCLUDE as the first line and the BAS file as the last line '$INCLUDE. As the BI file '$INCLUDE is already in the demo program, I removed it from the library's BAS file. Yet I still get errors (in one case to do with constants another with illegal TYPE). What am I doing wrong?

FWIW I have two libraries that I am certain I could get to work with a bit of help, at least one other but that'll need a further question down the line and another that I have my doubts on but that's a question even further down the line.

Thanks.

TR


RE: Some Noob (to QB64) Questions - SMcNeill - 05-12-2022

Can you share the libraries? I'm certain somebody would be happy to look into helping convert them.


RE: Some Noob (to QB64) Questions - TarotRedhand - 05-13-2022

Well if you insist... This library (when it will compile) brings mathematical sets (like in Pascal) to QB64. It worked fine in QuickBasic 4.5. In order to explain about what it actually does I'll quote the original readme I included with it -

Quote:So what is charset I hear you ask. Charset consists of three files, Charset.BI, Charset.BAS and Testsets.BAS. The first 2 files are the interface and the source code for a small library that deals with an abstract data type while the final file is a very rough and ready test program for the library. The abstract data type that is dealt with is called a CharSet and is a simulation of mathematical sets in the domain of the 256 different characters of the PC's (western) character set (cor! What a mouthful! :-) ). In other words you now no longer need Pascal if you want to use sets of characters. In fact with my implementation you have 18 different things you can do with sets as opposed to the ten you can with Pascal.

If you know about set theory please skip to the next section because what I am about to say is for those who have no idea what I'm talking about up to this point. Beware what follows is a gross over-simplification and is the absolute minimum needed in order to make full use of the charset library.

What is a set? A set is a collection of things, with no duplicates. What sort of items. Well in our case characters (those things you get when you use CHR$() :-) ). So what is the minimum number of items needed for a collection of items to be a set? Absolutely zero (this is termed the empty set). The items that are part of a set are termed the members of the set and the number of members a set has is termed the cardinality of the set. Another term to do with sets is subset, which is itself a set. Suppose you have two sets, one set will be a subset of the other if all of its members are included in the other. By this definition the empty set is a subset of all other sets and a set is a subset of itself. There is another type of subset, called a strict (or proper) subset. This type of subset is identical to an ordinary subset except that a set cannot be a strict subset of itself. Five set operations that you need to know about are Union, difference, intersection and symmetric set difference and complement. The first 4 of these operations take 2 arguments and return a third.

Set union - The action of this operation is to combine the contents of the 2 arguments and place the result in the third. The order of the 2 arguments is not important.

Set difference - This operation removes those items contained in the second argument that also occur in the first argument, from the first argument and places the result in the third. The order of the first 2 arguments is  paramount.

Set intersection - All the items that occur in both the first argument and the second argument are placed in the third. Order of the first 2 arguments is unimportant.

Symmetric set difference - All the items that occur in either the first argument or the second argument but do not occur in both arguments simultaneously are placed in the third. Order of the first 2 arguments is not a problem for this operation.

Set complement - This operation takes a single argument and returns a second. In order to explain what this operation does I will have to introduce another term. That term is "the universe of a set". The universe of a set is all the items that could possibly be held in a set. In the case of the library that I have placed in this echo that is all the characters in the PC's (western) character set i.e. CHR$(0) to CHR$(255) inclusive. What set complement does is to place into the second all the items in the universe of the set *except* those that are already in the first
        argument.

Having dealt with sets in general, I will now deal with the library I have written. As I have already said a number of times, the sets that are manipulated in this library deal exclusively with characters. This is not as great a limitation as might at first be imagined as (at least in Pascal) sets of characters are by far the most heavily used type of set. So what can you do with these sets of characters? Below is a list of all the routines that are in the library. Those items marked with a * are also supported by Pascal, while those that are marked with an M are part of formal set theory. Those which remain are there to increase the usefulness of the library as a whole. For further information see the comments in CharSet.BI.

Code: (Select All)
Initialise a set                        (InitialiseSet)         *
Add items to a set                      (IncludeInSet)          *
Remove items from a set                 (ExcludeFromSet)        *
Assign one set to another               (CopySet)               *
Make a set completely empty             (MakeSetEmpty)
Copy the contents of a set to a string  (GetSetContents)

How many items are in a set             (Cardinality%)           M
Is an item a member of set              (IsMember)              *M
Is a set empty                          (SetIsEmpty)
Are two sets identical                  (SetEquality)           *M
Are two sets not identical              (SetInequality)         *M
Is one set a subset of another          (IsSubsetOf)            *M
Is one set a strict subset of another   (IsStrictSubsetOf)       M

Set Complement                          (SetComplement)          M
Set Union                               (SetUnion)              *M
Set Difference                          (SetDifference)         *M
Set Intersection                        (SetIntersection)       *M
Symmetric Set Difference                (SymmetricSetDifference) M


Code in next post.

TR


RE: Some Noob (to QB64) Questions - TarotRedhand - 05-13-2022

So here is the BI (CHARSET.BI) file with the DECLARE statements removed -
Code: (Select All)
REM ******************************************************
REM * Filespec  :  charset.bas charset.bi                *
REM * Date      :  June 23 1997                          *
REM * Time      :  12:01                                 *
REM * Revision  :  1.0B                                  *
REM * Update    :                                        *
REM ******************************************************
REM * Released to the Public Domain                      *
REM ******************************************************

CONST SetSize = 32      ' Number of bytes to store set contents

TYPE CharSet
    MySet AS STRING * SetSize
    MySize AS INTEGER
END TYPE

Having removed all those DECLAREs, I have moved the comments into the BAS (CHARSET.BAS) file. This means that it is now 360+ lines long now -

Code: (Select All)
'$INCLUDE: 'CHARSET.BI'

CONST Last = SetSize - 1
CONST TRUE  = -1
CONST FALSE = 0

REM ******************************************************
REM * Private SUB - Do not call directly                *
REM ******************************************************
SUB SetError ( ErrMessage AS STRING )
    PRINT "ERROR : ";ErrMessage
    PRINT "ABORTING NOW!"
    STOP
END SUB

REM ******************************************************
REM * Private SUB - Do not call directly                *
REM ******************************************************
SUB LoadSet ( A AS CharSet, LoadChars AS STRING )
    IF LoadChars <> "" THEN
        LoadSize% = LEN(LoadChars)
        Here% = 1
        LocationNext% = INSTR(Here%, LoadChars, "...")
        DO WHILE LocationNext% > 0
            Start% = ASC(MID$(LoadChars, LocationNext% - 1, 1))
            Fini%  = ASC(MID$(LoadChars, LocationNext% + 3, 1))
            Here%  = LocationNext% + 4
            IF Start% > Fini% THEN
                Start% = (Start% XOR Fini%)
                Fini%  = (Start% XOR Fini%)
                Start% = (Start% XOR Fini%)
            END IF
            FOR X% = Start% TO Fini%
                Y% = 1 + (X% \ 8)
                Z% = X% MOD 8
                MID$(A.MySet, Y%, 1) = CHR$(ASC(MID$(A.Myset, Y%, 1)) OR PowerOf2%(Z%))
            NEXT X%
            IF Here% >= LoadSize% THEN
                EXIT DO
            END IF
            LocationNext% = INSTR(Here%, LoadChars, "...")
        LOOP
        IF Here% < LoadSize% THEN
            FOR X% = Here% TO LoadSize%
                AChar$ = MID$(LoadChars, X%, 1)
                Y% = 1 + (ASC(AChar$) \ 8)
                Z% = ASC(AChar$) MOD 8
                MID$(A.MySet, Y%, 1) = CHR$(ASC(MID$(A.MySet, Y%, 1)) OR PowerOf2%(Z%))
            NEXT X%
        END IF
    END IF
END SUB

REM ******************************************************
REM * Private SUB - Do not call directly                *
REM ******************************************************
SUB Recount ( A AS CharSet )
    A.MySize = 0
    FOR X% = 1 TO SetSize
        TestChar$ = MID$(A.MySet, X%, 1)
        FOR Y% = 0 TO 7
            IF (ASC(TestChar$) AND PowerOf2%(Y%)) <> 0 THEN
                A.MySize = A.MySize + 1
            END IF
        NEXT Y%
    NEXT X%
END SUB

REM ******************************************************
REM * Private FUNCTION - Do not call directly            *
REM ******************************************************
FUNCTION PowerOf2% ( Power AS INTEGER )
    SELECT CASE Power
        CASE 0
            PowerOf2% = 1
        CASE 1
            PowerOf2% = 2
        CASE 2
            PowerOf2% = 4
        CASE 3
            PowerOf2% = 8
        CASE 4
            PowerOf2% = 16
        CASE 5
            PowerOf2% = 32
        CASE 6
            PowerOf2% = 64
        CASE 7
            PowerOf2% = 128
        CASE ELSE
            PowerOf2% = 0
    END SELECT
END FUNCTION

REM *****************************************************************
REM * Must be called before a charset is used unless that charset  *
REM * is used to hold the results of a set operation.  Valid set    *
REM * operations that can be called in lieu of this routine are -  *
REM * CopySet, MakeSetEmpty, SetComplement, SetUnion, SetDifference,*
REM * SetIntersection and SymmetricSetDifference, where without    *
REM * exception the uninitialised set would be used for the        *
REM * rightmost parameter.                                          *
REM *                                                              *
REM * The string InitialChars is used to specify the initial        *
REM * contents of the CharSet being initialised.  The format of    *
REM * the string is as follows.                                    *
REM *                                                              *
REM * If an empty set is desired it is possible to pass an empty    *
REM * string "" to this routine, although the routine MakeSetEmpty  *
REM * would probably be quicker.                                    *
REM *                                                              *
REM * A range of characters can be specified by the use of a        *
REM * trigraph (...) in the form a...z which would tell this        *
REM * routine to include all the characters from lower case 'a' to  *
REM * lower case 'z' inclusive.  More than one range of characters  *
REM * may be specified for a set, but all ranges MUST be the first  *
REM * of the characters specified.                                  *
REM *                                                              *
REM * A list of the actual characters required to be contained      *
REM * within the set such as "axwf9\" may be part of (or the whole  *
REM * of) the string, but MUST appear after any range(s) of        *
REM * characters.                                                  *
REM *                                                              *
REM * See the example program for more help.                        *
REM *****************************************************************

SUB InitialiseSet ( A AS CharSet, InitialChars AS STRING )
    MakeSetEmpty A
    LoadSet A, InitialChars
    Recount A
END SUB

REM *****************************************************************
REM * Copies the contents of one set to another.                    *
REM *****************************************************************

SUB CopySet ( This AS CharSet, ToThis AS CharSet )
    ToThis.MySet = This.MySet
    ToThis.MySize = This.Mysize
END SUB

REM *****************************************************************
REM * Adds the characters of the string IncludeChars to set A.  The *
REM * same rules for the contents of the string used by the routine *
REM * InitialiseSet apply.                                          *
REM *****************************************************************

SUB IncludeInSet ( A AS CharSet, IncludeChars AS STRING )
    LoadSet A, IncludeChars
    Recount A
END SUB

REM *****************************************************************
REM * If any of the characters in ExcludedChars are also part of    *
REM * set A, such characters will be removed from set A.            *
REM *****************************************************************

SUB ExcludeFromSet ( A AS CharSet, ExcludedChars AS STRING )
    DIM TempSet AS CharSet
    IF ExcludedChars = "" THEN
        SetError("ExcludeFromSet - No chars to exclude!")
    END IF
    InitialiseSet TempSet, ExcludedChars
    FOR X% = 1 TO SetSize
        MID$(A.MySet, X%, 1) = CHR$(ASC(MID$(A.MySet, X%, 1)) AND NOT(ASC(MID$(TempSet.MySet, X%, 1))))
    NEXT X%
    Recount A
END SUB

REM *****************************************************************
REM * Returns the number of elements of set A.                      *
REM *****************************************************************

FUNCTION Cardinality% ( A AS CharSet )
    Cardinality% = A.MySize
END FUNCTION

REM *****************************************************************
REM * Tests for set A being empty.                                  *
REM *****************************************************************

FUNCTION SetIsEmpty ( A AS CharSet )
    SetIsEmpty = (A.MySize = 0)
END FUNCTION

REM *****************************************************************
REM * Empties set A.                                                *
REM *****************************************************************

SUB MakeSetEmpty ( A AS CharSet )
    FOR X% = 1 TO SetSize
        MID$(A.MySet, X%, 1) = CHR$(0)
    NEXT X%
    A.MySize = 0
END SUB

REM *****************************************************************
REM * In order to use this routine, the string TestChar MUST only  *
REM * have a single character.  If the string is empty or it has    *
REM * more than 1 character, an error message will be displayed and *
REM * the program will be STOPped.                                  *
REM *                                                              *
REM * This routine tests whether the character TestChar is a member *
REM * of set A (TestChar IN A).                                    *
REM *****************************************************************

FUNCTION IsMember ( A AS CharSet, TestChar AS STRING )
    IF TestChar = "" THEN
        SetError("IsMember - No char to test!")
    END IF
    IF LEN(TestChar) > 1 THEN
        SetError("IsMember - Too many chars to test!")
    END IF
    Y% = 1 + (ASC(TestChar) \ 8)
    Z% = ASC(TestChar) MOD 8
    IsMember = ((ASC(MID$(A.MySet, Y%, 1)) AND PowerOf2(Z%)) <> 0)
END FUNCTION

REM *****************************************************************
REM * Converts the set A to the string OutChars for PRINTING etc.  *
REM *****************************************************************

SUB GetSetContents ( A AS CharSet, OutChars AS String )
    OutChars = ""
    FOR X% = 1 TO SetSize
        Temp$ = MID$(A.MySet, X%, 1)
        FOR Y% = 0 TO 7
            IF (ASC(Temp$) AND PowerOf2%(Y%)) <> 0 THEN
                OutChars = OutChars + CHR$(((X% - 1) * 8) + Y%)
            END IF
        NEXT Y%
    NEXT X%
END SUB

REM *****************************************************************
REM * Tests for A = B.                                              *
REM *****************************************************************

FUNCTION SetEquality ( A AS CharSet, B AS CharSet )
    SetEquality = (A.MySet = B.MySet)
END FUNCTION

REM *****************************************************************
REM * Tests for A <> B.                                            *
REM *****************************************************************

FUNCTION SetInequality ( A AS CharSet, B AS CharSet )
    SetInequality = (A.MySet <> B.MySet)
END FUNCTION

REM *****************************************************************
REM * Tests to see if all of the characters contained in the set    *
REM * This are also present in the set OfThis, i.e that the set    *
REM * This is a subset of the set OfThis.  Note if the 2 sets are  *
REM * equal or the set This is empty then the set This IS a subset  *
REM * of the set OfThis.                                            *
REM *****************************************************************

FUNCTION IsSubsetOf ( This AS CharSet, OfThis AS CharSet )
    IF SetEquality(This, OfThis) THEN
        IsSubsetOf = TRUE
        EXIT FUNCTION
    END IF
    IF SetIsEmpty(This) THEN
        IsSubsetOf = TRUE
        EXIT FUNCTION
    END IF
    IF This.MySize > OfThis.MySize THEN
        IsSubsetOf = FALSE
        EXIT FUNCTION
    END IF
    FOR X% = 1 TO SetSize
        TestChar1$ = MID$(This.MySet, X%, 1)
        TestChar2$ = MID$(OfThis.MySet, X%, 1)
        FOR Y% = 0 TO 7
            Z% = PowerOf2%(Y%)
            P% = (ASC(TestChar1$) AND Z%)
            Q% = (ASC(TestChar2$) AND Z%)
            IF ((P% <> 0) AND (Q% = 0)) THEN
                IsSubsetOf = FALSE
                EXIT FUNCTION
            END IF
        NEXT Y%
    NEXT X%
    IsSubsetOf = TRUE
END FUNCTION

REM *****************************************************************
REM * Identical to the routine IsSubsetOf with the exception that  *
REM * the 2 sets may not be equal (This <> OfThis).                *
REM *****************************************************************

FUNCTION IsStrictSubsetOf ( This AS CharSet, OfThis AS CharSet )
    IF SetEquality(This, OfThis) THEN
        IsStrictSubsetOf = FALSE
        EXIT FUNCTION
    END IF
    IsStrictSubsetOf = IsSubsetOf(This, OfThis)
END FUNCTION

REM *****************************************************************
REM * The operation set complement places all the characters that  *
REM * are NOT part of the set A into the set ComplementOfA.        *
REM *****************************************************************

SUB SetComplement ( A AS CharSet, ComplementOfA AS CharSet )
    FOR X% = 1 TO SetSize
        MID$(ComplementOfA.MySet, X%, 1) = CHR$((ASC(MID$(A.MySet, X%, 1))) XOR 255)
    NEXT X%
    Recount ComplementOfA
END SUB

REM *****************************************************************
REM * The operation set union combines all the characters that are  *
REM * in set A and all the characters that are in set B and returns *
REM * the result of this in set C.                                  *
REM *****************************************************************

SUB SetUnion ( A AS CharSet, B AS CharSet, C AS CharSet )
    FOR X% = 1 TO SetSize
        MID$(C.MySet, X%, 1) = CHR$(ASC(MID$(A.MySet, X%, 1)) OR ASC(MID$(B.MySet, X%, 1)))
    NEXT X%
    Recount C
END SUB

REM *****************************************************************
REM * The operation set difference places only those characters of  *
REM * set A which are NOT part of set B into set C.                *
REM *****************************************************************

SUB SetDifference ( A AS CharSet, B AS CharSet, C AS CharSet )
    FOR X% = 1 TO SetSize
        MID$(C.MySet, X%, 1) = CHR$(ASC(MID$(A.MySet, X%, 1)) AND NOT(ASC(MID$(B.MySet, X%, 1))))
    NEXT X%
    Recount C
END SUB

REM *****************************************************************
REM * After this operation set C will contain only those characters *
REM * which occur in both set A and set C.                          *
REM *****************************************************************

SUB SetIntersection ( A AS CharSet, B AS CharSet, C AS CharSet )
    FOR X% = 1 TO SetSize
        MID$(C.MySet, X%, 1) = CHR$(ASC(MID$(A.MySet, X%, 1)) AND ASC(MID$(B.MySet, X%, 1)))
    NEXT X%
    Recount C
END SUB

REM *****************************************************************
REM * This operation is the set equivalent of the logical operation *
REM * exclusive or, in that after this operation set C will contain *
REM * only those characters that occur in either set A or set B but *
REM * not in both.                                                  *
REM *****************************************************************

SUB SymmetricSetDifference ( A AS CharSet, B AS CharSet, C AS CharSet )
    FOR X% = 1 TO SetSize
        MID$(C.MySet, X%, 1) = CHR$(ASC(MID$(A.MySet, X%, 1)) XOR ASC(MID$(B.MySet, X%, 1)))
    NEXT X%
    Recount C
END SUB

And finally the demo/test program (TESTSETS.BAS) -
Code: (Select All)
'$INCLUDE: 'charset.bi'

DIM ASet AS CharSet, BSet AS CharSet, CSet AS CharSet, DSet AS CharSet
DIM ESet AS CharSet, FSet AS CharSet, GSet AS CharSet, HSet AS CharSet
DIM ISet AS CharSet, JSet AS CharSet, KSet AS CharSet, SetL AS CharSet
DIM MSet AS CharSet, NSet AS CharSet, OSet AS CharSet, SetP AS CharSet
DIM QSet AS CharSet, SetR AS CharSet, SSet AS CharSet, TSet AS CharSet
AStr$ = CHR$(129) + "..." + CHR$(147)
BStr$ = CHR$(0) + "..." + CHR$(31)
CStr$ = CHR$(148) + "..." + CHR$(255)
DStr$ = CHR$(33) + "..." + CHR$(127)
EStr$ = CHR$(0) + "...MO..." + CHR$(255)
CLS
PRINT "Working .";
InitialiseSet ASet, "A...Za...z"
PRINT ".";
InitialiseSet BSet, ",.<>;':@#~{}[]"
PRINT ".";
InitialiseSet CSet, "0...9!œ$%^&*()_-+=\|"
PRINT ".";
InitialiseSet DSet, AStr$
PRINT ".";
InitialiseSet ESet, "a...z0...9!œ$%^&*()_-+=\|;:'@#~[]{}"
PRINT ".";
InitialiseSet FSet, "acegikmoqsuwy"
PRINT ".";
InitialiseSet GSet, "A...Z"
PRINT ".";
InitialiseSet HSet, "a...z"
PRINT ".";
CopySet ASet, ISet
PRINT ".";
InitialiseSet JSet, ""
PRINT ".";
SetComplement JSet, KSet
PRINT ".";
MakeSetEmpty SetL
PRINT ".";
InitialiseSet MSet, DStr$
PRINT ".";
InitialiseSet NSet, EStr$
PRINT ".";
SetComplement NSet, OSet
PRINT ".";
CopySet NSet, SetP
PRINT ".";
ExcludeFromSet NSet, BStr$
PRINT ".";
GetSetContents ASet, FStr$
PRINT "."
PRINT "Set A contains - "; FStr$
GetSetContents BSet, FStr$
PRINT "Set B contains - "; FStr$
GetSetContents CSet, FStr$
PRINT "Set C contains - "; FStr$
GetSetContents DSet, FStr$
PRINT "Set D contains - "; FStr$
GetSetContents ESet, FStr$
PRINT "Set E contains - "; FStr$
GetSetContents FSet, FStr$
PRINT "Set F contains - "; FStr$
GetSetContents GSet, FStr$
PRINT "Set G contains - "; FStr$
GetSetContents HSet, FStr$
PRINT "Set H contains - "; FStr$
GetSetContents ISet, FStr$
PRINT "Set I contains - "; FStr$
GetSetContents JSet, FStr$
PRINT "Set J contains - "; FStr$
ExcludeFromSet KSet, BStr$
GetSetContents KSet, FStr$
IncludeInSet KSet, BStr$
PRINT "Set K contains - "; FStr$
GetSetContents SetL, FStr$
PRINT "Set L contains - "; FStr$
GetSetContents MSet, FStr$
PRINT "Set M contains - "; FStr$
GetSetContents NSet, FStr$
PRINT "Set N contains - "; FStr$
GetSetContents OSet, FStr$
PRINT "Set O contains - "; FStr$
ExcludeFromSet SetP, BStr$
GetSetContents SetP, FStr$
IncludeInSet SetP, BStr$
PRINT "Set P contains - "; FStr$
WaitKey
PRINT
PRINT "Cardinality of A = "; Cardinality%(ASet)
PRINT "Cardinality of B = "; Cardinality%(BSet)
PRINT "Cardinality of C = "; Cardinality%(CSet)
PRINT "Cardinality of D = "; Cardinality%(DSet)
PRINT "Cardinality of E = "; Cardinality%(ESet)
PRINT "Cardinality of F = "; Cardinality%(FSet)
PRINT "Cardinality of G = "; Cardinality%(GSet)
PRINT "Cardinality of H = "; Cardinality%(HSet)
PRINT "Cardinality of I = "; Cardinality%(ISet)
PRINT "Cardinality of J = "; Cardinality%(JSet)
PRINT "Cardinality of K = "; Cardinality%(KSet)
PRINT "Cardinality of L = "; Cardinality%(SetL)
PRINT "Cardinality of M = "; Cardinality%(MSet)
PRINT "Cardinality of N = "; Cardinality%(NSet)
PRINT "Cardinality of O = "; Cardinality%(OSet)
PRINT "Cardinality of P = "; Cardinality%(SetP)
WaitKey
PRINT
IF SetIsEmpty(SetL) THEN
    PRINT "Set L is EMPTY!"
ELSE
    PRINT "Error in SetIsEmpty!"
    STOP
END IF
IF IsMember(HSet, "a") THEN
    PRINT "The letter 'a' is a member of set H."
ELSE
    PRINT "Error in IsMember!"
    STOP
END IF
IF SetEquality(ASet, ISet) THEN
    PRINT "Set A = Set I"
ELSE
    PRINT "Error in SetEquality!"
    STOP
END IF
IF SetInequality(ASet, BSet) THEN
    PRINT "Set A <> Set B"
ELSE
    PRINT "Error in SetInequality!"
    STOP
END IF
IF IsSubsetOf(ISet, ASet) THEN
    PRINT "Set I is a subset of Set A"
ELSE
    PRINT "Error in IsSubsetOf!"
    STOP
END IF
IF NOT (IsStrictSubsetOf(ISet, ASet)) AND IsStrictSubsetOf(FSet, ASet) THEN
    PRINT "Set I is NOT a strict subset of A while Set F is."
ELSE
    PRINT "Error in IsStrictSubsetOf!"
    STOP
END IF
WaitKey
PRINT
PRINT"Testing the operation of set union on -> G + B = Q."
PRINT
GetSetContents GSet, FStr$
PRINT"Set G contains - ";FStr$
GetSetContents BSet, FStr$
PRINT"Set B contains - ";FStr$
SetUnion GSet, BSet, QSet
GetSetContents QSet, FStr$
PRINT"After set union set Q contains - ";FStr$
PRINT
PRINT"Testing the operation of set Difference on -> H - F = R."
PRINT
GetSetContents HSet, FStr$
PRINT"Set H contains - ";FStr$
GetSetContents FSet, FStr$
PRINT"Set F contains - ";FStr$
SetDifference HSet, FSet, SetR
GetSetContents SetR, FStr$
PRINT"After set difference set R contains - ";FStr$
PRINT
PRINT"Testing the operation of set Intersection on -> H * E = S."
PRINT
GetSetContents HSet, FStr$
PRINT"Set H contains - ";FStr$
GetSetContents ESet, FStr$
PRINT"Set E contains - ";FStr$
SetIntersection HSet, ESet, SSet
GetSetContents SSet, FStr$
PRINT"After set intersection set S contains - ";FStr$
PRINT
PRINT"Testing the operation of symmetric set difference on -> C / E = T."
PRINT
GetSetContents CSet, FStr$
PRINT"Set C contains - ";FStr$
GetSetContents ESet, FStr$
PRINT"Set E contains - ";FStr$
SymmetricSetDifference CSet, ESet, TSet
GetSetContents TSet, FStr$
PRINT"After set symmetric set difference set T contains - ";FStr$
PRINT
WaitKey
PRINT"All tests complete."
END

SUB WaitKey
    DO
    LOOP WHILE INKEY$ = ""
END SUB

'$INCLUDE: 'charset.bas'

One thing I have noticed is that constants only seem to be valid in the file in which they occur because with the way the code above is I get an invalid declaration in CHARSET.BAS but if I move the CONST line out of CHARSET.BI into CHARSET.BAS above the first CONST in that file, the problem goes away. Is it supposed to be like that or is it a bug?

TR


RE: Some Noob (to QB64) Questions - SMcNeill - 05-13-2022

Move the 3 CONST from the second file to the first:

CONST Last = SetSize - 1
CONST TRUE = -1
CONST FALSE = 0

Then save the second file as "CHARSET.BM" <-- don't use the BI extension. Make it .BM instead.


Then at the 3rd file, instead of including the .bas file, $INCLUDE:'CHARSET.BM' for that last line.