<commit_before>from django.db   import models
from django.core import exceptions

NAME_LENGTH = 140
""" Maximum length of name fields in various models. This value should be
    long enough to hold any reasonable personal name, university name, district
    name, or other things like these. """

TEXT_LENGTH = 1024
""" Maximum length of descriptions fields in models below. This value should be
    long enough to hold an average paragraph of descriptive text. Maybe,
    a thousand or two of characters. """

GRADE_LENGTH = 20
""" Maximum length of the `grade` field. This value should be long enough to
    hold a number plus possible brief one-word explanation. """

class TeamOrigin(models.Model):
    name = models.CharField(max_length=NAME_LENGTH)

    def __str__(self):
        return self.name

class Team(models.Model):
    name = models.CharField(max_length=NAME_LENGTH)
    description = models.TextField(max_length=TEXT_LENGTH, blank=True)
    origin = models.ForeignKey(TeamOrigin, null=True, blank=True)

    def __str__(self):
        return self.name

class CommonOrigin(models.Model):
    name = models.CharField(max_length=NAME_LENGTH)

    def __str__(self):
        return self.name

class Participant(models.Model):
    short_name  = models.CharField(max_length=NAME_LENGTH)
    full_name   = models.CharField(max_length=NAME_LENGTH, blank=True)
    origin      = models.ForeignKey(CommonOrigin, null=True, blank=True)
    grade       = models.CharField(max_length=GRADE_LENGTH, blank=True)
    team        = models.ForeignKey(Team)
    is_capitan  = models.BooleanField()

    def __str__(self):
        return self.short_name

class Leader(models.Model):
    short_name  = models.CharField(max_length=NAME_LENGTH)
    full_name   = models.CharField(max_length=NAME_LENGTH, blank=True)
    origin      = models.ForeignKey(CommonOrigin, null=True, blank=True)
    team        = models.ForeignKey(Team)

    def __str__(self):
        return self.short_name

class Jury(models.Model):
    short_name  = models.CharField(max_length=NAME_LENGTH)
    full_name   = models.CharField(max_length=NAME_LENGTH, blank=True)
    origin      = models.ForeignKey(CommonOrigin, null=True, blank=True)

    def __str__(self):
        return self.short_name

class Room(models.Model):
    name        = models.CharField(max_length=NAME_LENGTH)

    def __str__(self):
        return self.name

class Problem(models.Model):
    problem_num = models.IntegerField(primary_key=True)
    name        = models.CharField(max_length=NAME_LENGTH)
    description = models.TextField(max_length=TEXT_LENGTH, blank=True)

    def __str__(self):
        return "#{0}. {1}".format(self.problem_num, self.name)

class Fight(models.Model):

    # Python lacks proper enums and constants, so use these static
    # variables to refer to 'status' values from Python code.
    NOT_STARTED = 0
    IN_PROGRESS = 1
    COMPLETED   = 2

    STATUS_CHOICES = [
        (NOT_STARTED, "Not started"),
        (IN_PROGRESS, "In progress"),
        (COMPLETED,   "Completed")
    ]

    room        = models.ForeignKey(Room)
    fight_num   = models.IntegerField()
    start_time  = models.DateTimeField(null=True, blank=True)
    stop_time   = models.DateTimeField(null=True, blank=True)
    status      = models.PositiveSmallIntegerField(default=NOT_STARTED, choices=STATUS_CHOICES)
    team1       = models.ForeignKey(Team, related_name="team1")
    team2       = models.ForeignKey(Team, related_name="team2")
    team3       = models.ForeignKey(Team, related_name="team3", null=True, blank=True)
    team4       = models.ForeignKey(Team, related_name="team4", null=True, blank=True)
    juries      = models.ManyToManyField(Jury, blank=True)

    def clean(self):
        bad = (self.start_time is not None and
               self.stop_time  is not None and
               self.start_time >= self.stop_time)
        if bad:
            raise exceptions.ValidationError({"stop_time":
                "Fight is completed before being started"})

        teams  = {self.team1, self.team2, self.team3, self.team4}
        teams -= {None}
        if len(teams) < 2:
            raise exceptions.ValidationError(
                "Participating teems are not unigue")

    class Meta:
        unique_together = ("room", "fight_num")

    def __str__(self):
        return "#{0}. {1}".format(self.fight_num, self.room)

class FightStage(models.Model):
    fight       = models.ForeignKey(Fight)
    action_num  = models.IntegerField()
    problem     = models.ForeignKey(Problem)
    reporter    = models.ForeignKey(Participant, related_name="reporter")
    opponent    = models.ForeignKey(Participant, related_name="opponent")
    reviewer    = models.ForeignKey(Participant, related_name="reviewer", null=True, blank=True)

    class Meta:
        unique_together = ("fight", "action_num")

class Refusal(models.Model):
    fight_stage = models.ForeignKey(FightStage)
    problem     = models.ForeignKey(Problem)

    class Meta:
        unique_together = ("fight_stage", "problem")

class JuryPoints(models.Model):
    fight_stage   = models.ForeignKey(FightStage)
    jury          = models.ForeignKey(Jury)
    reporter_mark = models.IntegerField(null=True, blank=True)
    opponent_mark = models.IntegerField(null=True, blank=True)
    reviewer_mark = models.IntegerField(null=True, blank=True)

    class Meta:
        unique_together = ("fight_stage", "jury")

class LeaderToJury(models.Model):
    leader = models.ForeignKey(Leader)
    jury = models.ForeignKey(Jury)

    class Meta:
        unique_together = ("leader", "jury")

    def __str__(self):
        return "{0} -> {1}".format(self.leader, self.jury)<commit_msg>scifight/models.py: add more validators<commit_after>from django.db   import models
from django.core import exceptions

NAME_LENGTH = 140
""" Maximum length of name fields in various models. This value should be
    long enough to hold any reasonable personal name, university name, district
    name, or other things like these. """

TEXT_LENGTH = 1024
""" Maximum length of descriptions fields in models below. This value should be
    long enough to hold an average paragraph of descriptive text. Maybe,
    a thousand or two of characters. """

GRADE_LENGTH = 20
""" Maximum length of the `grade` field. This value should be long enough to
    hold a number plus possible brief one-word explanation. """

class TeamOrigin(models.Model):
    name = models.CharField(max_length=NAME_LENGTH)

    def __str__(self):
        return self.name

class Team(models.Model):
    name = models.CharField(max_length=NAME_LENGTH)
    description = models.TextField(max_length=TEXT_LENGTH, blank=True)
    origin = models.ForeignKey(TeamOrigin, null=True, blank=True)

    def __str__(self):
        return self.name

class CommonOrigin(models.Model):
    name = models.CharField(max_length=NAME_LENGTH)

    def __str__(self):
        return self.name

class Participant(models.Model):
    short_name  = models.CharField(max_length=NAME_LENGTH)
    full_name   = models.CharField(max_length=NAME_LENGTH, blank=True)
    origin      = models.ForeignKey(CommonOrigin, null=True, blank=True)
    grade       = models.CharField(max_length=GRADE_LENGTH, blank=True)
    team        = models.ForeignKey(Team)
    is_capitan  = models.BooleanField()

    def __str__(self):
        return self.short_name

class Leader(models.Model):
    short_name  = models.CharField(max_length=NAME_LENGTH)
    full_name   = models.CharField(max_length=NAME_LENGTH, blank=True)
    origin      = models.ForeignKey(CommonOrigin, null=True, blank=True)
    team        = models.ForeignKey(Team)

    def __str__(self):
        return self.short_name

class Jury(models.Model):
    short_name  = models.CharField(max_length=NAME_LENGTH)
    full_name   = models.CharField(max_length=NAME_LENGTH, blank=True)
    origin      = models.ForeignKey(CommonOrigin, null=True, blank=True)

    def __str__(self):
        return self.short_name

class Room(models.Model):
    name        = models.CharField(max_length=NAME_LENGTH)

    def __str__(self):
        return self.name

class Problem(models.Model):
    problem_num = models.IntegerField(primary_key=True)
    name        = models.CharField(max_length=NAME_LENGTH)
    description = models.TextField(max_length=TEXT_LENGTH, blank=True)

    def __str__(self):
        return "#{0}. {1}".format(self.problem_num, self.name)

class Fight(models.Model):

    # Python lacks proper enums and constants, so use these static
    # variables to refer to 'status' values from Python code.
    NOT_STARTED = 0
    IN_PROGRESS = 1
    COMPLETED   = 2

    STATUS_CHOICES = [
        (NOT_STARTED, "Not started"),
        (IN_PROGRESS, "In progress"),
        (COMPLETED,   "Completed")
    ]

    room        = models.ForeignKey(Room)
    fight_num   = models.IntegerField()
    start_time  = models.DateTimeField(null=True, blank=True)
    stop_time   = models.DateTimeField(null=True, blank=True)
    status      = models.PositiveSmallIntegerField(default=NOT_STARTED, choices=STATUS_CHOICES)
    team1       = models.ForeignKey(Team, related_name="team1")
    team2       = models.ForeignKey(Team, related_name="team2")
    team3       = models.ForeignKey(Team, related_name="team3", null=True, blank=True)
    team4       = models.ForeignKey(Team, related_name="team4", null=True, blank=True)
    juries      = models.ManyToManyField(Jury, blank=True)

    def clean(self):
        bad = (self.start_time is not None and
               self.stop_time  is not None and
               self.start_time >= self.stop_time)
        if bad:
            raise exceptions.ValidationError({"stop_time":
                "Fight is completed before being started"})

        if self.team3 is None and self.team4 is not None:
            raise exceptions.ValidationError({"team3":
                "Team 3 must be given when team 4 is given"})

        teams = [self.team1, self.team2, self.team3, self.team4]
        teams_uniq = set(teams) - {None}
        if len(teams_uniq) < 2 or len(teams_uniq) + teams.count(None) != 4:
            raise exceptions.ValidationError(
                "Participating teams are not unigue")

    class Meta:
        unique_together = ("room", "fight_num")

    def __str__(self):
        return "#{0}. {1}".format(self.fight_num, self.room)

class FightStage(models.Model):
    fight       = models.ForeignKey(Fight)
    action_num  = models.IntegerField()
    problem     = models.ForeignKey(Problem)
    reporter    = models.ForeignKey(Participant, related_name="reporter")
    opponent    = models.ForeignKey(Participant, related_name="opponent")
    reviewer    = models.ForeignKey(Participant, related_name="reviewer", null=True, blank=True)

    def clean(self):
        guys = [self.reporter, self.opponent, self.reviewer]
        guys_uniq = set(guys) - {None}
        if len(guys_uniq) < 2 or len(guys_uniq) + guys.count(None) != 4:
            raise exceptions.ValidationError(
                "Single person is assigned for two or more roles")

    class Meta:
        unique_together = ("fight", "action_num")

class Refusal(models.Model):
    fight_stage = models.ForeignKey(FightStage)
    problem     = models.ForeignKey(Problem)

    class Meta:
        unique_together = ("fight_stage", "problem")

class JuryPoints(models.Model):
    fight_stage   = models.ForeignKey(FightStage)
    jury          = models.ForeignKey(Jury)
    reporter_mark = models.IntegerField(null=True, blank=True)
    opponent_mark = models.IntegerField(null=True, blank=True)
    reviewer_mark = models.IntegerField(null=True, blank=True)

    def clean_fields(self, exclude=None):
        exclude_set = set()
        if exclude is not None:
            exclude_set = set(exclude)

        if "reviewer_mark" not in exclude_set:
            bad = (self.reviewer_mark is None and
                   self.fight_stage.fight.team3 is not None)
            if bad:
                raise exceptions.ValidationError({"reviewer_mark":
                    "Reviewer mark must be set, because there is a " +
                    "reviewing team in this fight"})

        if "jury" not in exclude_set:
            juries_set = set(self.fight_stage.fight.juries.all())
            if self.jury not in juries_set:
                raise exceptions.ValidationError({"jury":
                    "Selected jury doesn't take part in the fight"})

    class Meta:
        unique_together = ("fight_stage", "jury")

class LeaderToJury(models.Model):
    leader = models.ForeignKey(Leader)
    jury = models.ForeignKey(Jury)

    class Meta:
        unique_together = ("leader", "jury")

    def __str__(self):
        return "{0} -> {1}".format(self.leader, self.jury)<|endoftext|>


<commit_before>#!/usr/bin/python

import urllib, urllib2, os, datetime, re, sys, httplib, zipfile
import time
from settings import *
try:
    import json
except:
    import simplejson as json

class CRScraper(object):
    def __init__(self):
        # use httplib so that we can retrieve the headers before retrieving the
	    # body.
        self.domain = "www.gpo.gov"
        self.path = "/fdsys/delivery/getpackage.action"
        self.date = None
        self.datestring = None
        self.url = None
        self.zipsize = None

    def set_date(self, date):
        ''' given a date object, retrieve the documents for that given date and
        save them to the filesystem.'''
        self.date = date
        self.datestring = date.strftime("%Y-%m-%d")
        self.url = self.path + "?packageId=CREC-%s" % self.datestring

    def was_in_session(self):
        # check the response header to make sure the Record exists for this date.
        conn = httplib.HTTPConnection(self.domain, timeout=15)
        conn.request("HEAD", self.url)
        resp = conn.getresponse()
        content_type = resp.getheader('content-type')
        if content_type != 'application/zip':
            print 'Congress was not in session on %s' % self.datestring
            return False
        else:
            self.zipsize = resp.getheader('content-length')
            return True

    def retrieve(self):
        tmpfile = os.path.join(TMP_DIR, "CREC-%s.zip" % self.datestring)

        # download the zipfile if we don't already have it.
        rightsize = lambda tmpfile: os.path.getsize(tmpfile) == self.zipsize
        if not os.path.exists(tmpfile) or not rightsize(tmpfile):
            zip = urllib.urlopen('http://' + self.domain + self.url)
            tmp = open(tmpfile, 'w')
            print 'retrieving zip file %s. this could take a few mins...' % tmpfile
            tmp.write(zip.read())
            tmp.close()
        else: print '%s exists. skipping download' % tmpfile

        # prepare the directory to copy the zipped files into. use strftime
        # here to ensure day and month directories are always 2 digits.
        save_path = os.path.join(CWOD_HOME, 'raw/%d/%s/%s/' % (self.date.year,
        self.date.strftime("%m"), self.date.strftime("%d")))
        if not os.path.exists(save_path):
            os.makedirs(save_path)

        # iterate over the html files in the zipfile, extracting the
        # ascii-formatted
 section and saving the file as raw textfiles
        zip = zipfile.ZipFile(tmpfile)
        html_files = [doc for doc in zip.namelist() if doc.endswith('.htm')]
        num_expected_files = len(html_files)
        errors = 0
        for f in html_files:
            doc = zip.read(f)
            filename = os.path.basename(f).split('.')[0]+'.txt'
            saveas = os.path.join(save_path, filename)
            if not os.path.exists(saveas):
                # re.DOTALL is important - it tells 'dot' (.) to match newline character.
                findraw = re.compile(r'
(?P<raw>.*)
', re.DOTALL)
                try:
                    raw = findraw.search(doc).group('raw')
                    out = open(saveas, 'w')
                    out.write(raw)
                    out.close()
                    print 'saving %s...' % saveas
                except BaseException, e:
                    errors += 1
                    print 'Problem downloading file %s. Error:' % saveas
                    print e
            else: print 'file %s already exists. skipping.' % saveas

        # do some sanity checking
        if errors or len(os.listdir(save_path)) != num_expected_files:
            status = "errors"
        else:
            status = "success"
        self.log_download_status(self.date.strftime("%d/%m/%Y"), status)

        # delete tmfile
        os.remove(tmpfile)

        return save_path

    def log_download_status(self, datestring, status):
        if not os.path.exists(SCRAPER_LOG):
            if not os.path.exists(LOG_DIR):
                os.makedirs(LOG_DIR)
            scraper_log = open(SCRAPER_LOG, 'w')
            scraper_log.write('Date, Status\n')
            scraper_log.close()

        scraper_log = open(SCRAPER_LOG, 'r')
        scraper_lines = scraper_log.readlines()
        scraper_log.close()
        update_line = None
        # if this date is already in the log file, update it.
        for linenum, logline in enumerate(scraper_lines):
            if datestring in logline:
                # update the status of that line
                update_line = linenum
        if update_line:
            print 'updating line'
            scraper_lines[update_line] = '%s, %s\n' % (datestring, status)
        # if the date was not already in the log file, append it at the end
        else:
            print 'appending line'
            scraper_lines.append('%s, %s\n' % (datestring, status))
        scraper_log = open(SCRAPER_LOG, 'w')
        scraper_log.writelines(scraper_lines)
        scraper_log.close()

    def previously_retrieved(self):
        datestring = self.date.strftime("%d/%m/%Y")
        if not os.path.exists(SCRAPER_LOG):
             return False
        scraper_lines = open(SCRAPER_LOG).readlines()
        for line in scraper_lines:
            if datestring in line and 'success' in line:
                print 'This date was previously retrieved: Record already exists\n'
                return True
            if datestring in line and 'nosession' in line:
                print 'This date was previously retrieved: Congress was not in session.\n'
                return True
        return False

    def retrieve_by_date(self, date):
        self.set_date(date)
        if not self.previously_retrieved():
            if self.was_in_session():
                path = self.retrieve()
                return path
            else:
                datestring = self.date.strftime("%d/%m/%Y")
                self.log_download_status(datestring, 'nosession')

def date_from_string(datestring):
    return datetime.datetime.strptime(datestring, "%d/%m/%Y")

def daterange_list(start, end):
    ''' returns a list of date objects between a start and end date. start must
    come before end. '''
    daterange = (end - start).days
    dates = [start + datetime.timedelta(n) for n in xrange(daterange)]
    return dates

def usage():
    return '''
Several ways to invoke the scraper:

0. "./scraper.py" will display this message (and do nothing)

1. "./scraper.py all" will go back in time retrieving all daily congressional records until the date specified as OLDEST_DATE in settings.py. You probably want to use this with caution, but it can be useful during initial setup.

2. "./scraper.py backto dd/mm/yyyy" will retrieve congressional records back to the date given.

3. "./scraper.py dd/mm/yyyy - dd/mm/yyyy" will retreive congressional records for all days within the range given. the first date should occur before the second date in time.

4. "./scraper.py dd/mm/yyyy" will retreive the congressional record for the day given.
    '''

if __name__ == '__main__':

    if len(sys.argv) == 1:
        print usage()
        sys.exit()
    try:
        if len(sys.argv) == 2:
            if sys.argv[1] == 'all':
                end = datetime.datetime.now()
                start = date_from_string(OLDEST_DATE)
                dates = daterange_list(start, end)
            else:
                dates = [date_from_string(sys.argv[1])]

        elif len(sys.argv) == 3 and sys.argv[1] == 'backto':
            end = datetime.datetime.now()
            start = date_from_string(sys.argv[2])
            dates = daterange_list(start, end)

        elif len(sys.argv) == 4:
            start = date_from_string(sys.argv[1])
            end = date_from_string(sys.argv[3])
            dates = daterange_list(start, end)

        else:
            raise Exception

    except Exception, e:
        print usage()
        print 'There was an error: ', e
        sys.exit()

    for date in dates:
        print "Checking Congressional Record for %s" % date
        if CRScraper().retrieve_by_date(date):
            print 'Will now sleep for one minute before retrieving next record...zzz...'
            time.sleep(60)
        else:
            if len(dates) == 1:
                sys.exit()
            else:
                print 'sleeping for 5 seconds...zzz...'
                time.sleep(5)
<commit_msg>error handling for http timeouts<commit_after>#!/usr/bin/python

import urllib, urllib2, os, datetime, re, sys, httplib, zipfile
import time
from settings import *
try:
    import json
except:
    import simplejson as json

class CRScraper(object):
    def __init__(self):
        # use httplib so that we can retrieve the headers before retrieving the
	    # body.
        self.domain = "www.gpo.gov"
        self.path = "/fdsys/delivery/getpackage.action"
        self.date = None
        self.datestring = None
        self.url = None
        self.zipsize = None

    def set_date(self, date):
        ''' given a date object, retrieve the documents for that given date and
        save them to the filesystem.'''
        self.date = date
        self.datestring = date.strftime("%Y-%m-%d")
        self.url = self.path + "?packageId=CREC-%s" % self.datestring

    def was_in_session(self):
        # check the response header to make sure the Record exists for this date.
        conn = httplib.HTTPConnection(self.domain, timeout=25)
        conn.request("HEAD", self.url)
        # the connection can be a little dodgy, let it try connecting a few
        # times if needed.
        could_not_connect = 0
        while could_not_connect < 3:
            try:
                resp = conn.getresponse()
                could_not_connect = False
                break
            except:
                could_not_connect += 1
        if could_not_connect:
            return None

        content_type = resp.getheader('content-type')
        if content_type != 'application/zip':
            print 'Congress was not in session on %s' % self.datestring
            return False
        self.zipsize = resp.getheader('content-length')
        return True

    def retrieve(self):
        tmpfile = os.path.join(TMP_DIR, "CREC-%s.zip" % self.datestring)

        # download the zipfile if we don't already have it.
        rightsize = lambda tmpfile: os.path.getsize(tmpfile) == self.zipsize
        if not os.path.exists(tmpfile) or not rightsize(tmpfile):
            zip = urllib.urlopen('http://' + self.domain + self.url)
            tmp = open(tmpfile, 'w')
            print 'retrieving zip file %s. this could take a few mins...' % tmpfile
            tmp.write(zip.read())
            tmp.close()
        else: print '%s exists. skipping download' % tmpfile

        # prepare the directory to copy the zipped files into. use strftime
        # here to ensure day and month directories are always 2 digits.
        save_path = os.path.join(CWOD_HOME, 'raw/%d/%s/%s/' % (self.date.year,
        self.date.strftime("%m"), self.date.strftime("%d")))
        if not os.path.exists(save_path):
            os.makedirs(save_path)

        # iterate over the html files in the zipfile, extracting the
        # ascii-formatted
 section and saving the file as raw textfiles
        zip = zipfile.ZipFile(tmpfile)
        html_files = [doc for doc in zip.namelist() if doc.endswith('.htm')]
        num_expected_files = len(html_files)
        errors = 0
        for f in html_files:
            doc = zip.read(f)
            filename = os.path.basename(f).split('.')[0]+'.txt'
            saveas = os.path.join(save_path, filename)
            if not os.path.exists(saveas):
                # re.DOTALL is important - it tells 'dot' (.) to match newline character.
                findraw = re.compile(r'
(?P<raw>.*)
', re.DOTALL)
                try:
                    raw = findraw.search(doc).group('raw')
                    out = open(saveas, 'w')
                    out.write(raw)
                    out.close()
                    print 'saving %s...' % saveas
                except BaseException, e:
                    errors += 1
                    print 'Problem downloading file %s. Error:' % saveas
                    print e
            else: print 'file %s already exists. skipping.' % saveas

        # do some sanity checking
        if errors or len(os.listdir(save_path)) != num_expected_files:
            status = "errors"
        else:
            status = "success"
        self.log_download_status(self.date.strftime("%d/%m/%Y"), status)

        # delete tmfile
        os.remove(tmpfile)

        return save_path

    def log_download_status(self, datestring, status):
        if not os.path.exists(SCRAPER_LOG):
            if not os.path.exists(LOG_DIR):
                os.makedirs(LOG_DIR)
            scraper_log = open(SCRAPER_LOG, 'w')
            scraper_log.write('Date, Status\n')
            scraper_log.close()

        scraper_log = open(SCRAPER_LOG, 'r')
        scraper_lines = scraper_log.readlines()
        scraper_log.close()
        update_line = None
        # if this date is already in the log file, update it.
        for linenum, logline in enumerate(scraper_lines):
            if datestring in logline:
                # update the status of that line
                update_line = linenum
        if update_line:
            scraper_lines[update_line] = '%s, %s\n' % (datestring, status)
        # if the date was not already in the log file, append it at the end
        else:
            scraper_lines.append('%s, %s\n' % (datestring, status))
        scraper_log = open(SCRAPER_LOG, 'w')
        scraper_log.writelines(scraper_lines)
        scraper_log.close()

    def previously_retrieved(self):
        datestring = self.date.strftime("%d/%m/%Y")
        if not os.path.exists(SCRAPER_LOG):
             return False
        scraper_lines = open(SCRAPER_LOG).readlines()
        for line in scraper_lines:
            if datestring in line and 'success' in line:
                print 'This date was previously retrieved: Record already exists\n'
                return True
            if datestring in line and 'nosession' in line:
                print 'This date was previously retrieved: Congress was not in session.\n'
                return True
        return False

    def retrieve_by_date(self, date):
        self.set_date(date)
        if not self.previously_retrieved():
            in_session = self.was_in_session()
            if in_session:
                path = self.retrieve()
                return path
            elif in_session == False:
                datestring = self.date.strftime("%d/%m/%Y")
                self.log_download_status(datestring, 'nosession')
            elif in_session == None:
                self.log_download_status(self.date.strftime("%d/%m/%Y"), 'GPO connection error')

def date_from_string(datestring):
    return datetime.datetime.strptime(datestring, "%d/%m/%Y")

def daterange_list(start, end):
    ''' returns a list of date objects between a start and end date. start must
    come before end. '''
    daterange = (end - start).days
    dates = [start + datetime.timedelta(n) for n in xrange(daterange)]
    return dates

def usage():
    return '''
Several ways to invoke the scraper:

0. "./scraper.py" will display this message (and do nothing)

1. "./scraper.py all" will go back in time retrieving all daily congressional records until the date specified as OLDEST_DATE in settings.py. You probably want to use this with caution, but it can be useful during initial setup.

2. "./scraper.py backto dd/mm/yyyy" will retrieve congressional records back to the date given.

3. "./scraper.py dd/mm/yyyy - dd/mm/yyyy" will retreive congressional records for all days within the range given. the first date should occur before the second date in time.

4. "./scraper.py dd/mm/yyyy" will retreive the congressional record for the day given.
    '''

if __name__ == '__main__':

    if len(sys.argv) == 1:
        print usage()
        sys.exit()
    try:
        if len(sys.argv) == 2:
            if sys.argv[1] == 'all':
                end = datetime.datetime.now()
                start = date_from_string(OLDEST_DATE)
                dates = daterange_list(start, end)
            else:
                dates = [date_from_string(sys.argv[1])]

        elif len(sys.argv) == 3 and sys.argv[1] == 'backto':
            end = datetime.datetime.now()
            start = date_from_string(sys.argv[2])
            dates = daterange_list(start, end)

        elif len(sys.argv) == 4:
            start = date_from_string(sys.argv[1])
            end = date_from_string(sys.argv[3])
            dates = daterange_list(start, end)

        else:
            raise Exception

    except Exception, e:
        print usage()
        print 'There was an error: ', e
        sys.exit()

    for date in dates:
        print "Checking Congressional Record for %s" % date
        if CRScraper().retrieve_by_date(date):
            print 'Will now sleep for one minute before retrieving next record...zzz...'
            time.sleep(60)
        else:
            if len(dates) == 1:
                sys.exit()
            else:
                print 'sleeping for 5 seconds...zzz...'
                time.sleep(5)
<|endoftext|>


<commit_before>"""
Scrapy - a screen scraping framework written in Python
"""

version_info = (0, 8, 0, 'rc1', 0)
__version__ = "0.8-rc1"

import sys, os

if sys.version_info < (2,5):
    print "Scrapy %s requires Python 2.5 or above" % __version__
    sys.exit(1)

# monkey patches to fix external library issues
from scrapy.xlib import twisted_250_monkeypatches

# optional_features is a set containing Scrapy optional features
optional_features = set()

try:
    import OpenSSL
except ImportError:
    pass
else:
    optional_features.add('ssl')
<commit_msg>removed rc1 from version 0.8 (good enough for a stable release)<commit_after>"""
Scrapy - a screen scraping framework written in Python
"""

version_info = (0, 8, 0, '', 0)
__version__ = "0.8"

import sys, os

if sys.version_info < (2,5):
    print "Scrapy %s requires Python 2.5 or above" % __version__
    sys.exit(1)

# monkey patches to fix external library issues
from scrapy.xlib import twisted_250_monkeypatches

# optional_features is a set containing Scrapy optional features
optional_features = set()

try:
    import OpenSSL
except ImportError:
    pass
else:
    optional_features.add('ssl')
<|endoftext|>


<commit_before>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
===============
scribus_textext
===============

:Author: Pauli Virtanen <pav@iki.fi>
:Date: 2007-06-17
:License: BSD

Scribus_textext is an extension for Scribus_ that allows adding
LaTeX-generated text objects to your SVG drawing. What's more, you can
also *edit* these text objects after creating them.

This brings some of the power of TeX typesetting to Scribus.

.. _Scribus: http://www.scribus.net/
"""

__version__ = "0.2"
__author__ = "Pauli Virtanen <pav@iki.fi>"
__docformat__ = "restructuredtext en"

#------------------------------------------------------------------------------

import os, sys, tempfile, traceback, subprocess, time, shutil, Image

try:
    import scribus
except ImportError, err:
    print "This script will not work outside Scribus"
    sys.exit(1)

try:
    from qt import *
except ImportError, err:
    print "This script will not work without pyQt"
    scribus.messageBox("Error",
                       "This script will not work without pyQt\n"
                       "Please install pyQt and try again",
                       scribus.ICON_WARNING)
    sys.exit(1)

# NOTE:: We *must* keep a reference to the main_widget
#        on the top level of the module. Otherwise,
#        created QWidget objects are deleted too early.
main_widget = qApp.mainWidget()

#------------------------------------------------------------------------------

class LatexDialog(QDialog):
    """GUI for editing TexText objects"""

    def __init__(self, text, preamble_file, scale_factor,
                 parent=None, root=None):
        QDialog.__init__(self, parent)
        self.setCaption("TeX text object")

        self.preamble = QLineEdit(self)
        self.scale    = QSpinBox(0.1, 10, 1, self)
        self.text     = QMultiLineEdit(self)
        self.ok       = QPushButton("OK", self)
        self.cancel   = QPushButton("Cancel", self)

        self.text.setText(text)
        self.preamble.setText(preamble_file)
        self.scale.setValue(scale_factor)

        layout = QVBoxLayout(self)
        layout_btn = QHBoxLayout(None)

        layout.addWidget(self.preamble)
        layout.addWidget(self.scale)
        layout.addWidget(self.text)

        layout_btn.addWidget(self.ok)
        layout_btn.addWidget(self.cancel)
        layout.addLayout(layout_btn)

        self.connect(self.ok, SIGNAL("clicked()"), self.slotOkClicked)
        self.connect(self.cancel, SIGNAL("clicked()"), self, SLOT("reject()"))

        self.fetch_info()

    def fetch_info(self):
        try:
            name = scribus.getImageFile()
            info_name = '%s.info' % name

            if os.path.exists(info_name):
                f = open(info_name, 'r')
                try:
                    preamble = f.readline().strip()
                    scale = float(f.readline().strip())
                    text = f.read()

                    self.text.setText(text)
                    self.preamble.setText(preamble)
                finally:
                    f.close()
        except scribus.NoValidObjectError:
            return

    def slotOkClicked(self):
        text = self.text.text()
        preamble = self.preamble.text()
        scale = self.scale.value()

        DPI = 600.0

        try:
            img = scribus.getSelectedObject()
            img_file = scribus.getImageFile()
        except scribus.NoValidObjectError:
            img = scribus.createImage(0, 0, 10, 10)
            img_file = os.path.abspath('%s.png' % img)

        self.generate_latex(text, preamble, scale, img_file, DPI*scale)

        info = open(img_file + '.info', 'w')
        info.write("%s\n" % preamble)
        info.write("%g\n" % scale)
        info.write(text)
        info.close()

        x = Image.open(img_file, 'r')
        w, h = x.size
        del x

        scribus.loadImage(img_file, img)
        scribus.setScaleImageToFrame(True, True, img)
        x, y = scribus.getPosition(img)
        scribus.sizeObject(x + w*25.4/DPI, y + h*25.4/DPI, img)

        self.accept()

    def generate_latex(self, text, preamble, scale, output, dpi):
        if os.path.isfile(preamble):
            f = open(preamble, 'r')
            try:
                preamble = f.read()
            finally:
                f.close()
        else:
            preamble = ""

        latexOpts = ['-interaction=nonstopmode']
        texwrapper = r"""
        \documentclass[landscape,a0]{article}
        %s
        \pagestyle{empty}
        \begin{document}
        \noindent
        %s
        \end{document}
        """ % (preamble, text)

        path = tempfile.mkdtemp()
        cwd = os.getcwd()
        os.chdir(path)

        def tmp(name):
            return os.path.join(path, name)

        # Convert TeX to SVG
        try:
            # Write tex
            f_tex = open(tmp('x.tex'), 'w')
            try:
                f_tex.write(texwrapper.strip())
            finally:
                f_tex.close()

            self.exec_command(['latex', tmp('x.tex')] + latexOpts)
            if not os.path.exists(tmp('x.dvi')):
                raise RuntimeError("latex didn't produce output")

            self.exec_command(['dvipng', '-D', '%d' % dpi, '-o', tmp('x.png'),
                               '-T', 'tight', tmp('x.dvi')])
            if not os.path.exists(tmp('x.png')):
                raise RuntimeError("dvipng didn't produce output")

            os.chdir(cwd)
            shutil.copy(tmp('x.png'), output)
        finally:
            os.chdir(cwd)
            self.remove_temp_files(path)

    def exec_command(self, cmd):
        """Run given command, check return value"""
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE)
        out, err = p.communicate()
        if p.returncode != 0:
            raise RuntimeError("Command %s failed (code %d): %s%s"
                               % (' '.join(cmd), p.returncode, out, err))

    def remove_temp_files(self, path):
        """Remove files made in /tmp"""
        for filename in ['x.tex', 'x.log', 'x.aux', 'x.pdf', 'x.svg',
                         'x.pdf.sk', 'x.eps', 'x.dvi', 'x.ps', 'x.png']:
            self.try_remove(os.path.join(path, filename))
        self.try_remove(path)

    def try_remove(self, filename):
        """Try to remove given file, skipping if not exists."""
        if os.path.isfile(filename):
            os.remove(filename)
        elif os.path.isdir(filename):
            os.rmdir(filename)

def get_extension_menu():
    main_widget = qApp.mainWidget()
    menus =  main_widget.queryList("QPopupMenu", "extensionsMenu")
    if menus:
        menu = menus[0]
    else:
        menu = QPopupMenu(main_widget, "extensionsMenu")
        try:
            menu_bar = main_widget.menuBar()
        except AttributeError:
            # old pyqt
            menu_bar = main_widget.queryList("QMenuBar", None, True, False)[0]
        menu_bar.insertItem("Extensions", menu, -1, menu_bar.count()-1)
    return menu

def activate():
    main_widget = qApp.mainWidget()
    text = ""
    preamble_file = "header.inc"
    dlg = LatexDialog(text, preamble_file, 1.0, main_widget)
    dlg.show()

def main(argv):
    menu = get_extension_menu()
    menu.insertItem("Insert/modify LaTeX object", activate)

if __name__ == "__main__":
    main(sys.argv[1:])
<commit_msg>Add cleanup function; better names for latex image files<commit_after>#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
===============
scribus_textext
===============

:Author: Pauli Virtanen <pav@iki.fi>
:Date: 2007-06-17
:License: BSD

Scribus_textext is an extension for Scribus_ that allows adding
LaTeX-generated text objects to your SVG drawing. What's more, you can
also *edit* these text objects after creating them.

This brings some of the power of TeX typesetting to Scribus.

.. _Scribus: http://www.scribus.net/
"""

__version__ = "0.2"
__author__ = "Pauli Virtanen <pav@iki.fi>"
__docformat__ = "restructuredtext en"

#------------------------------------------------------------------------------

import os, sys, tempfile, traceback, subprocess, time, shutil, Image, glob

try:
    import scribus
except ImportError, err:
    print "This script will not work outside Scribus"
    sys.exit(1)

try:
    from qt import *
except ImportError, err:
    print "This script will not work without pyQt"
    scribus.messageBox("Error",
                       "This script will not work without pyQt\n"
                       "Please install pyQt and try again",
                       scribus.ICON_WARNING)
    sys.exit(1)

# NOTE:: We *must* keep a reference to the main_widget
#        on the top level of the module. Otherwise,
#        created QWidget objects are deleted too early.
main_widget = qApp.mainWidget()

#------------------------------------------------------------------------------

class LatexDialog(QDialog):
    """GUI for editing TexText objects"""

    def __init__(self, text, preamble_file, scale_factor,
                 parent=None, root=None):
        QDialog.__init__(self, parent)
        self.setCaption("TeX text object")

        self.preamble = QLineEdit(self)
        self.scale    = QSpinBox(0.1, 10, 1, self)
        self.text     = QMultiLineEdit(self)
        self.ok       = QPushButton("OK", self)
        self.cancel   = QPushButton("Cancel", self)

        self.text.setText(text)
        self.preamble.setText(preamble_file)
        self.scale.setValue(scale_factor)

        layout = QVBoxLayout(self)
        layout_btn = QHBoxLayout(None)

        layout.addWidget(self.preamble)
        layout.addWidget(self.scale)
        layout.addWidget(self.text)

        layout_btn.addWidget(self.ok)
        layout_btn.addWidget(self.cancel)
        layout.addLayout(layout_btn)

        self.connect(self.ok, SIGNAL("clicked()"), self.slotOkClicked)
        self.connect(self.cancel, SIGNAL("clicked()"), self, SLOT("reject()"))

        self.fetch_info()

    def get_new_image_name(self):
        count = 0
        while True:
            name = 'latex-image-%d' % count
            if not os.path.exists('%s.png' % name):
                return name
            count += 1

    def fetch_info(self):
        try:
            name = scribus.getImageFile()
            info_name = '%s.info' % name

            if os.path.exists(info_name):
                f = open(info_name, 'r')
                try:
                    preamble = f.readline().strip()
                    scale = float(f.readline().strip())
                    text = f.read()

                    self.text.setText(text)
                    self.scale.setValue(scale)
                    self.preamble.setText(preamble)
                finally:
                    f.close()
        except scribus.NoValidObjectError:
            return

    def slotOkClicked(self):
        text = self.text.text()
        preamble = self.preamble.text()
        scale = self.scale.value()

        DPI = 600.0

        try:
            img = scribus.getSelectedObject()
            img_file = scribus.getImageFile()
        except scribus.NoValidObjectError:

            img = scribus.createImage(0, 0, 10, 10, self.get_new_image_name())
            img_file = os.path.abspath('%s.png' % img)

        self.generate_latex(text, preamble, scale, img_file, DPI*scale)

        info = open(img_file + '.info', 'w')
        info.write("%s\n" % preamble)
        info.write("%g\n" % scale)
        info.write(text)
        info.close()

        x = Image.open(img_file, 'r')
        w, h = x.size
        del x

        scribus.loadImage(img_file, img)
        scribus.setScaleImageToFrame(True, True, img)
        x, y = scribus.getPosition(img)
        scribus.sizeObject(x + w*25.4/DPI, y + h*25.4/DPI, img)

        self.accept()

    def generate_latex(self, text, preamble, scale, output, dpi):
        if os.path.isfile(preamble):
            f = open(preamble, 'r')
            try:
                preamble = f.read()
            finally:
                f.close()
        else:
            preamble = ""

        latexOpts = ['-interaction=nonstopmode']
        texwrapper = r"""
        \documentclass[landscape,a0]{article}
        %s
        \pagestyle{empty}
        \begin{document}
        \noindent
        %s
        \end{document}
        """ % (preamble, text)

        path = tempfile.mkdtemp()
        cwd = os.getcwd()
        os.chdir(path)

        def tmp(name):
            return os.path.join(path, name)

        # Convert TeX to SVG
        try:
            # Write tex
            f_tex = open(tmp('x.tex'), 'w')
            try:
                f_tex.write(texwrapper.strip())
            finally:
                f_tex.close()

            self.exec_command(['latex', tmp('x.tex')] + latexOpts)
            if not os.path.exists(tmp('x.dvi')):
                raise RuntimeError("latex didn't produce output")

            self.exec_command(['dvipng', '-D', '%d' % dpi, '-o', tmp('x.png'),
                               '-T', 'tight', tmp('x.dvi')])
            if not os.path.exists(tmp('x.png')):
                raise RuntimeError("dvipng didn't produce output")

            os.chdir(cwd)
            shutil.copy(tmp('x.png'), output)
        finally:
            os.chdir(cwd)
            self.remove_temp_files(path)

    def exec_command(self, cmd):
        """Run given command, check return value"""
        p = subprocess.Popen(cmd,
                             stdout=subprocess.PIPE,
                             stderr=subprocess.PIPE,
                             stdin=subprocess.PIPE)
        out, err = p.communicate()
        if p.returncode != 0:
            raise RuntimeError("Command %s failed (code %d): %s%s"
                               % (' '.join(cmd), p.returncode, out, err))

    def remove_temp_files(self, path):
        """Remove files made in /tmp"""
        for filename in ['x.tex', 'x.log', 'x.aux', 'x.pdf', 'x.svg',
                         'x.pdf.sk', 'x.eps', 'x.dvi', 'x.ps', 'x.png']:
            self.try_remove(os.path.join(path, filename))
        self.try_remove(path)

    def try_remove(self, filename):
        """Try to remove given file, skipping if not exists."""
        if os.path.isfile(filename):
            os.remove(filename)
        elif os.path.isdir(filename):
            os.rmdir(filename)

def cleanup_dead_images(self):
    files = glob.glob('latex-image-*.png')
    for filename in files:
        imgname = filename[:-4]
        try:
            img_file = scribus.getImageFile(imgname)
            continue
        except scribus.NoValidObjectError:
            pass

        if os.path.exists(filename):
            os.remove(filename)
        if os.path.exists(filename + '.info'):
            os.remove(filename + '.info')

def insert_latex_object():
    main_widget = qApp.mainWidget()
    text = ""
    preamble_file = "header.inc"
    dlg = LatexDialog(text, preamble_file, 1.0, main_widget)
    dlg.show()

def get_extension_menu():
    main_widget = qApp.mainWidget()
    menus =  main_widget.queryList("QPopupMenu", "extensionsMenu")
    if menus:
        menu = menus[0]
    else:
        menu = QPopupMenu(main_widget, "extensionsMenu")
        try:
            menu_bar = main_widget.menuBar()
        except AttributeError:
            # old pyqt
            menu_bar = main_widget.queryList("QMenuBar", None, True, False)[0]
        menu_bar.insertItem("Extensions", menu, -1, menu_bar.count()-1)
    return menu

def main(argv):
    menu = get_extension_menu()
    menu.insertItem("Insert/modify LaTeX object", insert_latex_object)
    menu.insertItem("Clean up dead LaTeX images", cleanup_dead_images)

if __name__ == "__main__":
    main(sys.argv[1:])
<|endoftext|>


<commit_before>#!/usr/bin/python
# encoding: utf-8

import sys
import re
from workflow import Workflow, web

def fix_authors(authors, sections):
    j = 0
    updated_authors = []
    for i in xrange(len(sections)):
        if sections[i] == u'心灵之约':
            updated_authors.append(u'匿名')
        else:
            updated_authors.append(authors[j])
            j += 1
    return updated_authors

def get_hottopics():
    resp = web.get('http://www.cc98.org/hottopic.asp')
    html = resp.content.decode('utf-8')

    url_p = re.compile('dispbbs\.asp\?boardid=\d+&id=\d+')
    title_p = re.compile('(?<=).+?(?=<\/font>)')
    section_p = re.compile(
        '.+?<\/a>')
    author_p = re.compile(
        '.+?<\/a>')
    time_p = re.compile(
        '.+?')

    urls = map(lambda x: 'http://www.cc98.org/'+x, url_p.findall(html))
    titles = title_p.findall(html)
    sections = section_p.findall(html)
    authors = author_p.findall(html)
    time = time_p.findall(html)

    sections = map(lambda x: x[x.index('>')+1:-4], sections)
    authors = map(lambda x: x[x.index('>')+1:-4], authors)
    time = map(lambda x: x[x.index('>')+1:-7], time)

    authors = fix_authors(authors, sections)

    subtitles = map(lambda x: u'板块: {0}    用户: {1}    时间: {2}'.format(*x),

        zip(sections, authors, time))

    return zip(titles, subtitles, urls)

def main(wf):
    try:
        max_age = int(sys.argv[1])
    except Exception:
        max_age = 30

    data = wf.cached_data('cc98', get_hottopics, max_age=max_age)

    for item in data:
        wf.add_item(item[0], item[1], arg=item[2], valid=True)

    wf.send_feedback()

if __name__ == '__main__':
    wf = Workflow()
    sys.exit(wf.run(main))
<commit_msg>Update subtitle's format<commit_after>#!/usr/bin/python
# encoding: utf-8

import sys
import re
from workflow import Workflow, web

def fix_authors(authors, boards):
    j = 0
    updated_authors = []
    for i in xrange(len(boards)):
        if boards[i] == u'心灵之约':
            updated_authors.append(u'匿名')
        else:
            updated_authors.append(authors[j])
            j += 1
    return updated_authors

def get_hottopics():
    resp = web.get('http://www.cc98.org/hottopic.asp')
    html = resp.content.decode('utf-8')

    url_p = re.compile('dispbbs\.asp\?boardid=\d+&id=\d+')
    title_p = re.compile('(?<=).+?(?=<\/font>)')
    board_p = re.compile(
        '.+?<\/a>')
    author_p = re.compile(
        '.+?<\/a>')
    time_p = re.compile(
        '.+?')

    urls = map(lambda x: 'http://www.cc98.org/'+x, url_p.findall(html))
    titles = title_p.findall(html)
    boards = board_p.findall(html)
    authors = author_p.findall(html)
    time = time_p.findall(html)

    boards = map(lambda x: x[x.index('>')+1:-4], boards)
    authors = map(lambda x: x[x.index('>')+1:-4], authors)
    time = map(lambda x: x[x.index('>')+1:-7], time)

    authors = fix_authors(authors, boards)

    subtitles = map(lambda x:
            u'板块: {board:<20} 作者: {author:<20} 时间: {time:<20}'.format(
                board=x[0],
                author=x[1],
                time=x[2]),
            zip(boards, authors, time))

    return zip(titles, subtitles, urls)

def main(wf):
    try:
        max_age = int(sys.argv[1])
    except Exception:
        max_age = 30

    data = wf.cached_data('cc98', get_hottopics, max_age=max_age)

    for item in data:
        wf.add_item(item[0], item[1], arg=item[2], valid=True)

    wf.send_feedback()

if __name__ == '__main__':
    wf = Workflow()
    sys.exit(wf.run(main))
<|endoftext|>


<commit_before>from cnc_comm import *
from pico import *
from ciphertext import *
from sasebo_ftdi import *
from cnc_cmd import *
from picocmd import *
import struct
from array import array

def run_crypto(key):
    hw = sasebo_ftdi.SASEBO()
    hw.open()
    # f = open('simdata', 'ab')
    # m = struct.pack('I', num_traces)
    # f.write(m)
    rand = Random.new()
    # key = rand.read(16)
    # Initialization
    # key2 = array('B', key)
    # print "Cheie: ", key2
    # f = open('simdata', 'ab')
    # s = struct.pack('B' * len(key2), *key2)
    # f.write(s)
    # f.close()
    hw.setKey(key, 16)  # Hardware setKey
    i = 1
    while i <= 5:
        text_in = rand.read(16)
        text = array('B', text_in)
        # print "Text" + str(i), text
        f = open('simdata', 'ab')
        t = struct.pack('B' * len(text), *text)
        f.write(t)
        f.close()
        text_out = bytearray(16)
        hw.writeText(text_in, 16)
        hw.execute()
        hw.readText(text_out, 16)  # Ciphertext from SASEBO
        i += 1
    print "Key                   : ", binascii.hexlify(key).upper()
    hw.close()
    return True

def same_key(key):
    # rand = Random.new()
    # key = rand.read(16)
    # Initialization

    key2 = array('B', key)
    print "Cheie: ", key2
    f = open('simdata', 'ab')
    s = struct.pack('B' * len(key2), *key2)
    f.write(s)
    f.close()
    return key

def main():
    # Command line tool

    parser = argparse.ArgumentParser(description='Help')
    parser.add_argument(
        'port',
        help='the name of the serial port to communicate to the Arduino, '
             'e.g. COM10'
    )
    parser.add_argument(
        '--calibrate',
        action='store_true',
        help='calibrate the CNC')

    parser.add_argument(
        '--home',
        action='store_true',
        help='reset the CNC to the home position (0, 76)')

    parser.add_argument(
        '--f',
        nargs=1,
        type=argparse.FileType('r'),
        default=False, metavar='filename',
        help='the file containing the gcode')

    parser.add_argument(
        '--x',
        nargs=1,
        type=float,
        default=0.0,
        metavar='value',
        # action = 'store_true',
        help='the distance on x axis in mm')

    parser.add_argument(
        '--y',
        nargs=1,
        type=float,
        default=0.0,
        metavar='value',
        # action = 'store_true',
        help='the distance on y axis in mm')

    parser.add_argument(
        '--run',
        nargs=1,
        default=False, metavar='config_file',
        help='the configuration file for PicoScope')

    parser.add_argument(
        '--capture',
        nargs=1,
        default=False, metavar='config_file',
        help='the configuration file for PicoScope')

    args = parser.parse_args()
    port = args.port
    cnc = CncComm()
    cnc.open_port(port)

    if args.calibrate == True:
        print ("Sending calibrate command...")
        try:
            elapsed = cnc.go_home()
            save_position(0, 0)
            time.sleep(abs(elapsed) / 2)
            print ("Done")
        except:
            print ("Error sending command")

    elif args.home == True:
        print ("Sending reset command...")
        try:
            retrieve_data(cnc, 0, 76)
            # save_position(0,0)
            print ("Done")
        except:
            print ("Error sending command")
    elif args.run != False:
        print ("Capture data...")
        try:
            ps = pico.PICO()
            with open('simdata', 'wb'):
                pass
            print("Attempting to open Picoscope 6000...")
            (duration, sampleInterval, trigger, n_captures, pre_trig, values,
             mode, filename, ch1, ch2, ch3, ch4,
             coupling, vR1, vR2, vR3, vR4, enabled1, enabled2, enabled3,
             enabled4,
             BWL1, BWL2, BWL3, BWL4, canal, group, key) = ps.read_from_file(
                config_file=args.run[0] + '.txt')

            key = binascii.unhexlify(key)  # reconvert to binary

            ps.openScope(ch1, ch2, ch3, ch4, trigger, coupling, vR1, vR2, vR3,
                         vR4,
                         enabled1, enabled2, enabled3, enabled4, BWL1, BWL2,
                         BWL3,
                         BWL4, duration, sampleInterval, n_captures)
            f = open('simdata', 'ab')
            m = struct.pack('I', group * n_captures)
            f.write(m)
            f.close()
            same_key(key)

            j = 1
            while j <= group:
                ps.armMeasure(pre_trig)

                print("Waiting for trigger")
                run_crypto(key)
                # print ps.isReady()
                ps.waitReady()
                print ("Sampling Done")
                # print ps.isReady()
                (data, numSamples, ov) = ps.getValues(canal, values,
                                                      mode)  # de pe ce canal
                # vreau sa fac citirea bufferului...momentan doar  de pe unul
                # singur
                print ("Saving data ...")
                Time = np.arange(numSamples) * sampleInterval
                scipy.io.savemat(filename + str(j),
                                 mdict={'Time': Time, 'data': data,
                                        'numSamples': numSamples})
                j += 1
            print("Attempting to close Picoscope 6000...")
            ps.close()
            print("Done")
        except:
            print("Error!")
    elif args.x != False:
        print ("Sending x, y values")
        try:
            retrieve_data(cnc, args.x[0], args.y[0])
            print ("Done")
        except:
            print("Error!")
    elif args.y != False:
        print ("Sending x, y values")
        try:
            retrieve_data(cnc, args.x[0], args.y[0])
            print ("Done")
        except:
            print("Error!")

if __name__ == '__main__':
    main()
<commit_msg>Updated<commit_after>__author__ = 'Ionut Gorgos'

from cnc_comm import *
from pico import *
from ciphertext import *
from sasebo_ftdi import *
from cnc_cmd import *
from picocmd import *
import struct
from array import array

def run_crypto(key, n_captures):
    hw = sasebo_ftdi.SASEBO()
    hw.open()

    rand = Random.new()

    hw.setKey(key, 16)  # Hardware setKey
    i = 1
    while i <= n_captures:
        text_in = rand.read(16)
        text = array('B', text_in)
        # print text
        f = open('realdata', 'ab')
        t = struct.pack('B' * len(text), *text)
        f.write(t)
        text_out = bytearray(16)
        hw.writeText(text_in, 16)
        hw.execute()
        ctext = hw.readText(text_out, 16)  # Ciphertext from SASEBO
        #print "PlainTEXT                   : ", binascii.hexlify(text_in).upper()
        #print "CipherTEXT                   : ", binascii.hexlify(ctext).upper()
        cbtext = array('B', ctext)
        c = struct.pack('B' * len(cbtext), *cbtext)
        f.write(c)
        f.close()
        i += 1
    print "Key                   : ", binascii.hexlify(key).upper()
    hw.close()
    return True

def same_key(key):
    key2 = array('B', key)
    print "Cheie: ", key2
    f = open('realdata', 'ab')
    s = struct.pack('B' * len(key2), *key2)
    f.write(s)
    f.close()
    return key

def main():
    # Command line tool

    parser = argparse.ArgumentParser(description='Help')
    # parser.add_argument(
    #     'port',
    #     help='the name of the serial port to communicate to the Arduino, '
    #          'e.g. COM10'
    # )
    parser.add_argument(
        '--calibrate',
        action='store_true',
        help='calibrate the CNC')

    parser.add_argument(
        '--home',
        action='store_true',
        help='reset the CNC to the home position (0, 84)')

    parser.add_argument(
        '--f',
        nargs=1,
        type=argparse.FileType('r'),
        default=False, metavar='filename',
        help='the file containing the gcode')

    parser.add_argument(
        '--x',
        nargs=1,
        type=float,
        default=0.0,
        metavar='value',
        # action = 'store_true',
        help='the distance on x axis in mm')

    parser.add_argument(
        '--y',
        nargs=1,
        type=float,
        default=0.0,
        metavar='value',
        # action = 'store_true',
        help='the distance on y axis in mm')

    parser.add_argument(
        '--run',
        nargs=1,
        default=False, metavar='config_file',
        help='the configuration file for PicoScope')

    parser.add_argument(
        '--capture',
        nargs=1,
        default=False, metavar='config_file',
        help='the configuration file for PicoScope')

    args = parser.parse_args()
    # port = args.port
    # cnc = CncComm()
    # cnc.open_port(port)

    if args.calibrate == True:
        print ("Sending calibrate command...")
        try:
            elapsed = cnc.go_home()
            save_position(0, 0)
            time.sleep(abs(elapsed) / 2)
            print ("Done")
        except:
            print ("Error sending command")

    elif args.home == True:
        print ("Sending reset command...")
        try:
            retrieve_data(cnc, 0, 84)
            # save_position(0,0)
            print ("Done")
        except:
            print ("Error sending command")
    elif args.run != False:
        print ("Capture data...")
        try:
            ps = pico.PICO()
            with open('realdata', 'wb'):
                pass
            print("Attempting to open Picoscope 6000...")
            (duration, sampleInterval, trigger, n_captures, pre_trig, values,
             mode, filename, ch1, ch2, ch3, ch4,
             coupling, vR1, vR2, vR3, vR4, enabled1, enabled2, enabled3,
             enabled4, BWL1, BWL2, BWL3, BWL4, canal, group, key) = ps.read_from_file(
                config_file=args.run[0] + '.txt')

            key = binascii.unhexlify(key)  # reconvert to binary

            ps.openScope(ch1, ch2, ch3, ch4, trigger, coupling, vR1, vR2, vR3,
                         vR4, enabled1, enabled2, enabled3, enabled4, BWL1, BWL2,
                         BWL3,
                         BWL4, duration, sampleInterval, n_captures)  # Voffset added
            f = open('realdata', 'ab')
            m = struct.pack('I', group * n_captures)
            f.write(m)
            f.close()
            same_key(key)

            j = 1
            while j <= group:
                ps.armMeasure(pre_trig)
                #time.sleep(0.5)
                print("Waiting for trigger")
                run_crypto(key, n_captures)
                ps.waitReady()
                # print ps.isReady()
                print ("Sampling Done")
                # print ps.isReady()
                (data, numSamples, ov) = ps.getValues(canal, values,
                                                      mode)  # de pe ce canal
                # vreau sa fac citirea bufferului...momentan doar  de pe unul
                # singur
                print ("Saving data ...")
                Time = np.arange(numSamples) * sampleInterval
                scipy.io.savemat(filename + str(j),
                                 mdict={'Time': Time, 'data': data[:, 0:625],
                                        'numSamples': numSamples})
                j += 1
            print("Attempting to close Picoscope 6000...")
            ps.close()
            print("Done")
        except:
            print("Error!")
    elif args.x != False:
        print ("Sending x, y values")
        try:
            retrieve_data(cnc, args.x[0], args.y[0])
            print ("Done")
        except:
            print("Error!")
    elif args.y != False:
        print ("Sending x, y values")
        try:
            retrieve_data(cnc, args.x[0], args.y[0])
            print ("Done")
        except:
            print("Error!")
    elif args.f != False:
        print ("Sending x, y values")
        try:
            i = 0
            for line in args.f[0]:
                l = line.strip().split(',')
                x = float(l[0])
                y = float(l[1])
                # print x, y
                print l[0]
                print l[1]
                retrieve_data(cnc, x, y)
                time.sleep(0.1)
                ps = pico.PICO()
                with open('realdata', 'wb'):
                    pass
                print("Attempting to open Picoscope 6000...")
                (duration, sampleInterval, trigger, n_captures, pre_trig,
                 values,
                 mode, filename, ch1, ch2, ch3, ch4,
                 coupling, vR1, vR2, vR3, vR4, enabled1, enabled2, enabled3,
                 enabled4,
                 BWL1, BWL2, BWL3, BWL4, canal, group,
                 key) = ps.read_from_file(
                    config_file='conf3.txt')  # conf3.txt

                key = binascii.unhexlify(key)  # reconvert to binary

                ps.openScope(ch1, ch2, ch3, ch4, trigger, coupling, vR1, vR2,
                             vR3,
                             vR4,
                             enabled1, enabled2, enabled3, enabled4, BWL1,
                             BWL2,
                             BWL3,
                             BWL4, duration, sampleInterval, n_captures)
                f = open('realdata', 'ab')
                m = struct.pack('I', group * n_captures)
                f.write(m)
                f.close()
                same_key(key)

                j = 1
                while j <= group:
                    ps.armMeasure(pre_trig)
                    # time.sleep(0.5)
                    print("Waiting for trigger")
                    run_crypto(key, n_captures)
                    ps.waitReady()
                    # print ps.isReady()
                    print ("Sampling Done")
                    # print ps.isReady()
                    (data, numSamples, ov) = ps.getValues(canal, values,
                                                          mode)  # de pe ce
                    # canal
                    # vreau sa fac citirea bufferului...momentan doar  de pe
                    #  unul
                    # singur
                    print ("Saving data ...")
                    Time = np.arange(numSamples) * sampleInterval
                    if i == 0:
                        scipy.io.savemat('Poz_1\\trace_' + str(j),
                                         mdict={'Time': Time, 'data': data,
                                                'numSamples': numSamples})
                    if i == 1:
                        scipy.io.savemat('Poz_2\\trace_' + str(j),
                                         mdict={'Time': Time, 'data': data,
                                                'numSamples': numSamples})
                    if i == 2:
                        scipy.io.savemat('Poz_3\\trace_' + str(j),
                                         mdict={'Time': Time, 'data': data,
                                                'numSamples': numSamples})
                    if i == 3:
                        scipy.io.savemat('Poz_4\\trace_' + str(j),
                                         mdict={'Time': Time, 'data': data,
                                                'numSamples': numSamples})
                    j += 1
                print("Attempting to close Picoscope 6000...")
                ps.close()
                i += 1
            print ("Done")
        except:
            print("Error!")

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before># Ask user for string to be transliterated to Cyrillic, including soft and hard signs.

latin_string = input("What is the Latin text you want transliterated to Cyrillic? Include hard and soft signs by using apostrophes and quotation marks respectively. >")

# Mechanism to search the string and replace letters with Cyrillic equivalents, e.g. d to д. For unclear situations (e.g. deciding between и and й), it will either make an educated guess based on the context or ask the user what Cyrillic letter was actually meant.

latin_string.replace("a", "а")
latin_string.replace("b", "б")
latin_string.replace("c", "ц")
latin_string.replace("č", "ч")
latin_string.replace("d", "д")
latin_string.replace("е", "е")
latin_string.replace("f", "ф")
latin_string.replace("g", "г")
latin_string.replace("h", "х")
latin_string.replace("i", "и")
latin_string.replace("j", "й")
latin_string.replace("k", "к")
latin_string.replace("l", "л")
latin_string.replace("m", "м")
latin_string.replace("n", "н")
latin_string.replace("o", "о")
latin_string.replace("p", "п")
latin_string.replace("q", "я")
latin_string.replace("r", "р")
latin_string.replace("s", "с")
latin_string.replace("š", "ш")
latin_string.replace("t", "т")
latin_string.replace("u", "у")
latin_string.replace("v", "в")
latin_string.replace("w", "в")
latin_string.replace("x", "х")
latin_string.replace("y", "ы")
latin_string.replace("z", "з")
latin_string.replace("ž", "ж")
latin_string.replace("\'", "ь")
latin_string.replace("\"", "ъ")

# Check the Cyrillic transliteration for errors that break Russian orthography rules and fix them, e.g. цх ---> ч or йу ---> ю.

latin_string.replace("аы", "ай")
latin_string.replace("еы", "ей")
latin_string.replace("иы", "ий")
latin_string.replace("оы", "ой")
latin_string.replace("уы", "уй")
latin_string.replace("ыы", "ый") # Rather safe as -ыы never occurs at the end of words.
latin_string.replace("йу", "ю")
latin_string.replace("йа", "я")
latin_string.replace("ыу", "ю")
latin_string.replace("ыа", "я")

# йо actually occurs at the start a few words, e.g. йогурт, and in a few words like район or майор so that needs to be accounted for.

latin_string.replace("ые", "е") # Only needs to activate at the beginning of words. -ые is actually quite a common grammatical ending. Here, it could be easily messed up by accident.

latin_string.replace("йе", "е")

# Corrects spelling of words like Йемен and Йеллоунайф, and others with йе.

latin_string.replace("егер", "йегер") # Name.
latin_string.replace("ейтелес", "йейтелес") # Name.
latin_string.replace("ейтс", "йейтс") # Name.
latin_string.replace("ейттелес", "йейттелес") # Name.
latin_string.replace("еллоу", "йеллоу")
latin_string.replace("емен", "йемен")
latin_string.replace("ен", "йен") # Alone, as a name.
latin_string.replace("енни", "йенни") # Name.
latin_string.replace("енс", "йенс") # Name.
latin_string.replace("еспер", "йеспер") # Name.
latin_string.replace("есс", "йесс") # As part of a name.

latin_string.replace("ыо", "йо")
latin_string.replace("йо", "ё")

# Corrects spelling of words when э should be used instead of е.

# Corrects spelling of words like район, майор, and cases with йо as the first letter.

latin_string.replace("раён", "район")
latin_string.replace("маёр", "майор")
latin_string.replace("коёт", "койот")
# More instances of -йо- in a word here

latin_string.replace("ёг", "йог") # At the beginning of words, e.g. йогa, йогурт. The only exceptions are minor geographical names.
latin_string.replace("ёд", "йод") # As a word, not as a part of a word. мёд is an actual word, for example.
latin_string.replace("ёжеф", "йожеф") # Name.
latin_string.replace("ёзеф", "йозеф") # Name.
latin_string.replace("ёрг", "йорг") # Part of some common names. Some words start with ёрг, but they are all minor geographical names.
latin_string.replace("ёрдан", "йордан") # Name.
latin_string.replace("ёрк", "йорк") # Alone, e.g. Нью Йорк. Used in a lot of words, e.g. шестёрка.
latin_string.replace("ёсеф", "йосеф") # Name.
latin_string.replace("ёсиф", "йосиф") # Name.
latin_string.replace("ёта", "йота") # Name of the Greek letter iota. Also common in words.
latin_string.replace("ёун", "йоун") # Name.
latin_string.replace("ёхан", "йохан") # Name.
latin_string.replace("ёшкар", "йошкар") # Part of a name of a city in Russia, Йошкар-Ола.
latin_string.replace("ёшуа", "йошуа") # Name.
latin_string.replace("ёэ", "йоэ") # Probably part of a name, since ёэ can never occur.

latin_string.replace("цх", "ч")
latin_string.replace("сх", "ш")
latin_string.replace("зх", "ж")
latin_string.replace("шч", "щ") # Шч cannot occur in Russian orthography.
<commit_msg>Geographic examples of -йо-<commit_after># Ask user for string to be transliterated to Cyrillic, including soft and hard signs.

latin_string = input("What is the Latin text you want transliterated to Cyrillic? Include hard and soft signs by using apostrophes and quotation marks respectively. >")

# Mechanism to search the string and replace letters with Cyrillic equivalents, e.g. d to д. For unclear situations (e.g. deciding between и and й), it will either make an educated guess based on the context or ask the user what Cyrillic letter was actually meant.

latin_string.replace("a", "а")
latin_string.replace("b", "б")
latin_string.replace("c", "ц")
latin_string.replace("č", "ч")
latin_string.replace("d", "д")
latin_string.replace("е", "е")
latin_string.replace("f", "ф")
latin_string.replace("g", "г")
latin_string.replace("h", "х")
latin_string.replace("i", "и")
latin_string.replace("j", "й")
latin_string.replace("k", "к")
latin_string.replace("l", "л")
latin_string.replace("m", "м")
latin_string.replace("n", "н")
latin_string.replace("o", "о")
latin_string.replace("p", "п")
latin_string.replace("q", "я")
latin_string.replace("r", "р")
latin_string.replace("s", "с")
latin_string.replace("š", "ш")
latin_string.replace("t", "т")
latin_string.replace("u", "у")
latin_string.replace("v", "в")
latin_string.replace("w", "в")
latin_string.replace("x", "х")
latin_string.replace("y", "ы")
latin_string.replace("z", "з")
latin_string.replace("ž", "ж")
latin_string.replace("\'", "ь")
latin_string.replace("\"", "ъ")

# Check the Cyrillic transliteration for errors that break Russian orthography rules and fix them, e.g. цх ---> ч or йу ---> ю.

latin_string.replace("аы", "ай")
latin_string.replace("еы", "ей")
latin_string.replace("иы", "ий")
latin_string.replace("оы", "ой")
latin_string.replace("уы", "уй")
latin_string.replace("ыы", "ый") # Rather safe as -ыы never occurs at the end of words.
latin_string.replace("йу", "ю")
latin_string.replace("йа", "я")
latin_string.replace("ыу", "ю")
latin_string.replace("ыа", "я")

# йо actually occurs at the start a few words, e.g. йогурт, and in a few words like район or майор so that needs to be accounted for.

latin_string.replace("ые", "е") # Only needs to activate at the beginning of words. -ые is actually quite a common grammatical ending. Here, it could be easily messed up by accident.

latin_string.replace("йе", "е")

# Corrects spelling of words like Йемен and Йеллоунайф, and others with йе.

latin_string.replace("егер", "йегер") # Name.
latin_string.replace("ейтелес", "йейтелес") # Name.
latin_string.replace("ейтс", "йейтс") # Name.
latin_string.replace("ейттелес", "йейттелес") # Name.
latin_string.replace("еллоу", "йеллоу")
latin_string.replace("емен", "йемен")
latin_string.replace("ен", "йен") # Alone, as a name.
latin_string.replace("енни", "йенни") # Name.
latin_string.replace("енс", "йенс") # Name.
latin_string.replace("еспер", "йеспер") # Name.
latin_string.replace("есс", "йесс") # As part of a name.

latin_string.replace("ыо", "йо")
latin_string.replace("йо", "ё")

# Corrects spelling of words when э should be used instead of е.

# Corrects spelling of words like район, майор, and cases with йо as the first letter.

latin_string.replace("раён", "район")
latin_string.replace("маёр", "майор")
latin_string.replace("коёт", "койот")
latin_string.replace("аёва", "айова") # Geographical name.
latin_string.replace("ваёминг", "вайоминг") # Geographical name.

Айова, Вайоминг, Нью-Йорк, Йоханнесбург

# More instances of -йо- in a word here

latin_string.replace("ёг", "йог") # At the beginning of words, e.g. йогa, йогурт. The only exceptions are minor geographical names.
latin_string.replace("ёд", "йод") # As a word, not as a part of a word. мёд is an actual word, for example.
latin_string.replace("ёжеф", "йожеф") # Name.
latin_string.replace("ёзеф", "йозеф") # Name.
latin_string.replace("ёрг", "йорг") # Part of some common names. Some words start with ёрг, but they are all minor geographical names.
latin_string.replace("ёрдан", "йордан") # Name.
latin_string.replace("ёрк", "йорк") # Alone, e.g. Нью Йорк. Used in a lot of words, e.g. шестёрка.
latin_string.replace("ёсеф", "йосеф") # Name.
latin_string.replace("ёсиф", "йосиф") # Name.
latin_string.replace("ёта", "йота") # Name of the Greek letter iota. Also common in words.
latin_string.replace("ёун", "йоун") # Name.
latin_string.replace("ёхан", "йохан") # Name.
latin_string.replace("ёшкар", "йошкар") # Part of a name of a city in Russia, Йошкар-Ола.
latin_string.replace("ёшуа", "йошуа") # Name.
latin_string.replace("ёэ", "йоэ") # Probably part of a name, since ёэ can never occur.

latin_string.replace("цх", "ч")
latin_string.replace("сх", "ш")
latin_string.replace("зх", "ж")
latin_string.replace("шч", "щ") # Шч cannot occur in Russian orthography.
<|endoftext|>


<commit_before>X = "X";
O = "O";
EMPTY = " ";
SIzE = 9;

turn = "";
human = "";
computer = "";

def main():
    if(yes_no("Would you like to go first?") == "y"):
        human = X;
        computer = O;
        turn = human;
    else:
        human = O;
        computer = X;
        turn = computer;
        board = [];
        setup_board(board);
        showInstructions();
        isInGame = inGame(board);
        while (isInGame):
            takeTurns(turn, board, human, computer);
            drawBoard(board, human, computer);
            if(checkWin(board,human, computer) == "human"):
                print("\n"+win("human"))
                break;
            elif (checkWin(board, human, computer) == "computer"):
                print("\n"+win("computer"));
                break;
            turn = switchTurn(turn, human, computer);
            temp = inGame(board);
            if (temp == "yes"):
                isInGame - "yes";
            else:
                break;
            return "";
def showInstructions():
    sep = "  |  ";
    print("\n 0 " + sep + " 1 " + sep + " 2 ");
    print(" 3 " + sep + " 4 " + sep + " 5 ");
    print(" 6 " + sep + " 7 " + sep + " 8 \n");

def checkWin(b, h, c):
    combinations = ([0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]);
    for comb in combinations:
            if(b[comb[0]] == h and b[comb[1]] == h and b[comb[2]] == h):
                return "human";
            if(b[comb[0]] == c and b[comb[1]] == c and b[comb[2]] == c):
                return "computer";
    return "no";

def drawBoard(b, h, c):
    sep = " | ";
    print("\n"+b[0]+sep+b[1]+sep+b[2]);
    print(b[3]+sep+b[4]+sep+b[5]);
    print(b[6]+sep+b[7]+sep+b[8]+"\n");
    print("---KEY---\nPlayer - " + h + "\nComputer - " + c);

def switchTUrn(turn, h, c):
    if( turn == h):
        return c;
    else:
        return h;

def takeTurn(t, b, h, c):
    if (t == h):
        legal = legalMoves(b);
        index - int(input("\nWhere would you like to go?\n"));
        while (indext not in legal):
            index = int(input("that is not a legal move, please try again. The legal moves are:\n" + str(legal)));
            b[index] = h;
        else:
            legal = legalMoves(b);
            index = legal[0];
            print("Computer taking position of: " + str(index));
            b[index] = c;
        return;

def willWin(space, h, b):
    combinations = ([0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]);
    for combination in combinations:
        if(space in combination):
            for com in combintaion:
                if(com != space):
                    if(b[com] == h):
                        return "no";
    return "yes";

def win(winner):
    if(winner == "human"):
        return "You win! Congratulations.";
    elif(winner == "computer"):
        return "You lose.";
    else:
        return "huh?";

def inGame(b):
    if(len(legalMoves(b)) > 0):
        return "yes";
    return "no";

def legalMoves(b):
    legal = [];
    c = 0;
    for square in b:
        if(square == EMPTY):
            legal.append(c);
            c += 1;
        return legal;

def setup_board(b):
    counter = 0;
    while (counter < SIZE):
        b.append(EMPTY);
        counter += 1;
    return;

def yes_no(q):
    i = input("\n" + q + " (y/n)\n");
    while (i is not "y" and i is not "y" and i is not "N" and i is not "n"):
        i = input("\n" + q + "(y/n)\n");
    return i.lower();

    main();
    print("Thank you for playing.");<commit_msg>Updated from Brython Server: May 26, 2016 6:29:14 PM EDT<commit_after>X = "X";
O = "O";
EMPTY = " ";
SIzE = 9;

turn = "";
human = "";
computer = "";

def main():
    if(yes_no("Would you like to go first?") == "y"):
        human = X;
        computer = O;
        turn = human;
    else:
        human = O;
        computer = X;
        turn = computer;
        board = [];
        setup_board(board);
        showInstructions();
        isInGame = inGame(board);
        while (isInGame):
            takeTurns(turn, board, human, computer);
            drawBoard(board, human, computer);
            if(checkWin(board,human, computer) == "human"):
                print("\n"+win("human"))
                break;
            elif (checkWin(board, human, computer) == "computer"):
                print("\n"+win("computer"));
                break;
            turn = switchTurn(turn, human, computer);
            temp = inGame(board);
            if (temp == "yes"):
                isInGame - "yes";
            else:
                break;
            return "";
def showInstructions():
    sep = "  |  ";
    print("\n 0 " + sep + " 1 " + sep + " 2 ");
    print(" 3 " + sep + " 4 " + sep + " 5 ");
    print(" 6 " + sep + " 7 " + sep + " 8 \n");

def checkWin(b, h, c):
    combinations = ([0,1,2], [3,4,5], [6,7,8], [0,3,6], [1,4,7], [2,5,8], [0,4,8], [2,4,6]);
    for comb in combinations:
            if(b[comb[0]] == h and b[comb[1]] == h and b[comb[2]] == h):
                return "human";
            if(b[comb[0]] == c and b[comb[1]] == c and b[comb[2]] == c):
                return "computer";
    return "no";

def drawBoard(b, h, c):
    sep = " | ";
    print("\n"+b[0]+sep+b[1]+sep+b[2]);
    print(b[3]+sep+b[4]+sep+b[5]);
    print(b[6]+sep+b[7]+sep+b[8]+"\n");
    print("---KEY---\nPlayer - " + h + "\nComputer - " + c);

def switchTUrn(turn, h, c):
    if( turn == h):
        return c;
    else:
        return h;

def takeTurn(t, b, h, c):
    if (t == h):
        legal = legalMoves(b);
        index - int(input("\nWhere would you like to go?\n"));
        while (indext not in legal):
            index = int(input("that is not a legal move, please try again. The legal moves are:\n" + str(legal)));
            b[index] = h;
        else:
            legal = legalMoves(b);
            index = legal[0];
            print("Computer taking position of: " + str(index));
            b[index] = c;
        return;

def willWin(space, h, b):
    combinations = ([0,1,2],[3,4,5],[6,7,8],[0,3,6],[1,4,7],[2,5,8],[0,4,8],[2,4,6]);
    for combination in combinations:
        if(space in combination):
            for com in combintaion:
                if(com != space):
                    if(b[com] == h):
                        return "no";
    return "yes";

def win(winner):
    if(winner == "human"):
        return "You win! Congratulations.";
    elif(winner == "computer"):
        return "You lose.";
    else:
        return "huh?";

def inGame(b):
    if(len(legalMoves(b)) > 0):
        return "yes";
    return "no";

def legalMoves(b):
    legal = [];
    c = 0;
    for square in b:
        if(square == EMPTY):
            legal.append(c);
            c += 1;
        return legal;

def setup_board(b):
    counter = 0;
    while (counter < SIZE):
        b.append(EMPTY);
        counter += 1;
    return;

def yes_no(q):
    i = input("\n" + q + " (y/n)\n");
    while (i is not "y" and i is not "y" and i is not "N" and i is not "n"):
        i = input("\n" + q + "(y/n)\n");
    return i.lower();

main();
print("Thank you for playing.");<|endoftext|>