nickcreel / hatsunem.icu Goto Github PK
View Code? Open in Web Editor NEWFlask-based website that loads a random Youtube video featuring virtual diva Hatsune Miku.
Home Page: http://www.hatsunem.icu/
License: MIT License
Flask-based website that loads a random Youtube video featuring virtual diva Hatsune Miku.
Home Page: http://www.hatsunem.icu/
License: MIT License
So here is some feedback on the repo, as requested:
All in all, it runs, and is readable, so thats better great. But there are a few improvements I would recommend making. If just to familiarize yourself with these parts of python.
I'll break it into a few things:
I would remove the pycache and DS_Store files from the repo, as those are local references to your system and dont serve any purpose to me other the making me thting its only meant for you to run or you forgot a .gitignore
file.
Just nix the ./__pycache__
and ./templates/.DS_Store
stuff and make a .gitignore
for the repo. Here is a good template to cover most junky files you dont want in a repo: https://github.com/python/mypy/blob/master/.gitignore
I'll mention this in the other repos, but is a problem there too. Their ignore lists will be different though.
To the base pip/venv/setup.py stuff is fine, but a lot of python houses like more formal package/env managers (though some really prefer this style of packaging). If you want, I would look into poetry
(stay a mile away from pipenv
). It will handle most of the root level project files and also give you a .lock
file for reproducible builds. Which is nice.
I would also make sure you're using something like pyenv
to manage your python versions, cause that helps with this package business.
The single-file-server is totally fine given the services size, but some of the commenting is a little oddly formatted.
A good rule of thtumb for comments in python are:
def foo(x)
""" This is for a person interfacing with the code.
"""
... # This is for maintainers of the code it is commenting on.
The triple-# thing feels like a racket
comment idiom to me. In python, an inline is to describe implementation
details vs a comment block which is to tell people who are using the code how to use it. Your comments bridge both. Also comments should match the indentation of the code thet are commenting to help connect its context.
I would also look into comment style linters.
The comment style just helps keep things consistent. You can use any of the major styles, but I would recommend googles.
But you can automate a lot of these these comment things with stuff like pylint.
Modern python has type annotations! I promise they make your life saner.
They are enforced by an external tool called mypy.
Lets take some un-annotated code:
def make_manifest_from_user(user_record, action=None, allow_empty_fields=True):
has_empty = len(user_record.values()) == len([val for val in user_record.values() if val ])
if has_empty and not allow_empty_fields:
raise RuntimeError(f'Empty values in user_record: {user_record}')
action_requested = action.get('action_requested')
return {
'user': user_record,
'action_requested': action_requested
}
Now if you needed to use this, you might be able to figure out what args are needed to work,
But some lines are rough. The action_requested = action.get('action_requested')
in particular. What is that value?
Lets redo it with annotations:
import typing as T
def make_manifest_from_user(
user_record: T.Dict[str, T.Any],
action: T.Dict[str, str]=None,
allow_empty_fields: bool = True
) -> T.Dict[str, T.Union[T.Dict, str]]:
has_empty: bool = len(user_record.values()) == len([val for val in user_record.values() if val])
if has_empty and not allow_empty_fields:
raise RuntimeError(f'Empty values in user_record: {user_record}')
action_requested: str = action.get('action_requested')
return {
'user': user_record,
'action_requested': action_requested
}
Now thats more complicated looking, but we have type info so there is some heads up about what values code is expected to handle. It also allows mypy
to catch type errors in your code, which has saved me a few times.
This segment of code is a little weird:
api_service_name = "youtube"
api_version = "v3"
DEVELOPER_KEY = #<insert developer key here>
That is, I suspect, something you are suppose to set manually before running. Which is fine, I have a lot of code that works that way. But there is also a better pattern: Singletons. Singletons are like objects, but there are only ever one of them.
So they can be used as stores for centralized data. Python doesnt have a lot of good way to handle them, but there are a few.
In particular, the feature dataclasses
.
They do most of the singleton work for you (though not all of it). I would recommend using a small wrapper to
help with configuration of code via data classes using this library: https://github.com/sandal-tan/pyenvclasses
Its from a coworker of mine.
It lets you write classes with attributes and, if there isnt a default assigned, if will look in your bash profile for
bash variables using the same name to populate the value.
for example:
$ export my_var='oh, hi!'
$python
Python 3.8.2 (default, Apr 15 2020, 17:12:22)
[Clang 11.0.0 (clang-1100.0.33.17)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import typing as T
>>> from envclasses import EnvClassMeta
>>>
>>> class MyEnv(metaclass=EnvClassMeta):
>>> my_var: str
>>>
>>> ENV = MyEnv()
>>> print(ENV.my_var)
'oh, hi!'
This might feel like a lot of stuff, but its mostly cause I am approaching this as a normal PR from my coworkers.
Its rad, and it works, and thats 90% of what matters.
This is nearly all stuff I learned after I got a job.
If you have any questions, I am more than happy to dig in further.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.