Image for post
Image for post

Improve your Python — Five features to include in your code

Solomon Akinyemi
Apr 12 · 7 min read

This article demonstrates libraries and features in Python I used to build an auction program. In summary the code takes in an input file with lots of rows of data and prints out the output of the auction items, sold and unsold in a summary.

Code repository

Code can be found:

https://github.com/solomonakinyemi/auction_project

Python features used within the program

Feature 1 [Map]

In addition, map is used a lot in this program because there are a lot of loops required when analysing the file input which serves as the instruction set for the program. Moreover the idea was stick to python default libraries. I am aware I could have used other external libraries to perform similar functionalities.

How I used map?

Code example:

The process instruction function uses the code snippet below, line 10 demonstrates the usage of map.

Code snippet of the function that reads in data from the auction file for processing

Feature 2 [named tuples]

How I use named tuple:

In addition, I chose named tuple because it makes it easier to retrieve an items value in each row read into the program by name rather than array index. For instance, if the program reads in the row below which is a bid:

1909|3|BID|tv_1|200.00

It creates a named tuple called bid with the following key value associations:

  • timestamp: 1909
  • user_id: 3
  • action: BID
  • item: tv_1
  • bid_amount: 200.00

The named tuple is declared like the example below after importing the collections library:

Code snippet example of the data classification function and declaring named tuples

The named tuples are created using the _make function like the example below:

bid = self.bid._make(row)

Moreover, rows within the file will always be ordered, which is an assumption I made, therefore, it made sense using named tuple because I can now reference each item within the named tuple by name rather than a position in an array. Additionally, I use the same data structure for user listings, heartbeats as well as the auction result summary.

To retrieve the bid amount for the specific row in the example above:

bid_submitted = bid.bid_amount

Feature 3 [Virtual environment]

How I use virtual environment?

The auction program has its own Python virtual environment and ships with Python 3.7.2. The only packaged currently installed is the nose==1.3.7 for unit testing.

To create a virtual environment, run the following command for (python > 3.7) and the second for (python < 3.6). Moreover, the ‘auction_env’ is the virtual environment folder name that would be created:

$ python3 -mvenv auction_envor$ pyvenv auction_env

Activate the virtual environment by running the following command:

$ source auction_env/bin/activate

and to deactivate:

$ deactivate

Install package using pip into the virtual environment:

$ pip install nose==1.3.7

Feature 4 [Unit testing with — Nose ]

How I use Nose library?

Furthermore, I created a python test class used to test the Server class which performs the grunt work of this program. The test class is called TestAuctionServer. Tests run within the virtual environment, once the nose library is installed using pip, the test can be run using the code snippet below. The examples shows the result of the tests:

$ nosetests -v test_auction.pyTest if data can be classified ... okTest empty list classification ... okTest if data type has been classified for timestamp ... okTest bid classification is accurate by using bid data type ... okTesting ability to process instructions ... okTesting the auction close times function ... ok....

Code snippet:

Snippet of TestAuctionServer class for unit testing

Feature 5 [Logging]

How I use logging?

When the Server class which performs most of the hard work in the auction program is initialised we make a call to a function within the class called set_up_logging

from logging.config import fileConfigclass Server:
def __init__(self, input_file=""):
self.logger = self.set_up_logging()

Furthermore, we read in the logging configuration file called logging_config.ini, select the logging configuration we want from within the config file and finally return the logger object for use within the program.

def set_up_logging(self):
"""
Function used to initialise logging of activities ...
"""
fileConfig('logging_config.ini')
logger = logging.getLogger('auctionLogger')
return logger

The program logs output to the ‘logs’ directory which contains a file called logfile.log.

Conclusion

The five things we talked about were:

  • The map function
  • Named tuples data structure
  • Virtual environment
  • Nose test library for unit testing
  • Logging module

More information on the challenge, assumptions and rule of the program can be found in the appendix section.

Appendix

The challenge

The program will receive an input file with a list of rows that are of three types. Additionally, each row is separated by a pipe-delimiter :

  • User listing: timestamp|user_id|action|item|reserve_price|close_time
  • Bid: timestamp|user_id|action|item|bid_amount
  • Heartbeat: timestamp

Expected summary output:

close_time|item|user_id|status|price_paid|total_bid_count|highest_bid|lowest_bid

Rules

  1. The price paid is the second highest valid bid
  2. Valid bids arrive after the auction start and before the auction closes
  3. Additionally, valid bids are larger than other previous bids submitted by the user
  4. At the end of the auction, the winner will pay the price of the second highest bidder
  5. If there is only a single valid bid the reserve price is paid
  6. If two bids are received for the same amount then the earliest bid wins the item

The project approach summary

In addition, the Server class processes the instructions (rows of data) from the input file classifying the rows into user listings, bid or heartbeat, evaluating the bids received for listings and creating the auction summary to name a few tasks.

Furthermore, the AuctionListing class is a data structure used to store information relating to a listed item. Data stored in the AuctionListing class will be printed out as part of the auction summary at the end of the program.

Project Assumptions

  • Auction opens as soon as the program starts running and ends when the program stops
  • Listings close once heartbeat matches the close time assigned to that specific listing
  • A user listing ‘item’ code is unique, if the same item name is presented as a listing then the first item will be listed whilst the second will be ignored
  • ‘Item’ name for user listing and ‘Item’ bid are the same in order to match bids to user listings
  • All bids include accepted bids. Bids below the reserve price but within the auction time will be counted

File input and output example:

Input file content example:10|199|SELL|table_1|10.00|16
12|236|SELL|bed_1|10.00|22
13|404|SELL|tshirt_1|10.00|20
15|898|BID|bed_1|7.50
16|626|BID|tshirt_1|12.50
17
18|475|BID|table_1|9.00
19
20|333|BID|tshirt_1|19.00
21
22|999|BID|bed_1|20.00
23
Output:23|table_1||UNSOLD|0.00|1|9.00|0.00
23|bed_1|999|SOLD|10.00|2|20.00|7.50
23|tshirt_1|333|SOLD|12.50|2|19.00|12.50

User listing row description

  • user_id is an integer
  • action will be the string “SELL”
  • item is a unique string code for that item
  • reserve_price is a decimal representing the item reserve price in the local currency
  • close_time will be an integer representing a unix epoch time

Bid row description

  • user_id is an integer
  • action will be the string “BID”
  • item is a unique string code for that item
  • bid_amount is a decimal representing a bid in the auction in the local currency

Heartbeat row description

  • timestamp integer representing epoch time

Summary row description

  • item is a unique string code for that item
  • user_id is an integer
  • status is either “SOLD” or “UNSOLD” depending on the auction outcome
  • price_paid price paid by the auction winner (0.00 if the item is UNSOLD), as a number to two decimal places
  • total_bid_count number of valid bids received for the item
  • highest_bid highest bid received for the item as a number to two decimal places
  • lowest_bid lowest bid placed on the item as a number to two decimal places

The Startup

Medium's largest active publication, followed by +716K people. Follow to join our community.

Solomon Akinyemi

Written by

I write code to automate manual systems. Additionally, the code I write allows different systems interact with each other to serve a business purpose.

The Startup

Medium's largest active publication, followed by +716K people. Follow to join our community.

Solomon Akinyemi

Written by

I write code to automate manual systems. Additionally, the code I write allows different systems interact with each other to serve a business purpose.

The Startup

Medium's largest active publication, followed by +716K people. Follow to join our community.

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store