Saturday, October 5, 2013

What does the cowsay?

Rather than wine-ing about how long it's been since my last post, I thought I would move directly into pop culture today. Many of you may have heard Ylvis's song "The Fox," where a single question is posed and repeated over and over again: "What does the fox say?" This is, of course, a silly question. The sound of the fox has been recorded before, and sounds nothing like Ylvis's interpretation of what they might sound like. That being said, today I would like to introduce an old linux command: cowsay. It's function is somewhat self-explanatory: it creates an ASCII cow that says whatever you want it to say.

What is the purpose in this command? There is none, and that's okay. If there were a purpose to every linux command, video games would never have been invented. Because the ASCII image is somewhat dependent on the text used, I will be posting the outputs directly from my terminal. Here is an example output:

$cowsay "Hey, at least I'm not a pig"



If you are anything like me, you might be thinking, "Okay. This command is cool, but what else does it do?" Short answer: a bunch more. 

  • -b enacts borg mode
  • -t yields a tired cow
  • -d provides a dead cow
  • -s surprises the cow (sometimes referred to as a "stoned cow")
  • -g makes the cow greedy
  • -p causes paranoia
  • -w causes the cow to be wide awake
  • -y gives the cow youthful, kiddy eyes
  • -l lists all the other cow files you can pull from (likely out of /usr/share/cows)
  • -f chooses an alternative cowfile to use from the "l" flag's list

What types of cows are available? Quite a few. A full list can be found at the end of this post. Before that, though, I would like to take a minute to go over a new "cow" I have created: the fox. Just how did I do this? Well, I created an ASCII fox image that looked something like this:



I then navigated to /usr/share/cows and created the file "fox.cow". Now, in order to format the file appropriately and allow the fox to have changeable eyes, the image in the file ended up resembling a headless chicken, rather than a fox. After using the command, though, it ended up working pretty well. Here is the text:

##
## A fox, Leios
##
$eyes = "oo" unless ($eyes);
$the_cow = <<EOC;
 $thoughts              /\\
  $thoughts             )~)
    /\\/\\       ( (
   ( $eyes )_-------_)
    \\__/         )
     \\/ /|/---\\|\\
      .. ..  ..  ..
EOC


If you simply copy and paste that into a new "fox.cow" file, located in your $COWPATH (likely /usr/share/cow), you should be able to see the following:

$cowsay -f fox "I really sound like a dog"



And there you have it folks! What does the fox say? Anything your little penguin heart desires. The following is a list of all the "cows" available for you after installing from the Arch repositories:

[WARNING] Most of these images were made by linux users. [/WARNING]

  • bong
  • bud-frogs 
  • bunny 
  • cheese 
  • cower 
  • daemon 
  • default 
  • dragon
  • dragon-and-cow 
  • elephant 
  • elephant-in-snake
  • eyes 
  • flaming-sheep 
  • ghostbusters 
  • head-in 
  • hellokitty 
  • kiss 
  • kitty 
  • koala 
  • kosh 
  • luke-koala 
  • meow 
  • milk
  • moofasa 
  • moose 
  • mutilated 
  • ren 
  • satanic 
  • sheep 
  • skeleton 
  • small 
  • sodomized
  • stegosaurus 
  • stimpy 
  • supermilker 
  • surgery 
  • telebears 
  • three-eyes 
  • turkey turtle
  • tux 
  • udder 
  • vader
  • vader-koala 
  • www

                                                                                      If there are any physicists still reading:


                                                                                      Monday, May 20, 2013

                                                                                      Winning With WINE


                                                                                      Gaming is becoming more and more common in the linux world thanks to the efforts of modern gaming companies like Valve. Because of this, more and more games have native linux clients available. For those games, Windows emulation is clearly not the best option, but for other games that have not yet been ported to linux, such as Guild Wars 2, windows emulation might be a good option. In those cases, search for the games or related software at WineHQ's application database. Their organization scheme system has five levels: Platinum, Gold, Silver, Bronze, and Garbage. Each one designates the level of usability of the software. If you check out specific pages, you can see why certain software has been given certain ranks and figure out how to make your Wine experience worthwhile. For some users, this is as far as they need to go. If a program is well-supported, they buy it. If not, the don't. Still, there is a lot more to Wine than meets the eye.

                                                                                      First of all, though I have been calling Wine a "Windows emulator," the acronym "WINE" stands for "Wine Is Not an Emulator." In fact, it is not. It is closer to a compatability layer. There are also many tricks you can use to ensure your game is running as effectively as possible. Remember that the generic Wine build is not the only one available, and as a user of open-source software, it is your right and privilege to modify or patch the software to fit your system.

                                                                                      The easiest way to modify your Wine build is to use the winecfg tool. After running the command, you should see the following GUI:


                                                                                      From here, you can change basic settings for your programs. Typically, the important changes to help your program along can be found in the AppDB.

                                                                                      The next important tool is regedit. After using this command, you will find the following filesystem appear:


                                                                                      The most common edit here is to add specifications such as video memory size. This can be done by navigating to the HKEY_CURRENT_USER/Software/Wine/Direcd3D folder, and adding in the string "VideoMemorySize" with a value appropriate for your graphics card. This can be done by right clicking and adding the folder Direct3D, and then adding and editing the string in the same fashion.

                                                                                      In addition to these two editors, you could also try Q4Wine for Qt systems, but the documentation is much more difficult to find.

                                                                                      If you wish to have different Wine builds for each different program, along with an easy install, you could install PlayOnLinux. Most Wine users will use PlayOnLinux to manage their Wine builds.

                                                                                      There is, of course, the option of compiling your own version of Wine for your system and applications using Wine-git using a tutorial found here. To do this, you must first use the mkdir command to create a wine-git directory, and then download the latest wine version to it, like so:


                                                                                      git clone git://source.winehq.org/git/wine.git ~/wine-git
                                                                                      cd ~/wine-git


                                                                                      Once done, you should be able to run


                                                                                      $ git config remote.origin.url


                                                                                      and receive the following result:


                                                                                      git://source.winehq.org/git/wine.git


                                                                                      In addition, if you plan on ever submitting a patch to WineHQ, you might want to set your name and e-mail address like so:


                                                                                      git config --global user.name "Your Name"
                                                                                      git config --global user.email "me@example.com"


                                                                                      You might want to also run:


                                                                                      git config --global color.ui auto


                                                                                      for some colored commands and:


                                                                                      git config --global format.suffix .txt


                                                                                      to make sure all of the patches you receive are converted into .txt files.

                                                                                      Once all that is done, we can begin working with Wine-git--however, that is a lot for a single blog post. I will save off on this until tomorrow and revise the schedule accordingly.

                                                                                      As always, thanks for reading.
                                                                                      -Leios

                                                                                      Sunday, May 19, 2013

                                                                                      Week 3 of KeroCG's Summer of Code!

                                                                                      Here is the posting schedule for this upcoming week:

                                                                                      Monday: Winning with WINE
                                                                                      Tuesday: Winning With WINE II
                                                                                      Wednesday: Qt's return
                                                                                      Thursday: GTK+ more
                                                                                      Friday: A look into game development
                                                                                      Saturday: C-world
                                                                                      Sunday: A look at OpenGL

                                                                                      Feel free to let me know if there is anything in particular you would like for me to cover.

                                                                                      Thanks again for reading!
                                                                                      -Leios

                                                                                      A Window into Windows: Linux Options

                                                                                      If you have used linux for any length in time, you might have noticed one of it's greatest fallbacks: compatability with Windows. The fact is that developers develop for Windows, and the linux crowd has to bend over backwards to use the software. In my case, I see this struggle every day with games of all kinds. I have also heard of artists complaining about limited access to adequate art programs or doctors using Windows-only technology. Though many companies are finally starting to back linux, it will still be at least a decade before any big paradigm shifts occur in the OS world. We will be stuck with Windows fore a while, that's for sure.

                                                                                      What do we do about it? Well, we find work arounds for the programs we need. Generally, there are four options:

                                                                                      1. Open-Source equivalents

                                                                                      2. Compatability Layers

                                                                                      3. Virtualization Environments

                                                                                      4. Dual-Booting

                                                                                      I will cover each in brief detail:


                                                                                      Using Open Source Equivalents

                                                                                      In many cases, linux communities from all around have created their own version of a necessary programs. For a simple 2-D art program, for example, there is GIMP, which also has it's own photoshop varient, and for 3-D modeling, there is Blender. Both of these projects have very well-done examples that prove they are equivalent to their closed-source brethren in almost every way. I am not an artist, but after using them for a bit, I feel I have become used to them and would love to do some more difficult projects with them in the future. That being said, open source equivalents are often different than their closed cousins and may take a little more time to get used to. 

                                                                                      These are, of course, just two examples of many. Your best bet to finding the open source equivalent to the software you want is to do a quick google search about it. Still, in some cases, like if you are an artist or a gamer, the open source equivalents are just not what you want. If that's the case, you should look into more complicated solutions.


                                                                                      Using Windows Compatability Layers

                                                                                      Most distributions nowadays come with a software package known as WINE somewhere in their software center. This is essentially a Windows emulation tool that allows linux-users to use many Windows programs while still on their linux desktop. In most cases, the application works fairly well and the software is usable, but not always as usable as in Windows natively. That being said, WINE is completely patchable and definitely worth a shot with whatever software you are looking for. 


                                                                                      Virtualization

                                                                                      In some cases, neither the open source varients or WINE are good enough. In these cases, you can use a virtualization environment, such as Virtualbox of VMWare, to run Windows inside of linux. These programs work by allowing Windows to leech off your RAM and act as if it were running outside of linux. If you have enough RAM, this might be a good option for you.

                                                                                      Alternatively, you could set up a Windows PC as a remote desktop server and access it with remote desktop applications like rdesktop or remmina. This solution is a little messier than standard virtualization, as it requires another system to be already running Windows somewhere over the rainbow, but it is certainly an available option.


                                                                                      Dual Booting

                                                                                      If all other solutions have failed you, you can always reboot your system into Windows when necessary to use the appropraite software. This is a pretty simple option and is used frequently for linux gamers who need as much performance as they get.


                                                                                      Even though developers do not often develop for linux, most of the time necessary software is available for us to use in some fashion. If you are currently using Windows and thinking about switching to linux, know that your favorite programs are mostly usable and that you do not have to be rid of your Windows installation completely. Ease yourself into the OS and get used to how it works first. If you like it, keep it. If you don't like it, stick to Windows. Whatever the case, do what makes sense for you.

                                                                                      Thanks for reading,
                                                                                      -Leios

                                                                                      Saturday, May 18, 2013

                                                                                      Linux Viruses: Fact or Fiction?

                                                                                      Imagine you are a malicious virus writer. Your goal is to spread some toxic code to as many people as quickly as possible without getting caught. You have three operating systems to choose from: 

                                                                                      -Linux, an OS that only about 1% of the population uses. It is riddled with different platforms along with a close-knit community to filter any malicious code that enters their user-repositories and also has additional security levels to break through. 

                                                                                      -Mac OSX, the second most popular OS that shares many of linux's security features but without the community or varied platforms. 

                                                                                      -Windows, the most popular desktop OS by a significant margin with completely closed-source code and few security features.

                                                                                      Which OS would you choose? Windows, obviously. What is your second choice? Mac. At least with Mac you know what you are dealing with. Writing viruses for Linux, though, is kind of like going to an archery range blindfolded while trying to hit a quarter-sized target 25 yards away. Sure, if you shoot enough arrows, you might hit your target, but you've got to have a lot of luck and a lot of spare time. 

                                                                                      Let's imagine, though, that you did have the time and luck. How would you go about infecting a linux computer? Well, you would first choose the distribution you would like to infect. That's not exactly the easiest thing to do, as there are hundreds of distributions to choose from. Generally speaking, though, these can be broken down into three different file formats: .deb, .rpm, and .tar.gz. If you want to infect Fedora or a BSD, choose .rpm. If you want to infect Arch, choose .tar.gz. If you want to infect Ubuntu, choose .deb.

                                                                                      Once that is decided, you then have to work your way through user permissions. Generally speaking, linux distributions have users with fewer rights than root. That means if you do successfully infect a linux computer, you can only go as far as the user allows. You would actually have to prompt the user to give you his root password to infect the entire computer. Otherwise, you would just have to settle with a measely home directory. That means you've got to be pretty sneaky to trick a user into installing your virus with the appropriate permissions.

                                                                                      The linux desktop environment also changes much faster than Windows or Mac, with popular distributions offering new releases every six months and some distributions offering immediate, bleeding-edge software packages. This means that your virus would have to stay current or else attack a package that does not update regularly. 

                                                                                      In addition, almost all distributions have a central repository to download software from that has definitely been checked for viruses and malware, which means that most linux users, unlike Windows users, do not download software online. You could, potentially, sneak your virus in to a non-official repository (such as the AUR), but even then packages are checked by the community members who use them. 

                                                                                      When it's all said and done, if you do try to write a virus for linux, you have a lot to go through for very little reward. That being said, there are a number of viruses (some of which are "proof of concept" viruses) that can infect your computer. On top of that, your linux computer can carry viruses to be sent through e-mail to Windows (or Mac) devices. If you intend to set up any sort of mail client, a virus-scanner is a must!

                                                                                      Bottom line: if you use linux do not think you are impervious to attacks. That is simply not the case. Any online information, such as your banking account, can be subject to attack and some malicious code can be snuck into any of your downloaded content. Be careful when downloading new content from online or non-official sources. Be sure the packages you use have high approval ratings. Above all, though, use common sense. If you ever seem to be alone on the internet or are the only user downloading a particular item, close your broswer or crash your code! Just because your machine is unlikely to get a virus does not mean you should put it at risk. 

                                                                                      It is also expected that the number of linux viruses will increase in the upcoming years due to the increasing popularity of the OS as a gaming platform and thus as a viable desktop operating system. If you are using a popularized distribution, like Ubuntu, you might be one of the first at risk. Even if you are not using a popular distribution, it is not good practice to go without a virus scanner on your computer.

                                                                                      A few weeks ago, a virus known as darkleech began attacking Apache servers everywhere, followed quickly by Cdorked. More technical information on Cdorked can be found here. These are both backdoors that allow hackers to upload malicious code directly to the infected server or drive traffic to malicious websites. We should be careful moving foward with Apache in the future because of this. I will probably return to the idea of viruses in more detail later (I'm becoming interested). 

                                                                                      Agian, though your own system might not be in as much risk as a Windows device, you might want to look into a virus scanner or two. I know from personal experience that the CLI for avast is decent for detecting Windows-only viruses. For linux viruses, sophos along with rkhunter and Chkrootkit should find them.

                                                                                      As always, thanks for reading and be safe out there.
                                                                                      -Leios.

                                                                                      Friday, May 17, 2013

                                                                                      Linux Hardware: A World of Possibilities?

                                                                                      Throughout the past year or so, I have been a part of a group that hosts several "linux nights," which are opportunities for us to get together to install linux or fix anything wrong with our systems. Generally speaking, I find them enjoyable and would encourage anyone interested in computing to host one or two to generate interested in linux and computing in general. At the last meeting, however, we discussed why linux cannot seem to compete as a desktop platform, when it is clearly successful everywhere else. In the end, we agreed that one reason is because linux does not come pre-installed on any real market computer. Users must go out of their way to use the OS, which means they must take time out of their day not only to learn an entirely new operating system, but they must also to proceed through a typically painful installation process. On top of that, rather than lending a helping hand to new users, a significant portion of the linux community will scoff and ask, "did you read the manual?" This is not cool.

                                                                                      That being said, linux is becoming much more popularized, especially in the gaming world, with Valve supporting it 100%. It is even competing with mac as a secondary gaming platform. Objectively speaking, though, Windows still beats the snot out of linux in the desktop market. When people buy computers, it generally comes pre-installed with Wndows unless it is a mac product. Because of that, most programs run on Windows, not mac or linux, and because of that, most consumers want to buy Windows products. It is a somewhat vicious marketing cycle for any consumer wishing to buy another OS. On top of that, most of the regular linux users are used to the installation processes of their primary distributions and don't mind writing over their Windows device after purchase. 

                                                                                      Generally speaking, if you wish to buy a natively linux computer, you only have a few vendors to choose from, none of which you are likely to find at your local Best Buy. Here are my top three choices:

                                                                                      Dell- On several devices, Dell offers Ubuntu as a pre-installed OS, however after this incident, they are probably wary to popularize it. Still, there are some decent deals, like this Alienware, for instance. Generally, though, Dell prefers to support Windows.

                                                                                      System76- This is my personal favorite Linux vendor. They offer competatively priced, ubuntu-only laptops, desktops, and servers, including some gaming powerhouses, like their Leopard Extreme desktop or Bonobo Extreme laptop. They also offer fantastic economy systems for the linuxer on a budget. On top of that, their Windows key has the Ubuntu logo on it.

                                                                                      ZaReason- Truth be told, this vendor costs a little more, but has many more options to choose from. They also support more than just Ubuntu and will install any distribution you wish. Beyond that, they allow you to use have a tux or Ubuntu logo on your Windows key, which is pretty cool in my book.

                                                                                      There are also some fringe vendors that cost too much or are too outdated to be mentioned here. You might be asking yourself, "How do linux computers cost more than Windows when the OS is free?" Well, that's because Windows comes with a bunch of bloatware to mitigate it's cost. That's the whole of it--the market economy, at its finest.

                                                                                      Though I would encourage using any of the above vendors, I understand that sometimes you might not have time for a new computer to come in or that it really is cheaper to buy a Windows machine and install linux on it yourself (be wary of Windows 8, though). That being said, here are a few tips to buying a PC for linux:

                                                                                      1. Be wary of AMD- Generally speaking, Nvidia and Intel graphics cards are much better adapted for linux machines. Though this is not as true for newer graphics cards, partially thanks to Valve's influence, it is still something to look out for.

                                                                                      2. Google the machine beforehand- Before purchasing a machine for linux, find out the model number and look it up along with the word "linux" in google. Also, make sure you have as much information about the system as possible before buying. This might be a silly rule, but it could definitely save you some trouble down the road.

                                                                                      3. Don't necessarily look for the latest and greatest- When shopping for a new PC, remember that it might take time for the linux community to work in new hardware advancements. Take, for example, Nvidia Optimus technology for laptops (which equipped particular models with 2 graphics cards to save battery life). It took some time for the linux community to finally create the bumblebee software (so linux users to choose which card is best for particular software).

                                                                                      4. Buy from a stable vendor- In order to compete with larger venders (like Dell, for instance), smaller companies often stuff their computers with cheaper hardware, which might not always work correctly on linux. Personally, my favorite hardware vender is Asus. Most of the time, their hardware works great with linux. 

                                                                                      5. Buy a back-up hard drive- This is just my personal preference. When you buy your computer, it will probably work out of the box with Windows. After installing linux, however, that might not be the case. Because of this, I will typically buy an extra hard drive with my computers and install linux fresh on that. If anythong goes wrong with the installation, I at least know that I have a usable windows PC to go back to. 

                                                                                      All that said, before you purchase your next computer, be sure to give a thought to linux.

                                                                                      Thanks for reading,
                                                                                      -Leios

                                                                                      Thursday, May 16, 2013

                                                                                      Web.by Web.py 2: Databases

                                                                                      Continuing from yesterday's post, today we will be using python to modify our site database(s). That being said, if you are new, you might want to check out the Apache web server, and your choice of either Postgresql or MariaDB for a database manager. Remember that python's primary purpose in the LAMP set-up is to communicate with both the web server and the database manager, meaning it will deal with most of the posting and getting back and forth. Like yesterday, we will start by starting the Apache and database manager daemons. From there, we will pull on the code from yesterday, which looked like this:


                                                                                      import web
                                                                                      render = web.template.render('templates/')
                                                                                      
                                                                                      urls = (
                                                                                          '/(.*)', 'index'
                                                                                      )
                                                                                      
                                                                                      class index:
                                                                                          def GET(self, name):
                                                                                              i = web.input(name=None)
                                                                                              return render.index(i.name)
                                                                                      
                                                                                      if __name__ == "__main__":
                                                                                          app = web.application(urls, globals())
                                                                                          app.run()


                                                                                      With a /templates/index.html that looked like this:


                                                                                      $def with (name)
                                                                                      
                                                                                      $if name:
                                                                                          I just wanted to say <em>hello</em> to $name.
                                                                                      $else:
                                                                                          <em>Hello</em> world!


                                                                                      Again, we will be working off of this tutorial. First things first, we must tell web.py which database manager we are using by using something similar to the following line:


                                                                                      db = web.database(dbn='postgres', user='username', pw='password', db='dbname')


                                                                                      to be placed under the headers. If you wish to use MariaDB instead of Postgresql, simply replace "postgres" with "mysql." If you have not set up a username, password, or databasename, please refer back to my SoC posts about Postgres or MariaDB. In both cases, we finished the day in the same way: by accessing the database manager's admin interface. 

                                                                                      Now, let's create a simple "to do" list again, like we did the other day, except that we will be using our database managers and web.py instead of just Python. To do this, we must create a table in our databases called "todo." First, we must access our database manager's admin interface (assuming it is set up properly).

                                                                                      For Postgres:


                                                                                      $ psql -d myDatabaseName


                                                                                      For MariaDB:


                                                                                      $ mysql -u user -p'password' databasename


                                                                                      Once done, simply type (or copy and paste) the following lines:


                                                                                      CREATE TABLE todo (
                                                                                        id serial primary key,
                                                                                        title text,
                                                                                        created timestamp default now(),
                                                                                        done boolean default 'f'    );


                                                                                      This, is simply creating a table with the title "todo" with otherwise standard formatting. We can add a first line by typing:


                                                                                      INSERT INTO todo (title) VALUES ('Learn web.py');


                                                                                      Which inputs the phrase "learn web.py" into the table. I might suggest opening up a second terminal here to have access to both your admin database management and your code, because now we must go back to our code.py and alter the index.GET function to read our table:


                                                                                      def GET(self):
                                                                                          todos = db.select('todo')
                                                                                          return render.index(todos)


                                                                                      This is following the same format as yesterday. This time, though, we create a variable that uses the select function of our database to choose the "todo" table we just created. It will then return a rendering of that variable. We should also change the url scheme at the top of the file back to how it was:


                                                                                      '/', 'index',


                                                                                      Finally, to read the table, we must change our templates/index.html file to:


                                                                                      $def with (todos)
                                                                                      <ul>
                                                                                      $for todo in todos:
                                                                                          <li id="t$todo.id">$todo.title</li>
                                                                                      </ul>


                                                                                      Which uses python to select out the "todo" table within the variable "todos" we just created. We then use html to title each item and give it a line to itself. If you visit your site by running the code, you should see the phrase "Learn web.py", Which means we have successfully read from our database. Now, let's work on writing to it. In this case, we will add in any values we place in the url by adding in the following class:


                                                                                      class add:
                                                                                          def POST(self):
                                                                                              i = web.input()
                                                                                              n = db.insert('todo', title=i.title)
                                                                                              raise web.seeother('/')
                                                                                      


                                                                                      This is very similar to when we input our name yesterday, except now we are adding the data directly into the database. Of course, to do this, we must change the allowed urls to:


                                                                                      '/', 'index',
                                                                                      '/add', 'add'


                                                                                      Which allows for the subdirectory "add" with the class "add" in the url. 

                                                                                      Finally, we must add


                                                                                      <form method="post" action="add">
                                                                                      <p><input type="text" name="title" /> <input type="submit" value="Add" /></p>
                                                                                      </form>
                                                                                      


                                                                                      to the end of templates/index.html to allow posting through the site, itself. In full, your code.py should look like:


                                                                                      import web
                                                                                      render = web.template.render('templates/')
                                                                                      db = web.database(dbn='postgres', user='user', pw='password', db='dbname')
                                                                                      
                                                                                      urls = (
                                                                                          '/', 'index',
                                                                                          '/add', 'add'
                                                                                      )
                                                                                      
                                                                                      class index:
                                                                                          def GET(self):
                                                                                              todos = db.select('todo')
                                                                                              return render.index(todos)
                                                                                      
                                                                                      class add:
                                                                                          def POST(self):
                                                                                              i = web.input()
                                                                                              n = db.insert('todo', title=i.title)
                                                                                              raise web.seeother('/')
                                                                                      
                                                                                      if __name__ == "__main__":
                                                                                          app = web.application(urls, globals())
                                                                                          app.run()
                                                                                      


                                                                                      And templates/index.html:


                                                                                      $def with (todos)
                                                                                      <ul>
                                                                                      $for todo in todos:
                                                                                          <li id="t$todo.id">$todo.title</li>
                                                                                      </ul>
                                                                                      
                                                                                      <form method="post" action="add">
                                                                                      <p><input type="text" name="title" /> <input type="submit" value="Add" /></p>
                                                                                      </form>
                                                                                      

                                                                                      Once done, run code.py one more time, and you should have a box that dynamically posts more data into your database. In my opinion, that's pretty cool. 

                                                                                      From here, you should have enough information about web.py to tackle some more code from their code samples and cookbook pages. We will probably return to web.py later, but for now we have done enough.

                                                                                      As always, thanks for reading.
                                                                                      -Leios.