------------------------------------------------------------------------- | TTTTT H H EEEE | | T H H E | | T HHHH EEE | | T H H E | | T H H EEEE | | | | A M M A TTTTTTT EEEEE U U RRRR | | A A M M M M A A T E U U R R | | A A M M M M A A T EEE U U RRRR | | AAAAA M MM M AAAAA T E U U R R | | A A M M A A T EEEEE UUU R R | | | | CCCC OO MM MM PPP U U TTTTT EEEE RRRR III SSS TTTTT | | C O O M M M P P U U T E R R I S T | | C O O M M M PPPP U U T EEE RRRR I S T | | C O O M M P U U T E R R I S T | | CCCC OO M M P UU T EEEE R R III SSS T | |-------------------------------------------------------------------------| | Winter/Spring 1992 Vol 4 No. 2/3 | ------------------------------------------------------------------------- "Any society that is alive is a society with a history." -Vaclav Havel WELCOME TO THE WONDERFUL WORLD OF COMPUTERS VRS PLANT CLOSURES GM STYLE 4 Years of Amateur Computerist (Editor's Note: With this issue the Amateur Computerist begins its 5th year of publication. Also, we are including in this issue, a complete index of back issues.) February 11, 1988 was the first issue of the Amateur Computerist. The issue was "dedicated to the Flint Sit Down pioneers on the victory of their battle to win industrial unionism 51 years ago." ("Dedication", vol I, no 1) In our first issue, we wrote: "There was an effort by administrators of the UAW-Ford program at the Dearborn Engine Plant to kill interest in computers and computer programming. We want to keep interest alive because computers are the future." ("Introduction", vol I,no 1) One UAW pioneer, Jack Palmer, in summing up the heritage the sitdowners were passing on, wrote: "Each generation has to solve its own problems. The sit-down generation solved the problem of organization. The postwar (W.W.II-ed) generation solved the problem of pensions and inflation. Not entirely, but a good start was begun. The present generation is faced with the greatest problems of all. They are Automation, Peace and Politics." (from the Searchlight, newspaper of UAW Local 659, Flint, MI, April 21, 1960, p.2, quoted in "Dedication", vol. I, no. 1). The Amateur Computerist is an effort to carry forward the torch passed on by the sitdowners - the need to solve the problem of automation. The welcoming of this newsletter by Floyd Hoke-Miller, a pioneer of the Flint Sitdown Strike, demonstrated that there was a continuum between the Sitdown generation and the current genera- tion. In his article, "Dawn of A New Era," Floyd wrote, "From the Great Wall to the Great Pyramid, from the hieroglyphics to the screen of the computer, mankind is still progressing. So make the new born science, that has given us the computer for the amateur and not as a prerogative of the professional to be shrouded in se- crecy from humanity, the choice of the individual, not an election of a minority. (vol I,no. 1) But what has happened in the past 4 years? Has automation in the auto industry made any headway? Has the use of computers and computer education gone forward? In February, 1992, GM announced plans for massive layoffs and plant closings in North America. The high price of automobiles in the U.S. shows that the problem of automation in the auto industry has not been solved. Instead there have been disincentives to the introduction of new technology in the U. S. auto industry similar to those that led to the unraveling of the Soviet Union's so called "command economy." A recent article in Fortune Magazine (vol. 125, no. 1 January 13, 1992 "Can GM Remodel Itself?" by Alex Taylor III) describes GM's inability to utilize new technology. "For example," Taylor writes, "GM put $77 billion into new plants and equipment to reduce labor costs....Some robots it acquired in the mid-1980s stand unused today. The highly automated equipment never delivered the promised savings because GM did not train workers properly to use it, and... failed to design new models for easy robot assembly."(pg 34) As articles in previous issues of the Amateur Computerist have shown, investment in the U.S. auto industry in the 1980's was not in automation that would result in less labor being needed to produce an automobile. No effort was made to reduce the price of a car so more people could afford to buy cars. Instead, U.S. autos were downsized and redesigned, and some of auto company profits were used to set up so called "joint" labor-management labor relations programs or to invest in other companies or abroad. (See for example, "Labor Relations Hoax", vol 2, no. 4) U.S. auto companies instituted a plethora of cost cutting initiatives which removed the incentive for investment in new technology. For a company to invest in modern technology, labor saving devices must cost less than the labor they are replacing. (See "Shorter Hours Are Needed....", vol 2, no. 3) Record profits had been reported in the industry in the 1980s. Yet Wall Street analysts like Maryann Keller sharply criticized new technology being introduced into companies like GM. Instead GM adopted the model of Japanese labor relations introduced into Toyota in the 1950s. This model had been developed based on research that GM conducted during a 1947 labor relations experiment which they called the "My Jobs Contest." (See "When Will Their Walls Come Tumbling Down," vol 3 no. 1) Once again in the 1980s and now in the 1990s such labor relations schemes are being heralded as the savior of a "failing General Motors" and as a model for the rest of U.S. industry. For example, the design for GM's new Saturn plant was premised on GM's commitment to making labor more intense rather than introducing labor saving technology. A spokesperson explains Saturn's philosophy: "In Saturn, we believe that to automate... does not make good business sense. When you consider the capital investment required for robots or other automated systems, you have to look at the variable labor cost as an alternative. Automated equipment is limited! On the other hand, people, if properly trained, can and have taken costs out of an operation when given the opportunity." (Joseph F. Malotke, Labor Law Journal, Aug. 1985,p. 568) GM's Saturn model is a reversal of lessons learned over the past 50 years about the social benefits of new machinery. As Howard Foster, a UAW pioneer in Flint, describing the benefits of modern machinery, explained: "When mass production methods were introduced in the automobile industry, the price of cars went down. This was because the labor time on each car was greatly reduced. Yet we auto workers got higher wages through our union." (See "Technology: To Develop or Stagnate," vol 1, no 2) In opposition to similar labor relations experiments, G.M. auto workers in Flint, MI, in 1947-48, successfully campaigned for wage increases that would match inflation. Their battle against GM management and the UAW International Union officialdom who opposed such wage increases, was victorious. Thus pattern setting wage increases known as C.O.L.A. (Cost of Living Adjustment) and A.I.F. (Annual Improvement Factor) were introduced into the UAW-GM con- tract in 1948. These wage increases made it profitable for GM to introduce new machinery and update production methods in GM plants.(See "Technology, to Develop or Stagnate" vol I,no 2) By 1950, contract language describing the A.I.F. affirmed the social desirability of using new technology to decrease the labor needed to produce an auto. The 1950 GM-UAW contract granted workers a wage increase based "on technological progress, better tools, methods, processes and equipment and a cooperative attitude on the part of all parties in such progress. It further recognizes the principle that to produce more with the same amount of human effort is a sound and economic and social objective." (See "Upcoming Elections and Computers," vol. I, no.3) Union-management jointness experiments of the 1980s are a violation of the principle "that to produce more is a sound and economical objective." The UAW-Ford National Development and Training Center founded in 1982, and similar experiments at GM and Chrysler, are labor relations experiments. Their aim is to "promote training, retraining and development activities," instead of "technological progress, better tools, processes and equipment," (See "Labor Relations Hoax," vol. 2, no. 4) Because their aim is not education in high technology, there was a battle at the Dearborn Engine Plant over the cancellation of computer programming classes. UAW members wrote: "How can UAW members be trained in high technology by cutting computer classes out... we sent letters everywhere. We are tired of being denied benefits we're entitled to. We are tired of being shuffled from one person to another to cover up who we're fighting...we can't sit back and let happen at the Rouge what has happened at GM - the wholesale closing of plants...WE NEED AN INVESTIGATION INTO WHAT IS GOING ON IN THE UAW FORD PROGRAM at the Dearborn Engine Plant. (See "When Will Their Walls Come Down, vol. 3, no. 1) In a subsequent issue of the Amateur Computerist, Floyd Hoke-Miller contributed articles explaining why there is more thinking needed among those who do the work of the society. "We, as the working class," he wrote, "are the `low men on the totem pole' or like Atlas `bearing the world on our shoulders'." (See "Pass the Profits, Please," vol. 1, no. 2) He championed the need for fewer hours of work to have any benefit from new technology and reminded workers that they are still working at least the same 8 hour day "gained by a hard struggle of the transportation unions prior to W.W.I." (Ibid., See also "Shorter Hours are Needed for Computers to Benefit Labor", vol 2, no. 3) The problem of the 1990s is similar to the problem of the early post W.W.II years - how to utilize significant new technological developments to make life better for the people of the society. Large scale industry needs to be under some form of social control and strict regulation for technological progress to serve the society. The birth of the personal computer in 1974 and its development and evolution into the 1990s has put the promise of a better world on the horizon for people in the U.S. and around the world. At the computer classes at the Ford Rouge Plant, before the programming classes were cancelled to make way for the labor relations experiments that replaced them, one auto worker wrote: "Welcome to the Wonderful World of the Computer." The cancelling of those classes in 1987 has made clear that that wonderful world cannot be gained by going backward to ever more labor intensive production, (i.e. speed up), less and less manufacturing capacity (shortages), and ever increasing prices. This is the economic program that U.S. corporations and the U.S. government are promoting in Eastern Europe and the result is massive human hardship and economic dislocation. This economic program will result in the same economic dislocations in the U.S. economy as are currently plaguing Eastern Europe. Thus once again, as in the immediate post W.W.II period, there are serious economic problems in the U.S. and the world. There is a need to have auto workers and others, particularly those who work in large scale industry, consider and debate the economic problems of our times. History has shown that this is the only way that solutions which lead the society forward can be found. Prohibitions against workers writing in their local union newspapers to prevent public criticisms of trade union officials or policies, as exist in the UAW, need to be overturned. (See for example Convention Pro- ceedings of 1951 UAW Convention and UAW Public Review decisions like No. 888, Bier vrs. Local Union 2500 Executive Board, UAW, and No. 238, Plyer vrs. Local 599 (1961)) As Carl Johnson, a UAW pioneer explained, auto workers are capable of solving the problems facing them if they have access to organs of free discussion. Johnson wrote: "If local union publi- cations...provide the ranks with a freer discussion which alone can prepare the ranks for the fight which is sure to be plenty tough, then we need not worry too much, for American labor proved in '36 and '37 that it can move fast and furiously when it knows where to go."(Carl Johnson, "Only More Democracy Can Save Democracy," Feb. 1, 1945, The Searchlight, UAW Local 659, Flint) Describing the important role to be filled by an uncensored labor press, he wrote,"If the Labor press does not try to give Labor the whole truth, where will Labor get it? This, of course, raises the question: Who is right about Labor's destiny? Certainly we can't rely on the capitalist press to tell us, for it is obvious that their interest is the opposite of Labor's interest. But who, from the ranks of Labor? Let them all speak -- that's what Free Speech was intended for! Let them all present their view in a forum. From that the reader will have a fair chance to decide." (Ibid., Oct. 29, 1949) Once again, in 1992, there is the need for access to the uncen- sored local union newspaper. This tradition was pioneered by auto workers in Flint in the 1940's to carry on the militant Spirit of the Sit Down Strike, the "Spirit of '37." This press made it possible for those who do the work of the society to be able to analyze the current problems and debate the way forward. This uncensored labor press no longer exists, but computer bulletin boards across the U.S. and the world are providing access to uncen- sored discussion so the momentous problems of our times can be debated and analyzed. On computer bulletin boards like Usenet News, MNET (Ann Arbor, MI), etc., such discussion is now taking place. (We plan to include articles describing this important development in future issues.) Also, there is a need for education, independent of large corporate employers like GM or Ford, and for a press to express a working class voice, independent, as well, of any censorship from union officials. To this end the Amateur Comp- uterist is dedicated and we need and welcome your participation in helping to create this independent voice so as to be able to gain the fruits of the computer revolution for those who do the work of this society. Floyd Hoke-Miller, a pioneer of the Flint Sitdown Strike wrote the following poem as part of his commitment to the need for an uncensored press: Voice of the Chevrolet Worker It matters not what bossman say, How much they rant and rave Their Sunday suit and higher pay, Do not exclude the grave. *** The wage-slaves toil at their behest, Producing only by their word There's no denying one request, Their voices must be heard. *** They know quite well that banker men, And owners of the tools Connive with pie cards when they can, To treat the laborers as fools. *** Their language may not stand all tests, But let them have their say For on their backs the burden rests, They MAKE the Chevrolet. by Floyd Hoke-Miller AMATEUR COMPUTERIST INDEX Volume 1 No 1 INTRODUCTION DAWN OF A NEW ERA DEDICATION THE WORLD OF TELECOMMUNICATIONS TRY THIS (GRAPHICS) THE FUTURE BELONGS TO PROGRAMMERS THE FIRST PROGRAMMER (PICTURE) WHY LEARN PROGRAMMING COVER OF PERSONAL COMPUTING (PICTURE) COMMODORE TIPS & TRICKS Volume 1 No 2 THE BIG MACHINE PASS THE PROFITS, PLEASE TECHNOLOGY: TO DEVELOP OR STAGNATE? CARTOON BY "DOC" WILSON SAMPLE BASIC GRAPHIC PROGRAM TRY THIS (IBM) THE WORLD OF TELECOM... CORRECTIONS GERMAN VOCABULARY HELPER PROGRAMMING IN BASIC OR C? CONFIGURING YOUR SYSTEM LETTER TO THE EDITOR Volume 1 No 3 LETTER PUBLISHED IN RADIO-ELECTRONICS RESPONSES FROM AROUND THE COUNTRY EDITORIAL SAVIOR IN WAITING HOW TO USE THE MERIT NETWORK? VIRTUAL DRIVES & BATCH FILES TRY THIS (EQUATION OF A STRAIGHT LINE) AS I WAS SAYING... (WHY COMPUTERISM?) COMPUTERS AND FREE SPEECH LETTER TO THE EDITOR PLANT LIFE (PICTURE) Volume 2 No 1 RETURN TO SANITY WITH THE AMATEUR & THE PRO LETTERS FROM READERS PROBLEM CORNER TRY THIS FOR IBM (INPUT NUMBER FROM 20-150) SYSTEM DIAGRAM FOR QUADRAPHONIC SOUND SYS.) RESPONSE TO OCTOBER EDITORIAL CARTOONS (COMMODORE COUNTY) WELCOME TO COMMODORE COUNTY USA COMPUTER HACKING, A CRIME? IBM KEY ASSIGNMENTS USING THE "PROMPT"... HISTORY OF COMPUTERS... PART I Volume 2 No 2 WHY LEARN TO PROGRAM? (DISCUSSION) LETTERS TRY THIS (MESSAGE) "SE Q" FOR IBM AS I WAS SAYING (JOBS: HOURS AND SENSE...) OVERTIME AND UNDER PAY MAY DAY SAMPLE BATCH FILE HISTORY OF COMPUTERS PART II Volume 2 No 3 IMPACT OF COMPUTERS ON SOCIETY: A DEBATE LETTERS TO THE EDITOR COCO CORNER (GRAIL QUEST-PIP) COMMODORE COUNTY USA (CURSOR COLOR CHANGE) OUT OF THE HEART OF THE ABACUS... HISTORY OF THE COMPUTER PART III Volume 2 No 4 LETTER FROM PROSECUTOR OPPOSING VIEWPOINT... LETTERS TO THE EDITOR WANTED ALIVE (AD) COCO CORNER (EQUATION GRAPHING PRG.) TRUE HEROES TRIGONOMETRY LESSON FOR IBM HISTORY OF THE COMPUTER PART IV Volume 3 No 1 LETTER FROM EDITOR OF DETROIT NEWS DON'T REPLICATE UAW-FORD SCHOOL LETTERS TO EDITOR COMMODORE COUNTY USA (CARTOON) THE SPIRIT OF BABBAGE COCO CORNER (POKE & PEAK) CAD/CAM/CIM HISTORY OF COMPUTERS PART V Volume 3 No 2 THE LABORER, YES FLOYD HOKE-MILLER (1898-1990) THE PICKET IN HONOR OF LABOR'S POET LAUREATE COMPUTER EDUCATION AND GOVERNMENT REG. LETTER FROM SUPERINTENDENT OPEN LETTER TO SUPERINTENDENT BEMIS LETTER TO GOVERNOR COMMODORE COUNTY U.S.A. (SHIMMERING TEXT) C64 MUSIC DIGITIZER IBM LABEL PROGRAM COCO CORNER (CALORIE COUNTER) BULLETIN BOARD NUMBERS Volume 3 No 3 WHAT CRITICISMS HAVE YOU OF THE A.C.? TIPS AND TRICKS (IBM BOOT PROBLEM) LETTER TO EDITOR EDITORIAL A COMMON MAN OF GREATNESS COCO CORNER (CORRECTION) EXCERPTS FORM BBS (DISCUSSION-TRADE UNIONS) COMMODORE C64 RESET SWITCH DIAGRAM #1 (FOR RESET SWITCH) Volume 3 No 4 HATS OFF TO PATRIOT AMATEURS ARE NEEDED MORE THAN EVER COCO CORNER (MORE POKE & PEAK) BRINGING AUTOMATION HOME COMPUTER BBS DISCUSSION ON THE WAR COMPUTERS FOR THE PEOPLE: PART I Volume 4 No 1 COMPUTERS FOR THE PEOPLE - A HISTORY PART II LETTERS TO THE EDITOR TEN COMMANDMENTS OF GOOD NETWORKING TRY THIS PROGRAM (GRAPHIC "HI") THE USSR AND THE COMPUTER COMMAND LINE CALCULATOR THE QUESTION OF CENSORSHIP PROBLEM CORNER I have a problem and I'm hoping that somebody can help. I upgraded my XT compatible by installing high density floppy drives and they work just fine, but when I put a 360K or a 720K diskette in, it will not read it unless I reboot. After using the low density diskettes I must reboot again before I can use high density diskettes. Is there something I can do to make the computer read the floppy whatever the diskette is? PUZZLED UNION FOREVER Tho' politicians come and politicians go Let Unionism go on forever. But vote for him whose records show He kept the workers' cause his first endeavor. Now has he fought for higher wages And the thirty-hour week; The dream through the ages Of the lowly and the weak. Because machines are taking powers That were our jobs of yesterday But it's the same old tedious hours With the same old lousy pay. by Floyd Hoke-Miller Letter To The Editor (Editor's Note: The following letter by a staff member of this newsletter was recently published in the Columbia Daily Spectator in N.Y.C.) To the Editor, Probably unbeknownst to many students, the rally and entering of Low Memorial Library on Tuesday, February 11, 1992, was in the tradition of a glorious victory that took place 55 years ago. On February 11, 1937, General Motors autoworkers in Flint, Michigan emerged from the factories they had occupied, victorious. As part of a long series of strikes nationwide, this forty-four day long Sit-Down Strike won GM autoworkers the right to have the United Auto Workers (UAW) represent them as their bargaining agent to GM. This was the beginning of the official recognition of the UAW by auto manufacturers. The sit-in at Columbia to achieve more of a student voice in University decision making is a poignant reminder of the similar fight that occurred 55 years ago in Flint, Michigan. Just as those workers fought the auto industry for a voice, the students of Columbia are likewise fighting to have their voice heard. By learning more of the tradition behind the battle for democratic rights, we shall be stronger. Michael Hauben Letters to Amateur Computerist Dear Editor: Along with your history of computers, there is one bit of government action your readers might find interesting. In the late '50s the U.S. government had at least three competitors in the running for a contract to design a computer utility. The phone, the electric, the gas, and the computer were all to be durable and available for Americans. The names that took part in the design competition were Dartmouth with its DTSS time-sharing system, Bell Labs with the forerunner of the now popular Unix, and MIT with Multics. Unix, you are all familiar with now. Dartmouth time-sharing, last I knew, was still a basic entry level operating system running at least at GM Tech Center on a dual big box Honeywell system. MIT won the contract with its Multics operating system. General Electric won the contract to build the iron to fit the then existing software. The GE645 computer hit the field in 1962 with absolutely no fanfare whatever. (The government's support evaporated somewhere around this time.) Multics languished around the military and institutions for the next twenty years. Honeywell entered the picture when the government refused to allow GE to buy out Honeywell's computer department. So instead they sold out to Honeywell. Honeywell Info Systems was a poor company. The de- velopment money was non-existent. With the financial crisis of the '70s many attempts were made to terminate Multics. The necessary iron to run the system was more complicated than Honeywell was willing to spend the money to speed up, so the generation of vlsi was never developed. Honeywell Info Systems was in big trouble in the '80s, the French bought the company and it is now _Bull. As to software, Multics is still the undisputed king of security, flexibility, purity of design, and ease of use (after learning). Near what appeared to me to be the end of its troubled history, Multics had earned the B2 level of security from the National Security Administration. If anyone listened to them, Multics is the only machine any government entity is allowed to use. The main problem with selling or describing Multics is that no outsider has any frame of reference to it. Ford Research Center is the largest user of Multics. Management made a determined effort to stop development and get off Multics when the product was scraped by Honeywell in 1985. To this day no replacement has been found to even approximate the most basic functionality inherent in Multics from its early days. The system is fully paged and segmented, gated, ring bracketed protected and written 99.96% in PL/1. Even most of the PL/1 compiler is written in an escalating style of PL/1. Most big box operating systems have a known errors file a foot thick. Multics had no known errors. Ford did run into an upper limit in that no single array could be larger than 1 megabyte and you could have no more than 256K segments (programs, objects) open at one time to a single process (the program in control of the job flow). Locally they moved those limits up a ways. When I left, two systems were in use by Ford world wide and were as large as the iron would allow. Six processors, 64 megabytes of memory, a sea of disk drives and every known style of communica- tions device and protocol. A system, new in 1985, had cast the ultimate computer for the world, that of, Multics hooked at 50 megabaud to a Cray XMP. Rick Strome Dearborn Multics hardware repair till 1986 Dear Sir, I have read in Hacktic that you make the magazine THE AMATEUR COMPUTERIST. I don't know the price of your magazine or what the magazine contains therefore I have a question. What is the price of your magazine and how can I be a member? I hope you would answer my questions and I would appreciate it when you send me a sample issue. I am looking forward to receiving your reply, meanwhile hearty thanks. Yours Truly R.H.SMIT THE NETHERLANDS Open Letter to Editor of Utne Reader (Editor's Note: This letter was sent to the editor of the Utne Reader. It was not published.) Dear Editor, Instead of pointing to important articles in the 'zine press in "Notes from Underground" (Nov/Dec issue), your article mischaracterizes this section of the alternative press as `unconventional' and `obscure'. For example, you write: "There are few 'zines coming from minority or working-class communities... proportionally fewer women publish 'zines than men, and when they do, they tend to be feminist or Pagan-oriented." I am one of the editors of a 'zine that comes from a working class community and this 'zine is neither `feminist' nor `Pagan-oriented'. A recently published book, Technoculture, by Andrew Ross and Constance Pawley, (University of Minnesota Press, 1991, p. 125) describes our newsletter: "When worker education classes in computer programming were discontinued by management at the Ford Rouge Plant in Dearborn, Michigan, United Auto Workers members began to publish a newsletter called the Amateur Computerist to fill the gap. Among the columnists and correspondents in the magazine have been veterans of the Flint sit-down strikes who see a clear historical continuity between the problem of labor organization in the thirties and the problem of automation and deskilling today. Workers' computer literacy is seen as essential not only to the demystification of the computer and the reskilling of workers, but also to labor's capacity to intervene in decisions about new technologies that might result in shorter hours and thus in `work efficiency' rather than worker efficiency." It would be good to have Utne Reader include worthy reprints from 'zines like the Amateur Computerist as this is a part of the alternative press which provides a rarely heard voice in American society. Sincerely, Ronda Hauben Review from the ęPERIPHERAL ISSUE 20 FEBRUARY 1992 (Editor's Note: This review of the Amateur Computerist appeared in an Australian computer newsletter. We are reprinting it because of the interesting historical coincidence it points out regarding the appearance of the first Australian kit computer distributed in a popular electronics magazine.) THE AMATEUR COMPUTERIST We received an exchange copy of Vol 4,No 1, for Fall 1991, from Ronda Hauben, P.O. Box 4344, Dearborn, Mi. 48126 USA. A twelve page double column issue, featuring how hackers gave birth to the personal computer (second part of a four part series) covering ENIAC, David Ahl and Creative Computing, the Dartmouth Basic of Kemeny and Kurtz, Ted Nelson's wonderful book Computer Lib, and Jonathan Titus' Mark 8 computer in Radio Electronics. Incidently, Jim Rowe's all TTL EDUC-8 in Electronics Australia missed out by one month in being the first kit computer circuit distributed in a popular electronics magazine, and it was the Mark 8 which appeared first. OK, other articles include ten commandments on networking (mostly Novell on PCs), a short on USSR computers, a command line calculator in Quick C which does trigs, powers and root (about 300 lines) plus letters. Ronda asked by E-mail whether anyone knows of other computer magazine editors who can be reached by E-mail? Her address is: au329@cleveland.freenet.edu ( ęPeripheral is available from Eric Lindsay, 6 Hillcrest Avenue, Faulconbridge, NSW, 2776, Australia. Electronic Mail Address: eric@zen.maths.uts.edu.au. ) Tribute to a Modern Computer Pioneer: Grace Hopper (1906-1992) A New York Times headline on January 3, 1992 read: "Rear Adm. Grace M. Hopper Dies; Innovator in Computers was 85." She had died at home New Year's Day after a recent illness. Until then, Grace Hopper had been involved with computers and computer programming since 1944. As one of the pioneers of modern computing, her life exemplifies the activities and goals that propelled computing for- ward. Hopper joined the U.S. Navy during World War II. Having a Ph.D. in mathematics, after Midshipman's school, she was assigned to the Bureau of Ships Computational Project at Harvard University. Her first day at the Project, she met Howard Aiken and his new calculating apparatus. The Mark I, as it was called, was 51 feet long, 8 feet high, 2 feet thick, weighing 4 tons. It had three quarters of a million parts, 500 miles of wiring and three million wire connectors. In order to operate this first operational program controlled computer made in America, rotary knob like switches had to be set manually. Hopper was fascinated by the challenge of such a gadget having been a tinkerer when she was a kid. One story is told of how as a girl she dismantled and reassembled all the family's alarm clocks. Aikin handed her a code book and asked her to work out the coefficients for the interpolation of the arc tangent function to be entered into the Mark I. It was a sudden but exciting introduction to her first computer. She was 37 years old at the time. Aiken helped all his colleagues deal with their new tasks by suggesting that they read portions of Charles Babbage's writings. Hopper appreciated the importance of such reading. She recalled that when she was growing up, "Each summer we had to read 20 books and write reports on them. You were educated and had some background when you were through then. It gave us an interest in reading and in history." Aiken also assigned Hopper to write the first operation manual for the Mark I which she did as well as eventually writing over 50 articles, especially on programming. The Mark I was the first computer to be sequentially programmed and Hopper was at it from its beginning. Since at the time programming essentially meant writing out strings of numbers as switch settings, codings, operating and plugging instructions, etc., errors could easily be made. Also many strings of numbers had to be repeated frequently. So the habit arose of writing out pieces of code that were already checked out in notebooks and passing the notebooks around to be copied from when needed. During the summer of 1947 there was trouble with the Mark II computer (successor to Mark I.) The trouble was traced to a mechanical relay in which a moth had been trapped and beaten to death. The body of the moth was removed with tweezers and taped into the log book as the cause of the problem. Grace Hopper is given credit for coining the term "bug" for computer problems and for the explanation to Aiken when he asked what's holding up the numbers, that she and others were "debugging" the machine. Hopper left Harvard in 1949 and joined the Eckert-Mauchly Corporation which was working on building its UNIVAC I. Programming for computers like Mark I, II, III and UNIVAC I was necessarily in full detail including at times the specification of individual bit patterns and number strings. But many programs contained identical subroutines or subprograms even though the total objective of such programs may have differed. Hopper energetically encouraged the gathering of such subroutines into permanent subroutine libraries. She also spearheaded an effort to program computers to utilize such subroutines. The idea was to create a program that could receive as input a set of high level spoken language-like commands and produce as output an integrated program made up of appropriate subroutines. In order to create such a program, Hopper had to overcome the prevailing prejudice that computers could do wonders at arithmetic but could not do analytic work like programming. She and her team at Rand Corporation succeeded at creating the A-O and other compilers that showed the cynics were too limited in their expectations of what computers would be able to do. Also in her quest to show that the new machines were more than number crunchers, Hopper sought to demonstrate their analytic capabilities. One such program she wrote was designed to take as input mathematical functions and gave as output the derivative of such functions. Upon seeing the program perform, one researcher who had spent months finding the first 15 derivatives of a complicated function, insisted that Hopper must have had some hidden person feeding the derivatives into the computer. He felt no machine could do in eighteen minutes what it had taken him 6 months to do. (from Robert Slater, Portraits in Silicon, Cambridge Mass, 1987) Hopper had succeeded in demonstrating that the computer was basically a symbol manipulator: whether the symbols were numbers, letters, words or other data structures, was a detail for the programmer, not a complication for the computer. She drove this home by writing a compiler that could receive high level code written in English, French or German. Again, someone who saw this program in operation could not believe a computer made in the U.S. could understand European languages and wondered what the trick was. Based on this work, by 1957, Hopper and her staff had created "Flow-matic," the first computer language employing words. (Ibid., p. 225) Hopper's work on "Flow-matic" was seminal and was followed by other achievements such as Commercial Translator by IBM. But Hopper and others saw a danger in the prospect of having many different languages. She was, therefore, part of the process of creating COBOL, an easy to read machine independent language not identified with any specific computer manufacturer. There were those who denounced COBOL because of its flaws and a rumor spread that it was dead. But COBOL has in fact, like BASIC, opened the door to a significantly large universe of users and it is still in use today 30 years after its introduction. Her work in support of COBOL was part of Hopper's campaign for standards for languages, archi- tectures, data structures and networks, standards set for the use of all and not by any dominant firm. From 1944 until her death New Year's Day 1992, Grace Hopper spent her life pushing the use of computers forward and also spreading that use. She especially enjoyed the opportunity to challenge young people to explore and develop the most infinite possibilities she saw inherent in computer technology. Her understanding was that we are today just "at the very beginning of the mass use of the computer. We haven't even begun to exploit its potential." (Marguerite Zientara, The History of Computing, A Biographical Portrait of the Visionaries Who Shaped the Destiny of the Computer Industry, Framingham, 1981, p. 53) Interview with Staff Member Michael Hauben on the Occasion of the 10th Anniversary of the Personal Computer Part I (Editor's Note: This interview was conducted on August 11, 1991. It has been edited.) Ronda: Tomorrow is the 10th anniversary of the introduction of the IBM personal computer on August 12, 1981. Also, one of our staff members, Michael Hauben, is leaving Michigan to go to college in N.Y. Therefore, it seemed an appropriate time to look back on the past 10 years and to review how the introduction of the personal computer has affected our lives. Michael is now 18. In 1981 he was 8 years old and already involved with computers. Michael is not only one of the beneficiaries of the computer revolution. The computer revolution was carried out, not so much by companies like IBM, but more importantly, by computer hobbyists like Michael Hauben. Thus in honor of the computer hobbyists, who gave birth to and developed the personal computer, we would like to review some of your experiences, Michael, with the computer. Bill: How did you get started with computers? Michael: The first place I really saw computers was at an exhibit in Toronto over 10 years ago. There was a robot that was like the 4 axes machine that auto workers use. They also had a computer exhibit. I don't remember what kind of computer was on display but they were just a bunch of computers running different kinds of programs set up there at the Canadian National Exhibit. That really peaked my interest somehow. When I was 8 (in 1981), I took a computer class at Schoolcraft Community College, in what was called the Kids College. It was part of what they called the TAG (Talented and Gifted) Program. The teacher's name was Mrs. Brown. We learned on the Apple II+'s. The first day of class, Mrs. Brown lifted the top of the APPLE and said, "There, that's all there is to it, There's nothing to be afraid of." That was a very good introduction to the computer because it showed there was nothing to be afraid of. That we could completely control it. I learned BASIC there. I took several other classes in that program. I think I took three. I didn't take all the BASIC language classes offered. But I took a test that they had for their normal BASIC college level classes and I wound up getting three college credits for the BASIC language class. And I didn't do so good because I ended up only getting a B on the test. But the experience was interesting and from then on whenever there was a computer available I tried to use it. After the trip to Toronto, I always wanted to buy a computer. There was the Texas Instruments 99/4a (TI 99/4a) and I don't remember how much it cost, but it was expensive. There was the Timex Sinclair 1000 (TS 1000) and that was much cheaper. My family and I had seen sinclair computers in England when we visited. These computers could be hooked up to a normal t.v. set. I saved up my money and bought a TS-1000. Using it I more thoroughly learned BASIC. My father and I programmed a lot in BASIC with only 2K memory. We never seemed to run out of memory. We just played around and tried to do lots of different things, tried writing little games, graphics and we dabbled a little in machine language, not a lot however. Whenever I had the chance, whether it was summer camp or in a computer store, I'd try to do something with the computer. I learned BASIC, I learned LOGO on the TI-99/4a in Camp, and I played around with APPLES and with Commodore PETS. In my elementary school, there was a terminal hooked in with the mainframe of the Dearborn Schools. At that time there were many programs on the mainframe. They had BASIC. They had games like the OREGON TRAIL, etc. I subscribed to two or three magazines for the TS-1000. I bought books, did all the TRY THIS type of small programs. Those were always fun because there would always be problems with the programs. There would always be bugs. The books and sample programs were exciting somehow. I haven't found many books similar for programming on the IBM Pcs today, books that I have found exciting for a hobbyist. And this is sad. Soon after I bought the TS-1000, it couldn't have been more than a couple of years, I was trying to choose between the TS-2068 and the Commodore 64. I think the Commodore was more expensive. The TS-2068 had better color, and a more developed version of BASIC. The Commodore 64 was better in that it had a disk drive and the TS-1000 only had a tape drive you could use. The Commodore also had a real keyboard, while the Timex utilized raised chicklets. I bought the TS-2068. Then I had my first real lesson in the computer world. Three months after I bought the TS-2068, Timex stopped selling it and supporting it. Timex made a deal with Commodore. There was an agreement to sell the Sinclair in England and Europe and Commodore in the United States. That was a shock because I thought I made a better choice, but it turned out the better deal is not always the best choice. And my father and I did programming on that, but not really as much as we did on the TS-1000. It was a lot less, even though there was the added attraction of the color and the sound and the joystick port. And so I still did things and I tried to pick up on things whenever I could. Christmas of 1984, we bought a Sanyo MBC-550-2 which was a MS- Dos compatible, but not an IBM compatible, machine. The operating system was IBM compatible, but the graphics were different, the sound was different, and the BASIC was different. The Sanyo was a better machine for graphics, I think 640 x 400 with 4 colors if not 16. And Wordstar worked. That's why my family got it -- as a wordprocessor. I learned MS-Dos. I got more into the PC world. We subscribed to a Sanyo magazine for a while. We went to the Sanyo Users' groups for a while. We occasionally went to SEMCO (Southeast Michigan Computer Organization), but somehow that was already oriented toward business and they weren't very interested in helping us. Then in 1985, through INACOMP, my mother won a Compaq Portable. It was one of the earliest to come out that was fully IBM compatible. It was a luggable portable, and it weighed about 20 pounds, if not more. And that's how I really got into IBM. We had a choice between a modem and a hard drive. We got a modem. It was a breakthrough. The hard drive seemed important but the modem was more important. We wound up getting a hard drive later on. With the modem, it lets you connect to the outside world. With your own little system you'd be like a hermit, but in connecting with the rest of the world, it's other people's opinions, different discus- sions about computers, about current events, debates about what's going on in the world and just general BS also. And you came into contact with people, you came into contact with different files to use with your computer, with what was going on with the computer scene and so somehow it was like a replacement for a user group. And depending upon the time, there was either a lot going on or a little going on. Ronda: What do you mean? Michael: Well right now not many boards I know have much debate on them. There are two that I am on. Both of them have debates on- going. I'm sure there are others, but I just haven't had time to look. But for a while I was on many of the boards and at one point many of the boards were silly contests to see who could post the most numerous messages. Ronda: Do you have a sense what you were looking for on the BBS's? You used to spend a lot of time on them. Michael: Well at first I wasn't on local BBS's. Originally, I was on COMPUSERVE. Bill: Free time? M: Well, the first two hours were free. I almost became a Beta Tester for Infocom through Compuserve. I sent in the application forms. I then received a congratulations letter, but Infocom never sent me any games to test. The only response was a Christmas card. That was a soured Compuserve memory. I found some local BBS numbers listed on Compuserve and from my father and some friends of his from work. For a while I was mostly on Commodore BBS's and not many IBM boards. But then I started calling the IBM boards. It was new for me when I started. Modeming was a connection to the outside world to other people with similar interests. It was interesting -- the debates about current events. Somehow there was the possibility for intellectual discussion which I couldn't find elsewhere besides my parents and a few friends like Floyd Hoke-Miller. But among my friends at school or neighbors, there wasn't much of a possibility. When we lived in East Dearborn, our next door neighbor, Tom, had an Atari and a Commodore 64. He shared an interest in computers with me. He was my friend, even though there was a large age gap, because we were both interested in computers. He let me come over and try some things on his computer and I'd go with him to computer stores. Bill: Another thing about modems you can't tell the age. Treats you more like an equal. Michael: There's an anonymity. You don't know anything about the other users. So you are more willing to accept them. There are still first impressions. If you act like a real idiot, people won't like you. But the full element of first impressions is left out. And people tend to rank you or be friends with you on how you act on-line, what you speak about. It does help. You tend to get to know the people and there isn't as much blocking. And my first handle was Wizkid. I changed my handle 2 or 3 years ago to Sentinel. And there was one person who signed on and said it was great knowing you. He was one of the people who knew me as Wizkid. There was a "Remembering the OLD Days" theme area on one of the BBS's and someone said, "remember that Wizkid." And I said, "that was me." And he said he didn't know that. When people change their handles, it's public but somehow people don't always realize it. When I changed my handle, I decreased my activity. When I decreased my activity it was because there were just silly messages that didn't mean anything, or they just seemed juvenile, and I don't know if that's because the people calling were younger or they were more juvenile. The way people accept you is based on your maturity on-line and your maturity showed through more than your age. And there was one debate where someone said you are just a kid. And I used to have the handle Wizkid. But it didn't matter what your age was, it was more how mature you were. He was trying to say "Well you're just a kid, you can't know anything." But he was wrong. So there is less age discrimination on the boards. Ronda: Why did you decrease the time you spent on the boards? Michael: I had to spend more time with school, with friends, with my job. Whenever I used to come home from school, I used to spend 2 or 3 hours, but then my mom said, "We need the phone." So I didn't spend my free time before homework on the modem. And then with work, I wasn't even home on certain days to use the modem. Ronda: But it seemed you were also a little disappointed. There were user parties, but it seemed the computer world didn't extend outside of the modem. Michael: It did to a certain extent, but it didn't include everyone. Like some people were friends before. There were modem parties where people from the boards got together, whether it was a software swap or a party. Ronda: There weren't many, were there? Michael: Well, what happened was the main person who had the parties was from a TAG board in Taylor. He had his computer stolen after the 2nd or 3rd party. So he stopped holding them. Then there were multi-user boards. There was MNET which was a multi-user. The general ages of the users on M-Net was older than on the other single-user BBS's. And it was more serious. It was more a UNIX board. It was a different bunch. It was not the home but the people in school, in Ann Arbor. It seemed like the multi-user boards made it easier to hold parties because users could chat live one-on-one. And when AMUSERS (a multi-user board) closed down, I didn't get on other multi-users that were like AMUSERS. Some people already were friends but you didn't end up doing much so it was a little disappointing. Cause it didn't seem like there was any -- it didn't get anywhere -- it was just on-line so that was a little disconcerting. It was disappointing because that was where I had found more intellectual people but it didn't go anywhere. And things like COMPUSERVE cost a lot of money. There's COMPUSERVE, there's Delphi, there's Geni, there's PC Link, there's Q-link, there's a couple of services but they all cost money, so that's hard to deal with. And then there are bigger boards that exist. But they all cost money. There's the WELL. That's in California. You also pay per hour like Compuserve. So it's harder to be on. It's like M-Net. It's the same software as M-Net. And maybe I did find it disappointing. It used to be there would be lots of new BBS's popping up. But they were interesting. And now there still are lots of new BBS's popping up. But they're silly. So it's gone downhill a little bit. And also BBS's are similar to the CB or the Ham radio in that people voice their opinions, or have discussions or chat or there used to be DDial's -- all they were were multi-user, people chatting, but they were 300 baud so they were super slow. Some of those you had to acquire membership. But they were linked up across the country. There were things called LINKS that would connect you to other DDials around the country. So that way you could talk to people. Somehow the thing about BBS's was it was the ultimate vehicle of Free Speech, uncensored speech. For the most part things were not censored. What you posted was left alone. It was like everyone's Letter to the Editor was allowed to be printed. There would be letters debating other previous letters. Different sysops had different rules and some would delete messages that contained pro- fanity or were only personal attacks or something. BBS's are the greatest form of free speech. The problem was you needed a modem and a computer to get into it. So it's not as free as it might be, but compared to the newspapers, the newspapers print what they choose, whereas on BBS's everything is printed, everything is pub- lished. It's more of a dynamic medium than a static medium because depending on the board there's different forms of dealing with messages. For example, some boards after the first 50 messages go by, the first message is deleted, so it's a dynamic thing. Unless somebody prints out a copy or saves it to disk, it doesn't stay static. Like on M-Net, things aren't deleted. They are deleted when the message sysop of the area decides no one is interested anymore. That's more of a choice method of deletion, than where it deletes messages or the new one pops in, the old one pops out and it's deleted. And even depending on what happens, it's still an impor- tant medium. There was, for example, just a debate about the war against IRAQ on BBS's. Usually you didn't see where there was dissent. Whereas on the computer, if people wanted to, they could debate it and there was debate about it. A free medium. It's open access. Not closed. It's also a field where the hobbyist still exists. There are people who develop ways of using the modem, whether it's dif- ferent compression techniques where you can send more and larger files quicker, or whether it's different file protocols that send them faster over phone lines. Those are constantly developing. That is a hobbyist frontier now. Maybe there are less people than when the computer started out. But it still exists. It's a frontier that's not closed up yet. It's not definite yet. New things are continuing to come out. For example, higher speed chips for the serial ports in the computer so that the computer can talk to the modem at a higher speed and everything. To be continued in next issue One Line Program In BASIC 10 FOR I=38 TO 255:PRINT"CHR$(";I;") = ";CHR$(I);" ";:NEXT (Editor's Note: We welcome other one line programs from readers.) Computers For The People A History Part III And it was indeed. "In January, 1975, six months after the introduction of [Titus' computer-ed] the Mark-8, Popular Electron- ics published the first installment of a two-part article on a much more sophisticated computer, the Altair 8800," writes Stan Augarten (in Bit by Bit, NY, 1984). "The Altair was the first... full fledged personal computer on the market." And it was available in kit form for $395,or in assembled form for $650. "Thousands of orders poured into MITS", the manufacturer of the Altair, after the article was published. The article was featured on the front cover of the magazine: "Project Breakthrough: World's First Minicomputer Kit to Rival Commercial Models Altair 8800. Save over $1000." ( p 270-273) The firm was overwhelmed with orders. Auguarten explains, "If you wanted to get the Altair to do something...you had to write a program in machine code and enter it, bit by bit, via the toggle switches on the front panel." It only had a 256-byte memory, too small to do much with. "As a result," writes Augarten, "all you could really do with the Altair was play with it, and one of its first programs was a game that generated increasingly complicated patterns of lights on the front panel to be duplicated by the players." (p 274) What the Altair needed was an interpreter -- a program that would allow the machine's users to write programs in a simple computer language like BASIC. Paul Allen, was a programmer working in the Boston area. He had been a computer hacker during his teen years. He was strolling through Harvard Square one day when he noticed the January, 1975 issue of Popular Electronics on the newsstand. He bought the magazine and went to visit his friend and fellow hacker, William Gates, who was a freshman at Harvard. Allen is reported to have greeted Gates waving the article in front of Gates' face and saying "Look, it's going to happen! I told you this was going to happen! And we're going to miss it.!" ( Paul Freiberger and Michael Swaine, Fire in the Valley, Berkeley, 1984, p 141) Freiberger and Swaine, describe what followed: "Gates had to admit that his friend was right; it sure looked as though the `something' they had been looking for had found them. He immediately phoned MITS [producer of the Altair-ed ], and claimed that he and his partner had a BASIC language usable on the Altair. When Ed Roberts [owner of MITS - ed] who had heard a lot of such promises asked Gates when he could come to Albuquerque to demon- strate it, Gates looked at his childhood friend, took a deep breath, and said, `Oh, in two or three weeks.' Gates put down the receiver, turned to Allen and said: `I guess we should go buy a manual.' They went straight to an electronics shop and purchased Adam Osborne's manual on the 8080." (Ibid., p. 141) Allen and Gates had committed themselves to producing a BASIC language for a machine they had not yet even seen. But they were both computer hackers from their junior high school days when they had worked for companies looking for bugs in commercial programs. Freiberger and Swine describe what happened next: "For the next few weeks, Gates and Allen worked day and night on the BASIC. As they wrote the program, they tried to determine the minimal features of an acceptable BASIC.... There was no established industry standard for BASIC or for any other software. There was no industry. By deciding themselves what BASIC required, Gates and Allen set a pattern for future software development that lasted for about six years. Instead of researching the market, the programmers simply decided, at the outset, what to put in." (p 141 - 142) Freiberger and Swaine continue their description of those significant days: "Both men threw themselves completely into the project, staying up late every night programming.... They were programming half-asleep sometimes. Once when Gates nodded off, head on the keys, he woke up suddenly, glanced at the screen, and immediately began typing. Paul Allen decided Bill must have been programming in his sleep and kept right on when he awoke." (p. 142) Six weeks later, Allen flew to Albuquerque with their BASIC interpreter. On the plane, he realized they hadn't written a program to load the language into the computer. He quickly made up a program on some scrap paper. Roberts met him at the airport and drove him to his workplace. He loaded the program into the Altair and it worked. Allen became MITS's software director. Gates soon dropped out of Harvard and became a freelance software writer. Gates and Allen later set up the Microsoft Corporation in Bellevue, Washington, now one of the largest software companies in the world. "The Altair inspired many hobbyists to design their own computers," writes Augarten, p 276. One of these was Stephen Wozniak. The ferment from the introduction of the Altair had led to the formation of computer clubs all over the country, including one in California's Silicon Valley. The atmosphere generated by the clubs inspired hobbyists and hackers like Stephen Wozniak and Steve Jobs to create and then market computers like the Apple. Woz, as Steve Wozniak is known, explains how the Apple was created. He bought an 8-bit microprocessor, the 6502 from MOS technology (now part of Commodore), and he wrote a BASIC interpreter for it. The device wasn't as powerful as the Altair, but it was cheaper and less complicated. Then he built a circuit board and he and Steve Jobs set out to market it as the Apple Computer. Later in 1977 they introduced the Apple II with 16K of Ram for $1,195. Woz who loved to play games had designed the computer with that purpose in mind. The Apple II provided a commercial personal computer that people and schools could begin to afford. But crucial to the development of the Apple computer and to all the other advances made during this fruitful period in the development of the personal computer was the role played by the Homebrew Computer Club. Woz went to the first meeting, in March, 1975. About 30 people showed up. But fueled by the excitement generated by the Altair, the club expanded rapidly. Soon the Club had 500 members. Meetings divided into a "random-access" period during which the floor was thrown open to anyone who had anything to say, and a "mapping" period when the audience broke up into small groups devoted to common concerns. Lee Felsenstein is the person credited with making the club the important gathering it became. Felsenstein had been active in the Free Speech Movement at the University of California at Berkeley. He had been arrested in 1964 along with 755 other students for sitting in at the University. He had worked on the Berkeley Barb and the Berkeley Tribe, two newspapers of the student anti-war movement of the 1960's. Lee Felsenstein, like Ted Nelson whose book Computer Lib became known as the Common Sense (a la Tom Paine) of the Technological Revolution, was one of a group of technological revolutionaries who were products of the radical 1960s. "A surprising number of them," write the authors of Fire in the Valley, "held political views that would have shocked the local Rotary Club and almost all had no love for IBM and the computer establishment." (Frieberger and Swaine, p108) Keith Britton, another early member of the Homebrew Club, recalls the atmosphere prevalent during the early days of the personal computer movement. "There was a strong feeling, " he writes, "that we were subversives. We were subverting the way the giant corporations had run things. We were upsetting the estab- lishment forcing our mores into the industry. I was amazed that we could continue to meet without people arriving with bayonets to arrest the lot of us." (Ibid. p 104) Britton saw himself and the other members of the Homebrew Club as "pivotal in an equivalent of the industrial revolution but more profoundly important to the human race."(Ibid.,p 108) To be continued Pascal Program Bridge_opening_bid_simulator Uses Printer (******************************************) (* Author : Ian Carsten *) (* *) (* Last Modified : 11-18-90 *) (* *) (* Input: menu choices 1-8 (integer), *) (* number or letter of card (char) and *) (* first letter of suit (char) *) (* *) (* Output: menu of options, 13-card hand, *) (* total points of hand, and opening bid *) (* based on points and distribution of *) (* cards in hand *) (* *) (* Purpose: To simulate the opening bid in*) (* the card game of bridge as an aid in *) (* learning the strategy of assigning *) (* points and giving the opening bid *) (* *) (* Features: In the change card option, if*) (* the user tries to remove a card which *) (* is not in the hand or tries to add a *) (* card which is already in the hand, then*) (* an appropriate error message is printed*) (* and the particular add or delete rou- *) (* tine is repeated until a valid card *) (* change is input. Further, at start-up, *) (* since the handarray is empty, if the *) (* user selects menu options 2,4,5,6, or 7*) (* an empty hand message is printed and *) (* the menu is presented to prevent mean- *) (* ingless execution and/or output. *) (* Although this program prevents copying *) (* an empty hand (52 ' 0 '--string3) to a *) (* file, nonetheless, an empty hand has *) (* been stored under 'hand0.dat' to demon-*) (* strate what would happen if an empty *) (* were stored using DOS commands and some*) (* one then tried to read the empty hand *) (* into the handarray. In bidding the case*) (* 13 <= points <= 18 and at least 5 cards*) (* in 1 or two suits, the bid is: 1 of the*) (* 5-card suit with the greatest number of*) (* points. If each of 2 5-card suits have *) (* the same number of points, then the bid*) (* is 1 of the first 5-card suit in the *) (* order Spade, Heart, Diamond, Club. *) (* Since Givopeningbid calls Showpointsof-*) (* hand, the bid can be used without first*) (* getting the points *) (******************************************) {Declaration of global variables} type string3 = string[3]; stringarray = array[1..4, 1..13] of string3; var choice : integer; {user's choice from menu} emptyhand : boolean; {emptyhand = true prevents meaningless output} card : string3; {representation of card in handarray} handarray : stringarray; {4 x 13 array representation of card hand} points : integer; {points of hand, used to determine bid} cardsinsuit : array [1..4] of integer; {number of cards in suit} pointsinsuit : array [1..4] of integer; {number of points in suit} (******************************************) (* Name : Initializearray *) (* *) (* Purpose : Initialize all elements of *) (* handarray to the placeholder ' 0 ' *) (* (string3) *) (* *) (* Preconditions : none *) (* *) (* Postconditions : all 52 elements of *) (* handarray are ' 0 ' (string3) *) (******************************************) procedure Initializearray(var handarray{input/output} : stringarray); var row : integer; col : integer; begin {Initializearray} for row := 1 to 4 do {set each element of handarray to 0 (string3)} begin {row-loop} for col := 1 to 13 do begin {col-loop} handarray[row, col] := ' 0 '; end; {col-loop} end; {row-loop} end; {Initializearray} (******************************************) (* Name : Testforemptyhand *) (* *) (* Purpose : Determines if hand- *) (* array is empty *) (* *) (* Preconditions : handarray is either *) (* empty (all elements are ' 0 ' ) or it *) (* contains 13 cards and 39 placeholding *) (* ' 0 ' *) (* *) (* Postconditions : emptyhand (boolean) is*) (* true if hand empty otherwise emptyhand *) (* is false *) (******************************************) procedure Testforemptyhand(hand- array{input} : stringarray; var emptyhand{output} :boolean); var row : integer; col : integer; begin emptyhand := true; {initial- ize} for row := 1 to 4 do begin {row-loop} for col := 1 to 13 do begin {col-loop} if handarray[row, col] <> ' 0 ' then emptyhand := false end; {col-loop} end; {row-loop} end; {Testforemptyhand} (******************************************) (* Name : Readcardandsuit *) (* *) (* Purpose : reads the two characters of *) (* user-input card and suit which user *) (* wishes to delete/add *) (* *) (* Preconditions : user has input card (1 *) (* or, in the case of a '10', 2 characters*) (* ), a space, and the first letter of the*) (* suit, each of type char *) (* *) (* Postconditions : charcard and *) (* charsuit have been assigned the *) (* upper case of user-input card *) (* and suit respectively *) (******************************************) procedure Readcardandsuit(var charcard{input/output} : char; var charsuit{input/output} : char); var space : char; charzero : char; begin read(charcard); if charcard <> '1' then readln(space, charsuit); if charcard = '1' then {user- input card is a '10'} readln(charzero, space, charsuit); charcard := upcase(charcard); charsuit := upcase(charsuit); end; (******************************************) (* Name : Displayhand *) (* *) (* Purpose : To print the hand cur- *) (* rently stored in handarray, with *) (* rows right-justified, lowest *) (* card to highest from left to *) (* right (reverse order of array), *) (* row 1 = Spades, row 2 = Hearts, *) (* row 3 = Diamonds, and row 4 = *) (* Clubs *) (* *) (* Preconditions : handarray has a *) (* nonempty hand of 13 unique cards *) (* and 39 placeholders (' 0 ') each *) (* of type string3 *) (* *) (* Postconditions : the hand has *) (* been printed *) (******************************************) procedure Displayhand(handarray {input} : stringarray); type string10 = string[10]; var row : integer; col : integer; suit : string10; begin {Displayhand} Testforemptyhand(handarray {input}, emptyhand{output}); if (not emptyhand) then begin {execute Displayhand-- nonempty hand} for row := 1 to 4 do begin {row-loop} case row of {assign suit based on its row number} 1 : suit := 'Spades '; 2 : suit := 'Hearts '; 3 : suit := 'Diamonds '; 4 : suit := 'Clubs '; end; {case} write(suit); write(Lst, suit); for col := 13 downto 1 do begin if handarray[row, col] <> ' 0 ' then begin {if} write(handarray [row, col]); write(Lst, hand array[row, col]); end; {if} end; {col-loop} writeln; writeln(Lst); end; {row-loop} writeln; writeln(Lst); end {execute Displayhand--non- empty hand} else begin {else} writeln('Current hand is empty. Choose 1) or 3) from menu to '); writeln('get a nonempty hand.'); writeln; writeln(Lst, 'Current hand is empty. Choose 1) or 3) from menu to '); writeln(Lst, 'get a non- empty hand.'); writeln(Lst); end; {else} end; {Displayhand} (******************************************) (* Name : Convertcard *) (* *) (* Purpose : Converts card and suit (char)*) (* input by user into their string equi- *) (* valents. Also, it assigns the row and *) (* col (integer) of the card (string3) in *) (* handarray *) (* *) (* Preconditions : charcard and charsuit *) (* have been assigned values (char) *) (* *) (* Postconditions : row, col (integer), *) (* and card (string3) have been assigned *) (* values *) (******************************************) procedure Convertcard( charcard {input} : char; charsuit{input} : char; var row{output} : integer; var col{output} : integer; var card{output} : string3); begin {Convertcard} if upcase(charsuit) = 'S' then {assign row number based on suit input } row := 1; {by user} if upcase(charsuit) = 'H' then row := 2; if upcase(charsuit) = 'D' then row := 3; if upcase(charsuit) = 'C' then row := 4; if charcard = 'A' then {assign col number and card based on charcard} begin {input by user} card := ' A '; col := 1; end; if charcard ='K' then begin card := ' K '; col := 2; end; if charcard = 'Q'then begin card := ' Q '; col := 3; end; if charcard = 'J' then begin card := ' J '; col := 4; end; if charcard = '1' then begin card := '10 '; col := 5; end; if charcard = '9' then begin card := ' 9 '; col := 6; end; if charcard = '8' then begin card := ' 8 '; col := 7; end; if charcard = '7' then begin card := ' 7 '; col := 8; end; if charcard = '6' then begin card := ' 6 '; col := 9; end; if charcard = '5' then begin card := ' 5 '; col := 10; end; if charcard = '4' then begin card := ' 4 '; col := 11; end; if charcard = '3' then begin card := ' 3 '; col := 12; end; if charcard = '2' then begin card := ' 2 '; col := 13; end; end; {Convertcard} (******************************************) (* Name : Translate *) (* *) (* Purpose : Translates cardnum (integer) *) (* into its equivalent card (string3) and *) (* assigns row (integer) and col (integer)*) (* which determines its appropriate *) (* location in handarray *) (* *) (* Preconditions : cardnum has been *) (* assigned an integer value from 1-52 *) (* *) (* Postconditions : row has been assigned *) (* an integer value from 1-4 and col has *) (* been assigned an integer value from 1- *) (* 13 and card (string3) has been assigned*) (* a value *) (******************************************) procedure Translate(cardnum : integer; var row : integer; var col : integer); begin {Translate} case cardnum of {assign row based on cardnum} 1..13 : row := 1; 14..26 : row := 2; 27..39 : row := 3; 40..52 : row := 4; end; {case-assign row} case cardnum of {assign col and card based on cardnum} 1,14,27,40 : begin col := 1; card := ' A ' end; 2,15,28,41 : begin col := 2; card := ' K ' end; 3,16,29,42 : begin col := 3; card := ' Q ' end; 4,17,30,43 : begin col := 4; card := ' J ' end; 5,18,31,44 : begin col := 5; card := '10 ' end; 6,19,32,45 : begin col := 6; card := ' 9 ' end; 7,20,33,46 : begin col := 7; card := ' 8 ' end; 8,21,34,47 : begin col := 8; card := ' 7 ' end; 9,22,35,48 : begin col := 9; card := ' 6 ' end; 10,23,36,49 : begin col := 10; card := ' 5 ' end; 11,24,37,50 : begin col := 11; card := ' 4 ' end; 12,25,38,51 : begin col := 12; card := ' 3 ' end; 13,26,39,52 : begin col := 13; card := ' 2 ' end; end; {case-assign col and card} end; {Translate} (******************************************) (* Name : Showmenu *) (* *) (* Purpose : To print a menu of options *) (* and prompt the user for his choice *) (* *) (* Preconditions : none *) (* *) (* Postconditions : menu and prompt *) (* have been printed *) (******************************************) procedure Showmenu; begin {Showmenu} writeln('1) Generate a random hand'); writeln('2) Save the current hand (to a text file)'); writeln('3) Read a hand (from a text file)'); writeln('4) Change a card in the current hand'); writeln('5) Display the current hand'); writeln('6) Show total points of the hand'); writeln('7) Give the opening bid with the current hand'); writeln('8) Quit'); writeln; write('Enter your choice '); writeln(Lst,'1) Generate a random hand'); writeln(Lst,'2) Save the cur- rent hand (to a text file)'); writeln(Lst,'3) Read a hand (from a text file)'); writeln(Lst,'4) Change a card in the current hand'); writeln(Lst,'5) Display the current hand'); writeln(Lst,'6) Show total points of the hand'); writeln(Lst,'7) Give the open- ing bid with the current hand'); writeln(Lst,'8) Quit'); writeln(Lst); write(Lst,'Enter your choice '); end; {Showmenu} (******************************************) (* Name : Generatehand *) (* *) (* Purpose : To generate 13 unique random *) (* integers from 1 to 52, translate them *) (* into string3 representing a hand of *) (* cards in the game of bridge and store *) (* the strings in in a 4 x 13 array *) (* representing the card hand according to*) (* the following scheme: *) (* top to bottom: row 1 = Spades, row 2 = *) (* Hearts, row 3 = Diamonds, row 4 = Clubs*) (* left to right: col 1 = ' A ', col 2 = *) (* ' K ',..., col 13 = ' 2 '. Also, all *) (* positions not holding card will have *) (* the string ' 0 ' (string3) as a *) (* placeholder *) (* *) (* Preconditions : handarray either holds *) (* 52 ' 0 ' placeholders or it holds 13 *) (* cards and 39 ' 0 ' placeholders, each *) (* of type string3 *) (* *) (* Postconditions : handarray has 13 *) (* unique cards(string3) and 39 ' 0 ' *) (* placeholders, each of type string3 *) (******************************************) procedure Generatehand(var hand- array : stringarray); type string10 = string[10]; var colindex : integer; cardsinhand : integer; {number of cards in hand} inhand : boolean; {true if card being checked is already in hand} cardnum : integer; {random number of card} row : integer; col : integer; suit : string10; begin {Generatehand} Initializearray(handarray); {to ' 0 '} cardsinhand := 0; {initialize number of cards in hand} while cardsinhand < 13 do begin {while} inhand := false; {reset to test next cardnum} cardnum := random(52) + 1; Translate(cardnum, row, col); {determines row, col} for colindex := 1 to 13 do begin {colindex-loop} if handarray[row, col- index] = card then inhand := true; end; {colindex-loop} if (not inhand) then begin {if-then} handarray[row,col] := card; {add card to handarray} cardsinhand := cards inhand + 1; end; {if-then} end; {while} end; {Generatehand} (******************************************) (* Name : Savehandtofile *) (* *) (* Purpose : saves cardhand to filename *) (* which user specifies just prior to save*) (* *) (* Preconditions : card hand exists and *) (* may be empty or nonempty *) (* *) (* Postconditions : nonempty card hand in *) (* handarray has been saved to user-input *) (* filename *) (******************************************) procedure Savehandtofile(handarray : stringarray); type string20 = string[20]; var row : integer; col : integer; outfile : text; cardfile : string20; begin {Savehandtofile} Testforemptyhand(handarray {input}, emptyhand{output}); if (not emptyhand) then begin {execute Savehandtofile- -nonempty hand} write('What is the name of the card file? '); write(Lst, 'What is the name of the card file? '); readln(cardfile); writeln(Lst, ' ', cardfile); assign(outfile, cardfile); rewrite(outfile); for row := 1 to 4 do begin for col := 1 to 13 do begin {col-loop} write(outfile, hand- array[row, col]); end; {col-loop} writeln(outfile); end; {row-loop} close(outfile); end {execute Savehandtofile-- nonempty hand} else begin writeln('Current hand is empty. Choose 1) or 3) from menu to '); writeln('get a nonempty hand.'); writeln; writeln(Lst, 'Current hand is empty. Choose 1) or 3) from menu to '); writeln(Lst, 'get a nonempty hand.'); writeln(Lst); end; end; {Savehandtofile} (******************************************) (* Name : Readhandfromfile *) (* *) (* Purpose : reads hand from user-input *) (* filename to handarray *) (* *) (* Preconditions : user-input filename *) (* exists and holds a card hand *) (* *) (* Postconditions : cardhand in filename *) (* has been copied to handarray *) (******************************************) procedure Readhandfromfile(var handarray : stringarray); type string20 = string[20]; var row : integer; col : integer; outfile : text; cardfile : string20; begin {Readhandfromfile} write('What is the name of the file? '); write(Lst, 'What is the name of the file? '); readln(cardfile); write(Lst, ' ', cardfile); assign(outfile, cardfile); reset(outfile); for row := 1 to 4 do begin {row-loop} for col := 1 to 13 do begin {col-loop} read(outfile, hand- array[row, col]); end; {col-loop} readln(outfile); end; {row-loop} writeln(Lst); close(outfile); Testforemptyhand(handarray {input}, emptyhand{output}); if (emptyhand) then begin {if-emptyhand} writeln('File ',cardfile, ' is empty. Choose 1) or 3) (with'); writeln('a nonempty file) from menu to get a non- empty hand.'); writeln; writeln(Lst, 'File ', cardfile, ' is empty. Choose 1) or 3) (with'); writeln(Lst, 'a nonempty file) from menu to get a nonempty hand.'); writeln(Lst); end; {if-emptyhand} end; {Readhandfromfile} (******************************************) (* Name : Changecard *) (* *) (* Purpose : first deletes a userspeci- *) (* fied card from handarray, then adds one*) (* to the array *) (* *) (* Preconditions : handarray exists and *) (* may be empty or nonempty (but Change- *) (* card will not execute if handarray *) (* empty) *) (* *) (* Postconditions : handarray has a *) (* unique nonempty hand (if Change- *) (* card executed) *) (******************************************) procedure Changecard(var handarray : stringarray); type string8 = string[8]; var charcard : char; space : char; charzero : char; charsuit : char; row : integer; col : integer; inhand : boolean; suit : string8; begin {Changecard} Testforemptyhand(handarray {input}, emptyhand{output}); if (not emptyhand) then begin {execute Changecard-- nonempty hand} {delete chosen card provided it is in hand} inhand := false; while (not inhand) do begin {while-not inhand} inhand := false; write('What card do you want to remove(card- suit) ? '); write(Lst, 'What card do you want to remove(card- suit) ? '); Readcardandsuit(charcard, charsuit); Convertcard(charcard, charsuit, row, col, card); case row of 1 : suit := 'Spades'; 2 : suit := 'Hearts'; 3 : suit := 'Diamonds'; 4 : suit := 'Clubs'; end; {case} writeln(Lst, card, ' ', charsuit); if (handarray[row, col] = card) then inhand := true; if (inhand) then begin {if-inhand} handarray[row, col] := ' 0 '; {delete card from hand} end {if-inhand} else begin {else} writeln(card, 'of ', suit, ' is not in hand'); writeln(Lst, card, 'of ', suit, ' is not in hand'); end; {else} end; {while-not inhand} {add chosen card if not already in hand} inhand := true; while inhand do begin {while-inhand} inhand := true; write('What card do you want to add(cardsuit) ? '); write(Lst, 'What card do you want to add(cardsuit) ? '); Readcardandsuit(charcard, charsuit); Convertcard(charcard, char- suit, row, col, card); case row of 1 : suit := 'Spades'; 2 : suit := 'Hearts'; 3 : suit := 'Diamonds'; 4 : suit := 'Clubs'; end; {case} writeln(Lst, card, ' ', char- suit); if (handarray[row, col] <> card) then inhand := false; if (not inhand) then begin {if} handarray[row, col] := card; {add card to hand} end {if} else begin {else} writeln(card, 'of ', suit, ' is already in hand'); writeln(Lst, card, 'of ', suit, ' is already in hand'); end; {else} end; {while-inhand} end {execute Changecard--non- empty hand} else begin {else} writeln('Current hand is empty. Choose 1) or 3) from menu to '); writeln('get a nonempty hand.'); writeln; writeln(Lst, 'Current hand is empty. Choose 1) or 3) from menu to '); writeln(Lst, 'get a nonempty hand.'); writeln(Lst); end; {else} end; {Changecard} (******************************************) (* Name : Showpointsofhand *) (* *) (* Purpose : calculates and prints the *) (* points of the hand *) (* *) (* Preconditions : handarray has a unique *) (* nonempty hand of card (this procedure *) (* will not execute with an empty hand) *) (* *) (* Postconditions : points (integer) have *) (* been assigned *) (******************************************) procedure Showpointsofhand(handarray {input} : stringarray; var points- {output} : integer ); var row : integer; col : integer; prevpoints : integer; begin {Showpointsofhand} Testforemptyhand(handarray- {input}, emptyhand{output}); if (not emptyhand) then begin {execute Showpoints- ofhand--nonempty hand} points := 0; prevpoints := 0; for row := 1 to 4 do begin {row-loop} cardsinsuit[row] := 0; for col := 1 to 13 do begin {col-loop} if handarray[row, col] = ' A ' then points := points + 4; if handarray[row, col] = ' K ' then points := points + 3; if handarray[row, col] = ' Q ' then points := points + 2; if handarray[row, col] = ' J ' then points := points +1; if handarray[row, col] <> ' 0 ' then cardsinsuit[row] := cardsinsuit- [row] + 1; end; {col-loop} case cardsinsuit[row] of 0 : points := points + 2; 1 : points := points + 1; end; {case} pointsinsuit[row] := points - prevpoints; prevpoints := points; end; {row-loop} if choice <> 7 then {choice = 7, points passed to Giveopeningbid} begin {if-choice <> 7} if points = 1 then begin {if-points = 1} writeln(points, ' point'); writeln(Lst, points, ' point'); end {if-points = 1} else begin {else} writeln(points, ' points'); writeln(Lst, points, ' points'); end; {else} end; {if--choice <> 7} end {execute Showpointsof- hand--nonempty hand} else begin {else} writeln('Current hand is empty. Choose 1) or 3) from menu to '); writeln('get a nonempty hand.'); writeln; writeln(Lst, 'Current hand is empty. Choose 1) or 3) from menu to '); writeln(Lst, 'get a nonempty hand.'); writeln(Lst); end; {else} end; {Showpointsofhand} (******************************************) (* Name : Giveopeningbid *) (* *) (* Purpose : computes and prints the *) (* opening bid *) (* *) (* Preconditions : handarray has a unique *) (* nonempty hand (will not execute with an*) (* empty hand *) (* *) (* Postconditions : opening bid has *) (* been computed and printed *) (******************************************) procedure Giveopeningbid(var points : integer); type string10 = string[10]; var bid : string10; suit : string10; row : integer; col : integer; rowindex : integer; cardsinrow : integer; mostcardsinsuit : integer; max : integer; begin {Giveopeningbid} Testforemptyhand(handarray- {input}, emptyhand{output}); if (not emptyhand) then begin {execute Giveopening- bid--nonempty hand} Showpointsofhand(hand- array{input}, points- {output}); mostcardsinsuit := 0; cardsinrow := 0; for row := 1 to 4 do begin {row-loop} for col := 1 to 13 do begin {col-loop} if handarray[row, col] <> ' 0 ' then cardsinrow := cardsinrow + 1 end; {col-loop} if cardsinrow > most- cardsinsuit then begin mostcardsinsuit := cardsinrow; rowindex := row end; {if} cardsinrow := 0 end; {row-loop} {case: causes bid to be 1 of which- } {ever 5-card suit has highest number} {of points. If 2 5-card suits have } {same number of points, then suit of} {lowest number rowindex will be bid } case rowindex of 1 : suit := 'Spade'; 2 : suit := 'Heart'; 3 : suit := 'Diamond'; 4 : suit := 'Club'; end; {case} if points < 13 then begin {bid-case 1} writeln('pass'); writeln(Lst, 'pass'); end; {bid-case 1} if (13 <= points) and (points <= 18) and (most- cardsinsuit >= 5) then begin {bid-case 2} max := 0; for row := 1 to 4 do begin {row-loop} if (cardsinsuit[row] >= 5) then begin {if} if pointsinsuit[row] > max then begin {if} max := pointsin- suit[row]; rowindex := row; end; {if} case rowindex of 1 : suit := ' Spade '; 2 : suit := ' Heart '; 3 : suit := ' Diamond '; 4 : suit := ' Club '; end; {case} end; {if} end; {row-loop} writeln('1 ', suit); writeln(Lst, '1 ', suit); end; {bid-case 2} if (13 <= points) and (points <= 15) and (most- cardsinsuit < 5) then begin {bid-case 3} writeln('1 club'); writeln(Lst, '1 club'); end; {bid-case 3} if (16 <= points) and (points <= 18) and (most cardsinsuit < 5) then begin {bid-case4} writeln('1 no trump'); writeln(Lst, '1 no trump'); end; {bid-case 4} if 18 < points then begin {bid-case 5} writeln('2 clubs'); writeln(Lst, '2 clubs '); end; {bid-case 5} end {execute Giveopeningbid-- nonempty hand} else begin {else} writeln('Current hand is empty. Choose 1) or 3) from menu to '); writeln('get a nonempty hand.'); writeln; writeln(Lst, 'Current hand is empty. Choose 1) or 3) from menu to '); writeln(Lst, 'get a nonempty hand.'); writeln(Lst); end; {else} end; {Giveopeningbid} (******************************************) begin {main} randomize; choice := 0; {initialize to insure entry into while loop} Initializearray(handarray); while choice <> 8 do begin {while} Showmenu; readln(choice); writeln(Lst,choice); case choice of 1 : Generatehand(handarray); 2 : Savehandtofile(handarray); 3 : Readhandfromfile(handarray); 4 : Changecard(handarray); 5 : Displayhand(handarray); 6 : Showpointsofhand(handarray{in- put}, points{output}); 7 : Giveopeningbid(points); else {quit if choice is 8} end; {case} end; {while} end. {main} Special Thanks to Tim Henderson for scanning the graphics and helping to produce this newsletter. (the Editors) ---------------------------------- | EDITORIAL STAFF | | Ronda Hauben | | William Rohler | | Norman O. Thompson | | Michael Hauben | | | |The Amateur Computerist invites | |contribution of articles, programs| |letters, etc. Send submissions to:| |R. Hauben, P.O. Box 4344, Dearborn| |Mi. 48126. Email address: | | au329@cleveland.freenet.edu | |Articles can be submitted on paper| |or diskette (in ASCII format) from| |either IBM or Commodore machines. | |One year subscription (4 issues) | |costs $5.00(US). Add $2.50(US) for| |foreign postage. Permission is | |granted to reprint any article | |herein, provided credit is given. | ----------------------------------