Hi guys!

I need your help with a simple program I'm trying to make. It's supposed to read values from a file, covert them (and add/multiply), sort, and then view the values to the user. The values looks like this:

Stockholm
650000
55.5
2100
08 123 456
Whateverstreet 123
...
New York
1250000
39
3500
...

As you might see the values are about apartments. First is the location, second is the price, third is the size, rent, telephone number, and last the address. I've read all the values with

File = open("bo.txt", "r")

List = File.read().split("\n")

The things I want to do is:

First I want to convert some of the values to the type int/float. How can I do this without having to convert each object in the list manually? For example I want to convert the price, size and rent to int/float so I can add and multiply them.

Second I want to calculate the total monthly cost for each apartment. I already have the formula for that but I dont know how to express for instance the price in a good way. Now it's List[2], List[10], List[18] etc... How can i express them differently?

And last, I want to be able to sort the apartments starting with the one with the lowest monthly cost.

I've already done the things above but it's not good programming (the code is really messy and alot longer than it "needs" to be). So I would really appreciate it if you guys could point me in the right direction.

Any ideas?

Thanks!

I need your help with a simple program I'm trying to make

It doesn't sound simple. It would be a fun problem to try to work on. Could you post the gist of your code.

It doesn't sound simple. It would be a fun problem to try to work on. Could you post the gist of your code.

Well, it did seem easy at first but now I realized that it might be more difficult than i thought.

Anyway, here a bit from my code. I have a menu and some other stuff I'm working on too but this is the essentials. A warning though: some parts of the code is in Swedish so it might be hard for you to understand. I've tried to comment all the parts so it makes more sense. And: I dont know much about python-programming (or any other programming language for that matter) so the code might look like crap :D

# This opens the file

oppna = open("bo.txt", "r")

lista = oppna.read().split("\n")



# This collects info from the user. It's the interest, "deposit", and tax deduction.     
ranta = input("Hur hög är den aktuella bankräntan i procent?")

insats = input("Hur stor kontantinsats kommer du att betala?")

avdrag = input("Vad ligger ränteavdraget på?")





lgh1 = []

lgh2 = []


# Here I'm trying to store the different apartments as lists. After that i should
# merge them into a list of list (matrix?) but im not sure how to do that.

i = 0 
for i in range(6):
    lgh1.append(lista[i])


t = 0
for t in range(7,13):
    lgh2.append(lista[t])
    
            

    
# This part converts some values in the list from string-datatype to float. 
price = float(lista[1])

rent = float(lista[3])

size = float(lista[2])



# Formula for total monthly cost and cost per size (squaremeters)

total_cost = (rent + ((price*(ranta*0.01)*(1-(avdrag*0.01)))/12))

costsize = total_cost/size



# Prints the values
print "Den totala månadskostaden är:", total_cost, "kr."

print "Din lägenhet kostar", costsize, "kr per kvadratmeter och månad."



# This part is supposed to add the values of monthly cost and cost per size.
# by doing that i could hopefully sort the apartments by total monthly cost

lista.append(total_cost)

lista.append(costsize)

And this is how bo.txt looks like (it should contain more apartments then that but i havent added them yet):

Solna
1250000
26
1800
073 94 09 233
Olof Af Acrels väg 3

Bagarmossen
450000
55.5
1450
08 621 33 04
Brickebacken 7

Edited 6 Years Ago by Adam2k: n/a

This is why we have SQL. I have a work in progress that generates simple SQLite code for throw away applications. This is the code it generated for your application. The test_data() function adds some records with the data you provided. You should be able to figure how to add all of the data by looking at the function. Also, the function list_all_recs() prints the file sorted on total cost, so that is an example of how to extract data in the order you want. If you can not adapt this to your application, post back, and note that there are couple of of functions that are not used but are there as a general reminder since this is just boiler plate.

import os
import sqlite3 as sqlite


##======================================================================
class DummyClass:
   def __init__( self ) :
      self.SQL_filename = './test_apt_dbf'
      self.open_files()

   ##   END  __init__()

   ##----------------------------------------------------------------------
   def add_rec( self ) :
      val_tuple=(self.a_city, self.a_price, self.a_size, self.a_rent, self.a_tel, self.a_address, self.a_total_cost, self.a_cost_size)
      self.cur.execute('INSERT INTO test_apt_dbf values (?,?,?,?,?,?,?,?)', val_tuple)
      self.con.commit()

   ##   END  AddRec()

   ##----------------------------------------------------------------------
   def copy_to_struct( self, rec ) :
      self.a_city = rec[0]
      self.a_price = rec[1]
      self.a_size = rec[2]
      self.a_rent = rec[3]
      self.a_tel = rec[4]
      self.a_address = rec[5]
      self.a_total_cost = rec[6]
      self.a_cost_size = rec[7]

   ##   END  copy_to_struct()

   ##----------------------------------------------------------------------
   def list_all_recs( self ) :
      self.cur.execute("select * from test_apt_dbf order by a_total_cost")
      recs_list = self.cur.fetchall()
      for rec in recs_list:
         print rec

   ##   END  list_all_recs

   ##----------------------------------------------------------------------
   def lookup_first_field( self ) :
      self.cur.execute("select * from test_apt_dbf where a_city==:dic_lookup", {"dic_lookup":"test_A_0"})
      recs_list = self.cur.fetchall()
      print
      print "lookup_first_field (test_A_0)" 
      for rec in recs_list:
         self.copy_to_struct(rec)
         self.print_rec()

   ##   END  lookup_first_field()

   ##----------------------------------------------------------------------
   def lookup_first_2_fields( self, lookup_dic ) :
      self.cur.execute("select * from test_apt_dbf where a_city==:dic_field_1 and a_price==:dic_field_2", lookup_dic)

      recs_list = self.cur.fetchall()
      print
      print "lookup_first_2_fields (test_A_0 + test_A_1)" 
      for rec in recs_list:
         print rec

   ##   END  lookup_first_2_field()

   ##----------------------------------------------------------------------
   def open_files( self ) :
         ##  a connection to the database file
         self.con = sqlite.connect('./test_apt_dbf')
         # Get a Cursor object that operates in the context of Connection con
         self.cur = self.con.cursor()

         self.cur.execute("CREATE TABLE IF NOT EXISTS test_apt_dbf(a_city varchar, a_price float, a_size float, a_rent float, a_tel varchar, a_address varchar, a_total_cost float, a_cost_size float)")

   ##   END  open_files()

   ##----------------------------------------------------------------------
   def print_rec( self ) :
      spaces = ""
      print spaces, "a_city =", self.a_city
      spaces = "     "
      print spaces, "a_price =", self.a_price
      print spaces, "a_size =", self.a_size
      print spaces, "a_rent =", self.a_rent
      print spaces, "a_tel =", self.a_tel
      print spaces, "a_address =", self.a_address
      print spaces, "a_total_cost =", self.a_total_cost
      print spaces, "a_cost_size =", self.a_cost_size

   ##   END  rec_struct()

   ##----------------------------------------------------------------------
   def rec_struct( self ) :
      self.a_city = ""
      self.a_price = ""
      self.a_size = ""
      self.a_rent = ""
      self.a_tel = ""
      self.a_address = ""
      self.a_total_cost = ""
      self.a_cost_size = ""

   ##   END  rec_struct()

##======================================================
def test_data(DM):
   test_data = ( ['Stockholm', '650000', '55.5', '2100', '08 123 456', 'Whateverstreet 123'], \
                 ['Solna ', '1250000', '26', '1800', '073 94 09 233', 'Olof Af Acrels vag 3'], \
                 ['Bagarmossen', '450000', '55.5', '1450', '08 621 33 04', 'Brickebacken 7'] )
   ranta = 10.1
   avdrag = 10.2

   for rec in test_data:
      DM.a_city = rec[0]
      DM.a_price = float(rec[1])
      DM.a_size = float(rec[2])
      DM.a_rent = float(rec[3])
      DM.a_tel = rec[4]
      DM.a_address = rec[5]
      DM.a_total_cost = DM.a_rent + ((DM.a_price*(ranta*0.01)*(1-(avdrag*0.01)))/12)
      DM.a_cost_size = float(DM.a_total_cost)/DM.a_size
      DM.add_rec()

##======================================================
if __name__ == '__main__':
   try :
      DM=DummyClass()
      test_data(DM)
      DM.list_all_recs()
   except :
      import traceback
      traceback.print_exc()
      raise

This is why we have SQL. I have a work in progress that generates simple SQLite code for throw away applications. This is the code it generated for your application. The test_data() function adds some records with the data you provided. You should be able to figure how to add all of the data by looking at the function. Also, the function list_all_recs() prints the file sorted on total cost, so that is an example of how to extract data in the order you want. If you can not adapt this to your application, post back, and note that there are couple of of functions that are not used but are there as a general reminder since this is just boiler plate.

import os
import sqlite3 as sqlite


##======================================================================
class DummyClass:
   def __init__( self ) :
      self.SQL_filename = './test_apt_dbf'
      self.open_files()

   ##   END  __init__()

...
...

Thanks for your reply!

Your code does look nice but I'm not supposed to use SQL (partly because I don't have any SQL-experience but also because it's not at part of the assignment).

Instead I'm working with classes and functions. Right now there's some stupid problem (I guess it's a typo) but I'll post back when I've got a code that at least is somewhat useful.

In the meantime though, I have one question: what's the easiest way to implement error handling from user input? Suppose I've got a bit of code that looks like this:

interest = raw_input("Whats the interest?")
deposit = raw_input("Whats the deposit?")
deduction = raw_input("Whats the deduction?")

And I want the program to say eg. "thats not a correct input, please try again" if the input is not a int/float. Could i use an if-statement like:

if raw_input != type(int, float):
      print "Thats not a number"
      break
else:
     ???

Or is there a better way to do it?

Edited 6 Years Ago by Adam2k: n/a

raw_input will never be a type int or float. I would use one function.

def get_input(literal):
    while True:
        str_in = raw_input("Whats the %s? " % (literal))
        try:
            float_in = float(str_in)
            return float_in
        except:
            print "Invalid input...try again"

interest = get_input("interest")
deposit = get_input("deposit")
deduction = get_input("deduction")
print interest, deposit, deduction

raw_input will never be a type int or float. I would use one function.

def get_input(literal):
    while True:
        str_in = raw_input("Whats the %s? " % (literal))
        try:
            float_in = float(str_in)
            return float_in
        except:
            print "Invalid input...try again"

interest = get_input("interest")
deposit = get_input("deposit")
deduction = get_input("deduction")
print interest, deposit, deduction

Ah, of course. Thank you.

Anyway, this is how my code looks right now. When it's run theres a key error (key error 'rent'). Could some of you guys see what's the problem? Btw don't mind the comments I've written, they're in swedish :D

#öppna fil
File = open("bo.txt", "r")
print "\n Välkommen till bostsadsprogrammet. \n Bostäder hämtade från bo.txt \n"

#typkonvertera lista
properties = ['location', 'price', 'size', 'rent', 'phone', 'address']
types = [str, int, float, int, str, str]
i_property = 0

#skapa upp lista
#läs in, strippa radbrytning, lägg till i listan
flats = []

for line in File:
    line = line.rstrip('\n')
    
    if i_property == 0:
        flats.append({})
 
    flats[-1][properties[i_property]] = types[i_property](line)
 
    i_property += 1
    if i_property == len(properties):
        i_property = 0


# funktion för total månadskostnad
def total_cost(flat):

    rent = flat["rent"]
    price = flat["price"]

    return (rent + (price - deposit) * interest * 0.01 * (1 - (deduction * 0.01) / 12))


#hämta data från användaren
def get_input(literal):
    while True:
        str_in = raw_input("Whats the %s? " % (literal))
        try:
            float_in = float(str_in)
            return float_in
        except:
            print "Felaktig inmatinng, försök igen."
            

interest = get_input("interest")
deposit = get_input("deposit")
deduction = get_input("deduction")


#sortera lägenheter
flats.sort(key=total_cost)

#skriv ut till användaren
for flat in flats:
    print flat['location'], total_cost(flat)

You have to skip the empty line in the data ,,,

# -*- coding: iso-8859-15 -*-

#öppna fil
File = open("bo.txt", "r")
print "\n Välkommen till bostsadsprogrammet. \n Bostäder hämtade från bo.txt \n"

#typkonvertera lista
properties = ['location', 'price', 'size', 'rent', 'phone', 'address']
types = [str, int, float, int, str, str]
i_property = 0

#skapa upp lista
#läs in, strippa radbrytning, lägg till i listan
flats = []

for line in File:
    line = line.rstrip('\n')
    # skip empty line
    if not line:
        continue
    #print line  # test

    if i_property == 0:
        flats.append({})

    flats[-1][properties[i_property]] = types[i_property](line)

    i_property += 1
    if i_property == len(properties):
        i_property = 0


# funktion för total månadskostnad
def total_cost(flat):

    rent = flat["rent"]
    price = flat["price"]

    return (rent + (price - deposit) * interest * 0.01 * (1 - (deduction * 0.01) / 12))


#hämta data från användaren
def get_input(literal):
    while True:
        str_in = raw_input("Whats the %s? " % (literal))
        try:
            float_in = float(str_in)
            return float_in
        except:
            print "Felaktig inmatinng, försök igen."

'''
interest = get_input("interest")
deposit = get_input("deposit")
deduction = get_input("deduction")
'''
# used for testing only
interest = 7
deposit = 300
deduction = 500

#sortera lägenheter
flats.sort(key=total_cost)

#skriv ut till användaren
for flat in flats:
    print flat['location'], total_cost(flat)

You have to skip the empty line in the data ,,,

# -*- coding: iso-8859-15 -*-

#öppna fil
File = open("bo.txt", "r")
print "\n Välkommen till bostsadsprogrammet. \n Bostäder hämtade från bo.txt \n"
...
...

Ah, thank you! Now the program works just fine.

But now I one other thing I would like to fix:

When I print the values I would like to be able to allow the user to change maximum limits for each value. For instance "price < 5000SEK" or "size >30kvm". (EDIT: I fixed this, so i don't need help with that anymore: I also would like the user to be able to sort the list of flats with regard to the rent, or the size. )
I have a menu for that which looks kind of like this (it's simplified and a lot shorter than it actually is):

def Meny():
    
    val = None
    while val != "0":
              print \
              """
             0 - Quit
             1 - Change rent
             2 - Change price
             3 - Sort by size
             4 - Sort by address
             5 - etc.
             """

             val = raw_input("Whats your choise?")

             if val == "0":
             print "Quit"

             elif val == "1":
             ???            (Can i write something like flats.sort(key="rent", max="5000"?)

             elif val == "3":
             flats.sort(key="size")        (is this how I should do it?)
             
             
             else:
             print "Thats not an option. Try again"

Edited 6 Years Ago by Adam2k: n/a

This article has been dead for over six months. Start a new discussion instead.