Star Generator

This is the place for queries that don't fit in any of the other categories.

Star Generator

Postby Alfapiomega » Thu Oct 17, 2013 8:44 am

Hello everyone,

I have been dealing with Python for some time now (couple of weeks) and I decided I will try to go for an entirely new project now for myself. I am going to create a generator that will create a random star according to real life data!
I did this before and it worked quite well just using the if / while statements and creating and assigning variables. But now that I am dealing with Objects I wanted to remake it but I ran into a problem I am having trouble with understanding.

The code I have for now looks like this:

Code: Select all
class Star:
    #The template class for all of the stars
   
    def __init__(self, number, name, random, type): #size, luminosity, temperature)
        self.number = number
        self.name = name
        self.random = random
        self.type = type
       # self.size = size
       # self.luminosity = luminosity
       # self.temperature = temperature
       
    def descriptionStar(self):
        print("The local star does not cross-match any star in the databanks")
        time.sleep(0.5)
        print("- adding new data in the database -")
        time.sleep(0.5)
        print("..")
        time.sleep(0.5)
        print("..")
        time.sleep(0.5)
        print("..")
        print("new data succesfully added in the database")
        print("The local star is marked as:", self.number, self.name,)
        if self.random <= 30:
            setattr(self, "temperature", random.randrange(20))
            setattr(self, "type", "O")
        elif self.random > 30 and <= 130030:
            setattr(self, "temperature", random.randrange(40))
            setattr(self, "type", "B")
        elif self.random > 130030 and <= 730030:
            setattr(self, "temperature", random.randrange(60))
            setattr(self, "type", "A")   


But when I test it I get "invalid syntax" error on: elif self.random > 30 and <= 130030:

Is Python unable to combine if statements and def statements while in Class?
Also general advice is welcome! I know that objects are an entire new, broad chapter and this project will take some time to finish so if you see a way of streamlining this, go right ahead! :)

Thank you very much!
Alfapiomega
 
Posts: 7
Joined: Thu Oct 17, 2013 8:14 am

Re: Star Generator

Postby metulburr » Thu Oct 17, 2013 9:18 am

Code: Select all
 elif self.random > 30 and <= 130030


I believe you meant

Code: Select all
 elif self.random > 30 and self.random <= 130030
New Users, Read This
OS Ubuntu 14.04, Arch Linux, Gentoo, Windows 7/8
https://github.com/metulburr
steam
User avatar
metulburr
 
Posts: 1387
Joined: Thu Feb 07, 2013 4:47 pm
Location: Elmira, NY

Re: Star Generator

Postby Alfapiomega » Thu Oct 17, 2013 9:26 am

metulburr wrote:
Code: Select all
 elif self.random > 30 and <= 130030


I believe you meant

Code: Select all
 elif self.random > 30 and self.random <= 130030


Well that was quick...

thank you! Such a newbie mistake on my side! :)
Alfapiomega
 
Posts: 7
Joined: Thu Oct 17, 2013 8:14 am

Re: Star Generator

Postby stranac » Thu Oct 17, 2013 9:28 am

You can also write:
Code: Select all
elif 30 < self.random <= 130030:

Since the number being less or equal to 30 was already checked, it would also be enough to write:
Code: Select all
elif self.random <= 130030:
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1097
Joined: Thu Feb 07, 2013 3:42 pm

Re: Star Generator

Postby Alfapiomega » Thu Oct 17, 2013 9:36 am

stranac wrote:You can also write:
Code: Select all
elif 30 < self.random <= 130030:

Since the number being less or equal to 30 was already checked, it would also be enough to write:
Code: Select all
elif self.random <= 130030:


So I don't have to check it? I was a bit afraid that if I leave out the higher than I would get conflicting data.
Alfapiomega
 
Posts: 7
Joined: Thu Oct 17, 2013 8:14 am

Re: Star Generator

Postby stranac » Thu Oct 17, 2013 9:39 am

The elif block can only be executed if the if block was not.
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1097
Joined: Thu Feb 07, 2013 3:42 pm

Re: Star Generator

Postby Alfapiomega » Thu Oct 17, 2013 9:40 am

stranac wrote:The elif block can only be executed if the if block was not.


I know that but I will have quite a lot of elif blocks. Do those counter each other?
Alfapiomega
 
Posts: 7
Joined: Thu Oct 17, 2013 8:14 am

Re: Star Generator

Postby stranac » Thu Oct 17, 2013 9:42 am

Yes.
Friendship is magic!

R.I.P. Tracy M. You will be missed.
User avatar
stranac
 
Posts: 1097
Joined: Thu Feb 07, 2013 3:42 pm

Re: Star Generator

Postby Alfapiomega » Thu Oct 17, 2013 11:05 am

OK, I have another probably completely obvious mistake in my code that I cannot figure out if my life depended on it…

The code is as follows:

Code: Select all
class Star:
    ":The template class for all of the stars"
   
    def __init__(self, number, name, random, type): #size, luminosity, temperature)
        self.number = number
        self.name = name
        self.random = random
        self.type = type
       # self.size = size
       # self.luminosity = luminosity
       # self.temperature = temperature
       
    def descriptionStar(self):
        if self.random <= 30:
            setattr(self, "temperature", random.randrange(20))
            setattr(self, "type", "O")
        elif 30 > self.random <= 130030:
            setattr(self, "temperature", random.randrange(40))
            setattr(self, "type", "B")
        elif 130030 > self.random <= 730030:
            setattr(self, "temperature", random.randrange(60))
            setattr(self, "type", "A")
        elif 730030 > self.random <= 3730030:
            setattr(self, "temperature", random.randrange(80))
            setattr(self, "type", "F")
        elif 3730030 > self.random <= 11330030:
            setattr(self, "temperature", random.randrange(100))
            setattr(self, "type", "G")
        elif 11330030 > self.random <= 23430030:
            setattr(self, "temperature", random.randrange(100))
            setattr(self, "type", "K")
        elif 23430030 > self.random <= 99880030:
            setattr(self, "temperature", random.randrange(100))
            setattr(self, "type", "M")
        elif 99880030 > self.random <= 99978410:
            setattr(self, "temperature", random.randrange(1000))
            setattr(self, "type", "L")
        elif 99978410 > self.random <= 99992610:
            setattr(self, "temperature", random.randrange(100))
            setattr(self, "type", "T")
        else:
            setattr(self, "temperature", random.randrange(100))
            setattr(self, "type", "Y")

    def starDelete(self):
        del self


Then I execute following:

Code: Select all
name_choice = random.randrange(168)
local_star = Star(random.randrange(999), nameslist[name_choice], random.randrange(100000000), "")

and then the main cycle:

Code: Select all
        local_star.descriptionStar()
        print("Name of the local star is:", local_star.number, local_star.name)
        print("Local temperature is", local_star.temperature)
        print("Type of the Star:", local_star.type)
        print(local_star.random)


But whatever I do the game works properly for the name and number of the star. But the type is always marked as L and temperature is appropriate also from L.

So I get results like:

The local star is marked as: 130 Alfirk
Name of the local star is: 130 Alfirk
Local temperature is 912
Type of the Star: L
57407929

The local star is marked as: 148 Caph
Name of the local star is: 148 Caph
Local temperature is 508
Type of the Star: L
80416209

new data succesfully added in the database
The local star is marked as: 2 Sadachbia
Name of the local star is: 2 Sadachbia
Local temperature is 249
Type of the Star: L
99182734


I don’t get what I am doing wrong… I think there must be a typo. I tried using the del function but again it just generates correct name, number but assigns wrong type and temperature.
Alfapiomega
 
Posts: 7
Joined: Thu Oct 17, 2013 8:14 am

Re: Star Generator

Postby Mekire » Thu Oct 17, 2013 12:28 pm

Well your inequality checks are not written correctly.

I imagine instead of:
Code: Select all
elif 30 > self.random <= 130030:
you actually mean:
Code: Select all
elif 30 < self.random <= 130030:

Other than that, you are using setattr in a completely unnecessary way. Just set the attributes directly in this case.

ie this:
Code: Select all
setattr(self, "temperature", random.randrange(40))
Should just be:
Code: Select all
 self.temperature = random.randrange(40)

Aside from this I also think that in your case a long if/elif block just isn't the way to go. You could do the same using a dictionary.

Cheers,
-Mek
User avatar
Mekire
 
Posts: 986
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: Star Generator

Postby Alfapiomega » Thu Oct 17, 2013 12:49 pm

I JUST noticed that and fixed the issue...

I think I am too tired and should head to bed, I did a lot of experimenting and dealing with this today. Sorry for really dumb questions but sometimes by asking you think about it differently.

The other advice you gave me is superb! I just noticed that I can leave the attributes in the blank state by just assigning "" which then leaves them ready to be given any assignment. Do I get it correctly that the setattr creates a new one?

Regarding the dictionaries I looked into that a while ago but I am unsure how I should use it in your opinion. Mind you that there will be more, quite different attributes for each of the star type (luminosity, temperature will be greatly changed, size, elements...). Therefore the dictionary would be good i.e. for storing the elements that the star composes of but how would I put marked statistics in it? I mean it would just be a set of numbers in there and I would end up with numerous dictionaries instead...? Or can it store more than more than one value of each kind?

Thank you for all your replies btw, I am learning a lot from just reading your posts... :)
Alfapiomega
 
Posts: 7
Joined: Thu Oct 17, 2013 8:14 am

Re: Star Generator

Postby Mekire » Thu Oct 17, 2013 1:22 pm

Well keeping with your numbers; I was thinking something like this:

Code: Select all
import random

#dict of the form {chance : (type, max_temperature)}
STAR_TYPES = {30 : ("O", 20),
              130030 : ("B", 40),
              730030 : ("A", 60),
              3730030 : ("F", 80),
              11330030 : ("G", 100),
              23430030 : ("K", 100),
              99880030 : ("M", 100),
              99978410 : ("L", 1000),
              99992610 : ("T", 100),
              100000000 : ("Y", 100)}

class Star(object):
    def __init__(self):
        self.type, self.temperature = self.get_description()

    def __repr__(self):
        return "Type: {type}, Temperature: {temperature}".format(**vars(self))

    def get_description(self):
        roll = random.randrange(100000000)
        for chance in sorted(STAR_TYPES):
            if roll <= chance:
                star, temp_range = STAR_TYPES[chance]
                temp = random.randrange(temp_range)
                return star, temp

Note that your own given numbers are extremely weighted towards type "M", but other types do occur.
-Mek
User avatar
Mekire
 
Posts: 986
Joined: Thu Feb 07, 2013 11:33 pm
Location: Amakusa, Japan

Re: Star Generator

Postby Alfapiomega » Thu Oct 17, 2013 1:39 pm

Oh, I see!

Well the fact is I don't think that could work as the temperature / luminosity will be much more complex than that. I.e. I worked on the code a bit more now and this is what I have:

Code: Select all
# ---- Main Star

class Star:
    ":The template class for all of the stars"
   
    def __init__(self, number, name, random, type, temperature, luminosity, size):
        self.number = number
        self.name = name
        self.random = random
        self.type = type
        self.temperature = temperature
        self.luminosity = luminosity
        self.size = size
       # self.size = size
       
    def descriptionStar(self):
        print("The local star does not cross-match any star in the databanks")
        time.sleep(0.5)
        print("- adding new data in the database -")
        time.sleep(0.5)
        print("..")
        time.sleep(0.5)
        print("..")
        time.sleep(0.5)
        print("..")
        print("new data succesfully added in the database")
        print("The local star is marked as:", self.number, self.name,)
        if self.random <= 30:
            self.temperature = 40000 - ((self.random // 3) * 700)
            self.luminosity = 45000 - ((self.random // 3) * 1500)
            self.size = 51 - (random.randrange(100) * 0.36)
            self.type = "O"
            #only 1 in 300 000 are O class, lower the number appropriately - 0.00003%
            #temperatures exceeding 33,000 K
        elif self.random > 30 and self.random <= 130030:
            self.temperature = 33000 - ((self.random - 30) // 13000) * 2300
            self.luminosity = 30000 - ((self.random - 30) // 13000) * 500
            self.size = 16 - (random.randrange(100) * 0.13)
            self.type = "B"
            #0.13% of stars
            #temperatures between 10,000–33,000 K
        elif self.random > 130030 and self.random <= 730030:
            self.temperature = 10000 - ((self.random - 130030) // 60000) * 245
            self.luminosity = 25000 - ((self.random - 130030) // 60000) * 2450
            self.size = 2.1 - (random.randrange(100) * 0.007)
            self.type = "A"
            #0.6% of stars
            #temperatures between 7,500–10,000 K           
        elif self.random > 730030 and self.random <= 3730030:
            self.temperature = 7500 - ((self.random - 730030) // 300000) * 150
            self.luminosity = 5 - ((self.random - 730030) // 300000) * 0.35
            self.size = 1.4 - (random.randrange(100) * 0.0036)
            self.type = "F"
            #3% of stars
            #temperatures between 6,000–7,500 K
        elif self.random > 3730030 and self.random <= 11330030:
            self.temperature = 6000 - ((self.random - 3730030) // 760000) * 80
            self.luminosity = 1.5 - ((self.random - 3730030) // 760000) * 0.09
            self.size = 1.04 - (random.randrange(100) * 0.0024)
            self.type = "G"
            #7.6% of stars
            #temperatures between 5,200–6,000 K         
        elif self.random > 11330030 and self.random <= 23430030:
            self.temperature = 5200 - ((self.random - 11330030) // 1210000) * 150
            self.luminosity = 0.6 - ((self.random - 11330030) // 1210000) * 0.052
            self.size = 0.8 - (random.randrange(100) * 0.0035)
            self.type = "K"
            #12.1% of stars
            #temperatures between 3,700–5,200 K
        elif self.random > 23430030 and self.random <= 99880030:
            self.temperature = 3700 - ((self.random - 23430030) // 7645000) * 170
            self.luminosity = 0.08 - ((self.random - 23430030) // 7645000) * 0.007
            self.size = 0.45 - (random.randrange(100) * 0.004)
            self.type = "M"
            #76.45% of stars
            #temperatures between 2,000–3,700 K
        elif self.random > 99880030 and self.random <= 99978410:
            self.temperature = random.randrange(160)
            self.type = "L"
            #Brown Dwarf 82 ze 100
        elif self.random > 99978410 and self.random <= 99992610:
            self.temperature = random.randrange(180)
            self.type = "T"
            #Brown Dwarf 12 ze 100
        else:
            self.temperature = random.randrange(200)
            self.type = "Y"
            #Brown Dwarf 6 ze 100


The numbers are OK btw. The vast majority of stars is M class - I added some notes into the code that I had present in the original project I did. The luminosity too will vary with the number rolled, so will the size. It takes a bit of computing to get the numbersright but these do work ideally. I can't figure how that could work for the dictionary though...
Alfapiomega
 
Posts: 7
Joined: Thu Oct 17, 2013 8:14 am


Return to General Coding Help

Who is online

Users browsing this forum: W3C [Linkcheck] and 3 guests

cron