Solution for long repeat on checkio

I figured I’d share my solution for Long Repeat on Checkio. I got up this morning and had a few moments to solve. Did some research and found the groupby method from Itertools… there was an example online on how to use so I drew largely from that.

from itertools import groupby


def long_repeat(line):
    try:
        groups = groupby(line)
        result = [(k, sum(1 for _ in v)) for k, v in groups]
        occ = []
        for _ in result:
            k, v = _
            occ.append(v)
        return max(occ)
    except:
        return 0


if __name__ == '__main__':
    # These "asserts" using only for self-checking and not necessary for auto-testing
    assert long_repeat('sdsffffse') == 4, "First"
    assert long_repeat('ddvvrwwwrggg') == 3, "Second"
    assert long_repeat("") == 0
    assert long_repeat("abababaab") == 2
    print('"Run" is good. How is "Check"?')

MongoDB, standard library, considering rolling my own blog again…

As you well know, I started out rolling my own blog and couldn’t finish due to being an extreme n00b. Now that I’ve made fairly significant progress with my FlaskCasts site I am slightly considering transferring all of this over to a strictly Python blog….but….IDK. We will see.

I got hung up on a couple of things tonight trying to get my flask casts site up off of the ground. First off I really got hung up on name vs id in my form fields. Apparently Flasks Request isn’t too fond of having both a name and an ID…and playing around with Bootstrap the ID tag was automatically placed so I was stuck for several minutes…about an hour..kind of sucked. Again…SOMETHING SMALL! But…I just wrote about it…so all the while I kept telling myself IT HAS TO BE SOMETHING SMALL AND STUPID….ALWAYS IS.

    @staticmethod
    def update(post_id, title, content):
        mongo.db.posts.update({'_id': post_id}, {'$set': {"title": title, "content": content}})

Then I ran into an issue trying to update by post…I forgot the $set (loss for a word here) and ran into some issues…luckily solved em all.

Next up…the create method. This one will be a little tricky because Ive designed the site to show posts by the slug for SEO reasons…so I won’t be able to have duplicate slugs in the database. The slugs are generated with the object/Post itself based on the title….however…I’m leaving myself the option of changing the title/content if need be. This is a simple site so…a lot of common functionality really isn’t required but its fun to think through the possibilities.

 

Lets do some Checkio…

30 minutes later

 

and it beat me…lol

 

working on it,…..

 

Preparing for the future…

Basically all I am doing is focusing on my future, by learning new skills in the present. It’s easy to get sidetracked and think of new and interesting ideas, but staying focused is the key. One of the things I have been doing is browsing Upwork projects to see what people are looking for in developers/projects. I figure if I can sift through the postings and do my best to learn as much as I can about the technologies people are paying for, my chances of being successful when I am ready to bid. When will that be? I plan on trying to roll out several of my own projects as portfolio pieces and build up a solid amount of content and once I can find a project that I am 100% confident I can fit into my schedule and accomplish I will bid. My goal is 1 year.

I’ve also had a few mobile app ideas float through my head, so learning about REST-ful API’s is on the agenda in the coming months.

As far as my FlaskCasts site…I made a few minor adjustments today. Found a couple of minor bugs I need to work out once I get a minute. Plan to work on it quite a bit tomorrow evening.

Thanks for reading!

Learn by doing

It has become clear to me that the best way to learn something new is by getting your hands dirty and working on something. You can follow tutorials and watch someone else code a project, and follow along. You will definitely learn concepts, but the best way to learn this stuff is by tackling something on your own.  What kind of project should I build? You might ask.

I guarantee there is something that you have always thought would be a cool app or idea…even if it is something really small and trivial. Perhaps you just want a basic blog…which is what I am working on with FlaskCasts.

Today I worked out some login functionality using some of the concepts and methodology I picked up from a Udemy course I just took. This kept me from having to use some sort of extension that may provide way more functionality than I need. This also forced me to get my hands dirty and work out little bugs in the code as they came up.

Little bugs can be very frustrating and can somethings be disheartening. You should keep this in mind, from my experience 99% of the bugs you spend a ton of time on are so trivial that when you find them you feel stupid. One thing is for certain, you will likely remember that mistake going forward and will develop your code in such that you will not make the same mistake again. This might be new habits, or a change in the way you think about things….which the latter is most powerful.

For instance today I kept getting a 404 error on my login form…I couldn’t find the reason for the error…I realized that flasks request.form[‘variable’] is looking for the name=”variable” attribute in the form…not id=”variable”….stupid mistake, but I learned something new and will remember this going forward.  A lot of times it’s just small stuff like this that you learn from and in the end will make you a better developer.

Checkio

I tinkered with the site a little here and there but nothing ground breaking today. I am just slowly piecing it together and hope to release: 9/6/17 with a couple of videos.

I love py.checkio.org, it’s a cool  site that provides you with puzzles to solve in Python. Great learning tool. I embarked on The Angles of a Triangle today. https://py.checkio.org/mission/triangle-angles/

Never was all that great at trig but I love learning python so I tackled this one. Had help from this site: https://www.mathsisfun.com/algebra/trig-solving-sss-triangles.html

And a library I found called Triangle Solver… https://pypi.python.org/pypi/trianglesolver 

Checkio doesn’t support external packages but I was able to dig through the code and pull out what I needed to solve this one.  Here is my solution:

from math import pi, acos


def sss(a,b,c):
    degree = pi / 180
    assert a + b > c and b + c > a and c + a > b
    A = acos((b**2 + c**2 - a**2) / (2 * b * c))
    B = acos((c**2 + a**2 - b**2) / (2 * c * a))
    C = 180 - (A/degree) - (B/degree)
    return A/degree, B/degree, C


def checkio(a, b, c):
    try:
        A, B, C = sss(a, b, c)
        result = [
            round(A),
            round(B),
            round(C)]
        return sorted(result)
    except:
        return [0, 0, 0]


#These "asserts" using only for self-checking and not necessary for auto-testing
if __name__ == '__main__':
    assert checkio(4, 4, 4) == [60, 60, 60], "All sides are equal"
    assert checkio(3, 4, 5) == [37, 53, 90], "Egyptian triangle"
    assert checkio(2, 2, 5) == [0, 0, 0], "It's can not be a triangle"
    assert checkio(5, 4, 3) == [37, 53, 90]

Slugify

Today while working on the flask casts site, I decided it would be a good idea to generate a url slug. This is extremely important for search engine optimization. I thought about writing my own class to do this, then thought it might get ugly…so I searched for a package. I found Slugify: https://github.com/un33k/python-slugify

Pretty simple to use. When creating the Post object I just modified my __init__ to the following:

    def __init__(self, title, content, author, created=None):
        self.title = title
        self.slug = slugify(title)
        self.content = content
        self.author = author
        self.created = datetime.datetime.utcnow().strftime('%A %x @ %H:%M:%S') \
            if created is None else created

Now I can pass the slug to a url like: flaskcasts.com/post/this-is-the-post-title

@home.route('/post/<string:slug>')
def post(slug):
    post = Post.get_post(slug)
    author = User.get_user(post['author'])
    return render_template('home/post.html', post=post, author=author['fullname'])

Thanks for reading!

Pagination

So the concept escaped me for a couple of days. I actually had considered abandoning my MongoDB trials in favor of a SQL based system. What I discovered was that I am more persistent in finding a solution to my problem than I originally thought. I stumbled upon this Gist: https://gist.github.com/wonderb0lt/10645080

This is a very simple and basic Pagination class written for MongoEngine. Flask already has an extension for MongoEngine with this already built in. After looking at the code I realized all this is doing is passing an iterable to the Pagination class and then building links in the template. So I decided I would type it out line by line so I could get a better grasp on what was happening in the code.

So now I have Flask-PyMongo communicating with my database and was able to build the models in such a way that makes more sense to me at this stage of my learning.

For instance, my Post model looks like this:

class Post(object):


    def __init__(self, title, content, author, created=None):
        self.title = title
        self.content = content
        self.author = author
        self.created = datetime.datetime.utcnow().strftime('%A %x @ %H:%M:%S') \
            if created is None else created

    def __repr__(self):
        return "<Post {}>".format(self.title)

    def json(self):
        return {
            "title": self.title,
            "content": self.content,
            "author": self.author,
            "created": self.created
        }

    def save(self):
        mongo.db.posts.update({'title': self.title}, self.json(), upsert=True)

MongoEngine allows reference fields so you can actually store the author object in the post document…which is kind of cool becuase you could do something like this from the template post.author.full_name. So I was a little stuck on trying to find a way to do this using PyMongo until I read this post: https://docs.mongodb.com/manual/tutorial/model-referenced-one-to-many-relationships-between-documents/

It explains a more efficient way of doing this. In my case I am referencing the user by the author variable, so I have set my User class up so that _id is a unique username and will reference the user by the username.

See the User class:

class User(object):

    def __init__(self, _id, email, password, fullname):
        self._id = _id # username, unique
        self.email = email
        self.password = password
        self.fullname = fullname

    def __repr__(self):
        return "<User {}>".format(self.fullname)

    def json(self):
        return {
            "_id": self._id,
            "email": self.email,
            "password": self.password,
            "fullname": self.fullname
        }

    @staticmethod
    def get_user(user_id):
        return mongo.db.users.find_one({"_id": user_id})

    def save(self):
        mongo.db.users.update({"_id": self._id}, self.json(), upsert=True)

So using the get_user() method I can get the fullname…

LEARNING A LOT! and having a lot of fun!

Also found this library…for generating fake data…VERY useful http://mimesis.readthedocs.io/en/latest/

Change of plans…sort of…kind of…

I am currently reconsidering my options as far as the database for FlaskCasts. As a newbie to Flask and Python, I am starting to see that MongoDB may be more challenging to use than I had initially thought. However, I’m not one to give up so soon. A couple of things I am confused about stand out:

  1. Implementing Pagination for the list of videos on the front page.
  2. Sorting those in descending order.

Coming from an SQL background this isn’t so complicated and in fact a lot of the SQLAlchemy based libraries have a pagination method built in.

Right now I am looking at the Flask-PyMongo extension to see if this will make things any easier. So far I have used plain PyMongo (on my blog attempt I mentioned earlier) and wrote a lot of the DB methods myself. I’ve already came across YouTube videos showing how to sort with this library so I think I may be able to use this and roll my own pagination.

After a little more research, I found Flask-MongoEngine. With just a little tinkering I was able to implement a very basic pagination. So I am pretty happy with that. This library seems to be well supported so I may just stick with this.

from flask import Flask, request, Blueprint, render_template
from flask_mongoengine import *
from .models import Post

app = Flask(__name__)
app.config.from_object('config')
db = MongoEngine(app)

@app.route('/')
def hello_world():
    page = int(request.args.get('page') or 1)
    posts = Post.objects.order_by('-created')
    paginated_posts = Pagination(posts, page=page, per_page=2)
    return render_template('index.html', paginated_posts=paginated_posts)

This is my view. Basically it checks to see if a page variable is being passed through. Gets the posts in descending order. Passes the posts to the Pagination class that is built in with the current page and showing only 2 entries per page. Then it renders the template with the paginated_posts.

{% for post in paginated_posts.items %}
    <h2>{{ post.title }}</h2>
    <p>{{ post.content }}</p>
    <p>Posted by: {{ post.author.fullname }}</p>
{% endfor %}

{# Macro for creating navigation links #}
{% macro render_navigation(pagination, endpoint) %}
  <div class=pagination>
  {% for page in pagination.iter_pages() %}
    {% if page %}
      {% if page != pagination.page %}
        <a href="{{ url_for(endpoint, page=page) }}">{{ page }}</a>
      {% else %}
        <strong>{{ page }}</strong>
      {% endif %}
    {% else %}
      <span class=ellipsis>…</span>
    {% endif %}
  {% endfor %}
  </div>
{% endmacro %}

{{ render_navigation(paginated_posts, 'hello_world') }}

I’d never really messed wtih a Macro in Jinja before this so I need to do a little more studying to get a grasp on what is happening here.  But…it works, and is much easier to roll out than anything else I think I could have done.

The models are a bit confusing as these classes inherit from the Document class…and I have not yet worked with anything like this, I’ve written my own classes. I am going to play around with the concepts a little more to get confortable. Here is what they look like right now:

import datetime
from mongoengine import *


class User(Document):
    email = EmailField()
    password = StringField()
    fullname = StringField()


class Post(Document):
    title = StringField()
    content = StringField()
    author = ReferenceField(User)
    created = DateTimeField(datetime.datetime.now)

Going to work on this some more tomorrow. Very happy to have solved this pagination issue however.

 

Flask application structure…

One of the beautiful things about Flask is the freedom to do whatever the hell you want. Unfortunately, for me as a novice, this can be a huge disadvantage at the same time. Not knowing all of the best practices can cause some unnecessary headache. Lucky for me there are a lot of blog entries out there to help get this off the ground.

Blueprints is a flask feature that allows you to organize your app in a modular way. Each “section” will act almost as if it is it’s own application. I took a screenshot of my current directory structure to show you what it looks like. So the project itself would be considered a repository,

and will end up on github at some point as I make more solid plans.

Right now I just wanted to get something running even if it is technically just a simple and basic “Hello World.”

Currently the run.py file contains:

from flaskcasts import app

app.run(debug=app.config['DEBUG'])

When ran, it then goes to the flaskcasts directory since it is a module and runs the code in __init__.py:

from flask import Flask

app = Flask(__name__)

app.config.from_object('config')

from .views.home import home
app.register_blueprint(home)

This will go to the home blueprint and execute that code:

from flask import Blueprint

home = Blueprint('home', __name__)

@home.route('/')
def index():
    return "Welcome to the Index"

The only other file is config.py and it basically holds the DEBUG=True boolean only.

 

Structurally, for a very basic application that is only going to feed videos from a YouTube or similar service, this should suffice.

The one thing…

Had a long drive for work today. I usually listen to a lot of different podcasts on various topics. Lately my favorites are “Talk Python to Me” and the like… I listened “The SaaS podcast” because one of my goals from learning to code in Python is to develop a product, release it, and start earning supplemental income. Podcasts are great because not only will you learn things and absorb a lot of data, you find inspiration. The host kept talking about the book “The One Thing” by Gary Keller. Since I had 3 credits on Audible, I decided, why not! So far it is a GREAT book.

The main idea is to pick 1 thing, and focus on it with everything you have. Build habits by struggling with the difficulties of doing that 1 thing for 66 days on average and it becomes easy. So, I asked myself. What is the one thing that I can do today that will propel me toward my goal of becoming a successful freelancer and entrepreneur? The answer that came to mind is, Blog about coding and code. Talk about the things I am learning in a blog post and share with the world. Set aside some time to document, almost in a diary like format the things that I am working on and learning.

This will propel me in my coding career because the habit of blogging will force me to find things to write about. The process of finding things to write about will help me to learn new concepts and force me to produce code to share. Even on days when my normal job has sucked out all of my energy and I just don’t have it in me to write a line of code, I can talk about ways to find inspiration. I can talk about the feeling that comes from building something that works and solves a problem for someone. I can think about how satisfying it is to finally solve a bug in my code.

So, this is my blog. I am going to update this site regularly with information that will build confidence and keep me on track to success. I plan to work on some tutorials tomorrow and will write about my thoughts.