Forum Archive

Help! I need help thinking of python projects I can do.

Bumbo Cactoni

Help! I need help thinking of python projects I can do. I’m not very good at thinking of projects. I’m not looking for super advanced projects. Like, beginner-ish projects to help me learn more python. Don’t suggest, like, a web scraper or something like that. I’ve already done rock, paper, scissors; guess the number; calculator; dice; and flip the coin. Any other ideas?

mikael

@Bumbo-Cactoni, googling ”beginner Python projects” gave me quite a few good-looking hits, hangman game etc.

If you find something you like, but are concerned whether it would be doable on Pythonista, we will be happy to help.

stephen

@Bumbo-Cactoni
i just posted Space Escape

you could use this to understand Scene more and create somthing from there? or even add to it. im going to start a new project of a game that will let you set tasks and give experience acordingly with rewards. mostly for kids and to help motivate doing stuff like chores.

i alo have a RPG Template in the works.this is a more long term project but i hope to get it done soon lol

Bumbo Cactoni

Thank you!

robStacks

Hi maybe you can help me with this one?
I am trying to put together a tactical kneepad tool for virtual fighter pilots.
It helps with situational awareness concrening bullseye BRAA calls in game.
This is what i got so far and should work out of the box so you can check it out:

import matplotlib.pyplot as plt
import numpy as np
import math

class Vector (list):
    ''' Simple 2D vector class to make vector operations more convenient. If
    performance is a concern, you are probably better off looking at numpy.
    Supports the following operations:
    * Initialization from two arguments, two keyword  arguments (`x` and `y`),
    tuple, list, or another Vector.
    * Equality and unequality comparisons to other vectors. For floating point
    numbers, equality tolerance is 1e-10.
    * `abs`, `int` and `round`
    * Addition and in-place addition
    * Subtraction
    * Multiplication and division by a scalar
    * `len`, which is the same as `magnitude`, see below.
    Sample usage:
        v = Vector(x = 1, y = 2)
        v2 = Vector(3, 4)
        v += v2
        assert str(v) == '[4, 6]'
        assert v / 2.0 == Vector(2, 3)
        assert v * 0.1 == Vector(0.4, 0.6)
        assert v.distance_to(v2) == math.sqrt(1+4)
        v3 = Vector(Vector(1, 2) - Vector(2, 0)) # -1.0, 2.0
        v3.magnitude *= 2
        assert v3 == [-2, 4]
        v3.radians = math.pi # 180 degrees
        v3.magnitude = 2
        assert v3 == [-2, 0]
        v3.degrees = -90
        assert v3 == [0, -2]
    '''

    abs_tol = 1e-10

    def __init__(self, *args, **kwargs):
        x = kwargs.pop('x', None)
        y = kwargs.pop('y', None)

        if x and y:
            self.append(x)
            self.append(y)
        elif len(args) == 2:
            self.append(args[0])
            self.append(args[1])
        else:
            super().__init__(*args, **kwargs)

    @property
    def x(self):
        ''' x component of the vector. '''
        return self[0]

    @x.setter
    def x(self, value):
        self[0] = value

    @property
    def y(self):
        ''' y component of the vector. '''
        return self[1]

    @y.setter
    def y(self, value):
        self[1] = value

    def __eq__(self, other):
        return math.isclose(self[0], other[0], abs_tol=self.abs_tol) and math.isclose(self[1], other[1], abs_tol=self.abs_tol)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __abs__(self):
        return type(self)(abs(self.x), abs(self.y))

    def __int__(self):
        return type(self)(int(self.x), int(self.y))

    def __add__(self, other):
        return type(self)(self.x + other.x, self.y + other.y)

    def __iadd__(self, other):
        self.x += other.x
        self.y += other.y
        return self

    def __sub__(self, other):
        return type(self)(self.x - other.x, self.y - other.y)

    def __mul__(self, other):
        return type(self)(self.x * other, self.y * other)

    def __truediv__(self, other):
        return type(self)(self.x / other, self.y / other)

    def __len__(self):
        return self.magnitude

    def __round__(self):
        return type(self)(round(self.x), round(self.y))

    def dot_product(self, other):
        ''' Sum of multiplying x and y components with the x and y components of another vector. '''
        return self.x * other.x + self.y * other.y

    def distance_to(self, other):
        ''' Linear distance between this vector and another. '''
        return (Vector(other) - self).magnitude

    @property
    def magnitude(self):
        ''' Length of the vector, or distance from (0,0) to (x,y). '''
        return math.hypot(self.x, self.y)

    @magnitude.setter
    def magnitude(self, m):
        r = self.radians
        self.polar(r, m)

    @property
    def radians(self):
        ''' Angle between the positive x axis and this vector, in radians. '''
        #return round(math.atan2(self.y, self.x), 10)
        return math.atan2(self.y, self.x)

    @radians.setter
    def radians(self, r):
        m = self.magnitude
        self.polar(r, m)

    def polar(self, r, m):
        ''' Set vector in polar coordinates. `r` is the angle in radians, `m` is vector magnitude or "length". '''
        self.y = math.sin(r) * m
        self.x = math.cos(r) * m

    @property
    def degrees(self):
        ''' Angle between the positive x axis and this vector, in degrees. '''
        return math.degrees(self.radians)

    @degrees.setter
    def degrees(self, d):
        self.radians = math.radians(d)

    def steps_to(self, other, step_magnitude=1.0):
        """ Generator that returns points on the line between this and the other point, with each step separated by `step_magnitude`. Does not include the starting point. """
        if self == other:
            yield other
        else:
            step_vector = other - self
            steps = math.floor(step_vector.magnitude/step_magnitude)
            step_vector.magnitude = step_magnitude
            current_position = Vector(self)
            for _ in range(steps):
                current_position += step_vector
                yield Vector(current_position)
            if current_position != other:
                yield other

    def rounded_steps_to(self, other, step_magnitude=1.0):
        ''' As `steps_to`, but returns points rounded to the nearest integer. '''
        for step in self.steps_to(other):
            yield round(step)

bearingblue = int(input("Bearing blue:"))
rangeblue = int(input("Range blue:"))

bearingred = int(input("Bearing red:"))
rangered = int(input("Range red:"))

blue = Vector(rangeblue, 0)
blue.degrees = bearingblue

red = Vector(rangered, 0)
red.degrees = bearingred

delta = red - blue

print('Distance:', delta.magnitude)
print('Bearing:', delta.degrees)

thetablue= np.deg2rad(bearingblue)
thetared= np.deg2rad(bearingred)

fig = plt.figure()

ax = fig.add_subplot(111, projection='polar')

ax.scatter(thetablue,rangeblue)
ax.scatter(thetared,rangered, color='r')

ax.set_theta_direction(-1)
"""ax.set_rmax(120)"""
ax.set_theta_zero_location('N')
ax.set_title("Plot", va='bottom')

plt.show()

What i want to do next is integrate this into something like sketch.py demo.
To make it possible to draw things onto like flightpath & annotations etc.
Also the feature of exporting as img is handy for recap and debriefing.

Take a look maybe you like this project.

Regards,

Robert.

Bumbo Cactoni

@robStacks
You want me to help?
I don’t know much Python, so I don’t think I’ll be able to help. Sorry. I am working on learning a lot more python, but right now I just don’t have the knowledge or experience to help. I wish I could help. Sorry. :(

stephen

@Bumbo-Cactoni that request has already be takin care of in another thread but helping others is the best way to learn 😉 you will research stuff and learn aspects you may never have or create new objects to put in your cook book. for example i created this ButtonNode and i probably wouldnof made one at some point but not as neat and propbably not so universal in a way. jump out there help people help you 🤠 community is about teamwork💯

robStacks

Ok no worries Bumbo i am also a beginner in python and it is a great code language.
Its easy to read and understand and with a great communitie very helpfull.
I managed to create something awesome and usefull in a short time thx to that.
I'll show you my progress so you can see:

import math
import ui
import console
import photos
import matplotlib.pyplot as plt
import numpy as np
from io import BytesIO

class Vector(list):
    abs_tol = 1e-10

    def __init__(self, *args, **kwargs):
        x = kwargs.pop('x', None)
        y = kwargs.pop('y', None)

        if x and y:
            self.append(x)
            self.append(y)
        elif len(args) == 2:
            self.append(args[0])
            self.append(args[1])
        else:
            super().__init__(*args, **kwargs)

    @property
    def x(self):
        ''' x component of the vector. '''
        return self[0]

    @x.setter
    def x(self, value):
        self[0] = value

    @property
    def y(self):
        ''' y component of the vector. '''
        return self[1]

    @y.setter
    def y(self, value):
        self[1] = value

    def __eq__(self, other):
        return math.isclose(
            self[0], other[0], abs_tol=self.abs_tol) and math.isclose(
                self[1], other[1], abs_tol=self.abs_tol)

    def __ne__(self, other):
        return not self.__eq__(other)

    def __abs__(self):
        return type(self)(abs(self.x), abs(self.y))

    def __int__(self):
        return type(self)(int(self.x), int(self.y))

    def __add__(self, other):
        return type(self)(self.x + other.x, self.y + other.y)

    def __iadd__(self, other):
        self.x += other.x
        self.y += other.y
        return self

    def __sub__(self, other):
        return type(self)(self.x - other.x, self.y - other.y)

    def __mul__(self, other):
        return type(self)(self.x * other, self.y * other)

    def __truediv__(self, other):
        return type(self)(self.x / other, self.y / other)

    def __len__(self):
        return self.magnitude

    def __round__(self):
        return type(self)(round(self.x), round(self.y))

    def dot_product(self, other):
        ''' Sum of multiplying x and y components with the x and y components of another vector. '''
        return self.x * other.x + self.y * other.y

    def distance_to(self, other):
        ''' Linear distance between this vector and another. '''
        return (Vector(other) - self).magnitude

    @property
    def magnitude(self):
        ''' Length of the vector, or distance from (0,0) to (x,y). '''
        return math.hypot(self.x, self.y)

    @magnitude.setter
    def magnitude(self, m):
        r = self.radians
        self.polar(r, m)

    @property
    def radians(self):
        ''' Angle between the positive x axis and this vector, in radians. '''
        #return round(math.atan2(self.y, self.x), 10)
        return math.atan2(self.y, self.x)

    @radians.setter
    def radians(self, r):
        m = self.magnitude
        self.polar(r, m)

    def polar(self, r, m):
        ''' Set vector in polar coordinates. `r` is the angle in radians, `m` is vector magnitude or "length". '''
        self.y = math.sin(r) * m
        self.x = math.cos(r) * m

    @property
    def degrees(self):
        ''' Angle between the positive x axis and this vector, in degrees. '''
        return math.degrees(self.radians)

    @degrees.setter
    def degrees(self, d):
        self.radians = math.radians(d)

    def steps_to(self, other, step_magnitude=1.0):
        """ Generator that returns points on the line between this and the other point, with each step separated by `step_magnitude`. Does not include the starting point. """
        if self == other:
            yield other
        else:
            step_vector = other - self
            steps = math.floor(step_vector.magnitude / step_magnitude)
            step_vector.magnitude = step_magnitude
            current_position = Vector(self)
            for _ in range(steps):
                current_position += step_vector
                yield Vector(current_position)
            if current_position != other:
                yield other

    def rounded_steps_to(self, other, step_magnitude=1.0):
        ''' As `steps_to`, but returns points rounded to the nearest integer. '''
        for step in self.steps_to(other):
            yield round(step)

bearingblue = int(input("Bearing blue: "))
rangeblue = int(input("Range blue:   "))

bearingred = int(input("Bearing red:  "))
rangered = int(input("Range red:    "))

blue = Vector(rangeblue, 0)
blue.degrees = bearingblue

red = Vector(rangered, 0)
red.degrees = bearingred

delta = red - blue

way = np.loadtxt('waypoints.txt')
ways = way[:, 0]
r = way[:, 1]

if delta.degrees < 0:
    print('Bearing: ', int(delta.degrees + 360))
    print('Distance:', int(delta.magnitude))
else:
    print('Bearing: ', int(delta.degrees))
    print('Distance:', int(delta.magnitude))

thetablue= np.deg2rad(bearingblue)
thetared= np.deg2rad(bearingred)
thetawayp= np.deg2rad(ways)

class PathView(ui.View):
    def __init__(self, frame):
        self.frame = frame
        self.flex = 'WH'
        self.path = None
        self.action = None

    def touch_began(self, touch):
        x, y = touch.location
        self.path = ui.Path()
        self.path.line_width = 1
        self.path.line_join_style = ui.LINE_JOIN_ROUND
        self.path.line_cap_style = ui.LINE_CAP_ROUND
        self.path.move_to(x, y)

    def touch_moved(self, touch):
        x, y = touch.location
        self.path.line_to(x, y)
        self.set_needs_display()

    def touch_ended(self, touch):
        # Send the current path to the SketchView:
        if callable(self.action):
            self.action(self)
        # Clear the view (the path has now been rendered
        # into the SketchView's image view):
        self.path = None
        self.set_needs_display()

    def draw(self):
        if self.path:
            self.path.stroke()

ax = plt.subplot(111, projection='polar')
plt.polar(thetawayp, r)
plt.polar(thetawayp, r, 'k.', zorder=3)
ax.scatter(thetablue,rangeblue)
ax.scatter(thetared,rangered, color='r')
ax.set_theta_direction(-1)
ax.set_rmax(120)
ax.set_theta_zero_location('N')
ax.set_title("N ", va='bottom')
ax.grid(True)
b = BytesIO()

plt.savefig(b)


class SketchView(ui.View):
    def __init__(self, width=768, height=768):
        self.bg_color = '#ffffff'
        iv = ui.ImageView(frame=(0, 0, width, height))
        bg = ui.Image.from_data(b.getvalue())
        iv.image = bg
        iv.content_mode = ui.CONTENT_SCALE_ASPECT_FILL
        image_view = ui.ImageView()
        image_view.image = ui.Image.named('Bullseye.png')
        image_view.present()
        pv = PathView(frame=self.bounds)
        pv.action = self.path_action
        self.add_subview(iv)
        self.add_subview(pv)
        blue_button = ui.ButtonItem()
        blue_button.title = 'Bluebulls'
        blue_button.action = self.bluebulls_action
        red_button = ui.ButtonItem()
        red_button.title = 'Redbulls'
        red_button.tint_color = '#990000'
        red_button.action = self.redbulls_action 
        maps_button = ui.ButtonItem()
        maps_button.title = 'Maps'
        maps_button.tint_color = '#000d99'
        maps_button.action = self.map_action
        save_button = ui.ButtonItem()
        save_button.title = 'Save Image'
        save_button.action = self.save_action
        plot_button = ui.ButtonItem()
        plot_button.title = 'Plot'
        plot_button.tint_color = '#000d99'
        plot_button.action = self.plot_action
        clear_button = ui.ButtonItem()
        clear_button.title = 'Clear'
        clear_button.tint_color = '#af0000'
        clear_button.action = self.clear_action
        self.right_button_items = [save_button, plot_button, red_button]
        self.left_button_items = [clear_button, maps_button, blue_button]
        self.image_view = iv


    def map_action(self, sender):
# Show an image picker dialog (allowing multiple selection) and print the result
        assets = photos.pick_asset(title='Pick a Map', multi=True)


    def path_action(self, sender):
        path = sender.path
        old_img = self.image_view.image
        width, height = 768, 768

        with ui.ImageContext(width, height) as ctx:
            if old_img:
                old_img.draw()
            path.stroke()
            self.image_view.image = ctx.get_image()

    def redbulls_action(self, sender):
        m=1
    def bluebulls_action(self, sender):
        m=1
    def plot_action(self, sender):
        self.image_view.image = ui.Image.from_data(b.getvalue())

    def clear_action(self, sender):
        self.image_view.image = None

    def save_action(self, sender):
        if self.image_view.image:
            # We draw a new image here, so that it has the current
            # orientation (the canvas is quadratic).
            with ui.ImageContext(self.width, self.height) as ctx:
                self.image_view.image.draw()
                img = ctx.get_image()
                photos.save_image(img)
                console.hud_alert('Saved')
        else:
            console.hud_alert('No Image', 'error')


sv = SketchView()
sv.name = 'BullseyePad'
sv.present()

Its starting to look like an useable app already👍🏻

I am looking into API's right Now not so hard to use and lots of them look it up.
Maybe you can find a nice project for u with the use of API's

Goodluck finding a Nice project!

Bumbo Cactoni

Thank you!
Also, I kinda have a slightly random question. What is your favorite app or website to learn python on? I use SoloLearn right now, since it’s free.

mikael

@robStacks, suggest moving the Vector implementation to a file called vector.py in site-packages. Then you can import it and it does not distract you from your own code.

robStacks

@mikael Yes thx for pointing that out to me did so and is so much better👍🏻

Bumbo Cactoni

Yay! I’ve thought of a good project to do! Hopefully it won’t be too complicated... by the way, does anyone know how to display a picture? I’ve tried googling it, but it’s all a load of mumbo jumbo to me.

stephen

@Bumbo-Cactoni

Using Image Module:

import Image

with Image.open('my_img.png') as img:
    img.show()

Using ui Module:

import ui

class MyView(ui.View):
    def __init__(self, *args, **kwargs):
        self.img = ui.Image.named('my_img.png')
        self.iv = ui.ImageView(
            image=self.img,
            width=ui.get_screen_size()[0],
            height=ui.get_screen_size()[1])
        self.add_subview(self.iv)

MyView().present('fullscreen')

Using scene Module:

import scene

class MyScene(scene.Scene):
    def setup(self):
        self.sn=scene.SpriteNode(
            texture=scene.Texture('my_img.png'),
            parent=self,
            position=self.size/2)

scene.run(MyScene())
Bumbo Cactoni

@stephen
Thank you!

stephen

@Bumbo-Cactoni Your Welcome

Bumbo Cactoni

Now I have another question: How do you display a picture that you can move with your finger?

stephen

@Bumbo-Cactoni

😁 I like making these examples! Give me just a few.

Bumbo Cactoni

@stephen
Have you ever seen, like, those super simple block-programming apps? That they use to semi-teach people to program?

Bumbo Cactoni

I am trying to make my own block-programming thingy, but I don’t know how to create the blocks, make them movable, or even make them connect together.

stephen

@Bumbo-Cactoni

Like minecraft/terreria?

Bumbo Cactoni

@stephen

You mean like moving the items in the inventories?
If so, yes, that is kinda what I mean.

stephen

@Bumbo-Cactoni


from scene import *

def Dirt(parent, pos, size=(64, 64)):
    sn=SpriteNode(
        texture=Texture('plf:Ground_GrassCenter'),
        parent=parent,
        anchor_point=(0.0, 0.0),
        size=size,
        position=pos)
    return sn

def Stone(parent, pos, size=(64, 64)):
    sn=SpriteNode(
        texture=Texture('plf:Ground_DirtCenter'),
        parent=parent,
        anchor_point=(0.0, 0.0),
        size=size,
        position=pos)
    return sn

def fixed_position(x, fixed_val=64):
    return x - x%fixed_val

class MyScene(Scene):
    def setup(self):
        self.active_block=None
        self.anchor_point=(0.0, 0.0),
        self.dirt_button=Dirt(self, (self.size[0]/2-80, self.size[1]-196))
        self.stone_button=Stone(self, (self.size[0]/2+80, self.size[1]-196))



    def touch_began(self, touch):
        if touch.location in self.dirt_button.frame:
            self.active_block=Dirt(self, touch.location)
        if touch.location in self.stone_button.frame:
            self.active_block=Stone(self, touch.location)

    def touch_moved(self, touch):
        if self.active_block:
            self.active_block.position=touch.location


    def touch_ended(self, touch):
        x, y = self.active_block.position
        self.active_block.position=(fixed_position(x), fixed_position(y))
        self.active_block=None

run(MyScene())

Bumbo Cactoni

Thank you! I would not have been able to figure that out on my own.

Bumbo Cactoni

@stephen
Also, is there any way to set my own sprite/look for the objects? Like, make the dirt one look however I want it to?

ccc

texture=Texture('plf:Ground_DirtCenter') is what sets the look. Other textures (images) are available to you as discussed in the Pythonista docs You can access built-in images in Pythonista using the [+] button at the top of the editor.

stephen

@Bumbo-Cactoni said:

Thank you! I would not have been able to figure that out on my own.

no problem 😎 and im sure you would of got the hang of it. its only intimidating at first then once you get a couple projects done it goes smoothly.

@Bumbo-Cactoni said:

@stephen
Also, is there any way to set my own sprite/look for the objects? Like, make the dirt one look however I want it to?

just create a png jpg or tiff image, then import it and inside Texture() pass the string path or ui.Image for the one you made. keep in mind the balance of filesize to quality. and resizing if your going to use multiple coppies you want to change scale instead of size.

freindly tip:

Use a dict to cache your Texture for performance.


class MyScene(Scene):
    def setup(self):
        self.cache={"dirt":Texture('path/img1.png', "stone":Texture('path/img2.png'}

    def Dirt(self):
        node=SpriteNode(
            texture=self.cache['dirt'],
            parent=parent,
            anchor_point=(0.0, 0.0),
            size=size,
            position=pos)
        return node

instead of creating a new Texture each time

Drizzel

@Bumbo-Cactoni I'm a bit late to the party, but you could always check out Cambidge IGCSE Computer Science past papers. Just search for them in your favourite search engine. They provide beginner level excercises and solutions, since the exams are aimed at students with 2 years of coding experience.
Just be aware that for every year, there's one paper with a coding excercise (the one you want) and one paper with theory (boring).

I had to pass this exam in 2018, just as an example
There's more here.

Bumbo Cactoni

Thank you

donnybahama

@Bumbo-Cactoni
Can you think of something useful that you would use often? Even if it’s an app that you already have, you could write a clone from scratch. My first Python app will be an app that helps me with my small business (tracking and logging actions taken and status of individual jobs). It will automate/streamline a lot of the day-to-day stuff I do repetitively, help me stay organized, and prevent things from “slipping through the cracks”. I’m in the beginning phase, outlining the workflow and functionality. Once that’s done, I’ll do some screen mockups. Then...Pythonista time!

Bumbo Cactoni

@donnybahama
I have found something to set my mind on, which will actually be quite useful when finished. My 17 year-old brother has a self-run business where he uses his pickup to haul off people’s yard and house junk. I am currently designing a sort of calendar for him to schedule jobs. I know he could just use the calendar app, but I needed something to do. Anyways, I could also use some help with the scene module, as there are no instructions online, due to it being a pythonista-exclusive module.

mikael

@Bumbo-Cactoni, sounds like a cool project. I have yet to see a really good touch and visualization-friendly scheduling app on iOS.

For something like this, I would strongly recommend using the ui module instead of scene. On top of a
feeling based on years of using Pythonista, I base this recommendation on some real arguments:

  1. scene is meant for games.
  2. ui has built-in support for element level touch management and supporting stuff for e.g. gestures.
  3. ui is based on native iOS components in a way that is pretty well understood here. This means that if something does not work the way you want, it can most often be fixed or expanded with objc_util.
  4. I think you can tap into a broader set of experience in the forum.
Bumbo Cactoni

@mikael
Thanks for the suggestion! Also, do you happen to know how to use the ui module well? Just like scene, there are no tutorials online for me to follow.

mikael

@Bumbo-Cactoni, maybe, if you describe in broad terms what you want to make happen, we can start from there.

ccc

See ui-tutorial at https://github.com/Pythonista-Tools/Pythonista-Tools/blob/master/UI.md

Bumbo Cactoni

@ccc
Thanks for the link, and @mikael I don’t even know what I want to make happen. I’m probably going to read through some of the tutorial, so I can figure out something cool that would match the calendar I’m trying to design. I’ll get back to you in a lil bit.