Portal | Manuals | References | Downloads | Info | Programs | JCLs | Master the Mainframes
IBM Mainframe Computers Forums Index
 
Register
 
IBM Mainframe Computers Forums Index Mainframe: Search IBM Mainframe Forum: FAQ Memberlist Usergroups Profile Log in to check your private messages Log in
 

 

sequential file processing

 
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> COBOL Programming
View previous topic :: :: View next topic  
Author Message
imain
Warnings : 1

New User


Joined: 25 Jun 2006
Posts: 14
Location: US

PostPosted: Thu Oct 19, 2006 5:12 pm    Post subject: sequential file processing
Reply with quote

hi all,

i have two files in sequential format and also sorted
1.transaction file.(taccno,tdate,tamt and status(credit or debit)

2.master file.(accountno, name, balance)

I am reading transaction file and tries to find the taccno in master
file,for the first time it works well and good but for the second time
the master file will not read records previously read how can i solve
the problem.can i use file status codes to handle this condition.

thanks in advance
Back to top
View user's profile Send private message

DavidatK

Active Member


Joined: 22 Nov 2005
Posts: 700
Location: Troy, Michigan USA

PostPosted: Thu Oct 19, 2006 11:58 pm    Post subject: Re: sequential file processing
Reply with quote

If the files are already in sort order, why do you need to read previously read records?

Dave
Back to top
View user's profile Send private message
vijayamadhuri

Active User


Joined: 06 Apr 2005
Posts: 180

PostPosted: Fri Oct 20, 2006 2:16 am    Post subject: hello
Reply with quote

one way u can do is
load u r master file into an array.search (use search command) to search the array (keep incrementing the index( ix) till u find a match.once u find a match reset the index .

so for u r second record u would be reading the file from the begining..

i think the other method is binary search...


hope that helps...
Back to top
View user's profile Send private message
DavidatK

Active Member


Joined: 22 Nov 2005
Posts: 700
Location: Troy, Michigan USA

PostPosted: Fri Oct 20, 2006 2:48 am    Post subject: Re: sequential file processing
Reply with quote

VM,

Your solution is possible for small files, however not practical. What happens when the master file cantains large numbers of records. i.e. 150,000,000 records? And the transaction file contains 10,000,000 records?

The solution for "imain" is a single pass through the master file and the transaction file.

Dave
Back to top
View user's profile Send private message
azshukla

New User


Joined: 31 May 2006
Posts: 9
Location: Pune

PostPosted: Fri Oct 20, 2006 12:54 pm    Post subject:
Reply with quote

Hi DavidatK
The problem faced by imain is perhaps that he wants to search Accounts in master file corresponding to each taccno in transaction file. If it is one to one mapping then definitly he doesn't need to read a previously read record again , but if it is not one to one mapping there would be multiple records in any of the file corressponding to other file. in this case it is inevitable to do a search from starting each time.. i don't think there is any other possible way.. and if it is.. please share with us..
Mainframs are used for handling large files.. and thats thier advantage that they can handle these lengthy files.. if there is no other way, we will have to sacrifice the performence..
Back to top
View user's profile Send private message
MFRASHEED

Active User


Joined: 14 Jun 2005
Posts: 186
Location: USA

PostPosted: Fri Oct 20, 2006 8:23 pm    Post subject: Re: sequential file processing
Reply with quote

Let us look at this with functionality prespective.

We have a Master file (Assuming one record per Account)
We also have a transaction file (Assuming multiple records per Account)

If both files are sorted on Account# what would be need to look back on master file? I guess probably I don't understand what is need here can you clarify imain.

I would agree with DavidatK. Table processing for large files is bad design. In our shop we used to have program where a large 2 dimensional table was defined which increased the program run time 5 folds. This table was so large there were region issues, missed timelines etc. This situation was resolved by spliting program processing in two runs. If there is need for look back, these records can be written to a seperate file and next program will process only these records. And believe me this is much better than trying to do everything in one program. I guess if we understand the requirements a better solution can be thought of.

Even though mainframes can handle large volumes etc, but applications should be designed to make best use of available resources. MIPS add up and can prove costly and hurt bottom line.
Back to top
View user's profile Send private message
azshukla

New User


Joined: 31 May 2006
Posts: 9
Location: Pune

PostPosted: Sat Oct 21, 2006 2:48 am    Post subject: Re: sequential file processing
Reply with quote

Well i think these all talks are useless... untill you have the requirement , you can't design.. and what i believe assumptions made by a vender are the most serious mistakes done by their side.. untill you have a clear requirement .. you can not go ahead with assumptions.. for the lrage chunk of data pple usually keep them in segmented files which are again interlinked.. it is a complex design.. and i'm not sure whether IMAIN asked for that... his problem is
how to read the previous read record and do you have any other way to do that?? or else there are always better sollutions..coz nothing is perfect!!!
Back to top
View user's profile Send private message
dbzTHEdinosauer

Global Moderator


Joined: 20 Oct 2006
Posts: 6966
Location: porcelain throne

PostPosted: Sat Oct 21, 2006 3:08 am    Post subject:
Reply with quote

I think these forums are not useless: I can determine from answers who knows what they are talking about and those who want to just talk.

Actually, the problem is reading the previous record for sorted input files means faulty design/programming.

and your are right, nothing is perfect ........ but giving someone a means to do something slick, when the program sucks in the first place, is useless and does not aspire to the philosophy of these types of forums. So, I will continue to answer questions with what they need to know, not what they what to know.

yeah, I know. means someone has to learn something or do something different. some point or another you have to start over if what you have is wrong.
Back to top
View user's profile Send private message
dbzTHEdinosauer

Global Moderator


Joined: 20 Oct 2006
Posts: 6966
Location: porcelain throne

PostPosted: Sat Oct 21, 2006 3:51 am    Post subject: Sequential File Processing
Reply with quote

Basic Update 101----- Transaction file is the trigger file > T = t in case one forgets.

Masterfile is only read when the transaction file presents an account number greater than the masterfile account number. You never read backwards in sorted sequential file processing.

Sometimes I think that random access was developed because so few could write a logical program.

If anyone is offended by my remarks, I don't apologize. This level of silliness does not require diplomacy.
Back to top
View user's profile Send private message
mmwife

Super Moderator


Joined: 30 May 2003
Posts: 1592

PostPosted: Sun Oct 22, 2006 3:47 am    Post subject:
Reply with quote

Hi Imain,

This is one of two batch pgm algorithms that comprise more than 90% of batch pgms in existence today... so you better learn the concept.

The other one is the control break algorithm.

You begin by sorting both files on the same key.
I've included code as an example (sorry, I couldn't find how to use the attach function):
Code:
 00001  IDENTIFICATION DIVISION.
00002  PROGRAM-ID.    XXXXXXXX.
00003 *AUTHOR.       
00004 *DATE-WRITTEN   JANUARY  1997.
00005 *REMARKS.
00006 *
00007 *        THIS PROGRAM USES THE DAILY ACCRETION RECORDS TO ACCUM-
00008 *        ULATE MTD AND YTD ACCRETION AMOUNTS AND CREATES A NEW
00009 *        MASTER ACCRETION FILE.
00009 * NOTE!! AT NEW YEAR, A FALSE EOF ON THE MASTER FILE IS CREATED,
00009 *        DELETING ALL EXISTING MASTER RECS THEN ALL DAILY RECS
00009 *        ARE ADDED AS-IS TO THE MASTER FILE. THIS RESETS THE
00009 *        MASTER FILE FOR THE COMMING YEAR.
00010 **
00011 ******************************************************************
00012 *                           CHANGE LOG
00013 ******************************************************************
00014 *
00015 * 01/15/97 J.S. - CREATED.
00016 *
00017 ******************************************************************
00018
00019
00020  ENVIRONMENT DIVISION.
00021  INPUT-OUTPUT SECTION.
00022
00023  FILE-CONTROL.
00024      SELECT  DAILY-ACCRET-FILE-IP ASSIGN TO NT0290E1.
00025      SELECT MASTER-ACCRET-FILE-IP ASSIGN TO NT0290E2.
00026      SELECT MASTER-ACCRET-FILE-OP ASSIGN TO NT0290E3.
00027
00028  DATA DIVISION.
00029  FILE SECTION.
00030  FD  DAILY-ACCRET-FILE-IP.
00031  01  DAILY-ACCRET-REC-IP         PIC  X(150).
00032
00033  FD  MASTER-ACCRET-FILE-IP.
00034  01  MASTER-ACCRET-REC-IP        PIC  X(150).
00035
00036  FD  MASTER-ACCRET-FILE-OP
00037      RECORD CONTAINS 150 CHARACTERS
00038      BLOCK  CONTAINS 000 RECORDS.
00039  01  MASTER-ACCRET-REC-OP        PIC  X(150).
00040
00041  WORKING-STORAGE SECTION.
00042  77  FILLER                      PIC  X(035) VALUE
00043          '****WORKING STORAGE STARTS HERE****'.
00044
00045  01  WS-DAILY-HDR.
00046  ++INCLUDE XX0290E2
00047  01  WS-DAILY-DTL.
00048  ++INCLUDE XX0290E1
00049
00050  01  WS-MASTER-HDR.
00051  ++INCLUDE XX0290E2
00052  01  WS-MASTER-DTL.
00053  ++INCLUDE XX0290E1
00054
00055  01  WS-WORK-AREAS.
00056      05  WS-INFLAT-IDX-TODAY     PIC S9(003)V9(6) COMP-3.
00057      05  WS-INFLAT-IDX-NBDAY     PIC S9(003)V9(6) COMP-3.
00058      05  WS-ACCRET-REC-CNT       PIC S9(007) VALUE +0 COMP-3.
00059      05  WS-INFLAT-IDX-PGM       PIC  X(008) VALUE 'TRA800A'.
00060
00061      05  WS-CURR-DATE-CYMD.
00062          10  WCD-CC              PIC  X(002).
00063          10  WS-CURR-DATE-YMD.
00064              15  WCD-YY          PIC  X(002).
00065              15  WCD-MM          PIC  X(002).
00066              15  WCD-DD          PIC  X(002).
00067
00068  01  WS-SWITCHES-AND-COUNTERS.
00069
00070      05  WS-BOTH-FILES-EOF.
00071          88  BOTH-FILES-EOF                       VALUE 'YY'.
00072          10  FILLER              PIC  X(001) VALUE 'N'.
00073              88  DAILY-FILE-EOF                   VALUE 'Y'.
00074          10  FILLER              PIC  X(001) VALUE 'N'.
00075              88  MASTER-FILE-EOF                  VALUE 'Y'.
00076
00077      05  FILLER                  PIC  X(001) VALUE 'A'.
00078          88  NOT-AN-ACCRET-FILE                   VALUE 'N'.
00079
00080      05  WS-DAILY-REC-CNT        PIC S9(008) VALUE +0 COMP.
00081      05  WS-NO-DAILY-CNT         PIC S9(008) VALUE +0 COMP.
00082      05  WS-MASTER-REC-CNT       PIC S9(008) VALUE +0 COMP.
00083      05  WS-NO-MASTER-CNT        PIC S9(008) VALUE +0 COMP.
00084      05  WS-MATCH-CNT            PIC S9(008) VALUE +0 COMP.
00085      05  WS-MIS-MATCH-CNT        PIC S9(008) VALUE +0 COMP.
00086
00087  01  WS-WORK-FIELDS.
00088
00089      05  WS-BOTH-COMPARE-KEYS.
00090          10  WS-DAILY-COMPARE-KEY.
00091              15  WDC-USR-CDE     PIC  X(002).
00092              15  WDC-ACCT-NBR    PIC  X(008).
00093              15  WDC-SEC-NBR     PIC  X(005).
00094
00095          10  WS-MASTER-COMPARE-KEY.
00096              15  WMC-USR-CDE     PIC  X(002).
00097              15  WMC-ACCT-NBR    PIC  X(008).
00098              15  WMC-SEC-NBR     PIC  X(005).
00099
00100      05  WS-PROJ-START-DATE      PIC  X(008) VALUE
00101          '19970126'.
00102
00103
00104  PROCEDURE DIVISION.
00105 ***************
00106  000-MAIN-LINE.
           DISPLAY 'DEBUG-  000-MAIN-LINE.'
00107 ***************
00108      PERFORM 810-DISP-MSG-AND-OPEN-FILES
00109      PERFORM 820-VERIFY-HEADERS
00110      PERFORM 830-SET-GO-NOGO
00111      PERFORM 840-CHECK-FOR-NEW-YEAR
00112      PERFORM 850-GET-CURR-DATE
00113      WRITE MASTER-ACCRET-REC-OP  FROM WS-DAILY-HDR
00114      PERFORM 200-MATCH-DAILY-MASTER-RECS
00115        UNTIL BOTH-FILES-EOF
00116      PERFORM 900-END-IT
00117      STOP RUN
00118      .
00119 *****************************
00120  200-MATCH-DAILY-MASTER-RECS.
           DISPLAY 'DEBUG-  200-MATCH-DAILY-MASTER-RECS.'
00121 *****************************
00122      EVALUATE TRUE
00123      WHEN WS-DAILY-COMPARE-KEY = WS-MASTER-COMPARE-KEY
00124           PERFORM 210-UPDATE-MASTER-REC
00125           PERFORM 700-GET-BOTH-COMPARE-KEYS THRU 700-EXIT
00126      WHEN WS-DAILY-COMPARE-KEY > WS-MASTER-COMPARE-KEY
00127 *===> I.E., NO DAILY ACCRETION RECORD
00129           PERFORM 220-REWRITE-MASTER-REC
00130           PERFORM 700-GET-MASTER-COMPARE-KEY
00131      WHEN OTHER
00132 *===> I.E., NEW DAILY ACCRETION RECORD, ADD TO MASTER FILE
00134           WRITE MASTER-ACCRET-REC-OP        FROM WS-DAILY-DTL
00135           ADD  +1                             TO WS-NO-MASTER-CNT
00136           PERFORM 700-GET-DAILY-COMPARE-KEY
00137      END-EVALUATE
00138      .
00139 ***********************
00140  210-UPDATE-MASTER-REC.
           DISPLAY 'DEBUG-  210-UPDATE-MASTER-REC.'
00141 ***********************
00142      IF NEW-MONTH  IN WS-DAILY-HDR
00143         MOVE ZEROS TO PAD-MTD-ACCRET-AMT OF WS-MASTER-DTL
00144      END-IF
00145      COMPUTE PAD-MTD-ACCRET-AMT   OF WS-DAILY-DTL
00146              =
00147              PAD-MTD-ACCRET-AMT   OF WS-MASTER-DTL
00148              +
00149              PAD-DAY-ACCRET-AMT   OF WS-DAILY-DTL
00150      COMPUTE PAD-YTD-ACCRET-AMT   OF WS-DAILY-DTL
00151              =
00152              PAD-YTD-ACCRET-AMT   OF WS-MASTER-DTL
00153              +
00154              PAD-DAY-ACCRET-AMT   OF WS-DAILY-DTL
00155      WRITE MASTER-ACCRET-REC-OP FROM WS-DAILY-DTL
00156      .
00157 ************************
00158  220-REWRITE-MASTER-REC.
           DISPLAY 'DEBUG-  220-REWRITE-MASTER-REC.'
00159 ************************
00160      IF NEW-MONTH                        IN WS-DAILY-HDR
00161         MOVE ZEROS TO PAD-MTD-ACCRET-AMT OF WS-MASTER-DTL
00162      END-IF
00163      MOVE ZEROS TO PAD-DAY-ACCRET-AMT    OF WS-MASTER-DTL
00164      WRITE MASTER-ACCRET-REC-OP        FROM WS-MASTER-DTL
00165      ADD  +1                             TO WS-NO-DAILY-CNT
00166      .
00167 ***************************
00168  700-GET-BOTH-COMPARE-KEYS.
           DISPLAY 'DEBUG-  700-GET-BOTH-COMPARE-KEYS.'
00169 ***************************
00170      .
00171 ***************************
00172  700-GET-DAILY-COMPARE-KEY.
           DISPLAY 'DEBUG-  700-GET-DAILY-COMPARE-KEY.'
00173 ***************************
00174      IF NOT DAILY-FILE-EOF
00175         READ DAILY-ACCRET-FILE-IP  INTO WS-DAILY-DTL
00176         AT END
00177              SET DAILY-FILE-EOF TO TRUE
00178              MOVE HIGH-VALUES   TO WS-DAILY-COMPARE-KEY
00179         NOT AT END
00180              ADD  +1            TO WS-DAILY-REC-CNT
00181              MOVE PAD-USR-CDE   OF WS-DAILY-DTL
00182                   TO
00183                   WDC-USR-CDE
00184              MOVE PAD-ACCT-NBR  OF WS-DAILY-DTL
00185                   TO
00186                   WDC-ACCT-NBR
00187              MOVE PAD-SEC-NBR   OF WS-DAILY-DTL
00188                   TO
00189                   WDC-SEC-NBR
00190         END-READ
00191      END-IF
00192      .
00193 ****************************
00194  700-GET-MASTER-COMPARE-KEY.
           DISPLAY 'DEBUG-  700-GET-MASTER-COMPARE-KEY.'
00195 ****************************
00196      IF NOT MASTER-FILE-EOF
00197         READ MASTER-ACCRET-FILE-IP  INTO WS-MASTER-DTL
00198         AT END
00199              MOVE HIGH-VALUES    TO WS-MASTER-COMPARE-KEY
00200              SET MASTER-FILE-EOF TO TRUE
00201         NOT AT END
00202              ADD +1              TO WS-MASTER-REC-CNT
00203              MOVE PAD-USR-CDE    OF WS-MASTER-DTL
00204                   TO
00205                   WMC-USR-CDE
00206              MOVE PAD-ACCT-NBR   OF WS-MASTER-DTL
00207                   TO
00208                   WMC-ACCT-NBR
00209              MOVE PAD-SEC-NBR    OF WS-MASTER-DTL
00210                   TO
00211                   WMC-SEC-NBR
00212         END-READ
00213      END-IF
00214      .
00215  700-EXIT. EXIT.
00216
00217 *****************************
00218  810-DISP-MSG-AND-OPEN-FILES.
           DISPLAY 'DEBUG-  810-DISP-MSG-AND-OPEN-FILES.'
00219 *****************************
00220      DISPLAY '*****************************************'
00221      DISPLAY '             NT0290E STARTED             '
00222      DISPLAY '*****************************************'
00223      OPEN  INPUT MASTER-ACCRET-FILE-IP
00224                   DAILY-ACCRET-FILE-IP
00225           OUTPUT MASTER-ACCRET-FILE-OP
00226      .
00227 ********************
00228  820-VERIFY-HEADERS.
           DISPLAY 'DEBUG-  820-VERIFY-HEADERS.'
00229 ********************
00230 *===>    VERIFY DAILY HEADER
00231 *
00232      READ DAILY-ACCRET-FILE-IP    INTO WS-DAILY-HDR
00233      AT END
00234          SET NOT-AN-ACCRET-FILE     TO TRUE
00235      NOT AT END
00236          IF PAH-HDR-ID OF WS-DAILY-HDR NOT = 'HDR'
00237             SET NOT-AN-ACCRET-FILE  TO TRUE
00238          END-IF
00239      END-READ
00240      IF NOT-AN-ACCRET-FILE
00241         DISPLAY 'ERROR!!!! '
00242                 'INPUT FILE NOT A DAILY ACCRETION FILE'
00243         MOVE +2  TO RETURN-CODE
00244         STOP RUN
00245      END-IF
00246
00247 *===>    VERIFY MASTER HEADER
00248 *
00249      READ MASTER-ACCRET-FILE-IP    INTO WS-MASTER-HDR
00250      AT END
00251          SET MASTER-FILE-EOF         TO TRUE
00252          MOVE HIGH-VALUES            TO WS-MASTER-COMPARE-KEY
00253      NOT AT END
00254          IF PAH-HDR-ID OF WS-MASTER-HDR NOT = 'HDR'
00255             DISPLAY 'ERROR!!!! '
00256                     'INPUT FILE NOT A MASTER ACCRETION FILE'
00257             MOVE +2  TO RETURN-CODE
00258             STOP RUN
00259          END-IF
00260      END-READ
00261      .
00262 *****************
00263  830-SET-GO-NOGO.
           DISPLAY 'DEBUG-  830-SET-GO-NOGO.'
00264 *****************
00265 *===>  IF THE DAILY FILE CONTAINS NO ACCRETION DATA AND
00266 *===>     THE MASTER FILE IS A NULL FILE THE PROJECT HAS
00267 *===>     HAS NOT PRODUCED DATA YET. SET RC=2 TO NOT EXECUTE
00268 *===>     REPORT PROGRAM(NT0290F).
00269 *
00270      PERFORM 700-GET-DAILY-COMPARE-KEY
00271      IF DAILY-FILE-EOF
00272         AND
00273         MASTER-FILE-EOF
00274         DISPLAY 'NOTE!!!! '
00275                 'NO INPUT FOR INFLATION BONDS YET'
00276         MOVE +2  TO RETURN-CODE
00277         STOP RUN
00278      END-IF
00279      PERFORM 700-GET-MASTER-COMPARE-KEY
00280      .
00281 ************************
00282  840-CHECK-FOR-NEW-YEAR.
           DISPLAY 'DEBUG-  840-CHECK-FOR-NEW-YEAR.'
00283 ************************
00284 *===>     AT NEW YEAR FORCE NEW MASTER TO BE CREATED
00285 *
00286      IF NEW-YEAR            IN WS-DAILY-HDR
00287         MOVE HIGH-VALUES    TO WS-MASTER-COMPARE-KEY
00288         SET MASTER-FILE-EOF TO TRUE
00289      END-IF
00290      .
00291 *******************
00292  850-GET-CURR-DATE.
           DISPLAY 'DEBUG-  850-GET-CURR-DATE.'
00293 *******************
00294      ACCEPT WS-CURR-DATE-YMD       FROM DATE
00295      IF WCD-YY                        < '96'
00296         MOVE '20'                    TO WCD-CC
00297      ELSE
00298         MOVE '19'                    TO WCD-CC
00299      END-IF
00300      .
00301 ************
00302  900-END-IT.
           DISPLAY 'DEBUG-  900-END-IT.'
00303 ************
00304      CLOSE        DAILY-ACCRET-FILE-IP
00305                  MASTER-ACCRET-FILE-IP
00306                  MASTER-ACCRET-FILE-OP
00307      DISPLAY ' '
00308      EVALUATE TRUE
00309      WHEN NEW-YEAR IN WS-DAILY-HDR
00310           DISPLAY 'NOTE!!!! MTD AND YTD ACCRETION $ TOTALS '
00311                   'RESET FOR NEW YEAR'
00312           DISPLAY ' '
00313      WHEN NEW-YEAR IN WS-DAILY-HDR
00314           DISPLAY 'NOTE!!!! MTD ACCRETION $ TOTALS '
00315                   'RESET FOR NEW MONTH'
00316           DISPLAY ' '
00317      END-EVALUATE
00318      DISPLAY WS-DAILY-REC-CNT  '  DAILY RECORDS READ'
00319      DISPLAY WS-MASTER-REC-CNT ' MASTER RECORDS READ'
00320      DISPLAY ' '
00321      DISPLAY WS-MATCH-CNT      ' MASTER RECORDS UPDATED'
00322      DISPLAY WS-NO-DAILY-CNT   ' MASTER RECORDS UNCHANGED'
00323      DISPLAY WS-NO-MASTER-CNT  ' MASTER RECORDS ADDED'
00324      DISPLAY ' '
00325      DISPLAY '*****************************************'
00326      DISPLAY '        NT0290E ENDED RETURN CODE = ' RETURN-CODE
00327      DISPLAY '*****************************************'
00328      .
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic    IBMMAINFRAMES.com Support Forums -> COBOL Programming All times are GMT + 6 Hours
Page 1 of 1

 

Search our Forum:

Similar Topics
Topic Author Forum Replies Posted
No new posts SORTJOIN - Copy Matched and Unmatched... Steve Ironmonger DFSORT/ICETOOL 5 Tue Jan 17, 2017 4:26 pm
No new posts Copy RECFM =VB TO FB file with RECL =... sahil41352 DFSORT/ICETOOL 3 Wed Dec 28, 2016 11:29 pm
No new posts Add PD field from 2nd file to PD in 1st Sushant Garje DFSORT/ICETOOL 6 Thu Dec 01, 2016 4:32 pm
No new posts File Aid to File Manager conversion murali3955 IBM Tools 4 Thu Nov 24, 2016 3:41 pm
No new posts How to convert the VBM file to VB or... Sulabh Agrawal JCL & VSAM 4 Fri Nov 18, 2016 1:04 pm


Facebook
Back to Top
 
Mainframe Wiki | Forum Rules | Bookmarks | Subscriptions | FAQ | Tutorials | Contact Us