Python Class File to List - python

So I'm doing a project that I have to create a class that going to read information in a file like the one below, and put it in a list.
Each value in the list have to assign to a variable (name = 'Guillaume Dutroux')
Day: 2019-01-12
Time:
09:00
Company:
iCageDoree
Clients:
Guillaume Dutroux, london, 2019-03-12, 13:30, 55, 4*, plumbing, 4h00
Jose Quesada, madrid, 2019-03-12, 10:00, 30, 2*, refrigerators, 5h15
Martin Wyne, london, 2019-04-30, 19:45, 105, 3*, wifi, 0h30
class ReadClients:
def __init__(self, fileClients):
self._fileClients = fileClients
def readClients(self):
with open(self._fileClients, "r") as file:
for i in range(7):
file.readline()
self._clientsData = []
for line in file:
name, city, date, time, maxValue, minRep, domain, timeWork = line.strip(" ").split(",")
self._clientsData.append(Clients(name, city, date, time, maxValue, minRep, domain, timeWork))
self._nameCl = name
self._cityCl = city
self._dateCl = date
self._timeCl = time
self._maxValueCl = maxValue
self._minRepCl = minRep
self._domainCl = domain
self._timeWorkCl = timeWork
return self._clientsData
My code above is returning me:
[<clients.Clients object at 0x01B77170>, <clients.Clients object at 0x01B77230>, <clients.Clients object at 0x01B77310>]
and I don't know why.
Hope you can Help me.

Here is a small example of how you can play around with __repr__
class my_class:
def __init__(self,name,age):
self.name=name
self.age=age
def __repr__(self):
return "(name="+self.name+', '+"age"+str(self.age)+")"
my_list = [my_class('a',1),my_class('a',2)] # [(name=a, age1), (name=a, age2)]

Related

Including another object inside an object and calling a specific value

I'm trying to make a simple 5v5 sport management, but I'm not sure how can I link players to teams, in order to make the overall rating of the team be the sum of the players rating / amount of players. Unfortunately my current code only returns where the object is ( <main.Player object at 0x000001CED897FCD0>) but not the player at all, so of course the overall is off
class Player:
totalPlayers = 0
def __init__(self,PName, PYearBorn, POvr, PNumber, PIndex):
self.PName = PName
self.PYearBorn = PYearBorn
self.POvr = POvr
self.PNumber = PNumber
self.PIndex = PIndex
Player.totalPlayers += 1
def getPlayer(self):
return self.PName, self.PYearBorn, self.POvr, self.PNumber, self.PIndex
'''
Player Name
Year Born
Player Overall
Player Number
Player Index'''
class HistoricPlayer(Player):
def __init__(self,PName, PlayerAge, POvr, PNumber, PIndex):
self.PlayerAge=PlayerAge
Player.__init__(self,PName, PlayerAge, POvr, PNumber, PIndex,)
class Franchise():
totalFranchises = 0
def __init__(self, FName, region, championships, yearCreated, rivals):
self.FName = FName
self.region = region
self.championships = championships
self.yearCreated = yearCreated
self.rivals = rivals
Franchise.totalFranchises += 1
class Team(Franchise):
totalTeams = 0
def __init__(self, TName, FName, amountofplayers, maxplayercapacity, region, championships, yearCreated, rivals, currentplayers):
Franchise.__init__(self, FName, region, championships, yearCreated, currentplayers)
self.currentplayers = currentplayers
self.overall = currentplayers[1].POvr/amountofplayers
self.rivals = rivals
self.TName = TName
self.amountofplayers = amountofplayers
self.maxplayercapacity = maxplayercapacity
self.currentplayers = currentplayers
Team.totalTeams+=1
def getTeam(self):
return self.TName, self.FName, self.amountofplayers, self.maxplayercapacity, self.region, self.championships, self.yearCreated, self.rivals, self.currentplayers
''' #Team Class Values
Team Name
Franchise Name
Overall
Amount of current players
Maximum player capacity
Team Region
Championships
Year of Creation
Rivals
Current Players
'''
P01=Player('Francis', 2000, 8, 69, 'p01')
P02=Player('Franton', 2000, 8, 69, 'p01')
P03=Player('Frank', 2000, 8, 69, 'p01')
P04=Player('Felitio', 2000, 8, 69, 'p01')
P05=Player('Fred', 2000, 8, 69, 'p01')
T01=Team('5 Friends', "The friends' club", 5, 6, "Hometown", 0, 2022, 'Rich', (P01, P02, P03, P04, P05))
print(T01.getTeam())
Any idea what should or can I do/what am I doing wrong?

After you create a class, how do you add information from a csv to a python object, without using a module

I am struggling to understand classes/objects and using a csv with them.
I have a CSV with 26 rows, 1 being the header, the other containing rows of info. Small example below
id,food,food_print,cal1,cal2,expi1999,expi2000,expi2001
1,bun,bun_bun,45.3434,199.32323,23.3333,45.4444,33.33333
2,burger,burger_bun,45.342343,200.34243,34.3333,0,9
3,pickle,pickle_seed,67.345454,34.3434,34,56,33
4,chicken,chicken_egg,44.34343,43.343343,43,434,34343
I have my class as follows:
class City(object):
def __init__(self, food = 'n/a', foodprint = 'n/a', cal1 = -999, cal2 = -999,
expi1999 = -999, expi2000 = -999, expi2001 = -999)
self.food = food
self.foodprint = foodprint
self.cal1 = cal1
self.cal2 = cal2
self.expi1999 = expi1999
self.expi2000 = expi2000
self.expi2001 = expi2001
meals = []
foodfile = open('Food.csv', 'rt')
headers = foodfile.readline().strip().split(',')
headers = headers.split(',')
for line in foodfile:
foodfields = foodfile.readline().strip().split(',')
How do I write in the rows from my food csv into an object to be referenced in the class?
Assuming all colums are filled in every row:
try:
for line in foodfile:
foodfields = foodfile.readline().strip().split(',')
meals.append(City(foodfields[1],foodfields[2],foodfields[3],foodfields[4],foodfields[5],foodfields[6],foodfields[7]))
true tone to avoid dynamic classes. Because your code become unpredictable in future changes. Use dataclass instead. Also this behaviour let you refer to this "data model" as annotation during data exchange with any callable.
from dataclasses import dataclass
#dataclass
class City:
food: str = 'n/a'
foodprint: str = 'n/a'
cal1: int = -999
cal2: int = -999
expi1999: int = -999
expi2000: int = -999
expi2001: int = -999
But if you want to now how to do it - setattr function exists in global namespace.
class DynamicContainer:
#classmethod
def create(cls, headers: list[str], data: list[str]):
obj = cls()
for header, value in zip(headers, data):
setattr(obj, header, value)
return obj
headers = 'id,food,food_print,cal1,cal2,expi1999,expi2000,expi2001'.split(',')
data = '1,bun,bun_bun,45.3434,199.32323,23.3333,45.4444,33.33333'.split(',')
cont = DynamicContainer.create(headers, data)
print(cont.id, cont.cal1, cont.expi2000)
Here is how I would do it:
import csv
class City(object):
def __init__(self, food=None, foodprint=None, cal1=None, cal2=None, expi1999=None, expi2000=None, expi2001=None):
self.food = food
self.foodprint = foodprint
self.cal1 = float(cal1)
self.cal2 = float(cal2)
self.expi1999 = float(expi1999)
self.expi2000 = float(expi2000)
self.expi2001 = float(expi2001)
def __repr__(self):
return (
f"{self.__class__.__name__}("
f"food={self.food!r}"
f", "
f"food_print={self.foodprint!r}"
f", "
f"cal1={self.cal1!r}"
f", "
f"cal2={self.cal2!r}"
f", "
f"expi1999={self.expi1999!r}"
f", "
f"expi2000={self.expi2000!r}"
f", "
f"expi2001={self.expi2001!r}"
f")"
)
with open("Food.csv") as stream:
next(stream) # Skip the header row
reader = csv.reader(stream)
meals = [City(*row[1:]) for row in reader]
Here is what rows looks like:
[City(food='bun', food_print='bun_bun', cal1=45.3434, cal2=199.32323, expi1999=23.3333, expi2000=45.4444, expi2001=33.33333),
City(food='burger', food_print='burger_bun', cal1=45.342343, cal2=200.34243, expi1999=34.3333, expi2000=0.0, expi2001=9.0),
City(food='pickle', food_print='pickle_seed', cal1=67.345454, cal2=34.3434, expi1999=34.0, expi2000=56.0, expi2001=33.0),
City(food='chicken', food_print='chicken_egg', cal1=44.34343, cal2=43.343343, expi1999=43.0, expi2000=434.0, expi2001=34343.0)]
Notes
The repr function is to show the contents of the class object, you can ignore it
I use the csv module to ease parsing the CSV data
I also converted the values into floating point numbers.

How to print a 'particular' element in a list (not entire list), without brackets and quotes, while printing from class method?

I am trying to print a "particular" element from a list using below code.
While printing the class instance variable self.Engine, the output ['Merlin'] prints along with the quotes and brackets. How can I print simply the string, without quotes and brackets?
Here is the code:
class Rockets(object):
Stages = "2 Stage"
def __init__ (self,Rocket_name,Company_Name, CEO, Headquarters, Established):
self.Rocket_name = Rocket_name
self.Company_Name = Company_Name
self.CEO = CEO
self.Headquarters = Headquarters
self.Established = Established
self.Engine=[]
def add_engine(self,Engine_name):
self.Engine.append(Engine_name)
def Rocket_Details(self):
return(print("Rocket:",self.Rocket_name,"\nEngine:",self.Engine,"\nStages:",self.Stages,"\nCompany Name:",self.Company_Name,"\nCEO:",self.CEO,"\nHeadquarters:",self.Headquarters,"\nEstablished:",self.Established))
Falcon9 = Rockets("Flacon9","Space Exploration Technologies Corp.","Elon Musk","Hawthorne, California",2002)
Falcon9.add_engine('Merlin')
Falcon9.Rocket_Details()
Output:
Rocket: Flacon9
Engine: ['Merlin']
Stages: 2 Stage
Company Name: Space Exploration Technologies Corp.
CEO: Elon Musk
Headquarters: Hawthorne, California
Established: 2002
You can use str.join. For example:
class Rockets(object):
Stages = "2 Stage"
def __init__(
self, Rocket_name, Company_Name, CEO, Headquarters, Established
):
self.Rocket_name = Rocket_name
self.Company_Name = Company_Name
self.CEO = CEO
self.Headquarters = Headquarters
self.Established = Established
self.Engine = []
def add_engine(self, Engine_name):
self.Engine.append(Engine_name)
def Rocket_Details(self):
return print(
"Rocket:",
self.Rocket_name,
"\nEngine:",
" ".join(self.Engine), # <--- you can use str.join
"\nStages:",
self.Stages,
"\nCompany Name:",
self.Company_Name,
"\nCEO:",
self.CEO,
"\nHeadquarters:",
self.Headquarters,
"\nEstablished:",
self.Established,
)
Falcon9 = Rockets(
"Flacon9",
"Space Exploration Technologies Corp.",
"Elon Musk",
"Hawthorne, California",
2002,
)
Falcon9.add_engine("Merlin")
Falcon9.Rocket_Details()
Prints:
Rocket: Flacon9
Engine: Merlin
Stages: 2 Stage
Company Name: Space Exploration Technologies Corp.
CEO: Elon Musk
Headquarters: Hawthorne, California
Established: 2002
class Rockets(object):
Stages = "2 Stage"
def __init__ (self,Rocket_name,Company_Name, CEO, Headquarters, Established):
self.Rocket_name = Rocket_name
self.Company_Name = Company_Name
self.CEO = CEO
self.Headquarters = Headquarters
self.Established = Established
self.Engine=['Unknown'] # you can replace this with empty string ['']
def add_engine(self,Engine_name):
self.Engine.append(Engine_name)
def Rocket_Details(self):
return(print("Rocket:",self.Rocket_name,"\nEngine:",self.Engine[-1],"\nStages:",self.Stages,"\nCompany Name:",self.Company_Name,"\nCEO:",self.CEO,"\nHeadquarters:",self.Headquarters,"\nEstablished:",self.Established))
I am guessing that the reason you have the Engine as a list is because you are expecting that the engine will change over time. If that is the logic, than the above code will output the most recent assignment of the engine name. You could add one more attribute, like self.All_Engines which would output the whole lists of the engines that were used on the rocket.

Python script error sqlite3.OperationalError: no such column:

I get this error when I run the script and I cannot see the solution. This program is supposed to draw a giveaway from a sqlite3 file which has the number of raffle tickets for a user. And recently the program the gives that creates the sqlite3 file updated some stuff (The script is made by me) and I can figure out the solution.
Traceback (most recent call last):
File "C:\Users\Admin\Desktop\Draw\Test\dave-draw.py", line 244, in <module>
dd = DaveDraw()
File "C:\Users\Admin\Desktop\Draw\Test\dave-draw.py", line 64, in __init__
self.get_viewers()
File "C:\Users\Admin\Desktop\Draw\Test\dave-draw.py", line 215, in
get_viewers
''').fetchall()
sqlite3.OperationalError: no such column: viewer_id
there's the code
#!/usr/bin/env python3
import pdb
import random
import sqlite3
class Viewer(object):
def __init__(self,
viewer_id,
twitch_name,
beam_name,
beam_id,
viewer_type,
rank,
points,
points2,
hours,
raids,
gains_currency,
gains_hours,
in_giveaways,
last_seen,
sub,
entrance_message,
entrance_message_type,
entrance_sfx
):
self.viewer_id = viewer_id
self.twitch_name = twitch_name
self.beam_name = beam_name
self.beam_id = beam_id
self.viewer_type = viewer_type
self.rank = rank
self.points = points
self.points2 = points2
self.hours = hours
self.raids = raids
self.gains_currency = gains_currency
self.gains_hours = gains_hours
self.in_giveaways = in_giveaways
self.last_seen = last_seen
self.sub = sub
self.entrance_message = entrance_message
self.entrance_message_type = entrance_message_type
self.entrance_sfx = entrance_sfx
def win_chance(self, total_tickets):
"""
Takes the total tickets (points) as a paramter and works
out the percentage chance that the viewer has of winning.
Returns the viewers win chance in percent.
"""
percent = total_tickets / 100.00
return self.points2 / percent
class DaveDraw(object):
def __init__(self):
self.debug = False
self.database_path = 'Viewers3DB.sqlite'
self.db_conn = sqlite3.connect(self.database_path)
self.get_viewers()
self.calculate_total_points()
self.assign_tickets()
def assign_tickets(self):
"""
Assigns each user a number range based on the number of
tickets they have.
e.g.
10 1-10
10 11-20
30 21-50
1 51
"""
self.tickets = {}
latest_ticket = 0
for viewer in self.viewers:
# skip anyone with no points
if viewer.points2 == 0:
continue
ticket_range_beg = latest_ticket + 1
ticket_range_end = latest_ticket + 1 + viewer.points2
latest_ticket = ticket_range_end
viewer.tickets = range(ticket_range_beg, ticket_range_end)
# assign a range of tickets:
if self.debug:
print("Assigning viewer twitch: %s beam: %s tickets %i-%i" % (viewer.twitch_name, viewer.beam_name, viewer.tickets.start, viewer.tickets.stop))
if ticket_range_beg == ticket_range_end:
if self.debug:
print("Assigning ticket {} to {}".format(ticket_range_beg, viewer.twitch_name))
self.tickets[ticket_range_beg] = viewer
next
for ticket in viewer.tickets:
if self.debug:
print("Assigning ticket {} to {}".format(ticket, viewer.twitch_name))
self.tickets[ticket] = viewer
def calculate_total_points(self):
"""
Gets the total amount of points awarded to all
viewers.
"""
self.total_points = 0
for viewer in self.viewers:
self.total_points += viewer.points2
self.total_points_percent = self.total_points / 100
print("Total points awarded (total tickets): %s" % self.total_points)
def draw(self):
"""
Picks a random number between 1 and total tickets, finds
the user that has been assigned tickets within that range and
returns the user.
"""
ticket = random.randint(1, self.total_points)
try:
winner = self.tickets[ticket]
except:
pdb.set_trace()
print("\n===== WINNER Twitch: {} / Beam: {} =====\n".format(winner.twitch_name, winner.beam_id))
print("Picked ticket {}\n".format(ticket))
print("Winner win chance: {:f}".format(winner.win_chance(self.total_points)))
print("Winner's ticket range: {}-{}".format(winner.tickets.start, winner.tickets.stop))
print("Winner's ticket amount: {}\n".format(winner.points2))
self.display_viewer(winner)
def display_random_viewer(self):
"""
Displays random viewer.
"""
self.display_viewer(self.get_random_viewer())
def display_viewer(self, viewer):
"""
Outputs the data on all viewers.
"""
print("""Viewer ID: %s\nTwitch Name: %s\nBeam Name: %s\nBeam ID: %s\nRank: %s\nPoints: %s\nPoints2: %s\nHours: %s\nRaids: %s\nGains Currency: %s\nGains Hours: %s\nInGiveaways: %s\nLastSeen: %s\nEntrance Message: %s\nEntranceMsgType: %s\nEntranceSFX: %s"""
% (
viewer.viewer_id,
viewer.twitch_name,
viewer.beam_name,
viewer.beam_id,
viewer.rank,
viewer.points,
viewer.points2,
viewer.hours,
viewer.raids,
viewer.gains_currency,
viewer.gains_hours,
viewer.in_giveaways,
viewer.last_seen,
viewer.entrance_message,
viewer.entrance_message_type,
viewer.entrance_sfx
)
)
def get_random_viewer(self):
"""
Gets a completely random viewer.
"""
return random.choice(self.viewers)
def get_viewers(self):
"""
Gets data on all the viewers in the database and stores
the data in self.viewers.
"""
c = self.db_conn.cursor()
viewers = c.execute('''
SELECT
viewer_id,
TwitchName,
BeamName,
BeamID,
Type,
Rank,
Points,
Points2,
Hours,
Raids,
GainsCurrency,
GainsHours,
InGiveaways,
LastSeen,
Sub,
EntranceMessage,
EntranceMsgType,
EntranceSFX
FROM Viewer
WHERE Type != 1
AND TwitchName NOT IN (
\'treeboydave\',
\'treebotdave\'
);
''').fetchall()
self.viewers = []
for cur_viewer in viewers:
self.viewers.append(
Viewer(
cur_viewer[0],
cur_viewer[1],
cur_viewer[2],
cur_viewer[3],
cur_viewer[4],
cur_viewer[5],
cur_viewer[6],
cur_viewer[7],
cur_viewer[8],
cur_viewer[9],
cur_viewer[10],
cur_viewer[11],
cur_viewer[12],
cur_viewer[13],
cur_viewer[14],
cur_viewer[15],
cur_viewer[16],
cur_viewer[17]
)
)
if __name__ == '__main__':
dd = DaveDraw()
dd.draw()
All your other SQL columns are capitalised, any chance that's why it's not finding the viewer_id column? Maybe it's Viewer_Id or similar?
If you sql execute 'HELP TABLE Viewer' and print what it returns, it will give you an outline of all of the columns in that database table, so you can make sure you have the capitalisation correct, or whether the column actually isn't there at all.

Trying to iterate over a list attached to an object under a variable class(?)

Full code is at the end.
I've written a program that reads in data from a csv file. It creates a class of variable called "Facility". Each facility can have multiple water sources, so there is another class called "WaterSource" which appends a list of attributes for an individual water source to each Facility. If I call :
data['00312']
I get output:
Facility 00312 US Aggregates Inc IN
If I ask for data['00312'].records:
[ WaterSource 00312 WELL Willshire 80 683175 4511625,
WaterSource 00312 WELL Willshire 80 682550 4511750,
WaterSource 00312 INTAKE Willshire 1200 Unnamed Quarry 683225 4512075,
WaterSource 00312 INTAKE Willshire 1200 Unnamed Quarry 683225 4512050]
I need to create a report that iterates over every variable in the class and returns a list of Facilities that have multiple water sources. Thus the final output would a list of [RegNo, Facility Name, No. of WaterSources] such as:
[Facility 00312 US Aggregates Inc 4]
The issue I'm having is understanding how to iterate over the Facilities to count the records of the water sources appended to each Facilities object. I think I could add a method into the class somewhere, but I can't quite figure out where. I'm a python beginner, so please forgive me if this isn't quite the right vocabulary. I'm not even sure where to start, so any suggestions you could offer would be helpful.
class Facilities:
def __init__(self, regno, name, mwu): ##creates facility attributes
self.regno = regno
self.name = name
self.mwu = mwu
self.records = []
def add_record(self,record):
self.records.append(record)
def __repr__(self):
'''Makes a string representation'''
return 'Facility {0} {1} {2}'.format(self.regno, self.name, self.mwu)
class WaterSource(Facility):
'''holds info about the water source'''
def __init__(self, regno, source, quad, cap, body, utmE, utmN): ##creates water source attributes
self.regno = regno
self.source = source
self.quad = quad
self.cap = cap
self.body = body
self.utmE = utmE
self.utmN = utmN
self.records = []
def source_data(self):
regnos = []
sources = []
quads = []
caps = []
bodies = []
utmEs = []
utmNs = []
for record in self.records:
regnos.append(record.regno)
sources.append(record.source)
quads.append(record.quad)
caps.append(record.cap)
bodies.append(record.body)
utmEs.append(record.utmE)
utmNs.append(record.utmN)
return (regnos,sources,quads,caps,bodies,utmEs,utmNs)
def __repr__(self):
return ' WaterSource {0} {1} {2} {3} {4} {5} {6}'.format(self.regno, \
self.source, self.quad, self.cap, self.body, self.utmE, self.utmN)
def read_data(filename):
rv = {}
for r in csv.DictReader(open(filename, 'r', encoding='UTF-8')):
regno = r['RegNo']
if r['RegNo'] not in rv:
rv[regno] = Facilities(r['RegNo'],r['Facility'], r['MWU Code'])
rv[regno].add_record(WaterSource(regno, r['Source Code'], r['Quadrangle'], \
r['Capacity (GPM)'], r['Water Body Name'], r['UTM East'], r['UTM North']))
return rv
data = read_data('Fac-2013-2016.csv')
[Facility 00312 US Aggregates Inc 4]
The issue I'm having is understanding how to iterate over the
Facilities to count the records of the water sources appended to each
Facilities object.
From my understanding, simply add a method and return a count of the objects or straight up count the records using len unless there is something more to what you are asking for?
class Facilities:
def __init__(self, regno, name, mwu): ##creates facility attributes
self.regno = regno
self.name = name
self.mwu = mwu
self.records = []
def add_record(self,record):
self.records.append(record)
def __repr__(self):
'''Makes a string representation'''
return 'Facility {0} {1} {2} {3}'.format(self.regno, self.name, self.mwu , len(self.records))
All of your Facilities are stored as values in the dictionary data using the facility's RegNo for the keys. You can iterate over all the data using the dictionary items method. The length of each facility's records attribute is the number of water sources. You can build a format string to use the information you need.
for reg_no, facility in data.items():
no_of_sources = len(facility.records)
print(f'Facility {facility.regno} {facility.name} {no_of_sources}') #Python v3.6+
#print('Facility {} {} {}'.format(facility.regno, facility.name, no_of_sources)) #Python versions <3.6

Categories

Resources