Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
tef
May 30, 2004

-> some l-system crap ->

NtotheTC posted:

Does anyone know if pipenv can replicate the behaviour of vex? (https://pypi.python.org/pypi/vex) I've always found vex to be lightyears ahead of virtualenvwrapper for development (activating and deactivating virtualenvs manually is a horrible pattern) but I've never used pipenv and people seem very happy with it

To be clear, the behaviour I want to replicate is

Bash code:
vex myenv python myscript.py
instead of
Bash code:
workon myenv
python myscript.py
deactivate myenv

pipenv run python myscript.py

Adbot
ADBOT LOVES YOU

Seventh Arrow
Jan 26, 2005

The code cops are busting me with an "invalid syntax" error for the crime of trying to combine comparison operations in an if statement (I think):

code:
pr = [df["price"]]
cl = color
if pr <= 999:
    cl = 'green'
elif pr > 1000 and < 2000:
    cl = 'yellow'
elif pr > 2000 and < 3000:
    cl = 'orange'
else:
    cl = 'red'
The results from my googling efforts all had bad indentation of some sort, but I don't believe that's the case here - although I could be wrong.

Maybe the problem is trying to combine arithmetic operations on a single line? If so, I guess I could do it like this:

code:
pr = [df["price"]]
cl = color
if pr <= 999:
    cl = 'green'
elif pr <= 2000:
    cl = 'yellow'
elif pr <= 3000:
    cl = 'orange'
else:
    cl = 'red'
But this seems strange...if python sees that "pr" is less than 999 and also less than 2000, won't the universe collapse on itself or something?

Linear Zoetrope
Nov 28, 2011

A hero must cook
You can't be implicit in your comparison

You need something like
code:
elif pr >= 1000 and pr <= 2000:
Python also has a handy feature called chained comparisons where you can do

code:
elif 1000 <= pr <= 2000:
However, your second version is preferred. Python (and most any programming language) will only evaluate the conditionals in order from first to last, so if it's testing if pr <= 2000 it's already executed and proven that it's not <= 999

Seventh Arrow
Jan 26, 2005

Linear Zoetrope posted:

However, your second version is preferred. Python (and most any programming language) will only evaluate the conditionals in order from first to last, so if it's testing if pr <= 2000 it's already executed and proven that it's not <= 999

I kind of suspected that was the case. Thanks!

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!

Seventh Arrow posted:

The code cops are busting me with an "invalid syntax" error for the crime of trying to combine comparison operations in an if statement (I think):

code:
pr = [df["price"]]
cl = color
if pr <= 999:
    cl = 'green'
elif pr > 1000 and < 2000:
    cl = 'yellow'
elif pr > 2000 and < 3000:
    cl = 'orange'
else:
    cl = 'red'
The results from my googling efforts all had bad indentation of some sort, but I don't believe that's the case here - although I could be wrong.

Maybe the problem is trying to combine arithmetic operations on a single line? If so, I guess I could do it like this:

code:
pr = [df["price"]]
cl = color
if pr <= 999:
    cl = 'green'
elif pr <= 2000:
    cl = 'yellow'
elif pr <= 3000:
    cl = 'orange'
else:
    cl = 'red'
But this seems strange...if python sees that "pr" is less than 999 and also less than 2000, won't the universe collapse on itself or something?

I’m not sure how “correct” it is but I see and use this all the time. If pr <= 999 then the condition is met and nothing else will evaluate. If pr was not <= 999 then it moves onto the next condition, which is now implicitly “999 < pr <= 2000.

Seventh Arrow
Jan 26, 2005

Boris Galerkin posted:

I’m not sure how “correct” it is but I see and use this all the time. If pr <= 999 then the condition is met and nothing else will evaluate. If pr was not <= 999 then it moves onto the next condition, which is now implicitly “999 < pr <= 2000.

Yes, they have a section devoted to this in Python Crash Course but I lent it to a friend; still, I had a feeling this would be the case but I wasn't sure. The next trick will be to see if it fits with the rest of the code.

Seventh Arrow
Jan 26, 2005

Ok I'm back and it seems like my if/elif/else loop is not quite getting along with the rest of the code.

I started off trying to pull the latitude and longitude in a spreadsheet and put them as markers on a folium map. With some help from you guys, it worked with the following:

code:
import pandas as pd
import folium

df = pd.read_excel('df_condo_v9_t1.xlsx', sheetname=0, header=0)

df.shape

df.dtypes

map_center = [df["Latitude"].mean(), df["Longitude"].mean()]

map_1 = folium.Map(location=map_center, tiles="Stamen Terrain", zoom_start=12)

for i, row in df[["Latitude", "Longitude"]].dropna().iterrows():
    position = (row["Latitude"], row["Longitude"])
    folium.Marker(position).add_to(map_1)

map_1
This worked A-OK. Then I decided to get a little fancy and make the markers different colours based on the price, so $0 - $1000 would have a green marker, $1000 - $2000 would have a yellow marker, $2000 - $3000 would have an orange marker, and $3000 and above would have a red marker. So I added some variables and my if loop to get this:

code:
import pandas as pd
import folium

df = pd.read_excel('df_condo_v9_t1.xlsx', sheetname=0, header=0)

df.shape

df.dtypes

map_center = [df["Latitude"].mean(), df["Longitude"].mean()]

map_1 = folium.Map(location=map_center, tiles="Stamen Terrain", zoom_start=12)


pr = [df["Price"]]
cl = color
if pr <= 999:
    cl = 'green'
elif pr < 2000:
    cl = 'yellow'
elif pr < 3000:
    cl = 'orange'
else:
    cl = 'red'


for i, row in df[["Latitude", "Longitude"]].dropna().iterrows():
    position = (row["Latitude"], row["Longitude"])
    folium.Marker(position), icon=folium.Icon(color='cl').add_to(map_1)

map_1
When I try to run this in jupyter, I get:

code:
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-e9dbacbdd4bf> in <module>()
      1 pr = [df["Price"]]
      2 cl = color
----> 3 if pr < 999:
      4     cl = 'green'
      5 elif pr < 2000:

TypeError: unorderable types: list() < int()
Which is strange because at first it was telling me "color is not defined." Anyways, it might be because it sees the price field as float64? I'm not sure.

df.dtypes

Post_id float64
Price float64
Bedroom float64
Bathroom float64
Sqft float64
Latitude float64
Longitude float64
Description object
Latlng object
Postal_code object
dtype: object

SurgicalOntologist
Jun 17, 2004

You're getting that error in particular, because [df['Price']] is a list containing one item, the pandas column. You want just df['Price'].

However, that won't actually get the behavior you want, because just as you can't compare a list and an int, you can't compare a dataframe column and an int (well technically you can, but you won't get a True or False, you'll get a columns of True/False, which wont' work in that context). Notice that you're only setting this cl variable once, whereas you want it to take a different value for every row.

Your options are either:
1. You could set the color inside the loop by putting all that if/elif stuff inside the loop, therefore checking for a new color every time. You will need to change a couple other things which I leave as an excercise.
2. You could set all the colors ahead of time with something like pd.cut(df['Price'], [0, 1000, 2000, 3000], labels=['green', 'yellow', 'orange', 'red']).

Seventh Arrow
Jan 26, 2005

The if/elif stuff isn't in the loop already? I thought that the if/elif stuff was the loop :psyduck:

SurgicalOntologist
Jun 17, 2004

The loop is the part that starts with for and ends when the indentation returns to the previous level.

Seventh Arrow
Jan 26, 2005

Ah, I see what you mean. Thank you. I will take a swing at #1 and see how it goes.

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

A loop... loops! It can go around multiple times, until some condition is met

The if/elif stuff is just a conditional - you go through it once, and follow the first branch that matches, then you pop out the other side

You can put a conditional inside a loop of course, which is pretty common - iterating over several things, doing something different based on the current situation each time around

baka kaba fucked around with this message at 02:08 on Jan 23, 2018

Seventh Arrow
Jan 26, 2005

Ok I think I'm almost there. I've managed to twist its arm enough that it will post the map marker with a colour...once. So I think I'm in the ballpark, but I get a map with only one marker. Here's what I have so far:

code:
import pandas as pd
import folium

df = pd.read_excel('df_condo_v9_t1.xlsx', sheetname=0, header=0)

df.shape

df.dtypes

map_center = [df["Latitude"].mean(), df["Longitude"].mean()]

map_1 = folium.Map(location=map_center, tiles="Stamen Terrain", zoom_start=12)

class color:
    def out(self):
        print("successful.")

for i, row in df[["Latitude", "Longitude", "Price"]].dropna().iterrows():
    position = (row["Latitude"], row["Longitude"])
    pr = (row["Price"])
    cl = color
    if pr < 999:
        cl = 'green'
    elif pr < 2000:
        cl = 'yellow'
    elif pr < 3000:
        cl = 'orange'
    else:
        cl = 'red'
folium.Marker(position, icon=folium.Icon(color=cl)).add_to(map_1)

map_1
I think this could be due to one of two things:

A) The "dropna" and "iterrows" are working their magic with the "position" variable so that when the process gets around to "pr", almost all of the rows have been dropped. If this is true, then I don't know enough about python to properly address it.
B) It could be something folium-specific, since jupyter displays the following: <folium.map.Marker at 0x7efe9fd758d0>

Also, the "class color" thing is something I got off of Stack Overflow. If I don't put it in there, it says that "color is not defined."

Jose Cuervo
Aug 25, 2004

Seventh Arrow posted:

Ok I think I'm almost there. I've managed to twist its arm enough that it will post the map marker with a colour...once. So I think I'm in the ballpark, but I get a map with only one marker. Here's what I have so far:

code:
import pandas as pd
import folium

df = pd.read_excel('df_condo_v9_t1.xlsx', sheetname=0, header=0)

df.shape

df.dtypes

map_center = [df["Latitude"].mean(), df["Longitude"].mean()]

map_1 = folium.Map(location=map_center, tiles="Stamen Terrain", zoom_start=12)

class color:
    def out(self):
        print("successful.")

for i, row in df[["Latitude", "Longitude", "Price"]].dropna().iterrows():
    position = (row["Latitude"], row["Longitude"])
    pr = (row["Price"])
    cl = color
    if pr < 999:
        cl = 'green'
    elif pr < 2000:
        cl = 'yellow'
    elif pr < 3000:
        cl = 'orange'
    else:
        cl = 'red'
folium.Marker(position, icon=folium.Icon(color=cl)).add_to(map_1)

map_1
I think this could be due to one of two things:

A) The "dropna" and "iterrows" are working their magic with the "position" variable so that when the process gets around to "pr", almost all of the rows have been dropped. If this is true, then I don't know enough about python to properly address it.
B) It could be something folium-specific, since jupyter displays the following: <folium.map.Marker at 0x7efe9fd758d0>

Also, the "class color" thing is something I got off of Stack Overflow. If I don't put it in there, it says that "color is not defined."



You need to place the line

folium.Marker(position, icon=folium.Icon(color=cl)).add_to(map_1)

inside the for loop (so basically tab it over once).

Right now the only thing being added to the map is the last location.

EDIT: Also it looks like you chose to use the iterrows() solution that I proposed, but as pointed out that is probably the slowest way to do things, and you should probably use one of the other suggested methods.

Jose Cuervo fucked around with this message at 02:20 on Jan 24, 2018

Dr Subterfuge
Aug 31, 2005

TIME TO ROC N' ROLL

Your line:

code:
folium.Marker(position, icon=folium.Icon(color=cl)).add_to(map_1)
is only firing once because it isn't part of the for loop. The for loop only acts on things that are indented more than it, so what your program is doing is reassigning your color variable until your are done iterating over your column, exiting the for loop, and applying the last value it computed to the map. Just indent the folium line and you should be golden.

What you are doing is like this:

code:
num = 0
for i in range(5):
    num += i
print num
The behavior you want is like this:

code:
num = 0
for num in range(5):
    num += i
    print num

Seventh Arrow
Jan 26, 2005

:doh: I remember telling myself to put that line back, too. Woops! Thanks for the help.

Boris Galerkin
Dec 17, 2011

I don't understand why I can't harass people online. Seriously, somebody please explain why I shouldn't be allowed to stalk others on social media!
Here is why it says “color” is undefined without that class:

code:
for i, row in df[["Latitude", "Longitude", “Price"]].dropna().iterrows():
    position = (row["Latitude"], row["Longitude"])
    pr = (row["Price"])
    cl = color   # <——————!!!!
    if pr < 999:
        cl = 'green'
    ...
The important thing is that on the right hand side, you have color without any quote marks.

You could simply remove this line (and the “class color” segment you added above) and everything would be fine again. If the reason you have this line here is to pre declare “cl” as a variable then that’s not needed in Python.

Alternatively, you could change that line to

code:
cr = ‘color’
And that’ll fix it too. Putting color in quotes makes it a string, which is what you want anyway.

Seventh Arrow
Jan 26, 2005

Ok that does indeed make sense, thanks. But I think classes or their objects do need to be defined I think, right? That what "def __init__" is for?

Actually, I think I'll just look up the python documentation and review some of this stuff since I'm not gonna get my book back any time soon.

QuarkJets
Sep 8, 2008

Seventh Arrow posted:

Ok that does indeed make sense, thanks. But I think classes or their objects do need to be defined I think, right? That what "def __init__" is for?

Actually, I think I'll just look up the python documentation and review some of this stuff since I'm not gonna get my book back any time soon.

You don't have to pre-define cl, because it's definitely being defined in your if/elif/else block. You're setting cl to a string (eg "red", "blue", etc are all instances of the string class) in those blocks of code. This effectively means that the "cl = color" line does nothing and can just be deleted. An IDE like pycharm would point this out for you as well.

If you want an instance of a color class, then you would indeed need to define a color class first. But it doesn't sound like that's what you actually want; the function you're accessing just wants a string with the name of the requested color

baka kaba
Jul 19, 2003

PLEASE ASK ME, THE SELF-PROFESSED NO #1 PAUL CATTERMOLE FAN IN THE SOMETHING AWFUL S-CLUB 7 MEGATHREAD, TO NAME A SINGLE SONG BY HIS EXCELLENT NU-METAL SIDE PROJECT, SKUA, AND IF I CAN'T PLEASE TELL ME TO
EAT SHIT

If it helps, variables in python are basically just keys in a dictionary, so you can just go thing = whatever at any time and it just stores that key/value pair. So there's no need to pre-declare that variable like you would in other languages where you want to reuse the same reference - you're just overwriting the same entry in the dictionary

Rosalind
Apr 30, 2013

When we hit our lowest point, we are open to the greatest change.

How do I remove certain strings of text (e.g. any text in brackets) from a list of dictionaries?

To explain further, I have a list that contains dictionaries of song lyrics (each dictionary has two items: the song title and the lyrics). However, some of the lyrics contain various junk I want to get rid of like: "[Chorus]", "[Verse 1]", and "[Talking]". So I need something that goes through all the lyrics and removes anything that's in brackets basically. Sorry if this is an easy/stupid question--I'm very new to Python. I'm using Python 3 if that matters.

Dominoes
Sep 20, 2007

I'm not sure where in the list of dicts is your quoted strings are (keys? values?), but you could apply something like this to each string, in a loop or comprehension:

Python code:
import re

for lyrics in lyricses:   # Modify this loop based on where the lyrics are in your data.
    # \ escapes the brackets, which normally have a special meaning in regex. The period
    # means any char, and the * means any amount of the char. The parentheses specify what
    # to return by the .groups() method; ie all text between brackets.
    try:
        bracketed_phrases = re.search(r'\[(.*)\]', lyrics).groups()
    except AttributeError:  # the result of re.search is None if there's no bracketed text.
        continue
    for phrase in bracketed_phrases:
        # Code here to replace the text will vary depending on where these lyrics live in your structure.
        # You could apply x.replace('[', '') etc, or  x[1:-1] to the orig phrase
        # or replace the original phrase with phrase, which which is now trimmed.
        
It uses a mini-language called Regex, which is for pattern-matching in strings. The code above will probably fail if the bracket format is inconsistent, eg mismatched brackets.

Dominoes fucked around with this message at 18:35 on Jan 25, 2018

Dr Subterfuge
Aug 31, 2005

TIME TO ROC N' ROLL
Here's the documentation for the re module itself. And a how to that's a bit more digestible.

Rosalind
Apr 30, 2013

When we hit our lowest point, we are open to the greatest change.

Sorry I can be more specific and post a concrete example. Here's an example of one of the dictionaries in the list:

quote:

{'title': 'Pale Green Things', 'lyrics': "\n\n[Verse 1]\nGot up before dawn\nWent down to the racetrack\nRiding with the windows down\nShortly after your first heart attack\nYou parked behind the paddock\nCracking asphalt underfoot\nComing up through the cracks\n\n[Chorus]\nPale green things\nPale green things\n\n[Verse 2]\nYou watched the horses run their workouts\nYou held your stopwatch in your left hand\nAnd a Racing Form beneath your arm\nCasting your gaze way out to no man's land\nSometimes I'll meet you out there\nLonely and frightened\nFlicking my tongue out at the wet leaves\n\n[Chorus]\nPale green things\nPale green things\n\n[Verse 3]\nMy sister called at 3 AM\nJust last December\nShe told me how you'd died at last\nAt last\nThat morning at the racetrack\nWas one thing that I remembered\nI turned it over in my mind\nLike a living Chinese finger trap\nSeaweed in Indiana sawgrass\n\n[Chorus]\nPale green things\nPale green things\n\n"}

I want to remove all the bracketed text from the lyrics so that it in the end it looks like this:

quote:

{'title': 'Pale Green Things', 'lyrics': "\n\n\nGot up before dawn\nWent down to the racetrack\nRiding with the windows down\nShortly after your first heart attack\nYou parked behind the paddock\nCracking asphalt underfoot\nComing up through the cracks\n\n\nPale green things\nPale green things\n\n\nYou watched the horses run their workouts\nYou held your stopwatch in your left hand\nAnd a Racing Form beneath your arm\nCasting your gaze way out to no man's land\nSometimes I'll meet you out there\nLonely and frightened\nFlicking my tongue out at the wet leaves\n\n\nPale green things\nPale green things\n\n\nMy sister called at 3 AM\nJust last December\nShe told me how you'd died at last\nAt last\nThat morning at the racetrack\nWas one thing that I remembered\nI turned it over in my mind\nLike a living Chinese finger trap\nSeaweed in Indiana sawgrass\n\n\nPale green things\nPale green things\n\n"}

Dominoes
Sep 20, 2007

Python code:
import re

for song in songs:
    try:
        # This regex is modified from the example above to include the brackets in the groups.
        bracketed_phrases = re.search(r'(\[.*\])', song['lyrics']).groups()
    except AttributeError:  # the result of re.search is None if there's no bracketed text.
        continue
    for phrase in bracketed_phrases:
        song['lyrics'].replace(phrase, '')        

Rosalind
Apr 30, 2013

When we hit our lowest point, we are open to the greatest change.

That seems to have worked. Thank you!

Dr Subterfuge
Aug 31, 2005

TIME TO ROC N' ROLL
Pretty sure this would also work:

Python code:
import re

for song in songs:
    # This regex substitutes matches of a pattern with a supplied string and returns the result.
    lyrics = re.sub(r'(\[.*\])', '', song['lyrics'])
    song['lyrics'] = lyrics   

Dr Subterfuge fucked around with this message at 19:31 on Jan 25, 2018

Baronash
Feb 29, 2012

So what do you want to be called?
Hey, I'm trying to figure out how to end up with a csv file to do some basic data analysis. I've been building off some code that I shamelessly stole from someone else, which is scraping data from a prediction market and turning each security into a panda series with the date and price for the past year. I would like to take all the the securities on the market (about 1000), and have each security represented by a column in a csv file.

Python code:
full_list = Series([])
df = get_all_prices() #Returns a pandas dataframe with name and ticker symbol for every available security
security_list = df['Ticker']
for sec in security_list:
	s = get_historic(sec) #Returns panda series
	full_list = full_list.append(s)
        #print(full_list)
Series.to_csv(full_list,'hsx_security_history',header='date, price')
Currently, this is the csv file it gives me:
code:
2017-10-20,6.0
2017-10-21,5.97
2017-10-22,6.05
2017-10-23,5.9
2017-10-24,5.7
...
Is there a good way to have the extra series added as columns, rather than additional rows?

fantastic in plastic
Jun 15, 2007

The Socialist Workers Party's newspaper proved to be a tough sell to downtown businessmen.
I have an interview with a Python shop coming up and my background is in Ruby and JavaScript. The company told me to be prepared to demonstrate understanding of "lists, maps, and queues" in the interview and I want to sanity check that I have the right terminology. Am I correct in thinking that in Python, a list is the data structure that looks like [foo, bar, baz], a map is the data structure that looks like {"foo": "bar", "baz":"qux"} and a queue is implemented with collections.deque?

Dominoes
Sep 20, 2007

map is a function that applies another function to all items of an iterable (such as a list).

fantastic in plastic
Jun 15, 2007

The Socialist Workers Party's newspaper proved to be a tough sell to downtown businessmen.

Dominoes posted:

map is a function that applies another function to all items of an iterable (such as a list).

Okay, thanks. Is there anything more to it than meets the eye? It looks like I just do something like

code:
map(lambda x: x**2, [1, 2, 3])
and that's all there is to it.

The March Hare
Oct 15, 2006

Je ręve d'un
Wayne's World 3
Buglord

fantastic in plastic posted:

I have an interview with a Python shop coming up and my background is in Ruby and JavaScript. The company told me to be prepared to demonstrate understanding of "lists, maps, and queues" in the interview and I want to sanity check that I have the right terminology. Am I correct in thinking that in Python, a list is the data structure that looks like [foo, bar, baz], a map is the data structure that looks like {"foo": "bar", "baz":"qux"} and a queue is implemented with collections.deque?

Worth noting that they may not mean "be comfortable with lists maps and queues" in terms of their python implementations. They may just want you to write the code for a linked list or a queue or whatever.

fantastic in plastic
Jun 15, 2007

The Socialist Workers Party's newspaper proved to be a tough sell to downtown businessmen.
That's true, too. In the phone interview I did with an engineer there, we spoke a lot about queues, so I'm definitely expecting questions in that area. I just wanted to make sure I wasn't overthinking it.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

fantastic in plastic posted:

Okay, thanks. Is there anything more to it than meets the eye? It looks like I just do something like

code:
map(lambda x: x**2, [1, 2, 3])
and that's all there is to it.

It's not terribly uncommon for dictionaries to be referred to as "maps". It's not technically correct, but I'd lean towards them meaning dictionaries rather than the map function since they mentioned it in the context of two other data structures.

And yes, a dictionary is one of these:

Python code:
im_a_stupid_dict = {'one': 1, 7: 'seven', 'name': 'fred'}
Be aware, that if you don't have the key: value syntax in the curly braces, you're looking at a set data structure which looks like:

Python code:
im_a_set = {'a', 'b', 'c', 'd'}

Dr Subterfuge
Aug 31, 2005

TIME TO ROC N' ROLL

Baronash posted:

Is there a good way to have the extra series added as columns, rather than additional rows?

I've never actually used pandas, but I can tell you that you should be working with a DataFrame as your result. Series are one-dimensional arrays, which is why appending one to another only extends the length full_list.

vikingstrike
Sep 23, 2007

whats happening, captain
pd.concat(your list of series, axis=1) should do it.

Thermopyle
Jul 1, 2003

...the stupid are cocksure while the intelligent are full of doubt. —Bertrand Russell

Here's a neat thing if you're one of the cool people like me who can mostly move most of their projects to keep up with the latest python versions. Coming in Python 3.7 are data classes!

Data classes are kind of a hybrid between namedtuples and regular classes.

They look like this:

Python code:
@dataclass
class Person:
    first_name: str
    last_name: str
    country: str = 'USA'
You can then instantiate it like:

Python code:
>>> fred = Person(first_name='Fred', last_name='Smith')
>>> print(fred
Person(first_name="Fred", last_name="Smith", country="USA")
The main claim to fame is that data classes automatically implement a bunch of dunder methods (like __repr__, __eq__ etc)and are fully subclassable and can inherit from other classes.

They're a lot more powerful than this, so click through the the above-linked PEP to read more about em.

Being the typing fan that I am, I especially appreciate being able to restrict class vs instance variables, and also the ability to freeze instances.

Dominoes
Sep 20, 2007

Love it. Mutable too; a reason that sometimes keeps me from using namedtuples.

Dominoes
Sep 20, 2007

fantastic in plastic posted:

Okay, thanks. Is there anything more to it than meets the eye? It looks like I just do something like

code:
map(lambda x: x**2, [1, 2, 3])
and that's all there is to it.
That's the idea. I find that if you have to define an anonymous function within the map, it's usually cleaner to use a comprehension instead; map is nice when you already have a function, or are using a builtin/something from a library.

Adbot
ADBOT LOVES YOU

ZarathustraFollower
Mar 14, 2009



So I just started using python, and because I'm flailing around in the dark like an idiot, I could use some help. I'm trying to write a small script that runs some simulations and then saves the data out. Because I want to run many simulations with the same settings I would like to ideally give the functions the # of times to run and have it write out the data into a unique file. To do this, I want to make a filename string and tell it to write/append that file, however, when I run my script it's telling me that it can't take a tuple for the file name input and I don't understand why my data is a tuple to begin with. Everything else with the code works, and it's fine if I manually put in the filename into each open() call, but I want to automate as much as I can. Basically, I have this code:

quote:

filename=('HeteroFreq2.txt'),
with open(filename,'a') as f:
print(pop.dvars().gen, file = f)

and I get this error

quote:

TypeError: expected str, bytes or os.PathLike object, not tuple

What am I doing wrong with declaring the filename?

Edit: I'm an idiot who missed that extra ',' at the end of the filename declaration.

ZarathustraFollower fucked around with this message at 22:14 on Jan 25, 2018

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply