skip to navigation
skip to content

Planet Python

Last update: January 11, 2022 01:41 AM UTC

January 11, 2022


Codementor

One-Hot Encoding in Data Science

What is One-Hot Encoding in Data Science? and How to implement it in Python using Pandas or Scikit-Learn.

January 11, 2022 01:06 AM UTC

January 10, 2022


Inspired Python

Solving Wordle Puzzles with Basic Python

Solving Wordle Puzzles with Basic Python

Have you heard of Wordle? It’s a deceptively simple word puzzle. You’re asked to guess the word of the day, which is a five-letter word in English. If you guess wrong, you’re given a few hints: a letter in the word is green if your guess for that letter in that position is right; a yellow letter if that letter is present in the word, but not that position; and gray, if the letter is not in the word at all.

Deceptively simple, and yet quite challenging! Here’s how you can write a Wordle Solver with Python sets, list comprehensions, a bit of good luck!



Read More ->

January 10, 2022 03:38 PM UTC


Real Python

Build and Handle POST Requests in Django – Part 3

In this four-part tutorial series, you’re building a social network with Django that you can showcase in your portfolio. This project is strengthening and demonstrating your understanding of relationships between Django models and showing you how to use forms so that users can interact with your app and with each other. You’re also making your site look good by using the CSS framework Bulma.

In the previous part of this tutorial series, you built templates and views for displaying a list of all profiles, as well as individual profile pages. You also learned how to apply style rules defined by the CSS framework Bulma to make your pages look good.

In the third part of this tutorial series, you’ll learn how to:

  • Create the front-end interface to let users follow and unfollow profiles
  • Submit and handle a POST request in Django using buttons
  • Set up the model for your text-based content
  • Build styled templates to display content on the front end
  • Use intricate model relationships in template code

At the end of this part, your social network will have all the pages you’d expect, and you’ll be able to create dweets on the back end and display them on the front end. Your users will be able to discover and follow other users and read the contents of the profiles that they follow. They’ll also be able to click a button that sends an HTTP POST request handled by Django to unfollow a profile if they want to stop reading a certain user’s content.

You can download the code that you’ll need to start the third part of this project by clicking the link below and going to the source_code_start/ folder:

Get Source Code: Click here to get the source code you’ll use to build and handle POST requests with Django.

Demo

In this four-part tutorial series, you’re building a small social network that allows users to post short text-based messages. The users of your app can also follow other user profiles to see the posts of those users or unfollow them to stop seeing their text-based posts:

You’re also learning how to use the CSS framework Bulma to give your app a user-friendly appearance and make it a portfolio project you can be proud to show off!

In the third part of this tutorial series, you’ll continue working with Bulma-styled templates, and you’ll create the model for your text-based message content. You’ll also set up and handle HTTP POST request submissions on your Django app’s front end, which will allow users to follow or unfollow each other by clicking a button:

At the end of this tutorial, each user will be able to go to a new dashboard page to access a personal feed of dweets that’s based on which profiles they follow. They’ll also be able to follow and unfollow other users. That’s a giant leap ahead for your Django social network!

Project Overview

In this section, you’ll get an overview of what topics you’ll cover in this third part of the tutorial series. You’ll also get a chance to revisit the full project implementation steps, in case you need to skip back to a previous step from earlier in the series or if you want to see what’s still up ahead.

At this point, you should have finished working through parts one and two of this tutorial series. If you did, then you’re now ready to continue with the next steps of this tutorial series. These steps focus on the code logic for following and unfollowing profiles, as well as how to set up dweets:

After completing all the steps in the third part of the tutorial series, you can continue with part four.

To get a high-level idea of how you’re working through all four parts of this tutorial series on building your Django social network, you can expand the collapsible section below:

You’re implementing the project in a number of steps spread out over multiple separate tutorials in this series. There’s a lot to cover, and you’re going into detail along the way:

✅ Part 1: Models and Relationships

  • Step 1: Set Up the Base Project
  • Step 2: Extend the Django User Model
  • Step 3: Implement a Post-Save Hook

✅ Part 2: Templates and Front-End Styling

  • Step 4: Create a Base Template With Bulma
  • Step 5: List All User Profiles
  • Step 6: Access Individual Profile Pages

📍 Part 3: Follows and Dweets

  • Step 7: Follow and Unfollow Other Profiles
  • Step 8: Create the Back-End Logic For Dweets
  • Step 9: Display Dweets on the Front End

⏭ Part 4: Forms and Submissions

  • Step 10: Submit Dweets Through a Django Form
  • Step 11: Prevent Double Submissions and Handle Errors
  • Step 12: Improve the Front-End User Experience

Each of these steps will provide links to any necessary resources. By approaching the steps one at a time, you’ll have the opportunity to pause and come back at a later point in case you want to take a break.

With the high-level structure of this tutorial series in mind, you’ve got a good idea of where you’re at and which implementation steps you’ll handle in the last part.

Before getting started with the next step, take a quick look at the prerequisites to skim any links to other resources that might be helpful along the way.

Prerequisites

To successfully work through this part of your project, you need to have completed the first part on models and relationships and the second part on templates and styling, and you should confirm that your project is working as described there. It would be best if you’re also comfortable with the following concepts:

Read the full article at https://realpython.com/django-social-post-3/ »


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

January 10, 2022 02:00 PM UTC


ItsMyCode

How to Fix: KeyError in Pandas?

ItsMyCode |

The KeyError in Pandas occurs when you try to access the columns in pandas DataFrame, which does not exist, or you misspell them. 

Typically, we import data from the excel name, which imports the column names, and there are high chances that you misspell the column names or include an unwanted space before or after the column name.

The column names are case-sensitive, and if you make a mistake, then Python will raise an exception KeyError: ‘column_name

Let us take a simple example to demonstrate KeyError in Pandas. In this example, we create a pandas DataFrame of employee’s data, and let’s say we need to print all the employee names.

# import pandas library
import pandas
import numpy as np

# create pandas DataFrame
df =  pandas.DataFrame(np.array([["Jack", 22, "US"], ["Chandler", 55, "Canada"], ["Ross", 48, "India"]]),
                   columns=['name', 'age', 'country'])

# print names of employee
print(df["Name"])

Output

    raise KeyError(key) from err
KeyError: 'Name'

When we run the program, Python raises KeyError, since we have misspelled the “name” column as “Name”.

Solution KeyError in Pandas

We can fix the issue by correcting the spelling of the key. If we are not sure what the column names are, we can print all the columns into the list as shown below.

# import pandas library
import pandas
import numpy as np

# create pandas DataFrame
df =  pandas.DataFrame(np.array([["Jack", 22, "US"], ["Chandler", 55, "Canada"], ["Ross", 48, "India"]]),
                   columns=['name', 'age', 'country'])

# print names of employee
print(df["name"])

Output

0        Jack
1    Chandler
2        Ross
Name: name, dtype: object

We can now see a column called “name,” and we can fix our code by providing the correct spelling as a key to the pandas DataFrame, as shown below.

We can also avoid the KeyErrors raised by the compilers when an invalid key is passed. The DataFrame has a get method where we can give a column name and retrieve all the column values.

Syntax : DataFrame.get( 'column_name' , default = default_value_if_column_is_not_present)

If there are any misspelled or invalid columns, the default value will be printed instead of raising a KeyError. Let’s look at an example to demonstrate how this works.

# import pandas library
import pandas
import numpy as np

# create pandas DataFrame
df = pandas.DataFrame(np.array([["Jack", 22, "US"], ["Chandler", 55, "Canada"], ["Ross", 48, "India"]]),
                      columns=['name', 'age', 'country'])

# print names of employee
print(df.get("Name", default="Name is not present"))

Output

Name is not present

And if we provide the correct column name to the DataFrame.get() method, it will list all the column values present in that.

# import pandas library
import pandas
import numpy as np

# create pandas DataFrame
df = pandas.DataFrame(np.array([["Jack", 22, "US"], ["Chandler", 55, "Canada"], ["Ross", 48, "India"]]),
                      columns=['name', 'age', 'country'])

# print names of employee
print(df.get("name", default="Name is not present"))

Output

0        Jack
1    Chandler
2        Ross
Name: name, dtype: object

The post How to Fix: KeyError in Pandas? appeared first on ItsMyCode.

January 10, 2022 01:21 PM UTC

How to Fix in Python ValueError: Trailing data?

ItsMyCode |

In Python ValueError: Trailing data occurs when you try to load the JSON data or file into pandas DataFrame, and the data is written in lines separated with newline characters such as ‘\n’.

Typically, we import data from the JSON files, and there are higher chances that JSON data contains newline characters.

Let’s take a simple example to reproduce this error. We have a JSON file of employees, and the address property in the JSON has ‘\n’ 

ValueError: Expected object or valueJSON File
# import pandas library
import pandas as pd

# create pandas DataFrame
df = pd.read_json('employee.json')

# print names of employee
print(df)

Output

ValueError: Trailing data
Note: If the JSON data is malformed or the file path is invalid you will get an error ValueError: Expected object or value

Solution Python ValueError: Trailing data

The simplest way to fix this error is to pass the lines=True argument in the read_json() method while importing the JSON file.

The lines=True parameter ensures to read the JSON file as an object per line.

Now when we import the JSON file into a pandas DataFrame, it will load and print the data without any issue. 

# import pandas library
import pandas as pd

# create pandas DataFrame
df = pd.read_json('employee.json',lines=True)

# print names of employee
print(df)

Output

    ID      name  age                  address
0  123      Jack   25     #3, 5th Main \nIndia
1  124  Chandler   25        #5, 2nd Main \nUS
2  123      Jack   25  #3/2, 6th Main \nCanada

Another way is to remove the \n character from the address column. We can simply replace the \n character with an empty '' character, as shown below.

# import pandas library
import pandas as pd

# create pandas DataFrame
df = pd.read_json('employee.json',lines=True)
df['address'] = df['address'].str.replace('\n', ' ')

# print names of employee
print(df)

Output

    ID      name  age                 address
0  123      Jack   25     #3, 5th Main  India
1  124  Chandler   25        #5, 2nd Main  US
2  123      Jack   25  #3/2, 6th Main  Canada

The post How to Fix in Python ValueError: Trailing data? appeared first on ItsMyCode.

January 10, 2022 10:18 AM UTC


Mike Driscoll

PyDev of the Week: Lais Carvalho

This week we welcome Lais Carvalho (@lais_bsc) as our PyDev of the Week! Lais is active in multiple Python user groups in Ireland and has helped organize multiple Python conferences. She is on a recent episode of Python Bytes too, so be sure to check that out!

If you'd like to see what projects Lais is working on, head on over to GitHub.

Lais Carvalho

Let's spend a few moments getting to know Lais better!

Can you tell us a little about yourself (hobbies, education, etc.)

My name is Lais Carvalho and I work as Developer and Community Advocate for Quansight, a consultancy company that offers support for most of the Open Source libraries available, specially on the Python sphere. I have just graduated on IT (Information Technology), after studying engineering for two years. I also volunteer for Python Ireland and have helped organise a few Python conferences. My favourite ones are EuroPython (the biggest Python conference in Europe) and PyJamas, an online event where everyone is invited to present wearing pajamas.

Why did you start using Python?

I started using Python in my first year of engineering university. I was struggling to learn WolframAlpha to check if my handmade calculations were correct, but everything used to be so hard and take so long. That was when chatting to one of our teachers, he mentioned I might prefer to use Python for that. I thought “well, it doesn't cost me much to try” and have become a fan since then, which I believe was in 2014.

What other programming languages do you know and which is your favorite?

I am not a programmer, which means that my main line of work is with people (not code) but I can build small things using Java and Python. My R skills are not something to be proud of but I can make beautiful graphs and pretend I understand data analysis well enough. I would like to try and learn GoLang or Julia next.

My favourite do-it-all language is Python due to its versatility. But languages are tools, one is welcome to choose whichever (s)he knows best in order to get the job done. To expand on the metaphor, it is elementary that a plier will not be the most effective to hammer nails on a wall, but it might do a fine job on acceptable time if the amount of nails is small or the time is limited and hammers are not available.

What projects are you working on now?

I am currently on medical license due to a cancer diagnosis received two weeks before my thesis delivery deadline. I am now finished with the treatment (in theory) and waiting to hear results back from the hospital. Keeping fingers crossed.

Before that, I was working on updating the documentation of one of Quansight’s Open Source libraries named QHub.

Which Python libraries are your favorite (core or 3rd party)?

There are so many wonderful ones, which makes this a very challenging question but in summary, I quite like requests, making HTTP requests human-friendly since 2011. In addition, the more scientific ones like NumPy and SciPy, and the classy Manim for mathematical animations. Aw yes, and Flask for web apps! Not to mention the standard stuff, Python is all wonderful.

How did you become so active with Python user groups?

Lais Carvalho

I started volunteering for PyCon Ireland in my second year in college (2019), because I believed networking was the most effective way to get into the industry. At the event, I met so many wonderful people and everyone had a project or initiative in need of help, so I volunteered. I remember being extremely excited about partaking in such an inclusive and fun community, so much so that when COVID restrictions arrived I became almost fully dedicated to the user groups. It was a good way to cope with lockdown and to meet wonderful people that ended up becoming close-personal friends of mine.

What advice do you have for people who would like to start their own local Python user groups?

Look around and see if there are people interested in joining you. Look for inspiration in existing groups and persevere. This is a huge community we are part of and there will always be someone willing to help in some way. Be vocal, ask for help, and don’t give up. Finally, if you are thinking about starting your own Python User Group in Ireland, come and speak to us at Python Ireland, we would be happy to help in any way we can.

Is there anything else you’d like to say?

I have just recorded an episode of Python Bytes that you can find on their website or on Spotify. Wanna ask me something? DM me on Twitter at @lais_bsc.

Python Ireland:

PyLadies Dublin:

EuroPython will start looking for volunteers for the in person event as well soon

Pyjamas happens in December, want to be notified about it? Follow us on twitter @PyjamasConf and subscribe to our YouTube channel.

Thanks for doing the interview, Lais!

The post PyDev of the Week: Lais Carvalho appeared first on Mouse Vs Python.

January 10, 2022 06:05 AM UTC


Zato Blog

API development workflow with Zato

Zato is an integration platform and backend application server which means that, during most of their projects, developers using Zato are interested in a few specific matters.

The platform concentrates on answering these key, everyday questions that Python backend developers routinely ask:

The typical workflow

Dashboard

Python

# -*- coding: utf-8 -*-

# stdlib
from dataclasses import dataclass

# Zato
from zato.server.service import Model, Service

@dataclass(init=False)
class GetClientRequest(Model):
    client_id: int

@dataclass(init=False)
class GetClientResponse(Model):
    name:    str
    email:   str
    segment: str

class GetClient(Service):

    class SimpleIO:
        input  = GetClientRequest
        output = GetClientResponse

    def handle(self):

        # Enable type checking and type completion
        request = self.request.input # type: GetClientRequest

        # Log details of our request
        self.logger.info('Processing client `%s`', request.client_id)

        # Produce our response - in a full service this information
        # will be obtained from one or more databases or systems.
        response = GetClientResponse()
        response.name    = 'Jane Doe'
        response.email   = 'hello@example.com'
        response.segment = 'RNZ'

        # Return the response to our caller
        self.response.payload = response

Such a service can be assigned to one or more REST channels and we can invoke it now:

$ curl localhost:17010/api/v1/client -d '{"client_id":123}'
{"name":"Jane Doe","email":"hello@example.com","segment":"RNZ"}
$

Automation

OpenAPI

Let’s generate an OpenAPI definition for the GetClient service above:

$ zato openapi /path/to/server/server1 \
    --include "client*"                \
    --file /tmp/openapi.yaml

Now, we can import the OpenAPI definition to Postman and invoke our services from it:

Python once more

# -*- coding: utf-8 -*-

# Redis
import redis

# Connect to the database
conn = redis.Redis(host='localhost', port=6379, db=0)

# Set a key ..
conn.set('key', 'value')

# .. read it back ..
result = conn.get('key')

# .. and log what we received.
print('Result', result)
# -*- coding: utf-8 -*-

# Zato
from zato.server.service import Service

class MyService(Service):
    def handle(self):

        # Set a key ..
        self.kvdb.conn.set('key', 'value')

        # .. read it back ..
        result = self.kvdb.conn.get('key')

        # .. and log what we received.
        self.logger.info('Result %s', result)

Next steps

January 10, 2022 04:40 AM UTC


Armin Ronacher

Dependency Risk and Funding

I have a love/hate relationship with dependencies. I wrote about this extensively on this blog. Once about the challenges with scaling trust in dependencies and earlier about the problem with micro dependencies. Somehow very unsurprisingly nothing has actually improved in that regard in the last 5 years. In fact, I think the problem has become significantly worse. Where a few years back the main fear here was high profile developers being targeted, the dependency discussion is now overlapped and conflated with discussions about funding and sustainability.

I'm sure everybody remembers the XKCD on dependencies:

What I like about this comic is that you can insert a whole bunch of projects in your head into that comic. I like to imagine that the mentioned project is Curl. It's maintained largely by a single person — Daniel Stenberg — for more than 20 years. Curl is a good example of an actual crucial dependency. It's everywhere. I have seen it on game consoles, in cars, on MP3 players, smart speakers, bluray players, embedded devices, command line utilities, backend servers, … It's not only an incredible useful software, it's also solving a hard problem. It's also not a small dependency either. Curl is a whole package of useful functionality. If curl ceases to exist it would be clearly bad for society.

However. How can curl disappear? Curl is not just one of the most important dependencies, it's also one of the most resilient dependencies. When you or me install curl, we rarely install it from the official website. Curl is more likely to come from a mirror, vendored into a library we're using, there are a lot of forks in proprietary code bases etc. Curl is an unkillable dependency. Not only can the website go down, also the original developer could probably go away and someone would pick up the work, it's that useful.

Let's contrast this for a second with the situation on npm. One of the most dependent on libraries is in fact colors. The library is effectively emitting ANSI codes for colorization. A useful feature for sure, but not world shattering. I would go out on a limb and say that this type of functionality very often is implemented directly instead of depended on. For instance when I wrote click I purposefully decided to implement ANSI coloring right in my own library without depending on something. My hunch is that it wouldn't take long to rip out and replace that library.

A few days ago the developer behind that library decided to release a new version of the library that no longer does what it advertised on the tin. Since it was a minor update quite a few people ended up with that version. They didn't however even know that they were depending on “that one package”, they probably pulled it in because something else in their dependency chain needed it.

If you went to the GitHub repo of that developer you found two things: some conspirational content in the readme of the repo, but also a justification for why their library no longer did what it was supposed to do: the developer was dissatisfied with “fortune 500” using their code for free and asked for a six figure contract or for people to fork it.

What I wish people would actually start discussing when it comes to these things is that npm (and other package managers) have developed into incredible levers. Someone who has a package with a lot of dependents one can easily knock out that piece of all modern digital infrastructure. Daniel Stenberg of curl doesn't wield that power (and probably also doesn't want to).

The risk a dependency poses is high with small, more commonly used dependencies, by a single unvetted developer, installed through a package manager like npm, cargo, pypi or similar. Yet when something goes wrong there, everybody immediately notices and people quickly call for funding. Yet those are not the dependencies that actually support our economy. Many of those dependencies became that foundational, not because they are solving a hard problem, but because we collectively started embracing laziness over everything else. When we then focus our funding discussions around these types of dependencies, we're implicitly also putting the focus away from the actually important packages.

I appreciate what GitHub does with sponsors and I think it's an awesome idea. I also appreciate that GitHub puts a finger at funding Open Source being an issue, but unfortunately there is a dark side to this: it points the finger to where it's easy. GitHub like npm point the finger to what computers can easily explain. My code flew to mars. That's awesome. But that Badge of honor I now carry on my GitHub profile I got because they crawled the Python dependency list. Together with my badge the folks that created lxml got a badge. However Daniel Veillard who maintains the underling libxml2 library received no such badge. In fact many people probably forget that libxml2 even exists or that they might be using it, because it's hidden behind a much more fancy high level facade that hides it. Unlike an npm package, you don't download libxml2 from somewhere when you install lxml. libxml2 like curl doesn't have the lever or visibility. Yet the amount of work and dedication that went into the library is significant. And he's just one of thousands of developers who have created incredible libraries we all still use.

Clearly we need to solve funding of Open Source projects and I love that GitHub sponsors is a thing. But I think we need to find a better way to assess impact of libraries than just how many people depend on this on npm or other package managers. Because that's by far not the whole picture.

January 10, 2022 12:00 AM UTC

January 09, 2022


ItsMyCode

[Solved] NameError: name ‘pd’ is not defined

ItsMyCode |

In Python,  NameError: name ‘pd’ is not defined occurs when you import the pandas library but fail to provide the alias as pd while importing it.

In this article, let us look at what is NameError name pd is not defined and how to resolve this error with examples.

Solution NameError: name ‘pd’ is not defined

Let us take a simple example to reproduce this error. In the below example, we have imported the pandas library and created a pandas DataFrame.

# import pandas library
import pandas 
import numpy as np

# create pandas DataFrame
df =  pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
                   columns=['a', 'b', 'c'])

# print dataframe
print(df)

Output

Traceback (most recent call last):
  File "C:\Personal\IJS\Code\main.py", line 6, in <module>
    df =  pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
NameError: name 'pd' is not defined. Did you mean: 'id'?

When we run the code, we get  NameError: name ‘pd’ is not defined  since we did not provide an alias while importing the pandas library.

There are multiple ways to resolve this issue. Let us look at all the approaches to solve the NameError.

Method 1 – Importing pandas with Alias as pd

The simplest way to resolve this error is by providing an alias as pd while importing the pandas library. Let’s fix our code by providing an alias and see what happens.

# import pandas library
import pandas as pd
import numpy as np

# create pandas DataFrame
df =  pd.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
                   columns=['a', 'b', 'c'])

# print dataframe
print(df)

Output

   a  b  c
0  1  2  3
1  4  5  6
2  7  8  9

The syntax “import pandas as pd” is commonly used because it offers a more concise way to call pandas functions, and the code is more readable as we do not have to type “pandas” each time.

Method 2 – Importing all the functions from pandas

There might be a situation where you need to import all the functions from the pandas library, and to do that, we will be using the below syntax.

from pandas import *

In this case, you do not need any reference to call any functions of pandas. You can directly call the methods without using an alias, and in this example we can directly create the DataFrame as shown below.

# import pandas library
from pandas import *
import numpy as np

# create pandas DataFrame
df =  DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
                   columns=['a', 'b', 'c'])

# print dataframe
print(df)

Output

   a  b  c
0  1  2  3
1  4  5  6
2  7  8  9

Method 3 – Importing pandas package without an alias

Another way is to import a complete pandas package and call the functions directly with the pandas name without defining an alias.

# import pandas library
import pandas
import numpy as np

# create pandas DataFrame
df =  pandas.DataFrame(np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]),
                   columns=['a', 'b', 'c'])

# print dataframe
print(df)

Output

   a  b  c
0  1  2  3
1  4  5  6
2  7  8  9

In the above example, we import the complete pandas library and use pandas.DataFrame() method to create pandas DataFrame.

Note: If you are running the code in Jupyter notebook, ensure that you run the cell where you have imported the pandas and then run the rest of the code.

The post [Solved] NameError: name ‘pd’ is not defined appeared first on ItsMyCode.

January 09, 2022 08:26 PM UTC

[Solved] NameError: name ‘np’ is not defined

ItsMyCode |

In Python,  NameError: name ‘np’ is not defined occurs when you import the NumPy library but fail to provide the alias as np while importing it.

In this article, let us look at what is NameError name np is not defined and how to resolve this error with examples.

Solution NameError: name ‘np’ is not defined

Let us take a simple example to reproduce this error. In the below example, we have imported the NumPy library and defined a NumPy array. 

# import numpy library
import numpy 

# define numpy array
array = np.array([[12, 33], [21, 45]]) 

# print values in array format
print(array)

Output

Traceback (most recent call last):
  File "C:\Personal\IJS\Code\main.py", line 5, in <module>
    array = np.array([[12, 33], [21, 45]])
NameError: name 'np' is not defined

When we run the code, we get  NameError: name ‘np’ is not defined  since we did not provide an alias while importing the NumPy library.

There are multiple ways to resolve this issue. Let us look at all the approaches to solve the NameError.

Method 1 – Importing NumPy with Alias as np

The simplest way to resolve this error is by providing an alias as np while importing the NumPy library. Let’s fix our code by providing an alias and see what happens.

# import numpy library
import numpy as np

# define numpy array
array = np.array([[12, 33], [21, 45]]) 

# print values in array format
print(array)

Output

[[12 33]
 [21 45]]

The syntax “import numpy as np” is commonly used because it offers a more concise way to call NumPy functions, and the code is more readable as we do not have to type “numpy” each time.

Method 2 – Importing all the functions from NumPy

There might be a situation where you need to import all the functions from the NumPy library, and to do that, we will be using the below syntax.

from numpy import *

In this case, you do not need any reference to call any functions of NumPy. You can directly call the methods without using an alias, as shown below.

# import numpy library
from numpy import *

# define numpy array
array = array([[12, 33], [21, 45]]) 

# print values in array format
print(array)

Output

[[12 33]
 [21 45]]

Method 3 – Importing NumPy package without an alias

Another way is to import a complete NumPy package and call the functions directly with the NumPy name without defining an alias.

# import numpy library
import numpy 

# define numpy array
array = numpy.array([[12, 33], [21, 45]]) 

# print values in array format
print(array)

Output

[[12 33]
 [21 45]]

In the above example, we import the complete NumPy library and use numpy.array() method to create an array.

The post [Solved] NameError: name ‘np’ is not defined appeared first on ItsMyCode.

January 09, 2022 08:06 PM UTC

ValueError: If using all scalar values, you must pass an index

ItsMyCode |

If you pass all scalar values while creating pandas Dataframe in Python, you will encounter “ValueError: If using all scalar values, you must pass an index

In this tutorial, we will learn what is ValueError: If using all scalar values, you must pass an index error means and how to resolve this ValueError in your program with examples.

Let us take a simple example to reproduce this issue.

# import pandas library
import pandas as pd

#define scalar values
a = 1
b = 2
c = 3
d = 4

# creating DataFrame from scalar values
df = pd.DataFrame({'A': a, 'B': b, 'C': c, 'D': d})

print(df)

Output

    raise ValueError("If using all scalar values, you must pass an index")
ValueError: If using all scalar values, you must pass an index

In the above example, we have declared scalar value and attempted to create a pandas DataFrame by passing a scalar value. 

When we run the code, Python will raise ValueError: If using all scalar values, you must pass an index

How to fix ValueError: If using all scalar values, you must pass an index?

The most common way to create DataFrames in Python is by using lists and dictionaries. There are three ways to fix the error. Let us look at each of them with examples.

Method 1: Transform Scalar Values to List

The simplest way is to transform the scalar values into a list and pass it to a DataFrame, as shown below.

# import pandas library
import pandas as pd

#define scalar values
a = 1
b = 2
c = 3
d = 4

# creating DataFrame by transforming Scalar Values to List
df = pd.DataFrame({'A': [a], 'B': [b], 'C': [c], 'D': [d]})
print(df)

Output

   A  B  C  D
0  1  2  3  4

Method 2: Place Scalar Values into Dictionary 

Another way is to place the scalar values into the dictionary and pass it to Pandas DataFrame as shown below.

# import pandas library
import pandas as pd

#define scalar values
a = 1
b = 2
c = 3
d = 4

# storing the dictionary of scalar values
p_dict = {'A':1, 'B':2, 'C':3, 'D':4}

# creating DataFrame by passing dictionary into List
df = pd.DataFrame(p_dict)
print(df)

Output

   A  B  C  D
0  1  2  3  4

Method 3: Pass Scalar Values and Pass Index

We can even pass an index with scalar values to DataFrame. When you pass an index, pandas will treat your dictionary keys as column names and the values as what the column should contain for each of the values in the index.

# import pandas library
import pandas as pd

# define scalar values
a = 1
b = 2
c = 3
d = 4

# creating DataFrame from scalar values and passing index
df = pd.DataFrame({'A': a, 'B': b, 'C': c, 'D': d}, index=[0])
print(df)

Output

   A  B  C  D
0  1  2  3  4

The post ValueError: If using all scalar values, you must pass an index appeared first on ItsMyCode.

January 09, 2022 05:58 PM UTC

No handles with labels found to put in legend

ItsMyCode |

In Python matplotlib No handles with labels found to put in legend occur if you have not defined the label parameters whenever you plot the figure and try to call the plt.legend() method.

The matplotlib.pyplot  is a state-based interface to matplotlib and provides a way to plot interactive figures in Python.  

We can use matplotlib.pyplot.legend() method to place a legend on the axes.

However, if we do not add the labels parameter and then call the matplotlib.pyplot.legend() function, you will get No handles with labels found to put in legend. 

If you are using the latest version of Python, then the error would be No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 20, 2000)
y1 = np.sin(x)
y2 = np.arcsin(x)
plt.plot(x, y1)
plt.plot(x, y2)
plt.legend()
plt.show()

Output

No handles with labels found to put in legend.Note that artists whose label start with an underscore are ignored when legend() is called with no argument.

Another way you get this error is if you call the legend method before plotting it. Ensure to verify your code and call the legend function after completing the plotting.

Solution – No handles with labels found to put in legend

Now that we know why the error occurs, let us see how to resolve the error and plot the legends correctly.

There are three different ways to call the matplotlib.pyplot.legend() method in Python.

Calling legend() without any arguments

If you want the legends to be detected automatically, you can call legend() method without passing any arguments. This will automatically detect the legend elements, including the labels, and plot them for you.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 8, 1000)
y1 = np.sin(x)
y2 = np.arcsin(x)

plt.plot(x, y1, label='sin')
plt.plot(x, y2, label='arcsin')
plt.legend()
plt.show()

Output

Passing labels as arguments to legend() method

You can pass the labels as an argument to the legend() method as iterable of strings. 

Each string is used as a label for the elements in the order they were created.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 8, 1000)
y1 = np.sin(x)

plt.plot([4, 7, 9])
plt.plot(x, y1, '-b')
plt.legend(['Line1', 'Line2'])
plt.show()
Note: This is not the recommended approach since the relationship between the elements and the passed labels exist only through the order it created and can lead to confusion.

Passing handles and labels as a parameter to legend() method

If we need complete control, we can pass the elements followed by the iterable of strings as labels explicitly to the legend() function.

import numpy as np
import matplotlib.pyplot as plt

x = np.linspace(0, 8, 1000)
y1 = [4, 7, 9]
y2 = np.sin(x)
y3 = np.arcsin(x)

line, = plt.plot(y1)
sine, = plt.plot(x, y2)
arcsine, = plt.plot(x, y3)

plt.legend(handles = [line, sine, arcsine], 
           labels  = ['Line', 'Sine', 'Arcsine'])
plt.show()

Reference: Stackoverflow, Educative

The post No handles with labels found to put in legend appeared first on ItsMyCode.

January 09, 2022 04:22 PM UTC


Sebastian Pölsterl

scikit-survival 0.17 released

This release adds support for scikit-learn 1.0, which includes support for feature names. If you pass a pandas dataframe to fit, the estimator will set a feature_names_in_ attribute containing the feature names. When a dataframe is passed to predict, it is checked that the column names are consistent with those passed to fit. The example below illustrates this feature.

For a full list of changes in scikit-survival 0.17.0, please see the release notes.

Installation

Pre-built conda packages are available for Linux, macOS, and Windows via

 conda install -c sebp scikit-survival

Alternatively, scikit-survival can be installed from source following these instructions.

Feature Names Support

Prior to scikit-survival 0.17, you could pass a pandas dataframe to estimators’ fit and predict methods, but the estimator was oblivious to the feature names accessible via the dataframe’s columns attribute. With scikit-survival 0.17, and thanks to scikit-learn 1.0, feature names will be considered when a dataframe is passed.

Let’s illustrate feature names support using the Veteran’s Lung Cancer dataset.

from sksurv.datasets import load_veterans_lung_cancer
X, y = load_veterans_lung_cancer()
X.head(3)
Age_in_years Celltype Karnofsky_score Months_from_Diagnosis Prior_therapy Treatment
0 69.0 squamous 60.0 7.0 no standard
1 64.0 squamous 70.0 5.0 yes standard
2 38.0 squamous 60.0 3.0 no standard

The original data has 6 features, three of which contain strings, which we encode as numeric using OneHotEncoder.

from sksurv.preprocessing import OneHotEncoder
transform = OneHotEncoder()
Xt = transform.fit_transform(X)

Transforms now have a get_feature_names_out() method, which will return the name of features after the transformation.

transform.get_feature_names_out()
array(['Age_in_years', 'Celltype=large', 'Celltype=smallcell',
'Celltype=squamous', 'Karnofsky_score', 'Months_from_Diagnosis',
'Prior_therapy=yes', 'Treatment=test'], dtype=object)

The transformed data returned by OneHotEncoder is again a dataframe, which can be used to fit Cox’s proportional hazards model.

from sksurv.linear_model import CoxPHSurvivalAnalysis
model = CoxPHSurvivalAnalysis().fit(Xt, y)

Since we passed a dataframe, the feature_names_in_ attribute will contain the names of the dataframe used when calling fit.

model.feature_names_in_
array(['Age_in_years', 'Celltype=large', 'Celltype=smallcell',
'Celltype=squamous', 'Karnofsky_score', 'Months_from_Diagnosis',
'Prior_therapy=yes', 'Treatment=test'], dtype=object)

This is used during prediction to check that the data matches the format of the training data. For instance, when passing a raw numpy array instead of a dataframe, a warning will be issued.

pred = model.predict(Xt.values)
UserWarning: X does not have valid feature names, but CoxPHSurvivalAnalysis was fitted with feature names

Moreover, it will also check that the order of columns matches.

X_reordered = pd.concat(
(Xt.drop("Age_in_years", axis=1), Xt.loc[:, "Age_in_years"]),
axis=1
)
pred = model.predict(X_reordered)
FutureWarning: The feature names should match those that were passed during fit. Starting version 1.2, an error will be raised.
Feature names must be in the same order as they were in fit.

For more details on feature names support, have a look at the scikit-learn release highlights.

January 09, 2022 03:45 PM UTC


ItsMyCode

[Solved] Python can’t Multiply Sequence by non-int of type ‘str’

ItsMyCode |

The TypeError: can’t multiply sequence by non-int of type ‘str’ occurs if we multiply a string by another string without converting into an integer or floating-point.

In this tutorial, we will learn what exactly TypeError: can’t multiply sequence by non-int of type ‘str’ error means and how to resolve this TypeError in your program with examples.

TypeError: can’t multiply sequence by non-int of type ‘str’

Python is one of the best programming languages because of its features and simplicity. One such fantastic feature in Python is we can multiply strings with numbers.

Multiplying string with an integer

Let’s take an example to demonstrate multiplying string with numbers.

The other popular programming languages will never let you to multiple strings and integers. However, we can perform a multiplication between string and integer in Python. After the multiplication, the string is repeated for n times, as shown below.

text = "ItsMyCode"
n = 3
print(text*n)

Output

ItsMyCodeItsMyCodeItsMyCode

Here the string “ItsMyCode” is repeated multiplied by three and repeated three times in the output.

If we try to multiply the string with another string then the Python interpreter will throw TypeError: can’t multiply sequence by non-int of type ‘str’.

Multiplying string with another string

You cannot multiply a string with a non-integer value in Python. If we multiply a string with another string without converting to integer or floating point, we get an error can’t multiply sequence by non-int of type ‘str’.

Let us take a simple example of multiplying two numbers.

num1 ='5'
num2 ='6'
output =num1 * num2
print(output)

Output

Traceback (most recent call last):
  File "C:\Personal\IJS\Code\main.py", line 3, in <module>
    output =num1 * num2
TypeError: can't multiply sequence by non-int of type 'str'

Even though the number entered here is equal to the integer values, the Python interpreter will still consider it as a string and raise a TypeError.

The simplest way to resolve this issue is by converting both the strings into an integer and then performing a multiplication operation, as shown below.

num1 ='5'
num2 ='6'
output = int(num1) * int(num2)
print(output)

Output

30

Solution TypeError: can’t multiply sequence by non-int of type ‘str’

Now we know that TypeError: can’t multiply sequence by non-int of type str is caused by multiplying a string with another string. Let us see how we can resolve this error with an example.

Usually, we get this error when we receive input from the user, and the input() method alway returns the data in a string format.

Consider we have to calculate the total tax amount paid based on the distance traveled and the fare price.

In the above example, we are reading the fare price and distance data as user input, and we are calculating the tax amount by multiplying the (fare_price * distance)*(tax_percentage/100)

Even though the user inputs valid data, the input() method returns a string, meaning that fare_price and distance values are in string format. Hence we end up multiplying two strings resulting in the TypeError: can’t multiply sequence by non-int of type ‘str’.

tax_percentage = 5
fare_price = input("Please enter the fare amount charged  ")
distance = input("Please enter the distance travelled to calculate the total fare -  ")
total_fare = (fare_price * distance) * (5/100)
print(total_fare)

Output

Please enter the fare amount charged  100
Please enter the distance travelled to calculate the total fare -  5
Traceback (most recent call last):
  File "C:\Personal\IJS\Code\main.py", line 4, in <module>
    total_fare = (fare_price * distance) * 0.05
TypeError: can't multiply sequence by non-int of type 'str'

The best way to resolve this error is to convert the user input string to a floating-point using the float() method. 

This allows us to multiply the order_value and discount because both are floating-point numbers.

tax_percentage = 5
fare_price = float(input("Please enter the fare amount charged  "))
distance = float(input("Please enter the distance travelled to calculate the total fare -  "))
total_fare = (fare_price * distance) * (5/100)
print(total_fare)

Output

Please enter the fare amount charged  250.50
Please enter the distance travelled to calculate the total fare -  3.4
42.585
Note: We cannot multiply strings with floating-point numbers,if we do Python interpreter will throw TypeError: can't multiply sequence by non-int of type 'float'. Hence in the above example we have to convert both the inputs into floating-point and then perform multiplication.

Conclusion

We cannot multiply strings with any non integers values such as float, string etc. If we multiply a string with another string without converting into an integer we get TypeError: can’t multiply sequence by non-int of type 'str'

In order to solve this issue, TypeError: can’t multiply sequence by non-int of type ‘str’ ensure that either you are performing a multiplication between string and integer or alternatively you can convert all the string values into a floating-point number before performing any calculations. 

The post [Solved] Python can’t Multiply Sequence by non-int of type ‘str’ appeared first on ItsMyCode.

January 09, 2022 11:35 AM UTC


Juri Pakaste

Async Swift and ArgumentParser

Swift 5.5 brought us async functions. ArgumentParser is the most popular way to write command line interfaces with Swift. Swift 5.5 supports an asynchronous main function, but ArgumentParser does not, as of version 1.0.2.

To bridge this gap, you can call ArgumentParser manually from your asynchronous main function, like this:

import ArgumentParser

struct MyCommand: ParsableCommand {
    @Argument var arg: String

    // Usually you'd write a `run` function, but it has to be synchronous.
    func runAsync() async throws {
        /* … */
    }
}

@main
enum Main {
    static func main() async throws {
        let args = Array(CommandLine.arguments.dropFirst())
        do {
            let command = try MyCommand.parse(args)
            try await command.runAsync()
        } catch {
            MyCommand.exit(withError: error)
        }
    }
}

January 09, 2022 10:00 AM UTC


ItsMyCode

TypeError: list indices must be integers or slices, not str

ItsMyCode |

If you are accessing the elements of a list in Python, you need to access it using its index position or slices. However, if you try to access a list value using a string Python will raise TypeError: list indices must be integers or slices, not str exception.

In this tutorial, we will learn what “list indices must be integers or slices, not str” error means and how to resolve this TypeError in your program with examples.

TypeError: list indices must be integers or slices, not str

Lists are always indexed using a valid index number, or we can use slicing to get the elements of the list. Below is an example of indexing a list.

# Example 1: of list indexing
my_list = [1, 2, 3, 4, 5, 6, 7, 8]
print(my_list[5])

# Example 2: of list slicing
fruits = ["Apple", "Orange", "Lemon", "Grapes"]
print("Last 2 fruits is", fruits[2:4])

Output

6
Last 2 fruits is ['Lemon', 'Grapes']

The first example is we use an integer as an index to get the specific element of a list.

In the second example, we use a Python slicing technique by defining a start point and end-point to retrieve the sublist from the main list.

Now that we know how to access the elements of the list, there are several scenarios where developers tend to make mistakes, and we get a TypeError. Let us take a look at each scenario with examples.

Scenario 1: Reading string input from a user

It’s the most common scenario where we do not convert the input data into a valid type in Menu-driven programs, leading to TypeError. Let us take an example to reproduce this issue.

Consider an ATM menu-driven example where the user wants to perform certain operations by providing the input to the program.

menu = ["Deposit Cash", "Withdraw Case", "Check Balance", "Exit"]
choice = input(
    'Choose what would you like to perform (Valid inputs 0, 1, 2, 3)')
print(menu[choice])

Output

Choose what would you like to perform (Valid inputs 0, 1, 2, 3)2
Traceback (most recent call last):
  File "C:\Personal\IJS\Code\main.py", line 13, in <module>
    print(menu[choice])
TypeError: list indices must be integers or slices, not str

When the user inputs any number from 0 to 3, we get TypeError: list indices must be integers or slices, not str, because we are not converting the input variable “choice” into an integer, and the list is indexed using a string.

We can resolve the TypeError by converting the user input to an integer, and we can do this by wrapping the int() method to the input, as shown below.

menu = ["Deposit Cash", "Withdraw Case", "Check Balance", "Exit"]
choice = int(input(
    'Choose what would you like to perform (Valid inputs 0, 1, 2, 3) - ' ))
print(menu[choice])

Output

Choose what would you like to perform (Valid inputs 0, 1, 2, 3) - 2
Check Balance

Scenario 2: Trying to access Dictionaries list elements using a string

Another reason we get TypeError while accessing the list elements is if we treat the lists as dictionaries. 

In the below example, we have a list of dictionaries, and each list contains the actor and name of a movie.

actors = [
    {
        'name': "Will Smith",
        'movie': "Pursuit of Happiness"
    },

    {
        'name': "Brad Pitt",
        'movie': "Ocean's 11"
    },
    {
        'name': "Tom Hanks",
        'movie': "Terminal"
    },
    {
        'name': "Leonardo DiCaprio",
        'movie': "Titanic"
    },
    {
        'name': "Robert Downey Jr",
        'movie': "Iron Man"
    },
]

actor_name = input('Enter the actor name to find a movie -   ')
for i in range(len(actors)):
    if actor_name.lower() in actors['name'].lower():
        print('Actor Name: ', actors['name'])
        print('Movie: ', actors['movie'])
        break
else:
    print('Please choose a valid actor')

Output

Enter the actor name to find a movie -   Brad Pitt
Traceback (most recent call last):
  File "C:\Personal\IJS\Code\program.py", line 27, in <module>
    if actor_name.lower() in actors['name'].lower():
TypeError: list indices must be integers or slices, not str

We need to display the movie name when the user inputs the actor name.

When we run the program, we get TypeError: list indices must be integers or slices, not str because we are directly accessing the dictionary items using the key, but the dictionary is present inside a list. 

If we have to access the particular value from the dictionary, it can be done using the following syntax.

list_name[index_of_dictionary]['key_within_dictionary']

We can resolve this issue by properly iterating the dictionaries inside the list using range() and len() methods and accessing the dictionary value using a proper index and key, as shown below.

actors = [
    {
        'name': "Will Smith",
        'movie': "Pursuit of Happiness"
    },

    {
        'name': "Brad Pitt",
        'movie': "Ocean's 11"
    },
    {
        'name': "Tom Hanks",
        'movie': "Terminal"
    },
    {
        'name': "Leonardo DiCaprio",
        'movie': "Titanic"
    },
    {
        'name': "Robert Downey Jr",
        'movie': "Iron Man"
    },
]

actor_name = input('Enter the actor name to find a movie -   ')
for i in range(len(actors)):
    if actor_name.lower() in actors[i]['name'].lower():
        print('Actor Name: ', actors[i]['name'])
        print('Movie: ', actors[i]['movie'])
        break
else:
    print('Please choose a valid actor')

Output

Enter the actor name to find a movie -   Brad Pitt
Actor Name:  Brad Pitt
Movie:  Ocean's 11

Conclusion

The TypeError: list indices must be integers or slices, not str occurs when we try to index the list elements using string. The list elements can be accessed using the index number (valid integer), and if it is a dictionary inside a list, we can access using the syntax list_name[index_of_dictionary]['key_within_dictionary']

The post TypeError: list indices must be integers or slices, not str appeared first on ItsMyCode.

January 09, 2022 07:35 AM UTC

January 08, 2022


Brett Cannon

Unravelling `from` for `raise` statements

As part of my series on Python&aposs syntax, I want to tackle the from clause for raise statements. In case you&aposre unfamiliar, raise A from B causes B to be assigned to A.__cause__ which lets chained tracebacks exist (as well as __context__, but that&aposs not relevant to today&aposs topic). There is a restriction that only instances of exceptions can be assigned to __cause__, and if you specify an exception class then it gets instantiated before assignment. Trying to assign anything else triggers a TypeError.

So the first question is how much checking do we need to do for the from clause&aposs object to make sure it meets the requirement of being an (eventual) exception instance?

>>> exc1 = Exception()
>>> exc1.__cause__ = 42
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: exception cause must be None or derive from BaseException
>>> exc1.__cause__ = Exception
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: exception cause must be None or derive from BaseException
>>> exc1.__cause__ = Exception()
>>>
Exploring restrictions when assigning to BaseException.__cause__

It appears that only assigning an instance of an exception to __cause__ is allowed. This is convenient as we don&apost have to do the check for something not being an exception instance. But it&aposs also inconvenient as we do have to instantiate any exception class ourselves. What this says to me is the following:

  1. Assigning an exception instance is fine.
  2. Assigning a non-exception-related object is "fine" because the exception object will raise the exception.
  3. Assigning an exception class is problematic, and so we will have to handle the instantiation.

So how do we detect if an object is an exception class but not an instance? To tell if an object is a class, it needs to be an instance of type (as inspect.issclass() shows us); isinstance(obj, type). To tell if something is an exception instance, it needs to be an instance of BaseException; isinstance(obj, BaseException). And to tell if a class is an exception class, we need to know if it subclasses BaseException; issubclass(obj, BaseException). Now one thing to note is issubclass() will raise a TypeError if you pass anything that isn&apost a class as its first argument; isinstance() does not have the inverse issue of passing in a class as its first argument.

Oh, and we also have to make sure the object we are raising is also appropriately instantiated before we attempt any assignment to __cause__. That adds an extra wrinkle to this problem as it means we will have to raise the TypeError when the to-be-raised exception isn&apost an exception-related object.

This can all be summarized by the following function:

def exception_instance(obj):
    if isinstance(obj, BaseException):
        return obj
    elif isinstance(obj, type) and issubclass(obj, BaseException):
        return obj()
    else:
        raise TypeError("exceptions must derive from BaseException")
Utility function for getting an exception instance

When we unravel raise A from B, we can inline the logic and simplify it a bit:

  1. If we have an exception class, instantiate it.
  2. If we have a non-exception object for the raise clause, raise TypeError.
  3. Rely on the fact that assigning anything other than an exception instance to __cause__ raises the appropriate TypeError for us.
  4. Don&apost assign anything if the from clause evaluates to None.

This lets us unravel raise A from B to:

_raise = A
if isinstance(_raise, type) and issubclass(_raise, BaseException):
        _raise = _raise()
elif not isinstance(_raise, BaseException):
    raise TypeError("exceptions must derive from BaseException")

_from = B
if isinstance(_from, type) and issubclass(_from, BaseException):
        _from = _from()
if _from is not None:
	_raise.__cause__ = _from

raise _raise
Unravelling raise A from B

In the general case of raise A we don&apost have to do any of this as it&aposs part of Python&aposs semantics to handle the class-to-instance scenario.

January 08, 2022 11:07 PM UTC


ItsMyCode

Python String swapcase()

ItsMyCode |

Python string swapcase() method is a built-in function that converts all uppercase characters into lowercase and all lowercase characters into uppercase characters of a given string and returns a new string.

swapcase() Syntax

The Syntax of swapcase() method is:

string.swapcase()

swapcase() Parameters

The swapcase() method doesn’t take any parameters.

swapcase() Return Value

The swapcase() method returns a copy of the string where all the uppercase characters are converted into lowercase characters and vice-versa.

In case the string has other than alphabets those characters will not be converted and returned as-is.

Example: Python Program to change the case of a given string

text1 = "pYTHON tUTORIALS"
print(text1.swapcase())

text2 = "HELLO WORLD"
print(text2.swapcase())

text3 = "welcome to itsmycode"
print(text3.swapcase())

text4 ="12345!!!"
print(text4.swapcase())

Output

Python Tutorials
hello world
WELCOME TO ITSMYCODE
12345!!!
Note: If you want to convert given string into lowercase only it is recommended to use lower() method. Likewise, if you want to convert given string into uppercase only it is recommended to use upper() method.

The post Python String swapcase() appeared first on ItsMyCode.

January 08, 2022 11:50 AM UTC


Talk Python to Me

#347: Cinder - Specialized Python that Flies

The team at Instagram dropped a performance bomb on the Python world when they open-sourced Cider, their performance oriented fork of CPython. It contains a number of performance optimizations, including bytecode inline caching, eager evaluation of coroutines, a method-at-a-time JIT, and an experimental bytecode compiler that uses type annotations to emit type-specialized bytecode that performs better in the JIT. <br/> <br/> While it's not a general purpose runtime we can all pick up and use, it contains many powerful features and optimizations that may make their way back to mainline Python. <br/> <br/> We welcome Dino Viehland to dive into Cinder.<br/> <br/> <strong>Links from the show</strong><br/> <br/> <div><b>Dino on Twitter</b>: <a href="https://twitter.com/DinoViehland" target="_blank" rel="noopener">@DinoViehland</a><br/> <b>Cinder Python Runtime</b>: <a href="https://github.com/facebookincubator/cinder" target="_blank" rel="noopener">github.com/facebookincubator</a><br/> <b>Dino's PyCon talk</b>: <a href="https://www.youtube.com/watch?v=xGY45EmhwrE" target="_blank" rel="noopener">youtube.com</a><br/> <b>IronPython</b>: <a href="https://ironpython.net/" target="_blank" rel="noopener">ironpython.net</a><br/> <b>Sam Gross's NoGil work</b>: <a href="https://github.com/colesbury/nogil" target="_blank" rel="noopener">github.com/colesbury/nogil</a><br/> <b>Pyjion</b>: <a href="https://www.trypyjion.com/" target="_blank" rel="noopener">trypyjion.com</a><br/> <b>uWSGI</b>: <a href="https://uwsgi-docs.readthedocs.io/en/latest/" target="_blank" rel="noopener">uwsgi-docs.readthedocs.io</a><br/> <b>Configuring uWSGI at Bloomberg</b>: <a href="https://www.techatbloomberg.com/blog/configuring-uwsgi-production-deployment/" target="_blank" rel="noopener">techatbloomberg.com</a><br/> <b>Locust perf testing</b>: <a href="https://locust.io/" target="_blank" rel="noopener">locust.io</a><br/> <b>Watch this episode on YouTube</b>: <a href="https://www.youtube.com/watch?v=XHVaEj9fnA8" target="_blank" rel="noopener">youtube.com</a><br/> <b>Episode transcripts</b>: <a href="https://talkpython.fm/episodes/transcript/347/cinder-specialized-python-that-flies" target="_blank" rel="noopener">talkpython.fm</a><br/> <br/> <b>--- Stay in touch with us ---</b><br/> <b>Subscribe on YouTube</b>: <a href="https://talkpython.fm/youtube" target="_blank" rel="noopener">youtube.com</a><br/> <b>Follow Talk Python on Twitter</b>: <a href="https://twitter.com/talkpython" target="_blank" rel="noopener">@talkpython</a><br/> <b>Follow Michael on Twitter</b>: <a href="https://twitter.com/mkennedy" target="_blank" rel="noopener">@mkennedy</a><br/></div><br/> <strong>Sponsors</strong><br/> <a href='https://talkpython.fm/sentry'>Sentry Error Monitoring, Code TALKPYTHON</a><br> <a href='https://talkpython.fm/toptal'>TopTal</a><br> <a href='https://talkpython.fm/assemblyai'>AssemblyAI</a><br> <a href='https://talkpython.fm/training'>Talk Python Training</a>

January 08, 2022 08:00 AM UTC

January 07, 2022


Mikko Ohtamaa

Building cryptocurrency site with Svelte, Python and TimescaleDB

This blog post is a repost of the original technical overview of the Trading Strategy protocol software stack for community feed aggregators. Please read the original blog post for the best layout and formatting.

The audience of this post is software developers who are looking to build scalable software-as-a-service solutions and are interested in Svelte, Python and TimescaleDB technologies. Developers who are interested in Web3, Ethereum, cryptocurrency and blockchain technologies will also find this post useful.

What are Trading Strategy protocol and algorithmic trading?

Trading Strategy is a new service for algorithmic and technical trading of cryptocurrencies on decentralised exchange (DEXes).

Algorithmic trading is a derivative of technical analysis; taking trading positions based on pure mathematics and data. Algorithmic trading is part of quantitative finance, the opposite of value investing where trading decisions are made based on fundamentals. Algorithmic trading provides a systematic approach to trading compared to methods based on trader intuition or instinct. Whereas technical analysis often aids humans to take trading positions, in its purest form in algorithmic trading a trading program follows a set of trading rules and independently executes trades on the market 24/7.

Today, Trading Strategy offers market data feeds for Uniswap compatible exchanges across three different blockchains (Ethereum, Binance Smart Chain, Polygon). We expect to cover all major decentralised exchanges and exchange types on all major blockchains by the end of the year.

Our mission is to make algorithmic by developing and investing in algorithmic trading strategies easy. Although serving the market data is the first step, Trading Strategy is going to grow beyond the information service website. During the course of 2022, the service will be decentralised, so that the whole software solution, strategy and trade execution will be runnable anyone independently (so-called operating a node).

You can read more about our future plans in our vision blog post.

Rich in technical wealth

Trading Strategy chose modern architecture and the best components of 2021 for its software development, making its codebase high in technical wealth.

Technical wealth is the opposite of technical debt. As Trading Strategy was able to start as a clean slate project, we had the privilege to pick the latest technologies and build our architecture around these. This enables us to build faster and do changes more dynamically. As an example, a lot of out of the box features offered by TimescaleDB would have taken us months if we had built them ourselves.

The decentralised finance (DeFi) industry itself is high in technical wealth compared to traditional finance (TradFi). This is due to the use of public ledger (open data), free-as-in-speech codebases (open source) and permissionless public blockchains (open access). This is the opposite of the traditional financial services that are built around closed networks, private APIs and exclusive access. Privileged and siloed software development leads to high maintenance cost long term, as there are no people who are able to work with the code. For references, see this blog post on legacy investment bank software and Google’s woes about maintaining their own Linux kernel with 9000+ in-house patches. Writing financial applications for DeFi is 10x  – 100x more developer productive than writing them for TradFi.

What is a Web3?

From the software developer point of view, Web3 refers to backend-free services. No logins or registrations are needed. The user data is not processed and stored on a private server, but a public blockchain where the business logic is wired together using smart contracts. Any transaction, or a “POST request” in the traditional parlay, is initiated by users themselves, using their private key on their locally stored wallet application.

In this kind of model, there are no sysadmin fraud risks, no data loss risks or data liability risks with user identity information. The user is in 100% control. It is a fairer world where users have more control over the revenue streams they generate. Big IT like Facebook and Google have fewer unfair monetization opportunities on user data.

Only some services are a good fit for Web3. At the moment Web3 works best for pseudonymous and public data use cases. This is almost all finance, provenance (NFTs), public social media like Twitter and discussion forums and eCommerce.

Web3 is still early: though most pieces have been figured out in computer science theory, the implementation is still under development. For example, doing database-like traffic (ThreadDB) and storage (Arweave, Storj) can be still considered “alpha” today.

Software stack overview

Below is a walkthrough of how the HTTP requesting of Trading Strategy website is set up. Because Trading Strategy application is eventually going to be a Web3-like oracle node in a distributed network, everything built API first. There are no internal APIs – the website uses the same public market data APIs as everyone else.

Trading Strategy Oracle is a process that indexes blockchain data: DEX trading data, tokens and so on. Oracle and web processes communicate over TimescaleDB. Oracle is responsible for tasks like generating OHLCV candle data, generating liquidity maps and fetching US dollar reference prices. Oracle processes connect to various blockchain GoEthereum nodes that are part of the P2P network for the respective Ethereum Virtual Machine based blockchains.

Frontend: Why did we choose Svelte?

Svelte is a new JavaScript frontend framework and an alternative to React, Vue.js and Angular. Svelte comes with an integration package called SvelteKit that adds a standard web server, routing, server-side rendering and other core functionality needed to build a fully functional website.

We considered React for Trading Strategy . React is the de facto frontend framework choice of the cryptocurrency industry. However, even with our extensive experience in React, we chose Svelte because we believe Svelte is the framework of the future. Svelte offers reactivity with ahead-of-time compiled virtual DOM free approach. Svelte components are very maintanable single files, containing normal HTML template and normal CSS code instead of bastardized “styles-in-JS” or domain-specific templating approaches. Writing reactive logic in Svelte is easier than in other frameworks, due to its elegant design making the most developer-friendly frontend framework.

SvelteKit takes the developer experience of Svelte even further, by introducing the concepts of file-system based routing, simple server-side rendering and integrated web server (Vite). With SvelteKit’s batteries included approach an application developer spends less time on plumbing, boilerplate code and debugging async reactivity mess This all translates to better efficiency: the codebase is easier to read and maintain due to standardized coding conventions across open source libraries, components are faster to develop and new developers pick up the pace faster.

We also use components outside Svelte. We use uPlot for charting. Though the TradingView is the most popular JS framework for technical trading, we are puritans that go with 100% open-source approach as we are building for long term. uPlot was the charting library with an open-source license. For our number heavy tables we use DataTable library. For Web3 integration, we use web3.js through svelte-web3.

Backend: Why did we choose Python, Pyramid and SQLAlchemy?

Pyramid is a web framework for Python and SQLAlchemy is Python’s most popular ORM. We have experience writing Python applications since 2006 using Django, Flask and Pyramid. We also have experience writing backends in Node.js with various frameworks like Next.js.

For developers who know several programming languages, Python is superior choice for the backend. Writing Python programs takes fewer keystrokes. Python is the most readable of all programming languages. Optional typing support is a great way to make the code more static when the team grows.

There is a forever battle with sync vs. async. There is greater maintenance efficiency with colored function free, linear threaded, Python code. Our workloads are computationally sensitive, not IO sensitive, so using async IO would cause more headaches and we would get no benefits out of it.

We chose Pyramid and SQLAlchemy because we are doing API first backend and complex databasing with our special workload. Trading Strategy currently features tracking of 800k trading pairs (NASDAQ has only 3000). This is not your run of the mill CRUD and admin UI application. For this kind of use case, Pyramid and SQLALchemy are the choice today. This framework combo offers powerful tooling to cover advanced use cases without sacrificing developer productivity or being completely outside of an average backend developer skillset.

For our API tooling and developer communications we chose OpenAPI 3, also known as Swagger. Integration is mostly cost-free: pyramid_openapi3 validates the API definition, validates requests and replies, and can automatically route payloads to their corresponding endpoints and offers Swagger interactive API explorer. This all saves us a lot of manual development.

For background workers, we use Dramatiq library with Redis broker. Dramatiq task server is simpler, much easier to understand and maintain than more well-known Celery.

Data research: Why did we choose Jupyter notebook?

Most quantitative finance in the world uses Jupyter Notebooks and Python data science libraries like Pandas and Numpy. This is the strongest suite of Python that no other programming language can match. In fact, Pandas was originally developed by an investment bank.

Trading Strategy algorithm backtesting is done in Jupyter. We offer a Trading Strategy client library so that quants can develop their algos against decentralised exchanges without need to know low level blockchain specific details. If you are interested to see if you can beat the market please see Getting started tutorial (beta warning: better to join our Discord as well.)

Database: Why did we choose TimescaleDB?

TimescaleDB is a PostgreSQL extension specialised in time-series data, especially the “big” flavour of it. The alternatives included Clickhouse and xxx.

We chose TimescaleDB, because they are based on PostgreSQL. During the last 20 years, PostgreSQL has overtaken as the most advanced open-source database. PostgreSQL has the most vibrant database ecosystem on this planet. Tuning PostgreSQL is well-known: there are multiple products and companies to support in-house development.

Many of the core TimescaleDB features make our life easier. For example, hypertables provide fast insert times on large time-series datasets – otherwise inserting your one-billionth row starts to slow down. Continuous aggregates give us free upsampling 1-minute OHLCV candles to 5 minutes to 30 days periods.

TimescaleDB completed their Series B funding round where they raise $40M. Based on the quality of their product, the detail they go in their developer communications, we can see why they could be the winning horse of time-series databases.

TimescaleDB team has been the most responsive of any projects we have seen during the 25 years of open-source involvement. Their proactivity and helpfulness give us an assurance that TimescaleDB is serious about building an open-source community. All of our StackOveflow questions and Github issue reports, no matter how bad or novice has gone unanswered. We are pretty sure if one were to ask something offtopic, like making a coffee, and tagging with “timescaledb” it would still a receive perfect answer.

Why did we launch on Ethereum mainnet, Binance Smart Chain and Polygon?

When we started to build Trading Strategy early 2021, the layer 1 blockchains were not still on such rampage as they are today. Polygon and Binance Smart Chain were the layer 1 top dogs and no layer two was live yet. Ther chains had user adoption and active DEXes like PancakeSwap and QuickSwap. Today we have more competition with the likes of Avalanche, Fantom, Aurora and Telos EVM. Also we have non-EVM based solid solutions like NEAR, Elrond and Solana. We expect to integrate all of them during the source of 2022.

Ethereum mainnet has the best developer community. However, the Ethereum mainnet transaction costs are prohibitively expensive for the unforeseeable future, and thus it is unsuitable for our active trading strategies.

What challenges do we see?

Developing the means failing and retrying a few times, as your first guess is not always right one. We have some good lessons from 2021.

SvelteKit is still in beta. Some of the aspects of it are still under development and may not have complete documentation or supporting material like tutorial blog posts. We had to figure out a lot of aspects ourselves, especially what comes to SvelteKit server-side rendering speed and tuning. We feel the benefits of SvelteKit developer productivity greatly outweighs some learning curve and contributions to the documentation we had to do ourselves.

Svelte is new, thus it still does not have Svelte-native feature-rich charting libraries like uPlot and Datatables. They do not integrate to SvelteKit server-side rendering flow, making it not possible to serve pre-rendered pages.

Hosting Polygon and Binance Smart Chain nodes is tough. Both blockchain teams have issues with developer communications. There are no adequate manuals for running your own node. The expectation of using bug-ridden third-party API services goes against the blockchain ethos

Some queries on PostgreSQL are still unnecessary complex whereas other databases do better. Often we need to refer to the latest value, like the latest price, either for a single item or for a group. Unfortunately PostgreSQL does not offer any native “latest value” indices and it is often tricky to write an efficient query for this. Sometimes even simple ORDER LIMIT 1 seems to cause issues for PostgreSQL unless you create unnecessary fat indices.

We are open source

Trading Strategy frontend has been open source since the day one. If you are new to Svelte / SvelteKit you might find our repository interesting to read and learn why we have made certain design choices.

The same goes for the Jupyter Python trading strategy client. Oracle code and backend code will be eventually opened, as we start rolling out the protocol network later in 2022.

We are hiring

We are currently hiring for frontend (Svelte), backend (Python/PostgreSQL) and quant research (Jupytere Notebook/Pandas) positions. If you are interested to work with cryptocurrencies and algorithmic trading please email us careers@tradingstrategy.ai.

The cover photo by Alex Chumak.

 Subscribe to RSS feed Follow me on Twitter Follow me on Facebook Follow me Google+

January 07, 2022 12:02 PM UTC


Real Python

The Real Python Podcast – Episode #92: Continuing to Unravel Python's Syntatic Sugar With Brett Cannon

A year ago, we had Brett Cannon on the show to discuss his blog series about unravelling Python's syntactic sugar. Brett has written 15 more entries in the series, and he returns to the show this week to continue our conversation. We dive into unravelling 'async' and 'await' statements and their relationship with Python's generators.


[ Improve Your Python With 🐍 Python Tricks 💌 – Get a short & sweet Python Trick delivered to your inbox every couple of days. >> Click here to learn more and see examples ]

January 07, 2022 12:00 PM UTC


Mikko Ohtamaa

Building a cryptocurrency site with Svelte, Python and TimescaleDB

This post is the repost of the original Trading Strategy software architecture overview for community feed aggregators. Please read the original post for the best layout and formatting.

The audience of this post is software developers who are looking to build scalable software-as-a-service solutions and are interested in Svelte, Python and TimescaleDB technologies. Developers who are interested in Web3, Ethereum, cryptocurrency and blockchain technologies will also find this post useful.

What are Trading Strategy protocol and algorithmic trading?

Trading Strategy is a new service for algorithmic and technical trading of cryptocurrencies on decentralised exchange (DEXes).

Algorithmic trading is a derivative of technical analysis; taking trading positions based on pure mathematics and data. Algorithmic trading is part of quantitative finance, the opposite of value investing where trading decisions are made based on fundamentals. Algorithmic trading provides a systematic approach to trading compared to methods based on trader intuition or instinct. Whereas technical analysis often aids humans to take trading positions, in its purest form in algorithmic trading a trading program follows a set of trading rules and independently executes trades on the market 24/7.

Today, Trading Strategy offers market data feeds for Uniswap compatible exchanges across three different blockchains (Ethereum, Binance Smart Chain, Polygon). We expect to cover all major decentralised exchanges and exchange types on all major blockchains by the end of the year.

Our mission is to make algorithmic by developing and investing in algorithmic trading strategies easy. Although serving the market data is the first step, Trading Strategy is going to grow beyond the information service website. During the course of 2022, the service will be decentralised, so that the whole software solution, strategy and trade execution will be runnable anyone independently (so-called operating a node).

You can read more about our future plans in our vision blog post.

Rich in technical wealth

Trading Strategy chose modern architecture and the best components of 2021 for its software development, making its codebase high in technical wealth.

Technical wealth is the opposite of technical debt. As Trading Strategy was able to start as a clean slate project, we had the privilege to pick the latest technologies and build our architecture around these. This enables us to build faster and do changes more dynamically. As an example, a lot of out of the box features offered by TimescaleDB would have taken us months if we had built them ourselves.

The decentralised finance (DeFi) industry itself is high in technical wealth compared to traditional finance (TradFi). This is due to the use of public ledger (open data), free-as-in-speech codebases (open source) and permissionless public blockchains (open access). This is the opposite of the traditional financial services that are built around closed networks, private APIs and exclusive access. Privileged and siloed software development leads to high maintenance cost long term, as there are no people who are able to work with the code. For references, see this blog post on legacy investment bank software and Google’s woes about maintaining their own Linux kernel with 9000+ in-house patches. Writing financial applications for DeFi is 10x  – 100x more developer productive than writing them for TradFi.

What is a Web3?

From the software developer point of view, Web3 refers to backend-free services. No logins or registrations are needed. The user data is not processed and stored on a private server, but a public blockchain where the business logic is wired together using smart contracts. Any transaction, or a “POST request” in the traditional parlay, is initiated by users themselves, using their private key on their locally stored wallet application.

In this kind of model, there are no sysadmin fraud risks, no data loss risks or data liability risks with user identity information. The user is in 100% control. It is a fairer world where users have more control over the revenue streams they generate. Big IT like Facebook and Google have fewer unfair monetization opportunities on user data.

Only some services are a good fit for Web3. At the moment Web3 works best for pseudonymous and public data use cases. This is almost all finance, provenance (NFTs), public social media like Twitter and discussion forums and eCommerce.

Web3 is still early: though most pieces have been figured out in computer science theory, the implementation is still under development. For example, doing database-like traffic (ThreadDB) and storage (Arweave, Storj) can be still considered “alpha” today.

Software stack overview

Below is a walkthrough of how the HTTP requesting of Trading Strategy website is set up. Because Trading Strategy application is eventually going to be a Web3-like oracle node in a distributed network, everything built API first. There are no internal APIs – the website uses the same public market data APIs as everyone else.

Trading Strategy Oracle is a process that indexes blockchain data: DEX trading data, tokens and so on. Oracle and web processes communicate over TimescaleDB. Oracle is responsible for tasks like generating OHLCV candle data, generating liquidity maps and fetching US dollar reference prices. Oracle processes connect to various blockchain GoEthereum nodes that are part of the P2P network for the respective Ethereum Virtual Machine based blockchains.

Frontend: Why did we choose Svelte?

Svelte is a new JavaScript frontend framework and an alternative to React, Vue.js and Angular. Svelte comes with an integration package called SvelteKit that adds a standard web server, routing, server-side rendering and other core functionality needed to build a fully functional website.

We considered React for Trading Strategy . React is the de facto frontend framework choice of the cryptocurrency industry. However, even with our extensive experience in React, we chose Svelte because we believe Svelte is the framework of the future. Svelte offers reactivity with ahead-of-time compiled virtual DOM free approach. Svelte components are very maintanable single files, containing normal HTML template and normal CSS code instead of bastardized “styles-in-JS” or domain-specific templating approaches. Writing reactive logic in Svelte is easier than in other frameworks, due to its elegant design making the most developer-friendly frontend framework.

SvelteKit takes the developer experience of Svelte even further, by introducing the concepts of file-system based routing, simple server-side rendering and integrated web server (Vite). With SvelteKit’s batteries included approach an application developer spends less time on plumbing, boilerplate code and debugging async reactivity mess This all translates to better efficiency: the codebase is easier to read and maintain due to standardized coding conventions across open source libraries, components are faster to develop and new developers pick up the pace faster.

We also use components outside Svelte. We use uPlot for charting. Though the TradingView is the most popular JS framework for technical trading, we are puritans that go with 100% open-source approach as we are building for long term. uPlot was the charting library with an open-source license. For our number heavy tables we use DataTable library. For Web3 integration, we use web3.js through svelte-web3.

Backend: Why did we choose Python, Pyramid and SQLAlchemy?

Pyramid is a web framework for Python and SQLAlchemy is Python’s most popular ORM. We have experience writing Python applications since 2006 using Django, Flask and Pyramid. We also have experience writing backends in Node.js with various frameworks like Next.js.

For developers who know several programming languages, Python is superior choice for the backend. Writing Python programs takes fewer keystrokes. Python is the most readable of all programming languages. Optional typing support is a great way to make the code more static when the team grows.

There is a forever battle with sync vs. async. There is greater maintenance efficiency with colored function free, linear threaded, Python code. Our workloads are computationally sensitive, not IO sensitive, so using async IO would cause more headaches and we would get no benefits out of it.

We chose Pyramid and SQLAlchemy because we are doing API first backend and complex databasing with our special workload. Trading Strategy currently features tracking of 800k trading pairs (NASDAQ has only 3000). This is not your run of the mill CRUD and admin UI application. For this kind of use case, Pyramid and SQLALchemy are the choice today. This framework combo offers powerful tooling to cover advanced use cases without sacrificing developer productivity or being completely outside of an average backend developer skillset.

For our API tooling and developer communications we chose OpenAPI 3, also known as Swagger. Integration is mostly cost-free: pyramid_openapi3 validates the API definition, validates requests and replies, and can automatically route payloads to their corresponding endpoints and offers Swagger interactive API explorer. This all saves us a lot of manual development.

For background workers, we use Dramatiq library with Redis broker. Dramatiq task server is simpler, much easier to understand and maintain than more well-known Celery.

Data research: Why did we choose Jupyter notebook?

Most quantitative finance in the world uses Jupyter Notebooks and Python data science libraries like Pandas and Numpy. This is the strongest suite of Python that no other programming language can match. In fact, Pandas was originally developed by an investment bank.

Trading Strategy algorithm backtesting is done in Jupyter. We offer a Trading Strategy client library so that quants can develop their algos against decentralised exchanges without need to know low level blockchain specific details. If you are interested to see if you can beat the market please see Getting started tutorial (beta warning: better to join our Discord as well.)

Database: Why did we choose TimescaleDB?

TimescaleDB is a PostgreSQL extension specialised in time-series data, especially the “big” flavour of it. The alternatives included Clickhouse and xxx.

We chose TimescaleDB, because they are based on PostgreSQL. During the last 20 years, PostgreSQL has overtaken as the most advanced open-source database. PostgreSQL has the most vibrant database ecosystem on this planet. Tuning PostgreSQL is well-known: there are multiple products and companies to support in-house development.

Many of the core TimescaleDB features make our life easier. For example, hypertables provide fast insert times on large time-series datasets – otherwise inserting your one-billionth row starts to slow down. Continuous aggregates give us free upsampling 1-minute OHLCV candles to 5 minutes to 30 days periods.

TimescaleDB completed their Series B funding round where they raise $40M. Based on the quality of their product, the detail they go in their developer communications, we can see why they could be the winning horse of time-series databases.

TimescaleDB team has been the most responsive of any projects we have seen during the 25 years of open-source involvement. Their proactivity and helpfulness give us an assurance that TimescaleDB is serious about building an open-source community. All of our StackOveflow questions and Github issue reports, no matter how bad or novice has gone unanswered. We are pretty sure if one were to ask something offtopic, like making a coffee, and tagging with “timescaledb” it would still a receive perfect answer.

Why did we launch on Ethereum mainnet, Binance Smart Chain and Polygon?

When we started to build Trading Strategy early 2021, the layer 1 blockchains were not still on such rampage as they are today. Polygon and Binance Smart Chain were the layer 1 top dogs and no layer two was live yet. Ther chains had user adoption and active DEXes like PancakeSwap and QuickSwap. Today we have more competition with the likes of Avalanche, Fantom, Aurora and Telos EVM. Also we have non-EVM based solid solutions like NEAR, Elrond and Solana. We expect to integrate all of them during the source of 2022.

Ethereum mainnet has the best developer community. However, the Ethereum mainnet transaction costs are prohibitively expensive for the unforeseeable future, and thus it is unsuitable for our active trading strategies.

What challenges do we see?

Developing the means failing and retrying a few times, as your first guess is not always right one. We have some good lessons from 2021.

SvelteKit is still in beta. Some of the aspects of it are still under development and may not have complete documentation or supporting material like tutorial blog posts. We had to figure out a lot of aspects ourselves, especially what comes to SvelteKit server-side rendering speed and tuning. We feel the benefits of SvelteKit developer productivity greatly outweighs some learning curve and contributions to the documentation we had to do ourselves.

Svelte is new, thus it still does not have Svelte-native feature-rich charting libraries like uPlot and Datatables. They do not integrate to SvelteKit server-side rendering flow, making it not possible to serve pre-rendered pages.

Hosting Polygon and Binance Smart Chain nodes is tough. Both blockchain teams have issues with developer communications. There are no adequate manuals for running your own node. The expectation of using bug-ridden third-party API services goes against the blockchain ethos

Some queries on PostgreSQL are still unnecessary complex whereas other databases do better. Often we need to refer to the latest value, like the latest price, either for a single item or for a group. Unfortunately PostgreSQL does not offer any native “latest value” indices and it is often tricky to write an efficient query for this. Sometimes even simple ORDER LIMIT 1 seems to cause issues for PostgreSQL unless you create unnecessary fat indices.

We are open source

Trading Strategy frontend has been open source since the day one. If you are new to Svelte / SvelteKit you might find our repository interesting to read and learn why we have made certain design choices.

The same goes for the Jupyter Python trading strategy client. Oracle code and backend code will be eventually opened, as we start rolling out the protocol network later in 2022.

We are hiring

We are currently hiring for frontend (Svelte), backend (Python/PostgreSQL) and quant research (Jupytere Notebook/Pandas) positions. If you are interested to work with cryptocurrencies and algorithmic trading please email us careers@tradingstrategy.ai.

The cover photo by Alex Chumak.

January 07, 2022 11:59 AM UTC


Kushal Das

Trouble with signing and notarization on macOS for Tumpa

This week I released the first version of Tumpa on Mac. Though the actual changes required for building the Mac app and dmg file were small, but I had to reap apart those few remaining hairs on my head to get it working on any other Mac (than the building box). It was the classic case of Works on my laptop.

The issue

Tumpa is a Python application which uses PySide2 and also Johnnycanencrypt which is written in Rust.

I tried both briefcase tool and manual calling to codesign and create-dmg tools to create the tumpa.app and the tumpa-0.1.3.dmg.

After creating the dmg file, I had to submit it for notarisation to Apple, following:

xcrun /Applications/Xcode.app/Contents/Developer/usr/bin/altool --notarize-app --primary-bundle-id "in.kushaldas.Tumpa" -u "kushaldas@gmail.com" -p "@keychain:MYNOTARIZATION" -f macOS/tumpa-0.1.3.dmg

This worked successfully, after a few minutes I can see that the job passed. So, I can then staple the ticket on the dmg file.

xcrun stapler staple macOS/tumpa-0.1.3.dmg

I can install from the file, and run the application, sounds great.

But, whenever someone else tried to run the application after installing from dmg, it showed the following.

mac failure screenshot

Solution

It took me over 4 hours to keep trying all possible combinations, and finally I had to pass --options=runtime,library to the codesign tool, and that did the trick. Not being able to figure out how to get more logs on Mac was making my life difficult.

I had to patch briefcase to make sure I can keep using it (also created the upstream issue).

--- .venv/lib/python3.9/site-packages/briefcase/platforms/macOS/__init__.py	2022-01-07 08:48:12.000000000 +0100
+++ /tmp/__init__.py	2022-01-07 08:47:54.000000000 +0100
@@ -117,7 +117,7 @@
                     '--deep', str(path),
                     '--force',
                     '--timestamp',
-                    '--options', 'runtime',
+                    '--options', 'runtime,library',
                 ],
                 check=True,
             )

You can see my build script, which is based on input from Micah.

I want to thank all of my new friends inside of SUNET who were excellent helping hands to test the multiple builds of Tumpa. Later many folks from IRC also jumped in to help to test the tool.

January 07, 2022 09:10 AM UTC


Armin Ronacher

Rust Any Part 2: As-Any Hack

Yesterday I wrote about how to use the Any type in Rust to implement extension maps. One thing that was brought up as a response is that it's hard to implement Debug for the extension map as Any does not implement Debug. The challenge is that unfortunately in Rust you cannot do Box<dyn Any + Debug>. However there are ways around it.

The Simplifed Problem

Let's say you want to have a wrapper around a boxed any that you can debug. This is what we basically want to accomplish:

#[derive(Debug)]
struct AnyBox(Box<dyn Any + Debug>);

If we were to compile this, the compiler doesn't come back happy:

error[E0225]: only auto traits can be used as additional traits in a trait object
 --> src/main.rs:9:29
  |
9 | struct AnyBox(Box<dyn Any + Debug>);
  |                       ---   ^^^^^ additional non-auto trait
  |                       |
  |                       first non-auto trait
  |
  = help: consider creating a new trait with all of these as supertraits and
    using that trait here instead: `trait NewTrait: Any + Debug {}`

Supertraits

Thankfully the compiler actually tells is what the solution is: we need to create a new super trait that we can use. However it leaves us a bit in the dark of how to do this successfully. Basically we want to implement our super trait for all types implementing the individual traits. Something like this:

#[derive(Debug)]
struct AnyBox(Box<dyn Any + Debug>);

trait DebugAny: Any + Debug {}

impl<T: Any + Debug + 'static> DebugAny for T {}

This will in fact compile and you will be able to construct such a box, but what will not work is downcasting:

fn main() {
    let any_box = AnyBox(Box::new(42i32));
    dbg!(any_box.0.downcast_ref::<i32>());
}

The compiler will tell us that our value in the anybox has no method named downcast_ref:

error[E0599]: no method named `downcast_ref` found for struct
  `Box<(dyn DebugAny + 'static)>` in the current scope
  --> src/main.rs:15:20
   |
15 |     dbg!(any_box.0.downcast_ref::<i32>());
   |                    ^^^^^^^^^^^^ method not found in `Box<(dyn DebugAny + 'static)>`

The reason for this is that a Box<dyn DebugAny> unfortunately is not a Box<dyn Any> and as such we don't get the methods from it that we need. So how do we fix this? The simplest method is the “as any” pattern where we implement a method on our DebugAny trait that upcasts into an Any. This looks like this:

trait DebugAny: Any + Debug {
    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;
}

impl<T: Any + Debug + 'static> DebugAny for T {
    fn as_any(&self) -> &dyn Any { self }
    fn as_any_mut(&mut self) -> &mut dyn Any { self }
}

Now we still can't downcast_ref on the box, but we can take our value, call as_any on it, retrieve a &dyn Any and then go to town:

fn main() {
    let any_box = AnyBox(Box::new(42i32));
    dbg!(any_box.0.as_any().downcast_ref::<i32>());
    dbg!(&any_box);
}

Except if we run it, we get None. What's going on?

[src/main.rs:23] any_box.0.as_any().downcast_ref::<i32>() = None

The answer to this riddle has to do with how the method resolution works and blanket implementations. When we invoke as_any on Box<dyn DebugAny> we're not looking through the box, we're in fact invoking as_any on the Box<dyn DebugAny> itself since the box also implements our DebugAny now. So how do we reach through the box? By dereferencing it.

fn main() {
    let any_box = AnyBox(Box::new(42i32));
    dbg!((*any_box.0).as_any().downcast_ref::<i32>());
    dbg!(&any_box);
}

And now we get what we expect:

[src/main.rs:23] (*any_box.0).as_any().downcast_ref::<i32>() = Some(
    42,
)
[src/main.rs:24] &any_box = AnyBox(
    42,
)

Debuggable Extension Map

These learnings we can now take back to building an extension map which can be debug printed. Let's take the non sync extension map from last time and modify it so we can debug print it:

use std::any::{Any, TypeId};
use std::cell::{Ref, RefCell, RefMut};
use std::collections::HashMap;
use std::fmt::Debug;

trait DebugAny: Any + Debug {
    fn as_any(&self) -> &dyn Any;
    fn as_any_mut(&mut self) -> &mut dyn Any;
}

impl<T: Any + Debug + 'static> DebugAny for T {
    fn as_any(&self) -> &dyn Any { self }
    fn as_any_mut(&mut self) -> &mut dyn Any { self }
}

#[derive(Default, Debug)]
pub struct Extensions {
    map: RefCell<HashMap<TypeId, Box<dyn DebugAny>>>,
}

impl Extensions {
    pub fn insert<T: Debug + 'static>(&self, value: T) {
        self.map
            .borrow_mut()
            .insert(TypeId::of::<T>(), Box::new(value));
    }

    pub fn get<T: Default + Debug + 'static>(&self) -> Ref<'_, T> {
        self.ensure::<T>();
        Ref::map(self.map.borrow(), |m| {
            m.get(&TypeId::of::<T>())
                .and_then(|b| (**b).as_any().downcast_ref())
                .unwrap()
        })
    }

    pub fn get_mut<T: Default + Debug + 'static>(&self) -> RefMut<'_, T> {
        self.ensure::<T>();
        RefMut::map(self.map.borrow_mut(), |m| {
            m.get_mut(&TypeId::of::<T>())
                .and_then(|b| (**b).as_any_mut().downcast_mut())
                .unwrap()
        })
    }

    fn ensure<T: Default + Debug + 'static>(&self) {
        if self.map.borrow().get(&TypeId::of::<T>()).is_none() {
            self.insert(T::default());
        }
    }
}

Adding some stuff into the map and debug printing it makes it output something like this now:

[src/main.rs:63] &extensions = Extensions {
    map: RefCell {
        value: {
            TypeId {
                t: 13431306602944299956,
            }: 42,
        },
    },
}

In this case I placed a 32bit integer 42 in the map and we can see that it prints out the type id of that as key, and 42 as value.

Retaining Type Names

If we want to retain the original type name and not just type ID we could change our TypeId key for a custom type which also stores the original type name. This could be accomplished by creating a wrapper for our TypeId which uses std::any::type_name internally:

use std::any::{TypeId, type_name};
use std::hash::{Hash, Hasher};
use std::fmt::{self, Debug};

pub struct TypeKey(TypeId, &'static str);

impl TypeKey {
    pub fn of<T: 'static>() -> TypeKey {
        TypeKey(TypeId::of::<T>(), type_name::<T>())
    }
}

impl Hash for TypeKey {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.0.hash(state);
    }
}

impl PartialEq for TypeKey {
    fn eq(&self, other: &Self) -> bool {
        self.0 == other.0
    }
}

impl Eq for TypeKey {}

impl Debug for TypeKey {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        write!(f, "{}", self.1)
    }
}

Now we can replace our use of TypeId with TypeKey in the extension map and our debug output looks like this instead:

[src/main.rs:90] &extensions = Extensions {
    map: RefCell {
        value: {
            i32: 42,
            alloc::vec::Vec<i32>: [
                1,
                2,
                3,
            ],
        },
    },
}

Note that i additionally inserted a Vec<i32> into the map to get some more extra output.

January 07, 2022 12:00 AM UTC

January 06, 2022


Python for Beginners

Recursion In Python

You might have studied functions in python. You might also have used for loops and while loops to perform a task repetitively while programming in Python. In this article, we will discuss recursion and recursive functions in Python.

What Is Recursion?

Recursion is a mathematical concept in which we define something in terms of itself. 

For instance, we can define the sum of the first ten natural numbers as the sum of the first nine natural numbers added to the tenth number. 

Similarly, we can define the sum of the first nine natural numbers as the sum of the first eight natural numbers added to the ninth natural number.

Here, you can see that we are breaking the problem of the first ten natural numbers into smaller problems like finding the sum of the first 9 numbers, then finding the sum of the first 8 numbers, and so on. In this way, we will come to a position where we have to find the sum of the first natural number i.e. 1 itself. After that, we will have to perform only the atomic addition instead of worrying about the count of natural numbers we are finding the sum of. 

When To Use Recursion In Python?

As seen above, we can use recursion whenever we can break a problem into a similar but smaller problem.  The most common problems where we use recursion are:

  1. Binary tree traversal problems
  2. Finding the factorial of a number
  3. Tower of Hanoi problem
  4. Finding Fibonacci series

How To Use Recursion In Python?

In programming, if a function calls itself, we say that it is a recursive function i.e. it works on the concept of recursion. You can use recursion in python to implement the solution for any problem that can be reduced to a similar but smaller problem. 

For instance, let us try to find the sum of the first 10 natural numbers. For that, let us define a function sumOfNumbers() that receives an input number N and returns the sum of numbers from 1 to N.

We can implement the above algorithm as follows.

def sumOfNumbers(N):
    if N == 1:
        return N
    else:
        return N + sumOfNumbers(N - 1)


input_number = 10
output = sumOfNumbers(input_number)
print("Sum of first {} natural numbers is {}".format(input_number, output))
input_number = 20
output = sumOfNumbers(input_number)
print("Sum of first {} natural numbers is {}".format(input_number, output))

Output:

Sum of first 10 natural numbers is 55
Sum of first 20 natural numbers is 210

While using recursion, we must specify the base case. Otherwise, the program will continue its execution continuously and run into RecursionError. This is due to the fact that the maximum number of recursive calls a function can make is capped at 1000 in Python. If any function makes more than 1000 recursive calls, a RecursionError exception will occur.

Conclusion

In this article, we have discussed recursion in python. We have also implemented a program to find the sum of the first 10 natural numbers in Python. To learn more about functions, you can read this article on closures in python.

The post Recursion In Python appeared first on PythonForBeginners.com.

January 06, 2022 02:10 PM UTC